scemino / engge

Open source remake of Thimbleweed Park's engine
https://scemino.github.io/
MIT License
150 stars 15 forks source link

Actor vanishes if sentence contains {eyes_left} or {eyes_right} #75

Closed Mac1512 closed 4 years ago

Mac1512 commented 4 years ago

Hello,

I have seen that when Chapter 2 is executed, when Ray and Reyes are where (boris) died.

Reyes disappears when he says @ 20998: {eyes_left}It's need to know.

Ray disappears when he says @ 20999: {eyes_right}Look...

although Reyes reappears when they say:

21013 Body... 21014 Starting...

and disappears again by saying

21015 {eyes_left}To... 21016 {eyes_left}Pixelate...

And just before Ray says: {eyes_front} This is going to be a long night.

Reyes reappears and stays visible all the time. instead Ray is missing until it is selected and pressed at some point on the screen, with the mouse cursor, that is when Ray appears and works normally.


Edit: the actor also disappears when he says: "smile!" at the time of taking the photo to (boris) dead. reappears and disappears again in a sentence later, reappearing.

I have not continued testing, although it will surely disappear again at some other time in which I speak and know of a similar situation.

regards

scemino commented 4 years ago

Strange, I can't reproduce it, can you tell me with which commit you tested it ? Thank you.

Mac1512 commented 4 years ago

Hi,

The first thing to say is that I am using windows 10 x64, and I am compiling the 32-bit engine, using Visual Studio Conmunity 2019 with the tools of Visual Studio 2017.

