From 9f61c9e6ac6b1ac5692cf6352d2ebbd47a31a686 Mon Sep 17 00:00:00 2001 From: claude-bot Date: Mon, 13 Jul 2026 12:27:07 +0000 Subject: Import Cai1Hsu/re3 @ miami (reVC / GTA:VC decompilation) Snapshot import (no upstream history) into git.ancap.in.ua/claude, per @lzcnt. Source: https://github.com/Cai1Hsu/re3 branch miami. --- src/core/Zones.cpp | 772 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 772 insertions(+) create mode 100644 src/core/Zones.cpp (limited to 'src/core/Zones.cpp') diff --git a/src/core/Zones.cpp b/src/core/Zones.cpp new file mode 100644 index 0000000..85564f0 --- /dev/null +++ b/src/core/Zones.cpp @@ -0,0 +1,772 @@ +#include "common.h" + +#include + +#include "Zones.h" + +#include "Clock.h" +#include "Text.h" +#include "World.h" +#include "Timer.h" + +eLevelName CTheZones::m_CurrLevel; +int16 CTheZones::FindIndex; + +uint16 CTheZones::NumberOfAudioZones; +int16 CTheZones::AudioZoneArray[NUMAUDIOZONES]; +uint16 CTheZones::TotalNumberOfMapZones; +uint16 CTheZones::TotalNumberOfInfoZones; +uint16 CTheZones::TotalNumberOfNavigationZones; +CZone CTheZones::InfoZoneArray[NUMINFOZONES]; +CZone CTheZones::MapZoneArray[NUMMAPZONES]; +CZone CTheZones::NavigationZoneArray[NUMNAVIGZONES]; +uint16 CTheZones::TotalNumberOfZoneInfos; +CZoneInfo CTheZones::ZoneInfoArray[2*NUMINFOZONES]; + + +#define SWAPF(a, b) { float t; t = a; a = b; b = t; } + +wchar* +CZone::GetTranslatedName(void) +{ + return TheText.Get(name); +} + +void +CTheZones::Init(void) +{ + int i, j; + for(i = 0; i < NUMAUDIOZONES; i++) + AudioZoneArray[i] = -1; + NumberOfAudioZones = 0; + + for(i = 0; i < NUMNAVIGZONES; i++) + memset(&NavigationZoneArray[i], 0, sizeof(CZone)); + + for(i = 0; i < NUMINFOZONES; i++) + memset(&InfoZoneArray[i], 0, sizeof(CZone)); + + int x = 1000/9; + for(i = 0; i < 2*NUMINFOZONES; i++){ + // Cars + + ZoneInfoArray[i].carDensity = 10; + ZoneInfoArray[i].carThreshold[0] = x; + ZoneInfoArray[i].carThreshold[1] = ZoneInfoArray[i].carThreshold[0] + x; + ZoneInfoArray[i].carThreshold[2] = ZoneInfoArray[i].carThreshold[1] + x; + ZoneInfoArray[i].carThreshold[3] = ZoneInfoArray[i].carThreshold[2] + x; + ZoneInfoArray[i].carThreshold[4] = ZoneInfoArray[i].carThreshold[3] + x; + ZoneInfoArray[i].carThreshold[5] = ZoneInfoArray[i].carThreshold[4] + x; + ZoneInfoArray[i].carThreshold[6] = ZoneInfoArray[i].carThreshold[5] + x; + ZoneInfoArray[i].carThreshold[7] = ZoneInfoArray[i].carThreshold[6] + x; + ZoneInfoArray[i].carThreshold[8] = 1000; + + ZoneInfoArray[i].boatThreshold[0] = 500; + ZoneInfoArray[i].boatThreshold[1] = 1000; + + // What's going on here? this looks more like density + ZoneInfoArray[i].copThreshold = 50; + for(j = 0; j < NUM_GANGS; j++) + ZoneInfoArray[i].gangThreshold[j] = ZoneInfoArray[i].copThreshold; + + // Peds + + ZoneInfoArray[i].pedDensity = 12; + + // What's going on here? this looks more like density + ZoneInfoArray[i].copPedThreshold = 50; + for(j = 0; j < NUM_GANGS; j++) + ZoneInfoArray[i].gangPedThreshold[j] = ZoneInfoArray[i].copPedThreshold; + + ZoneInfoArray[i].pedGroup = 0; + } + + TotalNumberOfZoneInfos = 1; // why 1? + TotalNumberOfNavigationZones = 1; + TotalNumberOfInfoZones = 1; + + strcpy(InfoZoneArray[0].name, "CITYINF"); + InfoZoneArray[0].minx = -2400.0f; + InfoZoneArray[0].miny = -2000.0f; + InfoZoneArray[0].minz = -500.0f; + InfoZoneArray[0].maxx = 1600.0f; + InfoZoneArray[0].maxy = 2000.0f; + InfoZoneArray[0].maxz = 500.0f; + InfoZoneArray[0].level = LEVEL_GENERIC; + InfoZoneArray[0].type = ZONE_INFO; + + strcpy(NavigationZoneArray[0].name, "VICE_C"); + NavigationZoneArray[0].minx = -2400.0f; + NavigationZoneArray[0].miny = -2000.0f; + NavigationZoneArray[0].minz = -500.0f; + NavigationZoneArray[0].maxx = 1600.0f; + NavigationZoneArray[0].maxy = 2000.0f; + NavigationZoneArray[0].maxz = 500.0f; + NavigationZoneArray[0].level = LEVEL_GENERIC; + NavigationZoneArray[0].type = ZONE_DEFAULT; + + m_CurrLevel = LEVEL_GENERIC; + + for(i = 0; i < NUMMAPZONES; i++){ + memset(&MapZoneArray[i], 0, sizeof(CZone)); + MapZoneArray[i].type = ZONE_MAPZONE; + } + TotalNumberOfMapZones = 1; + strcpy(MapZoneArray[0].name, "THEMAP"); + MapZoneArray[0].minx = -2400.0f; + MapZoneArray[0].miny = -2000.0f; + MapZoneArray[0].minz = -500.0f; + MapZoneArray[0].maxx = 1600.0f; + MapZoneArray[0].maxy = 2000.0f; + MapZoneArray[0].maxz = 500.0f; + MapZoneArray[0].level = LEVEL_GENERIC; +} + +void +CTheZones::Update(void) +{ +#ifdef SQUEEZE_PERFORMANCE + if (CTimer::GetFrameCounter() % 5 != 0) + return; +#endif + CVector pos; + pos = FindPlayerCoors(); + m_CurrLevel = GetLevelFromPosition(&pos); +} + +void +CTheZones::CreateZone(char *name, eZoneType type, + float minx, float miny, float minz, + float maxx, float maxy, float maxz, + eLevelName level) +{ + char tmpname[24]; + char *p; + + if(minx > maxx) SWAPF(minx, maxx); + if(miny > maxy) SWAPF(miny, maxy); + if(minz > maxz) SWAPF(minz, maxz); + + // make upper case + for(p = name; *p; p++) if(islower(*p)) *p = toupper(*p); + + strncpy(tmpname, name, 7); + tmpname[7] = '\0'; + + // add zone + switch(type){ + case ZONE_DEFAULT: + case ZONE_NAVIG: + assert(TotalNumberOfNavigationZones < NUMNAVIGZONES); + strcpy(NavigationZoneArray[TotalNumberOfNavigationZones].name, tmpname); + NavigationZoneArray[TotalNumberOfNavigationZones].type = type; + NavigationZoneArray[TotalNumberOfNavigationZones].minx = minx; + NavigationZoneArray[TotalNumberOfNavigationZones].miny = miny; + NavigationZoneArray[TotalNumberOfNavigationZones].minz = minz; + NavigationZoneArray[TotalNumberOfNavigationZones].maxx = maxx; + NavigationZoneArray[TotalNumberOfNavigationZones].maxy = maxy; + NavigationZoneArray[TotalNumberOfNavigationZones].maxz = maxz; + NavigationZoneArray[TotalNumberOfNavigationZones].level = level; + TotalNumberOfNavigationZones++; + break; + case ZONE_INFO: + assert(TotalNumberOfInfoZones < NUMINFOZONES); + strcpy(InfoZoneArray[TotalNumberOfInfoZones].name, tmpname); + InfoZoneArray[TotalNumberOfInfoZones].type = type; + InfoZoneArray[TotalNumberOfInfoZones].minx = minx; + InfoZoneArray[TotalNumberOfInfoZones].miny = miny; + InfoZoneArray[TotalNumberOfInfoZones].minz = minz; + InfoZoneArray[TotalNumberOfInfoZones].maxx = maxx; + InfoZoneArray[TotalNumberOfInfoZones].maxy = maxy; + InfoZoneArray[TotalNumberOfInfoZones].maxz = maxz; + InfoZoneArray[TotalNumberOfInfoZones].level = level; + InfoZoneArray[TotalNumberOfInfoZones].zoneinfoDay = TotalNumberOfZoneInfos++; + InfoZoneArray[TotalNumberOfInfoZones].zoneinfoNight = TotalNumberOfZoneInfos++; + TotalNumberOfInfoZones++; + break; + case ZONE_MAPZONE: + assert(TotalNumberOfMapZones < NUMMAPZONES); + strcpy(MapZoneArray[TotalNumberOfMapZones].name, tmpname); + MapZoneArray[TotalNumberOfMapZones].type = type; + MapZoneArray[TotalNumberOfMapZones].minx = minx; + MapZoneArray[TotalNumberOfMapZones].miny = miny; + MapZoneArray[TotalNumberOfMapZones].minz = minz; + MapZoneArray[TotalNumberOfMapZones].maxx = maxx; + MapZoneArray[TotalNumberOfMapZones].maxy = maxy; + MapZoneArray[TotalNumberOfMapZones].maxz = maxz; + MapZoneArray[TotalNumberOfMapZones].level = level; + TotalNumberOfMapZones++; + break; + } +} + +void +CTheZones::PostZoneCreation(void) +{ + int i; + for(i = 1; i < TotalNumberOfNavigationZones; i++) + InsertZoneIntoZoneHierarchy(&NavigationZoneArray[i]); + InitialiseAudioZoneArray(); +#ifndef MASTER + CheckZonesForOverlap(); +#endif +} + +void +CTheZones::CheckZonesForOverlap(void) +{ + int i, j; + char str[116]; + + for(i = 1; i < TotalNumberOfInfoZones; i++){ + ZoneIsEntirelyContainedWithinOtherZone(&InfoZoneArray[i], &InfoZoneArray[0]); + + for(j = 1; j < TotalNumberOfInfoZones; j++) + if(i != j && ZoneIsEntirelyContainedWithinOtherZone(&InfoZoneArray[i], &InfoZoneArray[j])) + sprintf(str, "Info zone %s contains %s\n", InfoZoneArray[j].name, InfoZoneArray[i].name); + } +} + +void +CTheZones::InsertZoneIntoZoneHierarchy(CZone *zone) +{ + zone->child = nil; + zone->parent = nil; + zone->next = nil; + InsertZoneIntoZoneHierRecursive(zone, &NavigationZoneArray[0]); +} + +bool +CTheZones::InsertZoneIntoZoneHierRecursive(CZone *inner, CZone *outer) +{ + int n; + CZone *child, *next, *insert; + + // return false if inner was not inserted into outer + if(outer == nil || + !ZoneIsEntirelyContainedWithinOtherZone(inner, outer)) + return false; + + // try to insert inner into children of outer + for(child = outer->child; child; child = child->next) + if(InsertZoneIntoZoneHierRecursive(inner, child)) + return true; + + // insert inner as child of outer + // count number of outer's children contained within inner + n = 0; + for(child = outer->child; child; child = child->next) + if(ZoneIsEntirelyContainedWithinOtherZone(child, inner)) + n++; + inner->next = outer->child; + inner->parent = outer; + outer->child = inner; + // move children from outer to inner + if(n){ + insert = inner; + for(child = inner->next; child; child = next){ + next = child->next; + if(ZoneIsEntirelyContainedWithinOtherZone(child,inner)){ + insert->next = child->next; + child->parent = inner; + child->next = inner->child; + inner->child = child; + }else + insert = child; + } + } + + return true; +} + +bool +CTheZones::ZoneIsEntirelyContainedWithinOtherZone(CZone *inner, CZone *outer) +{ + char tmp[100]; + + if(inner->minx < outer->minx || + inner->maxx > outer->maxx || + inner->miny < outer->miny || + inner->maxy > outer->maxy || + inner->minz < outer->minz || + inner->maxz > outer->maxz){ + CVector vmin(inner->minx, inner->miny, inner->minz); + if(PointLiesWithinZone(&vmin, outer)) + sprintf(tmp, "Overlapping zones %s and %s\n", + inner->name, outer->name); + CVector vmax(inner->maxx, inner->maxy, inner->maxz); + if(PointLiesWithinZone(&vmax, outer)) + sprintf(tmp, "Overlapping zones %s and %s\n", + inner->name, outer->name); + return false; + } + return true; +} + +bool +CTheZones::PointLiesWithinZone(const CVector *v, CZone *zone) +{ + return zone->minx <= v->x && v->x <= zone->maxx && + zone->miny <= v->y && v->y <= zone->maxy && + zone->minz <= v->z && v->z <= zone->maxz; +} + +eLevelName +CTheZones::GetLevelFromPosition(CVector const *v) +{ + int i; +// char tmp[116]; +// if(!PointLiesWithinZone(v, &MapZoneArray[0])) +// sprintf(tmp, "x = %.3f y= %.3f z = %.3f\n", v.x, v.y, v.z); + for(i = 1; i < TotalNumberOfMapZones; i++) + if(PointLiesWithinZone(v, &MapZoneArray[i])) + return MapZoneArray[i].level; + return MapZoneArray[0].level; +} + +CZone* +CTheZones::FindInformationZoneForPosition(const CVector *v) +{ + int i; +// char tmp[116]; +// if(!PointLiesWithinZone(v, &InfoZoneArray[0])) +// sprintf(tmp, "x = %.3f y= %.3f z = %.3f\n", v.x, v.y, v.z); + for(i = 1; i < TotalNumberOfInfoZones; i++) + if(PointLiesWithinZone(v, &InfoZoneArray[i])) + return &InfoZoneArray[i]; + return &InfoZoneArray[0]; +} + +CZone* +CTheZones::FindSmallestNavigationZoneForPosition(const CVector *v, bool findDefault, bool findNavig) +{ + CZone *best = nil; + if(findDefault && NavigationZoneArray[0].type == ZONE_DEFAULT || + findNavig && NavigationZoneArray[0].type == ZONE_NAVIG) + best = &NavigationZoneArray[0]; + // zone to test next + CZone *zone = NavigationZoneArray[0].child; + while(zone) + // if in zone, descent into children + if(PointLiesWithinZone(v, zone)){ + if(findDefault && zone->type == ZONE_DEFAULT || + findNavig && zone->type == ZONE_NAVIG) + best = zone; + zone = zone->child; + // otherwise try next zone + }else + zone = zone->next; + return best; +} + +int16 +CTheZones::FindZoneByLabelAndReturnIndex(char *name, eZoneType type) +{ + char str[8]; + memset(str, 0, 8); + strncpy(str, name, 8); + switch(type){ + case ZONE_DEFAULT: + case ZONE_NAVIG: + for(FindIndex = 0; FindIndex < TotalNumberOfNavigationZones; FindIndex++) + if(strcmp(GetNavigationZone(FindIndex)->name, name) == 0) + return FindIndex; + break; + + case ZONE_INFO: + for(FindIndex = 0; FindIndex < TotalNumberOfInfoZones; FindIndex++) + if(strcmp(GetInfoZone(FindIndex)->name, name) == 0) + return FindIndex; + break; + + case ZONE_MAPZONE: + for(FindIndex = 0; FindIndex < TotalNumberOfMapZones; FindIndex++) + if(strcmp(GetMapZone(FindIndex)->name, name) == 0) + return FindIndex; + break; + } + return -1; +} + +int16 +CTheZones::FindNextZoneByLabelAndReturnIndex(char *name, eZoneType type) +{ + char str[8]; + ++FindIndex; + memset(str, 0, 8); + strncpy(str, name, 8); + switch(type){ + case ZONE_DEFAULT: + case ZONE_NAVIG: + for(; FindIndex < TotalNumberOfNavigationZones; FindIndex++) + if(strcmp(GetNavigationZone(FindIndex)->name, name) == 0) + return FindIndex; + break; + + case ZONE_INFO: + for(; FindIndex < TotalNumberOfInfoZones; FindIndex++) + if(strcmp(GetInfoZone(FindIndex)->name, name) == 0) + return FindIndex; + break; + + case ZONE_MAPZONE: + for(; FindIndex < TotalNumberOfMapZones; FindIndex++) + if(strcmp(GetMapZone(FindIndex)->name, name) == 0) + return FindIndex; + break; + } + return -1; +} + +CZoneInfo* +CTheZones::GetZoneInfo(const CVector *v, uint8 day) +{ + CZone *zone; + zone = FindInformationZoneForPosition(v); + if(zone == nil) + return &ZoneInfoArray[0]; + return &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight]; +} + +void +CTheZones::GetZoneInfoForTimeOfDay(const CVector *pos, CZoneInfo *info) +{ + CZoneInfo *day, *night; + float d, n; + int i; + + day = GetZoneInfo(pos, 1); + night = GetZoneInfo(pos, 0); + + if(CClock::GetIsTimeInRange(8, 19)) + *info = *day; + else if(CClock::GetIsTimeInRange(22, 5)) + *info = *night; + else{ + if(CClock::GetIsTimeInRange(19, 22)){ + n = (CClock::GetHours() - 19) / 3.0f; + assert(n >= 0.0f && n <= 1.0f); + d = 1.0f - n; + }else{ + d = (CClock::GetHours() - 5) / 3.0f; + assert(d >= 0.0f && d <= 1.0f); + n = 1.0f - d; + } + info->carDensity = day->carDensity * d + night->carDensity * n; + for(i = 0; i < ARRAY_SIZE(info->carThreshold); i++) + info->carThreshold[i] = day->carThreshold[i] * d + night->carThreshold[i] * n; + for(i = 0; i < ARRAY_SIZE(info->boatThreshold); i++) + info->boatThreshold[i] = day->boatThreshold[i] * d + night->boatThreshold[i] * n; + for(i = 0; i < ARRAY_SIZE(info->gangThreshold); i++) + info->gangThreshold[i] = day->gangThreshold[i] * d + night->gangThreshold[i] * n; + + info->copThreshold = day->copThreshold * d + night->copThreshold * n; + info->pedDensity = day->pedDensity * d + night->pedDensity * n; + info->copPedThreshold = day->copPedThreshold * d + night->copPedThreshold * n; + for(i = 0; i < ARRAY_SIZE(info->gangPedThreshold); i++) + info->gangPedThreshold[i] = day->gangPedThreshold[i] * d + night->gangPedThreshold[i] * n; + } + if(CClock::GetIsTimeInRange(5, 19)) + info->pedGroup = day->pedGroup; + else + info->pedGroup = night->pedGroup; +} + +void +CTheZones::SetZoneCarInfo(uint16 zoneid, uint8 day, int16 carDensity, + int16 copCarDensity, const int16 *gangCarDensities) +{ + CZone *zone; + CZoneInfo *info; + zone = GetInfoZone(zoneid); + info = &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight]; + + info->carDensity = carDensity; + info->copThreshold = copCarDensity; + info->gangThreshold[0] = gangCarDensities[0] + copCarDensity; + info->gangThreshold[1] = gangCarDensities[1] + info->gangThreshold[0]; + info->gangThreshold[2] = gangCarDensities[2] + info->gangThreshold[1]; + info->gangThreshold[3] = gangCarDensities[3] + info->gangThreshold[2]; + info->gangThreshold[4] = gangCarDensities[4] + info->gangThreshold[3]; + info->gangThreshold[5] = gangCarDensities[5] + info->gangThreshold[4]; + info->gangThreshold[6] = gangCarDensities[6] + info->gangThreshold[5]; + info->gangThreshold[7] = gangCarDensities[7] + info->gangThreshold[6]; + info->gangThreshold[8] = gangCarDensities[8] + info->gangThreshold[7]; +} + +void CTheZones::SetZoneCivilianCarInfo(uint16 zoneid, uint8 day, + const int16* carDensities, const int16* boatDensities) +{ + CZone* zone; + CZoneInfo* info; + zone = GetInfoZone(zoneid); + info = &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight]; + info->carThreshold[0] = carDensities[0]; + for (int i = 1; i < CCarCtrl::NUM_CAR_CLASSES; i++) + info->carThreshold[i] = carDensities[i] + info->carThreshold[i-1]; + info->boatThreshold[0] = boatDensities[0]; + for (int i = 1; i < CCarCtrl::NUM_BOAT_CLASSES; i++) + info->boatThreshold[i] = boatDensities[i] + info->boatThreshold[i - 1]; +} + +void +CTheZones::SetZonePedInfo(uint16 zoneid, uint8 day, int16 pedDensity, + int16 gang0Density, int16 gang1Density, int16 gang2Density, int16 gang3Density, + int16 gang4Density, int16 gang5Density, int16 gang6Density, int16 gang7Density, + int16 gang8Density, int16 copDensity) +{ + CZone *zone; + CZoneInfo *info; + zone = GetInfoZone(zoneid); + info = &ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight]; + info->pedDensity = pedDensity; + info->copPedThreshold = copDensity; + info->gangPedThreshold[0] = gang0Density; + info->gangPedThreshold[1] = gang1Density; + info->gangPedThreshold[2] = gang2Density; + info->gangPedThreshold[3] = gang3Density; + info->gangPedThreshold[4] = gang4Density; + info->gangPedThreshold[5] = gang5Density; + info->gangPedThreshold[6] = gang6Density; + info->gangPedThreshold[7] = gang7Density; + info->gangPedThreshold[8] = gang8Density; + + info->gangPedThreshold[0] += info->copPedThreshold; + info->gangPedThreshold[1] += info->gangPedThreshold[0]; + info->gangPedThreshold[2] += info->gangPedThreshold[1]; + info->gangPedThreshold[3] += info->gangPedThreshold[2]; + info->gangPedThreshold[4] += info->gangPedThreshold[3]; + info->gangPedThreshold[5] += info->gangPedThreshold[4]; + info->gangPedThreshold[6] += info->gangPedThreshold[5]; + info->gangPedThreshold[7] += info->gangPedThreshold[6]; + info->gangPedThreshold[8] += info->gangPedThreshold[7]; +} + +// unused +void +CTheZones::SetCarDensity(uint16 zoneid, uint8 day, uint16 cardensity) +{ + CZone *zone; + zone = GetInfoZone(zoneid); + ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].carDensity = cardensity; +} + +// unused +void +CTheZones::SetPedDensity(uint16 zoneid, uint8 day, uint16 peddensity) +{ + CZone *zone; + zone = GetInfoZone(zoneid); + ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedDensity = peddensity; +} + +void +CTheZones::SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup) +{ + CZone *zone; + zone = GetInfoZone(zoneid); + ZoneInfoArray[day ? zone->zoneinfoDay : zone->zoneinfoNight].pedGroup = pedgroup; +} + +int16 +CTheZones::FindAudioZone(CVector *pos) +{ + int i; + + for(i = 0; i < NumberOfAudioZones; i++) + if(PointLiesWithinZone(pos, GetAudioZone(i))) + return i; + return -1; +} + +void +CTheZones::AddZoneToAudioZoneArray(CZone *zone) +{ + int i, z; + + if(zone->type != ZONE_DEFAULT) + return; + + /* This is a bit stupid */ + z = -1; + for(i = 0; i < NUMNAVIGZONES; i++) + if(&NavigationZoneArray[i] == zone) + z = i; + assert(NumberOfAudioZones < NUMAUDIOZONES); + AudioZoneArray[NumberOfAudioZones++] = z; +} + +void +CTheZones::InitialiseAudioZoneArray(void) +{ + bool gonext; + CZone *zone; + + gonext = false; + zone = &NavigationZoneArray[0]; + // Go deep first, + // set gonext when backing up a level to visit the next child + while(zone) + if(gonext){ + AddZoneToAudioZoneArray(zone); + if(zone->next){ + gonext = false; + zone = zone->next; + }else + zone = zone->parent; + }else if(zone->child) + zone = zone->child; + else{ + AddZoneToAudioZoneArray(zone); + if(zone->next) + zone = zone->next; + else{ + gonext = true; + zone = zone->parent; + } + } +} + +void +CTheZones::SaveAllZones(uint8 *buffer, uint32 *size) +{ + INITSAVEBUF + int i; + +#define CZONE_SAVE_SIZE (sizeof(char)*8+sizeof(float)+sizeof(float)+sizeof(float)+sizeof(float)+sizeof(float)+sizeof(float)+sizeof(eZoneType)+sizeof(eLevelName)+sizeof(int16)+sizeof(int16)+sizeof(int32)+sizeof(int32)+sizeof(int32)) + + *size = SAVE_HEADER_SIZE + + sizeof(m_CurrLevel) + sizeof(FindIndex) + + sizeof(int16) // padding + + CZONE_SAVE_SIZE * ARRAY_SIZE(NavigationZoneArray) + CZONE_SAVE_SIZE * ARRAY_SIZE(InfoZoneArray) + sizeof(ZoneInfoArray) + + sizeof(TotalNumberOfNavigationZones) + sizeof(TotalNumberOfInfoZones) + sizeof(TotalNumberOfZoneInfos) + + sizeof(int16) // padding + + CZONE_SAVE_SIZE * ARRAY_SIZE(MapZoneArray) + sizeof(AudioZoneArray) + + sizeof(TotalNumberOfMapZones) + sizeof(NumberOfAudioZones); +#undef CZONE_SAVE_SIZE + + uint32 length = 0; + WriteSaveHeaderWithLength(buffer, length, 'Z', 'N', 'S', '\0', *size - SAVE_HEADER_SIZE); + + WriteSaveBuf(buffer, length, m_CurrLevel); + WriteSaveBuf(buffer, length, FindIndex); + WriteSaveBuf(buffer, length, (int16)0); // padding + + for(i = 0; i < ARRAY_SIZE(NavigationZoneArray); i++) + SaveOneZone(&NavigationZoneArray[i], &buffer, &length, ZONE_NAVIG); + + for(i = 0; i < ARRAY_SIZE(InfoZoneArray); i++) + SaveOneZone(&InfoZoneArray[i], &buffer, &length, ZONE_INFO); + + for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++) + WriteSaveBuf(buffer, length, ZoneInfoArray[i]); + + WriteSaveBuf(buffer, length, TotalNumberOfNavigationZones); + WriteSaveBuf(buffer, length, TotalNumberOfInfoZones); + WriteSaveBuf(buffer, length, TotalNumberOfZoneInfos); + WriteSaveBuf(buffer, length, (int16)0); // padding + + for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++) + SaveOneZone(&MapZoneArray[i], &buffer, &length, ZONE_MAPZONE); + + for(i = 0; i < ARRAY_SIZE(AudioZoneArray); i++) + WriteSaveBuf(buffer, length, AudioZoneArray[i]); + + WriteSaveBuf(buffer, length, TotalNumberOfMapZones); + WriteSaveBuf(buffer, length, NumberOfAudioZones); + + VALIDATESAVEBUF(*size) +} + +void +CTheZones::SaveOneZone(CZone *zone, uint8 **buffer, uint32 *length, eZoneType zoneType) +{ + WriteSaveBuf(*buffer, *length, *(uint32*)&zone->name[0]); + WriteSaveBuf(*buffer, *length, *(uint32*)&zone->name[4]); + + WriteSaveBuf(*buffer, *length, zone->minx); + WriteSaveBuf(*buffer, *length, zone->miny); + WriteSaveBuf(*buffer, *length, zone->minz); + WriteSaveBuf(*buffer, *length, zone->maxx); + WriteSaveBuf(*buffer, *length, zone->maxy); + WriteSaveBuf(*buffer, *length, zone->maxz); + + WriteSaveBuf(*buffer, *length, zone->type); + WriteSaveBuf(*buffer, *length, zone->level); + WriteSaveBuf(*buffer, *length, zone->zoneinfoDay); + WriteSaveBuf(*buffer, *length, zone->zoneinfoNight); + + int32 zoneId; + zoneId = GetIndexForZonePointer(zone->child); + WriteSaveBuf(*buffer, *length, zoneId); + zoneId = GetIndexForZonePointer(zone->parent); + WriteSaveBuf(*buffer, *length, zoneId); + zoneId = GetIndexForZonePointer(zone->next); + WriteSaveBuf(*buffer, *length, zoneId); +} + +void +CTheZones::LoadAllZones(uint8 *buffer, uint32 size) +{ + INITSAVEBUF + int i; + + uint32 length = 0; + CheckSaveHeaderWithLength(buffer, length, 'Z', 'N', 'S', '\0', size - SAVE_HEADER_SIZE); + + m_CurrLevel = ReadSaveBuf(buffer, length); + FindIndex = ReadSaveBuf(buffer, length); + ReadSaveBuf(buffer, length); + + for(i = 0; i < ARRAY_SIZE(NavigationZoneArray); i++) + LoadOneZone(&NavigationZoneArray[i], &buffer, &length, ZONE_NAVIG); + + for (i = 0; i < ARRAY_SIZE(InfoZoneArray); i++) + LoadOneZone(&InfoZoneArray[i], &buffer, &length, ZONE_INFO); + + for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++) + ZoneInfoArray[i] = ReadSaveBuf(buffer, length); + + TotalNumberOfNavigationZones = ReadSaveBuf(buffer, length); + TotalNumberOfInfoZones = ReadSaveBuf(buffer, length); + TotalNumberOfZoneInfos = ReadSaveBuf(buffer, length); + ReadSaveBuf(buffer, length); + + for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++) + LoadOneZone(&MapZoneArray[i], &buffer, &length, ZONE_MAPZONE); + + for(i = 0; i < ARRAY_SIZE(AudioZoneArray); i++) + AudioZoneArray[i] = ReadSaveBuf(buffer, length); + + TotalNumberOfMapZones = ReadSaveBuf(buffer, length); + NumberOfAudioZones = ReadSaveBuf(buffer, length); + + VALIDATESAVEBUF(size) +} + +void +CTheZones::LoadOneZone(CZone *zone, uint8 **buffer, uint32 *length, eZoneType zoneType) +{ + *(uint32*)&zone->name[0] = ReadSaveBuf(*buffer, *length); + *(uint32*)&zone->name[4] = ReadSaveBuf(*buffer, *length); + + zone->minx = ReadSaveBuf(*buffer, *length); + zone->miny = ReadSaveBuf(*buffer, *length); + zone->minz = ReadSaveBuf(*buffer, *length); + zone->maxx = ReadSaveBuf(*buffer, *length); + zone->maxy = ReadSaveBuf(*buffer, *length); + zone->maxz = ReadSaveBuf(*buffer, *length); + + zone->type = ReadSaveBuf(*buffer, *length); + zone->level = ReadSaveBuf(*buffer, *length); + zone->zoneinfoDay = ReadSaveBuf(*buffer, *length); + zone->zoneinfoNight = ReadSaveBuf(*buffer, *length); + + int32 zoneId; + zoneId = ReadSaveBuf(*buffer, *length); + zone->child = GetPointerForZoneIndex(zoneId); + zoneId = ReadSaveBuf(*buffer, *length); + zone->parent = GetPointerForZoneIndex(zoneId); + zoneId = ReadSaveBuf(*buffer, *length); + zone->next = GetPointerForZoneIndex(zoneId); +} \ No newline at end of file -- cgit v1.2.3