Change Side Image Expressions [SOLVED]

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
User avatar
Windchimes
Veteran
Posts: 288
Joined: Fri Nov 27, 2015 9:02 am
Projects: Reanimation Scheme, Emberfate: Tempest of Elements
Organization: Wind Chimes Games
Contact:

Change Side Image Expressions [SOLVED]

#1 Post by Windchimes »

Hey everyone!

Sorry for the probably silly question. I'd really appreciate any help!

Okay, so basically, I've been using ConditionSwitch and LiveComposite for sprites up until now when I tried to switch over to LayeredImages instead. Following the documentation, I managed to set up the sprite and the side image with this:

Code: Select all

layeredimage test:
    group outfit auto
    group face auto

image side test = LayeredImageProxy("test", Transform(zoom=0.5))

define t = Character("Testing", image="test")
I decided to go with a permanent side image (rather than only when that char is speaking), so I added

Code: Select all

define config.side_image_tag = "test"
Everything works fine, and I can change expressions and stuff with say attributes

Code: Select all

t happy "I am now happy"
But my question is... is it possible to change the side image's expression without using say with image attribute? For example, as I said, the side image is always on screen, so I want her to react to what other characters are saying while she isn't talking, so I can't use a say with image attribute.

I tried doing a normal show line, but the problem is, the sprite also shows on screen like a normal sprite, so now there's two of the same character (one on the side, one at center of screen behind textbox) when I only want the side image to change.

Code: Select all

t happy "I am happy"
show test neutral
t "Now I'm neutral but there's two of me!"
If I use "show side test neutral" instead of just "show test neutral", it only shows the neutral sprite on screen while the side image stays unchanged.

Since I used to use LiveComposite and ConditionSwitch for sprites including the side sprite, I could change the side image's expressions with a $ variable any time I want, even if the character isn't talking. So I basically want to do that now but I'm not sure how without duplicating the sprite on screen. Is that possible? I'm assuming it is but I'm just missing a really obvious answer or doing something silly.

In any case, thanks for your patience, and I would be very grateful for any help!
Last edited by Windchimes on Wed Jul 18, 2018 1:55 am, edited 2 times in total.

philat
Eileen-Class Veteran
Posts: 1900
Joined: Wed Dec 04, 2013 12:33 pm
Contact:

Re: Change Side Image Expressions

#2 Post by philat »

Does spoofing it with

Code: Select all

t neutral "{nw}"
work? (I never use side images so I can't test.)

User avatar
Windchimes
Veteran
Posts: 288
Joined: Fri Nov 27, 2015 9:02 am
Projects: Reanimation Scheme, Emberfate: Tempest of Elements
Organization: Wind Chimes Games
Contact:

Re: Change Side Image Expressions

#3 Post by Windchimes »

That does actually work! I ended up having to go into history screen and add a line so that if the dialogue is only {nw} it doesn't show in history so that there won't be awkward empty lines messing up the spacing. Everything else does work now the way I want it to. Thank you!

chigaijin
Newbie
Posts: 3
Joined: Sun Mar 18, 2018 1:08 pm
Contact:

Re: Change Side Image Expressions [SOLVED]

#4 Post by chigaijin »

Necro-ing this thread because I wasn't satisfied with the solution here—it still shows a flicker where it draws the say screen for the "{nw}". Similar to Windchimes' situation, I'm using the side image for a POV character, and I really wanted to be able to show their reactions to things. I ended up dipping into a bit of Python for this, but it seems to be working:

Code: Select all

default pov_chara = None

init python:
    def set_pov(who):
        """
        Sets the current POV character to ``who``, which may be ``None``.
        Also clears any attributes.
        """
        assert((not who) or (who is ADVCharacter))
        store.pov_chara = who
        if who:
            config.side_image_tag = who.image_tag
            pov_attrs()
        else:
            config.side_image_tag = None

    def update_attrs(who, *attrs):
        """
        Updates the attributes of ``who`` as if by a ``say`` statement,
        but without actually having that character speak a line of dialogue.

        Most useful for the POV character.
        """
        assert(who is ADVCharacter)
        old_attributes = renpy.game.context().say_attributes
        try:
            renpy.game.context().say_attributes = attrs
            who.resolve_say_attributes(predict=False)
        finally:
            renpy.game.context().say_attributes = old_attributes

    def pov_attrs(*attrs):
        """
        Updates the attributes of the current POV character, if there is one,
        without actually having that character speak a line of dialogue.
        """
        if not store.pov_chara:
            return
        update_attrs(store.pov_chara, *attrs)

    # EDIT: I didn't realize I'd need this when I first posted.
    config.after_load_callbacks.append(lambda: set_pov(store.pov_chara))

Code: Select all

    $ set_pov(eileen) # a Character, not an image tag
    eileen "I'm happy. See?"
    $ pov_attrs("happy")
    "And indeed she was."
This updates an image's attributes; the change will be flushed the next time things are displayed (usually a with or a line of dialogue). Strictly speaking, only the update_attrs function is necessary, but I figure I might build more POV functionality on top of this later.

The key feature here is the resolve_say_attributes function at renpy/character.py#L843. I don't love that I'm reaching into say_attributes to do this, even if I'm taking the same sort of precautions that the actual say implementation does, so maybe we should ask for some kind of offical function to do this? It's really close to what resolve_say_attributes already does, just reading the set of attributes from a parameter instead of this shared state in renpy.game.context(). (Unfortunately I'm not in a position where I can write the patch myself.)

Aside: I did consider using resolve_say_attributes' existing wanted and remove parameters, but that requires keeping track of what needs to be removed (whatever the current attributes are). That would either mean more work at the use site, or exclusively using my wrapper functions to change POV expressions rather than normally relying on say-with-attributes. (Alternately, I could just use a custom screen for this, or even a plain old image on a non-default layer, but the side image functionality is really close to what I want. I think.)

Note that I've only tested this with the version I have installed at the moment, which is 7.1.3.1092.

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot]