TeamREPENTOGON / REPENTOGON

Script extender for The Binding of Isaac: Repentance
https://repentogon.com/
GNU General Public License v2.0
135 stars 15 forks source link

Rooms in void_ex.stb don't show up when the subtype is above 0 #556

Open oilyspoily opened 2 days ago

oilyspoily commented 2 days ago

Cannot 100% confirm this, but by doing a lot of testing (i.e, reseeding a bunch until I found modded void rooms), it seems like they don't spawn when the subtype is above 0.

namishere commented 2 days ago

It looks like when getting room configs to fill the normal rooms, GetRandomRoom is called with subtype 0. This will require hooking that function to override the subtype if the requested StbType is Void (luckily, the calls still do pass Void as the floor despite generating from random stages). Before implementing this, I'd like to know what non-zero subtypes in void_ex.stb would accomplish, and investigate any possible repercussions of forcing to search a subtype of -1 (any subtype).

oilyspoily commented 2 days ago

In Fiend Folio, I believe Void subtypes were added to match the floor a room was in. For example, a Difficulty 20 room that is from the Downpour would have the subtype 31 to match the appearance of the Downpour floor. Thinking back on it, I do not think it's necessary to set a backdrop for the Void floor, as the backdrops are supposed to be random. And... I'm not sure if the subtype thing even worked, haha

Fixing the subtype issue might be good, to prevent others from being unaware that subtypes above 0 prevent rooms from spawning.

Though, if it is not worth the effort, that is okay as well.

namishere commented 1 day ago

It might be nice to implement that functionality for void_ex rooms. I'm still concerned about potential issues here, there's a chance it could start grabbing special rooms like Downpour's mirror room and Mine's button rooms. Will need to investigate.

guwahavel commented 1 day ago

It might be nice to implement that functionality for void_ex rooms. I'm still concerned about potential issues here, there's a chance it could start grabbing special rooms like Downpour's mirror room and Mine's button rooms. Will need to investigate.

The Subtype should only be considered for rooms that are pulled from the Void file directly, similar to how Super Secret Rooms use Subtype to determine their backdrop.

namishere commented 1 day ago

So; we already modify what rooms Void is able to generate, like so:

// The void now draws from all floors
bool __stdcall VoidGenerationOverride(RoomConfig* _this, std::vector<RoomConfig_Room*>* rooms, int type, int shape, int minVariant,
    int maxVariant, int minDifficulty, int maxDifficulty, unsigned int* doors, unsigned int subtype, int mode) {
    // we want to skip all this and let the game handle things if we're generating death certificate
    if (g_Game->GetDimension() != 2) {
        // to include Void portal rooms
        maxDifficulty = (maxDifficulty == 15 ? 20 : maxDifficulty);
        for (int id = 0; id < 36; ++id) {
            if (generateLevels.test(id)) {
                //ZHL::Log("Adding stage id %d\n", id + 1);
                std::vector<RoomConfig_Room*> stageRooms = _this->GetRooms(id + 1, type, shape, minVariant, maxVariant, minDifficulty, maxDifficulty, doors, subtype, mode);
                rooms->insert(rooms->begin(), stageRooms.begin(), stageRooms.end());
            }
        }
        return true;
    }
    return false;
}

A solution to knife puzzle rooms generating when they shouldn't could be to parse the RoomConfigRoom vector from GetRooms and manually strip out rooms with those subtypes.

guwahavel commented 1 day ago

So; we already modify what rooms Void is able to generate, like so:

// The void now draws from all floors
bool __stdcall VoidGenerationOverride(RoomConfig* _this, std::vector<RoomConfig_Room*>* rooms, int type, int shape, int minVariant,
  int maxVariant, int minDifficulty, int maxDifficulty, unsigned int* doors, unsigned int subtype, int mode) {
  // we want to skip all this and let the game handle things if we're generating death certificate
  if (g_Game->GetDimension() != 2) {
      // to include Void portal rooms
      maxDifficulty = (maxDifficulty == 15 ? 20 : maxDifficulty);
      for (int id = 0; id < 36; ++id) {
          if (generateLevels.test(id)) {
              //ZHL::Log("Adding stage id %d\n", id + 1);
              std::vector<RoomConfig_Room*> stageRooms = _this->GetRooms(id + 1, type, shape, minVariant, maxVariant, minDifficulty, maxDifficulty, doors, subtype, mode);
              rooms->insert(rooms->begin(), stageRooms.begin(), stageRooms.end());
          }
      }
      return true;
  }
  return false;
}

A solution to knife puzzle rooms generating when they shouldn't could be to parse the RoomConfigRoom vector from GetRooms and manually strip out rooms with those subtypes.

It would be better to only use non-0 Subtype rooms if the room is originally from the Void file. It should be easier that way instead of manual case checks for knife puzzle/marked skull rooms.

namishere commented 1 day ago

Good point.

The Subtype should only be considered for rooms that are pulled from the Void file directly, similar to how Super Secret Rooms use Subtype to determine their backdrop.

This should be easy to implement as well.

Guillotine-221 commented 1 day ago

In case you didn't know or forgot, according to the subtype numbers for the rooms in the unused void stb file, the subtype is set to match the id numbers in stages.xml rather than the ones in backdrops.xml.