Try / OpenGothic

Reimplementation of Gothic 2 Notr
MIT License
1.17k stars 85 forks source link

[MiniMod_Balance] Game reinitializes when coming back from Jharkendar first time #349

Closed sirsteve1 closed 2 years ago

sirsteve1 commented 2 years ago

Hi there

I have a strange issue. When entering Jharkendar and coming back to the new world the first time, the game reinitializes the new world. The intro-videos are replayed, the portal is closed and everything world-related is set back to start (npcs, monsters, items). Quest log, npc dialog options and player stats are correct. Water mages are not present in NewWorld but in Jharkendar (seems Quest related), yet Greg (probably due to the error that he is not appearing next to Dexter) is still in NewWorld even though he is also in Jharkendar as I already visited the pirates camp.

When I now re-enter Jharkendar (by reactivating the portal) and coming back to NewWorld a second time, the portal stays open and no intro videos are loaded (I guess that now the initialized state is stored correctly).

Is there a way to get around the reinitiliazation? Or checking the chapter, as I am already in chapter 2?

This is really an odd problem, also because all merchant trading inventories now are empty in NewWorld (which is really bad). Don't know if this is only for me.

I am playing though using the MiniMod Balance mod. So far everything worked quite well.

sirsteve1 commented 2 years ago

So I did find the issue regarding the reinitialization of the game.

I do play with MiniMod_Balance activated. So far all worked great. The problem arises during world changes back to newworld. The world name is handled differently, probably due to the installed mod. This might be a problem that arises also with other mods installed.

Without any mod, starting the game the world name is newworld.zen. Using __MiniMod_Balance__, the world name is NewWorld.zen.

As long as you are in the initial world, everything is fine. Switching to another world also is no problem. Switching back to the starting world for the first time tries to load newworld.zen and finds no stored WorldStateStorage, thus restarting the game with a full quest log and character stats. You start off at the closed (as initialzed) portal with a completely mixed game state.

I was able to solve the problem temporarily by modifiying the passed world name within GameSession::implChangeWorld in gamesession.cpp:

auto GameSession::implChangeWorld(std::unique_ptr<GameSession>&& game,
                                  const std::string& world, const std::string& wayPoint) -> std::unique_ptr<GameSession> {

  const char*   w   = world.compare("newworld\\newworld.zen") == 0 ? "newworld\\NewWorld.zen" : world.c_str();
  // const char*   w   = world.c_str();
  size_t        cut = world.rfind('\\');

I know that this hack only helps for the given Mod. Problably we would need adapt the initial world name when starting the game. For my current game this hotfix helps me to continue my game state. I tried also to simply adapt the world state within the savegame from NewWorld.zen to newworld.zen, but somehow the zip file format is not supported by plain gnu zip. I can extract the packages but not modify them correctly. The game simply does not load the modified savegame packages.

Try commented 2 years ago

Hi, @sirsteve1, and thanks for investigating problem !

I've made world name compare case-insensitive to fix the issue at 0e7b0f8

sirsteve1 commented 2 years ago

I tried that as well beforehand but for me it resulted in loading an empty WordStateStorage, thus there where no npcs, monsters or items anymore in NewWorld after entering it. I will test your code for both the original game and the Mod-game and let you know if it works.

Try commented 2 years ago

Hi, @sirsteve1 !

Sorry I forgot to submit one change, as part of 0e7b0f8. Case-insensitive compare was there, but never called :) Should be alright now.

sirsteve1 commented 2 years ago

Hi @Try

I've tested the code and the problem still exists for Mod-based games regardless of me using a savegame or a starting a new game. The mod initializes the main world as NewWorld.zen, OpenGothic stores that as WorldStateStorage and when switching between the worlds back to the main world it is both loaded and stored as newworld.zen, even though it finds the storage on first lookup.

I solved the issue by doing two things in gamesession.cpp:

https://github.com/Try/OpenGothic/blob/098744ddaa0b773ff0a4a847ae4aa4cbc9467d85/game/game/gamesession.cpp#L329-L330

After line 329 I updated the world name that is passed to the World instance (otherwise the loaded world state is still empty, thus no npcs):

  const WorldStateStorage& wss = findStorage(w);
  // Update world name for non-empty wss in case we have a mixed-case world name - otherwise wss is empty for already visited world
  if (!wss.isEmpty())
    w = wss.name;

And in line 355 the comparison is still case-sensitive, thus resulting in adding the world name also as visitedWorld https://github.com/Try/OpenGothic/blob/098744ddaa0b773ff0a4a847ae4aa4cbc9467d85/game/game/gamesession.cpp#L354-L359

I've tested the changes as mentioned with following scenarios:

Everything worked. Could you add the changes to the master branch?

Try commented 2 years ago

Everything worked. Could you add the changes to the master branch?

Yep, thanks!