until the last commit that worked well was, until Rename all headers to .hpp (https://github.com/scemino/engge/commit/ed2624f42d4105c09d3504063e46f33b426f6c82).

From the next commin, Fix animation with only 1 layer (https://github.com/scemino/engge/commit/5547b9228cceb30efc3715474c7a0ec8d565a1c7) , the actors disappear as I have told. In fact this happens to me until the last commit: Fix actor vanishes if sentence contains {notalk} (https://github.com/scemino/engge/commit/efd4b162f1eeca4368150757e3429fae9a2ade04).

In fact, the engine should execute the animation of the eyes, either right or left if it worked correctly, but instead, the actors disappear. On the other hand, even the commit that works for me (Rename all headers to .hpp), the animation of the left and right eyes does not run, but instead the actors do not disappear.

If from the commit, Fix animation with only 1 layer (https://github.com/scemino/engge/commit/5547b9228cceb30efc3715474c7a0ec8d565a1c7), until the commit, Start costume animation refactoring (https://github.com/scemino/engge/commit/c7e06bd22b6f1d7e65f7e76b6387f32bd8175d61). I modify the file Costume.cpp, in the function:

bool Costume :: setAnimation (const std :: string & animName)

I comment the following line:

//_pCurrentAnimation = nullptr;

The actors do not disappear when executing {eyes_left} or {eyes_right} before the sentence, working correctly for me with the animation fixed in front ({eyes_front}). That is, it does not run eyes left or right.

But from the following commit: Clean code and fix neverending animation(https://github.com/scemino/engge/commit/448bd6730b9aa35cff5ad6837eb99e908b2bf01e) until the last commit: Fix actor vanishes if sentence contains {notalk} (https://github.com/scemino/engge/commit/efd4b162f1eeca4368150757e3429fae9a2ade04). The actors disappear again when they meet {eyes_left} or {eyes_right} before the sentence.

I can no longer comment on that line because in the commit "Clean code and fix neverending animation", you delete it in the modification you make.

Also, as I had told you, he commits them where I receive this fault, If I keep trying, when taking the photo to boris (dead), and saying the word smile !, the actor disappears. This happens more times in the corresponding scene, but the rest of the words I have not written down.

All this I have observed in chapter 2 "The Body", which is where I tried, since every time I try I run from the beginning, setting the local variable doStart to false, in the file test.nut.

Cheers

Mac1512 commented 4 years ago

Hi, I found the bug when sentence contains {eyes_left} or {eyes_right}

in the file _TalkingState.hpp, within the function:

void loadId (int id)

After executing this function:

anim = tostring (matches [2] .str ()). data ();

The value of the variable anim is empty or at least not a printable value if I do the following:

printf ("anim =% s \ n", anim);

therefore, to the function:

_pActor-> getCostume (). setState (anim);

It has passed an empty value.


To solve it, I have changed this function to:

void loadId(int id)
    {
        setText(_pEngine->getText(id));

        const char* key = nullptr;
        if(!ScriptEngine::get(_pActor, "_talkieKey", key))
        {
            ScriptEngine::get(_pActor, "_key", key);
        }
        auto name = str_toupper(key).append("_").append(std::to_string(id));
        std::string path;
        path.append(name).append(".lip");

        _lipAnim.setActor(_pActor);

        // actor animation
        std::wregex re(L"(\\{([^\\}]*)\\})");
        std::wsmatch matches;

        //const char* anim = nullptr;
        std::string anim = "";

        bool loadLipAnim = true;
        if (std::regex_search(_sayText, matches, re))
        {
            //anim = tostring(matches[2].str()).data();
            anim = tostring(matches.str()).data();  
            anim = anim.substr(1, anim.length() - 2); 

            _sayText = matches.suffix();

            //if (anim && strcmp(anim, "notalk") == 0)
            if ((anim.c_str() != "") && strcmp(anim.c_str(), "notalk") == 0)
            {
                loadLipAnim = false;
            }
            else
            {
                //_pActor->getCostume().setState(anim);
                _pActor->getCostume().setState(anim.c_str());
            }
        }

        if(loadLipAnim)
        {
            _lipAnim.load(path);
        }
        else 
        {
            _lipAnim.clear();
        }

        auto hearVoice = _pEngine->getPreferences().getUserPreference(PreferenceNames::HearVoice, PreferenceDefaultValues::HearVoice);
        if(hearVoice) {
            setDuration(_lipAnim.getDuration());
        } else {
            auto sayLineBaseTime = _pEngine->getPreferences().getUserPreference(PreferenceNames::SayLineBaseTime, PreferenceDefaultValues::SayLineBaseTime);
            auto sayLineCharTime = _pEngine->getPreferences().getUserPreference(PreferenceNames::SayLineCharTime, PreferenceDefaultValues::SayLineCharTime);
            auto sayLineMinTime = _pEngine->getPreferences().getUserPreference(PreferenceNames::SayLineMinTime, PreferenceDefaultValues::SayLineMinTime);
            auto sayLineSpeed = _pEngine->getPreferences().getUserPreference(PreferenceNames::SayLineSpeed, PreferenceDefaultValues::SayLineSpeed);
            auto speed = (sayLineBaseTime + sayLineCharTime * _sayText.length()) / (0.2f + sayLineSpeed);
            if(speed < sayLineMinTime) speed = sayLineMinTime;
            setDuration(sf::seconds(speed));
        }

        const char* sayLine = tostring(_sayText).data();

        //ScriptEngine::call(_pActor, "sayingLine", anim, sayLine);
        ScriptEngine::call(_pActor, "sayingLine", anim.c_str(), sayLine);

        loadActorSpeech(name);
    }

There is still the problem of disappearance of the actor when taking the photo, when he says the phrase "Smile!".

And it also disappears between the phrases:

25644 There's no wallet in his pockets... 25645 ...but I found a card, possibly a keycard from a hotel.

when one of the agents registers the body and finds the hotel room card.

I will try to upload a video to YouTube so you can see the bugs. Without this correction I have made.

I have applied the correction to the commit, Fix pathfinding is still wrong (https://github.com/scemino/engge/commit/d309fa55437083dc0427f633a8d55a27e4c0f500).

Check the code and confirm that it is correct ... sure it can be improved :)

Cheers

Mac1512 commented 4 years ago

I pass you the link to the video, where you can see the bugs that I have told you, as well as other bugs that I had not told you:

  1. After the animation of when Boris is attacked by the shadow and before the title card2 "The Body", the following text should appear:

25545 None of us were prepared for what we'd find that night. 25546 Or how much it would change us all.

  1. Also when Reyes is writing in the notebook:

21013 Body... 21014 Starting... 21015 {eyes_left}To... 21016 {eyes_left}Pixelate...

The word Body, you don't hear that sound, maybe the engine doesn't load it.

an interference is appreciated, when the title card 2 begins, just when Ray and Reyes appear on the scene, that is not a fault, it is an interference in the recording of the video.

The link to the video is as follows:

https://youtu.be/BDnm120bLNs

This video is made before the arrangement that I have told you

scemino commented 4 years ago

Thank you for this and the video, I will check this.

scemino commented 4 years ago

I created and fixed an issue #77 for this:

After the animation of when Boris is attacked by the shadow and before the title card2 "The Body", the following text should appear: 25545 None of us were prepared for what we'd find that night. 25546 Or how much it would change us all.

And I fixed this one too #78:

The word Body, you don't hear that sound, maybe the engine doesn't load it.

Mac1512 commented 4 years ago

I tried this commit (https://github.com/scemino/engge/commit/44fec356d810c7577677bc2e91234f4720e99d2e) and the result is great xD

You have been correcting error after failure, in the correction I had told you about the function I modified: void loadId (int id)

I had not realized that this:

tostring(matches[2].str()).data();

It's the same as this:

tostring(matches.str()).data();
anim.substr(1, anim.length() - 2);

So the function can look like:

std::string aux = tostring(matches[2].str()).data(); anim = aux.c_str();

and so the function would remain, as it was originally, with only these two lines changed.

Therefore, the function would look like this:

void loadId(int id)
    {
        setText(_pEngine->getText(id));

        const char* key = nullptr;
        if(!ScriptEngine::get(_pActor, "_talkieKey", key))
        {
            ScriptEngine::get(_pActor, "_key", key);
        }
        auto name = str_toupper(key).append("_").append(std::to_string(id));
        std::string path;
        path.append(name).append(".lip");

        _lipAnim.setActor(_pActor);

        // actor animation
        std::wregex re(L"(\\{([^\\}]*)\\})");
        std::wsmatch matches;
        const char* anim = nullptr;
        bool loadLipAnim = true;
        if (std::regex_search(_sayText, matches, re))
        {
            //anim = tostring(matches[2].str()).data();    /* Chaged */
            std::string aux = tostring(matches[2].str()).data(); // New
        anim = aux.c_str(); //New

            _sayText = matches.suffix();
            if(anim && strcmp(anim,"notalk")==0)
            {
                loadLipAnim = false;
            }
            else
            {
                _pActor->getCostume().setState(anim);
            }
        }

        if(loadLipAnim)
        {
            _lipAnim.load(path);
        }
        else 
        {
            _lipAnim.clear();
        }

        auto hearVoice = _pEngine->getPreferences().getUserPreference(PreferenceNames::HearVoice, PreferenceDefaultValues::HearVoice);
        if(hearVoice) {
            setDuration(_lipAnim.getDuration());
        } else {
            auto sayLineBaseTime = _pEngine->getPreferences().getUserPreference(PreferenceNames::SayLineBaseTime, PreferenceDefaultValues::SayLineBaseTime);
            auto sayLineCharTime = _pEngine->getPreferences().getUserPreference(PreferenceNames::SayLineCharTime, PreferenceDefaultValues::SayLineCharTime);
            auto sayLineMinTime = _pEngine->getPreferences().getUserPreference(PreferenceNames::SayLineMinTime, PreferenceDefaultValues::SayLineMinTime);
            auto sayLineSpeed = _pEngine->getPreferences().getUserPreference(PreferenceNames::SayLineSpeed, PreferenceDefaultValues::SayLineSpeed);
            auto speed = (sayLineBaseTime + sayLineCharTime * _sayText.length()) / (0.2f + sayLineSpeed);
            if(speed < sayLineMinTime) speed = sayLineMinTime;
            setDuration(sf::seconds(speed));
        }

        const char* sayLine = tostring(_sayText).data();
        ScriptEngine::call(_pActor, "sayingLine", anim, sayLine);

        loadActorSpeech(name);
    }
scemino commented 4 years ago

OK I found the issue, it's there: anim = tostring(matches[2].str()).data()

I create a local variable with tostring(matches[2].str()) and I keep the pointer to anim, but the local variable is destroyed, so anim is always empty.

I fixed it, now I'm testing it and I will close this issue it works.