diff --git a/src/rct1.h b/src/rct1.h index ff55708b73..d9a2b0a157 100644 --- a/src/rct1.h +++ b/src/rct1.h @@ -556,6 +556,24 @@ enum { RCT1_SCENERY_THEME_PAGODA, }; +enum { + RCT1_PATH_ADDITION_NONE, + RCT1_PATH_ADDITION_LAMP_1, + RCT1_PATH_ADDITION_LAMP_2, + RCT1_PATH_ADDITION_BIN, + RCT1_PATH_ADDITION_BENCH, + RCT1_PATH_ADDITION_JUMPING_FOUNTAIN, + RCT1_PATH_ADDITION_LAMP_3, + RCT1_PATH_ADDITION_LAMP_4, + RCT1_PATH_ADDITION_BROKEN_LAMP_1, + RCT1_PATH_ADDITION_BROKEN_LAMP_2, + RCT1_PATH_ADDITION_BROKEN_BIN, + RCT1_PATH_ADDITION_BROKEN_BENCH, + RCT1_PATH_ADDITION_BROKEN_LAMP_3, + RCT1_PATH_ADDITION_BROKEN_LAMP_4, + RCT1_PATH_ADDITION_JUMPING_SNOW, +}; + enum { RCT1_RESEARCH_END_AVAILABLE = 0xFF, RCT1_RESEARCH_END_RESEARCHABLE = 0xFE, diff --git a/src/rct1/S4Importer.cpp b/src/rct1/S4Importer.cpp index aa700301f7..1e3dcba83b 100644 --- a/src/rct1/S4Importer.cpp +++ b/src/rct1/S4Importer.cpp @@ -74,6 +74,7 @@ void S4Importer::Initialise() Memory::Set(_smallSceneryTypeToEntryMap, 255, sizeof(_smallSceneryTypeToEntryMap)); Memory::Set(_largeSceneryTypeToEntryMap, 255, sizeof(_largeSceneryTypeToEntryMap)); Memory::Set(_wallTypeToEntryMap, 255, sizeof(_wallTypeToEntryMap)); + Memory::Set(_pathAdditionTypeToEntryMap, 255, sizeof(_pathAdditionTypeToEntryMap)); Memory::Set(_sceneryThemeTypeToEntryMap, 255, sizeof(_sceneryThemeTypeToEntryMap)); uint16 mapSize = _s4.map_size == 0 ? 128 : _s4.map_size; @@ -135,6 +136,7 @@ void S4Importer::CreateAvailableObjectMappings() case OBJECT_TYPE_SMALL_SCENERY: case OBJECT_TYPE_LARGE_SCENERY: case OBJECT_TYPE_WALLS: + case OBJECT_TYPE_PATH_BITS: { List * entries = GetEntryList(objectType); @@ -224,6 +226,9 @@ void S4Importer::AddAvailableEntriesFromMap() while (tileIndex < maxTiles) { switch (map_element_get_type(mapElement)) { + case MAP_ELEMENT_TYPE_PATH: + AddEntryForPathAddition(mapElement->properties.path.additions & 0x0F); + break; case MAP_ELEMENT_TYPE_SCENERY: AddEntryForSmallScenery(mapElement->properties.scenery.type); break; @@ -325,6 +330,24 @@ void S4Importer::AddEntryForWall(uint8 wallType) } } +void S4Importer::AddEntryForPathAddition(uint8 pathAdditionType) +{ + if (pathAdditionType == RCT1_PATH_ADDITION_NONE) return; + + if (_pathAdditionTypeToEntryMap[pathAdditionType] == 255) + { + uint8 normalisedPathAdditionType = RCT1::NormalisePathAddition(pathAdditionType); + if (_pathAdditionTypeToEntryMap[normalisedPathAdditionType] == 255) + { + const char * entryName = RCT1::GetPathAddtionObject(normalisedPathAdditionType); + _pathAdditionTypeToEntryMap[normalisedPathAdditionType] = (uint8)_pathAdditionEntries.GetCount(); + _pathAdditionEntries.Add(entryName); + } + + _pathAdditionTypeToEntryMap[pathAdditionType] = _pathAdditionTypeToEntryMap[normalisedPathAdditionType]; + } +} + void S4Importer::AddEntriesForSceneryTheme(uint8 sceneryThemeType) { if (sceneryThemeType == RCT1_SCENERY_THEME_GENERAL || @@ -589,6 +612,7 @@ void S4Importer::LoadObjects() LoadObjects(OBJECT_TYPE_SMALL_SCENERY, _smallSceneryEntries); LoadObjects(OBJECT_TYPE_LARGE_SCENERY, _largeSceneryEntries); LoadObjects(OBJECT_TYPE_WALLS, _wallEntries); + LoadObjects(OBJECT_TYPE_PATH_BITS, _pathAdditionEntries); LoadObjects(OBJECT_TYPE_SCENERY_SETS, _sceneryGroupEntries); LoadObjects(OBJECT_TYPE_PATHS, List({ "TARMAC ", @@ -599,16 +623,6 @@ void S4Importer::LoadObjects() "PATHCRZY", "PATHASH " })); - LoadObjects(OBJECT_TYPE_PATH_BITS, List({ - "LAMP1 ", - "LAMP2 ", - "LITTER1 ", - "BENCH1 ", - "JUMPFNT1", - "LAMP3 ", - "LAMP4 ", - "JUMPSNW1" - })); LoadObjects(OBJECT_TYPE_BANNERS, List({ "BN1 ", "BN2 ", @@ -1043,15 +1057,6 @@ static const uint8 RCT1PathTypeConversionTable[96] = 0, 0, 0, 0, }; -// rct2: 0x0098BCFF -static const uint8 RCT1PathAdditionConversionTable[15] = -{ - 0, - 1, 2, 3, 4, 5, 6, 7, - 0x80 | 1, 0x80 | 2, 0x80 | 3, 0x80 | 4, 0x80 | 6, 0x80 | 7, - 8, -}; - void S4Importer::FixPaths() { rct_map_element * mapElement = gMapElements; @@ -1067,6 +1072,7 @@ void S4Importer::FixPaths() mapElement->type &= 0xFC; mapElement->flags &= ~0x60; + mapElement->flags &= ~MAP_ELEMENT_FLAG_BROKEN; mapElement->properties.path.type &= 0x0F; footpath_scenery_set_is_ghost(mapElement, false); if (pathType & 0x80) @@ -1076,18 +1082,17 @@ void S4Importer::FixPaths() mapElement->properties.path.type |= pathType << 4; // Additions - int additions = RCT1PathAdditionConversionTable[footpath_element_get_path_scenery(mapElement)]; - if (additions & 0x80) + uint8 additionType = footpath_element_get_path_scenery(mapElement); + if (additionType != RCT1_PATH_ADDITION_NONE) { - additions &= ~0x80; - mapElement->flags |= MAP_ELEMENT_FLAG_BROKEN; + uint8 normalisedType = RCT1::NormalisePathAddition(additionType); + uint8 entryIndex = _pathAdditionTypeToEntryMap[normalisedType]; + if (additionType != normalisedType) + { + mapElement->flags |= MAP_ELEMENT_FLAG_BROKEN; + } + footpath_element_set_path_scenery(mapElement, entryIndex + 1); } - else - { - mapElement->flags &= ~MAP_ELEMENT_FLAG_BROKEN; - } - - footpath_element_set_path_scenery(mapElement, additions); break; } case MAP_ELEMENT_TYPE_ENTRANCE: @@ -1294,6 +1299,7 @@ List * S4Importer::GetEntryList(uint8 objectType) case OBJECT_TYPE_SMALL_SCENERY: return &_smallSceneryEntries; case OBJECT_TYPE_LARGE_SCENERY: return &_largeSceneryEntries; case OBJECT_TYPE_WALLS: return &_wallEntries; + case OBJECT_TYPE_PATH_BITS: return &_pathAdditionEntries; case OBJECT_TYPE_SCENERY_SETS: return &_sceneryGroupEntries; } return nullptr; diff --git a/src/rct1/S4Importer.h b/src/rct1/S4Importer.h index 511140267b..4bf996be4a 100644 --- a/src/rct1/S4Importer.h +++ b/src/rct1/S4Importer.h @@ -28,6 +28,7 @@ private: List _smallSceneryEntries; List _largeSceneryEntries; List _wallEntries; + List _pathAdditionEntries; List _sceneryGroupEntries; // Lookup tables for converting from RCT1 hard coded types to the new dynamic object entries @@ -36,6 +37,7 @@ private: uint8 _smallSceneryTypeToEntryMap[256]; uint8 _largeSceneryTypeToEntryMap[256]; uint8 _wallTypeToEntryMap[256]; + uint8 _pathAdditionTypeToEntryMap[16]; uint8 _sceneryThemeTypeToEntryMap[24]; // Research @@ -58,6 +60,7 @@ private: void AddEntryForSmallScenery(uint8 smallSceneryType); void AddEntryForLargeScenery(uint8 largeSceneryType); void AddEntryForWall(uint8 wallType); + void AddEntryForPathAddition(uint8 pathAdditionType); void AddEntriesForSceneryTheme(uint8 sceneryThemeType); void LoadObjects(); diff --git a/src/rct1/import.h b/src/rct1/import.h index 22958969e3..6f015df7a0 100644 --- a/src/rct1/import.h +++ b/src/rct1/import.h @@ -11,12 +11,14 @@ namespace RCT1 uint8 GetRideType(uint8 rideType); bool RideTypeHasVehicle(uint8 rideType); + uint8 NormalisePathAddition(uint8 pathAdditionType); const char * GetRideTypeObject(uint8 rideType); const char * GetVehicleObject(uint8 vehicleType); const char * GetSmallSceneryObject(uint8 smallSceneryType); const char * GetLargeSceneryObject(uint8 largeSceneryType); const char * GetWallObject(uint8 wallType); + const char * GetPathAddtionObject(uint8 pathAdditionType); const char * GetSceneryGroupObject(uint8 sceneryGroupType); const List GetSceneryObjects(uint8 sceneryType); diff --git a/src/rct1/tables.cpp b/src/rct1/tables.cpp index 6c364ac6e6..8ee12b0fa0 100644 --- a/src/rct1/tables.cpp +++ b/src/rct1/tables.cpp @@ -227,6 +227,19 @@ namespace RCT1 } } + uint8 NormalisePathAddition(uint8 pathAdditionType) + { + switch (pathAdditionType) { + case RCT1_PATH_ADDITION_BROKEN_LAMP_1: return RCT1_PATH_ADDITION_LAMP_1; + case RCT1_PATH_ADDITION_BROKEN_LAMP_2: return RCT1_PATH_ADDITION_LAMP_2; + case RCT1_PATH_ADDITION_BROKEN_BIN: return RCT1_PATH_ADDITION_BIN; + case RCT1_PATH_ADDITION_BROKEN_BENCH: return RCT1_PATH_ADDITION_BENCH; + case RCT1_PATH_ADDITION_BROKEN_LAMP_3: return RCT1_PATH_ADDITION_LAMP_3; + case RCT1_PATH_ADDITION_BROKEN_LAMP_4: return RCT1_PATH_ADDITION_LAMP_4; + } + return pathAdditionType; + } + const char * GetRideTypeObject(uint8 rideType) { static const char * map[] = @@ -820,6 +833,29 @@ namespace RCT1 return map[wallType]; } + const char * GetPathAddtionObject(uint8 pathAdditionType) + { + static const char * map[] = + { + " ", // RCT1_PATH_ADDITION_NONE + "LAMP1 ", // RCT1_PATH_ADDITION_LAMP_1 + "LAMP2 ", // RCT1_PATH_ADDITION_LAMP_2 + "LITTER1 ", // RCT1_PATH_ADDITION_BIN + "BENCH1 ", // RCT1_PATH_ADDITION_BENCH + "JUMPFNT1", // RCT1_PATH_ADDITION_JUMPING_FOUNTAIN + "LAMP3 ", // RCT1_PATH_ADDITION_LAMP_3 + "LAMP4 ", // RCT1_PATH_ADDITION_LAMP_4 + "LAMP1 ", // RCT1_PATH_ADDITION_BROKEN_LAMP_1 + "LAMP2 ", // RCT1_PATH_ADDITION_BROKEN_LAMP_2 + "LITTER1 ", // RCT1_PATH_ADDITION_BROKEN_BIN + "BENCH1 ", // RCT1_PATH_ADDITION_BROKEN_BENCH + "LAMP3 ", // RCT1_PATH_ADDITION_BROKEN_LAMP_3 + "LAMP4 ", // RCT1_PATH_ADDITION_BROKEN_LAMP_4 + "JUMPSNW1", // RCT1_PATH_ADDITION_JUMPING_SNOW + }; + return map[pathAdditionType]; + } + const char * GetSceneryGroupObject(uint8 sceneryGroupType) { static const char * map[] =