pokeheartgold/src/map_matrix.c
2025-07-25 18:13:43 -04:00

227 lines
6.7 KiB
C

#include "fielddata/mapmatrix/map_matrix.naix"
#include "global.h"
#include "constants/maps.h"
#include "filesystem.h"
#include "gf_rtc.h"
#include "map_header.h"
#include "map_matrix.h"
#include "safari_zone.h"
#include "save_vars_flags.h"
#include "sys_vars.h"
static void MapMatrix_MapMatrixData_Load(MAPMATRIXDATA *map_matrix_data, u16 matrix_id, u32 map_no) {
map_matrix_data->width = 0;
map_matrix_data->height = 0;
s32 i;
for (i = 0; i < MAP_MATRIX_MAX_SIZE; i++) {
map_matrix_data->headers[i] = 0;
map_matrix_data->altitudes[i] = 0;
map_matrix_data->maps.models[i] = 0;
}
for (i = 0; i < MAP_MATRIX_MAX_NAME_LENGTH; i++) {
map_matrix_data->name[i] = 0;
}
void *buffer = AllocAtEndAndReadWholeNarcMemberByIdPair(NARC_fielddata_mapmatrix_map_matrix, matrix_id, HEAP_ID_FIELD2);
u8 *cursor = (u8 *)buffer;
map_matrix_data->width = *(cursor++);
map_matrix_data->height = *(cursor++);
u8 has_headers_section = *(cursor++);
u8 has_altitudes_section = *(cursor++);
u8 name_length = *(cursor++);
GF_ASSERT(name_length <= MAP_MATRIX_MAX_NAME_LENGTH);
MI_CpuCopy8(cursor, &map_matrix_data->name, name_length);
cursor += name_length;
if (has_headers_section) {
MI_CpuCopy8(cursor, &map_matrix_data->headers, map_matrix_data->width * map_matrix_data->height * sizeof(u16));
cursor += map_matrix_data->width * map_matrix_data->height * sizeof(u16);
} else {
MIi_CpuClear16((u16)map_no, (u16 *)&map_matrix_data->headers, map_matrix_data->width * map_matrix_data->height * sizeof(u16));
}
if (has_altitudes_section) {
MI_CpuCopy8(cursor, &map_matrix_data->altitudes, map_matrix_data->width * map_matrix_data->height * sizeof(u8));
cursor += map_matrix_data->width * map_matrix_data->height * sizeof(u8);
}
MI_CpuCopy8(cursor, map_matrix_data->maps.models, map_matrix_data->width * map_matrix_data->height * sizeof(u16));
Heap_Free(buffer);
}
MAPMATRIX *MapMatrix_New(void) {
MAPMATRIX *map_matrix = Heap_Alloc(HEAP_ID_FIELD2, sizeof(MAPMATRIX));
map_matrix->width = 0;
map_matrix->height = 0;
map_matrix->matrix_id = 0;
return map_matrix;
}
void MapMatrix_Load(u32 map_no, MAPMATRIX *map_matrix) {
u16 matrix_id = MapHeader_GetMatrixId(map_no);
MapMatrix_MapMatrixData_Load(&map_matrix->data, matrix_id, map_no);
map_matrix->matrix_id = matrix_id;
map_matrix->height = map_matrix->data.height;
map_matrix->width = map_matrix->data.width;
}
void MapMatrix_Free(MAPMATRIX *map_matrix) {
Heap_Free(map_matrix);
}
u16 MapMatrix_GetMapModelNo(s32 map_no, MAPMATRIX *map_matrix) {
GF_ASSERT(map_no < map_matrix->width * map_matrix->height);
return map_matrix->data.maps.models[map_no];
}
u8 MapMatrix_GetWidth(MAPMATRIX *map_matrix) {
GF_ASSERT(map_matrix != NULL);
return map_matrix->width;
}
u8 MapMatrix_GetHeight(MAPMATRIX *map_matrix) {
GF_ASSERT(map_matrix != NULL);
return map_matrix->height;
}
u16 MapMatrix_GetMapHeader(MAPMATRIX *map_matrix, s32 x, s32 y) {
s32 width = map_matrix->width;
s32 height = map_matrix->height;
GF_ASSERT(x >= 0 && x < width);
GF_ASSERT(y >= 0 && y < height);
return map_matrix->data.headers[y * width + x];
}
u8 MapMatrix_GetMatrixId(MAPMATRIX *map_matrix) {
return map_matrix->matrix_id;
}
u8 MapMatrix_GetMapAltitude(MAPMATRIX *map_matrix, u8 matrix_id, u16 x, u16 y, int matrix_width) {
#pragma unused(matrix_id)
GF_ASSERT(x < matrix_width);
GF_ASSERT(y * matrix_width + x < MAP_MATRIX_MAX_SIZE);
return map_matrix->data.altitudes[y * matrix_width + x];
}
MAPDATA *MapMatrix_MapData_New(enum HeapID heapID) {
MAPDATA *map_data = Heap_Alloc(heapID, sizeof(MAPDATA));
void *buffer = AllocAtEndAndReadWholeNarcMemberByIdPair(NARC_fielddata_mapmatrix_map_matrix, 0, heapID);
u8 *cursor = (u8 *)buffer;
cursor += 4;
u8 name_length = *cursor;
cursor++;
cursor += name_length;
MI_CpuCopy8(cursor, map_data, sizeof(MAPDATA));
Heap_Free(buffer);
return map_data;
}
void MapMatrix_MapData_Free(MAPDATA *map_data) {
GF_ASSERT(map_data != NULL);
Heap_Free(map_data);
}
u16 GetMapModelNo(u32 map_no, MAPMATRIX *map_matrix) {
GF_ASSERT(map_matrix != NULL);
return MapMatrix_GetMapModelNo(map_no, map_matrix);
}
void RemoveMahoganyTownAntennaTree(MAPMATRIX *map_matrix) {
u16 *models = map_matrix->data.maps.models;
u8 width = map_matrix->width;
if (map_matrix->matrix_id != NARC_map_matrix_map_matrix_0000_EVERYWHERE_bin) {
return;
}
models[width * 5 + 16] = 86;
}
static inline BOOL MapAndDayCheck(u32 map_no, RTCDate *date) {
return (map_no == MAP_LAKE_OF_RAGE || map_no == MAP_ROUTE_43) && date->week == RTC_WEEK_WEDNESDAY;
}
BOOL ShouldUseAlternateLakeOfRage(SaveData *saveData, u32 map_no) {
RTCDate date;
SaveVarsFlags *state = Save_VarsFlags_Get(saveData);
GF_RTC_CopyDate(&date);
if (Save_VarsFlags_CheckFlagInArray(state, FLAG_RED_GYARADOS_MEET) == FALSE) {
// The player hasn't battled the Red Gyarados yet.
sub_02066C4C(state, 1);
return FALSE;
}
if (!MapAndDayCheck(map_no, &date)) {
sub_02066C4C(state, 1);
return FALSE;
} else {
sub_02066C1C(state, 1);
return TRUE;
}
}
void SetLakeOfRageWaterLevel(MAPMATRIX *map_matrix, BOOL lower_water_level) {
u16 *models = map_matrix->data.maps.models;
u8 width = map_matrix->width;
if (map_matrix->matrix_id != NARC_map_matrix_map_matrix_0000_EVERYWHERE_bin) {
return;
}
if (lower_water_level) {
models[width * 1 + 15] = 95;
models[width * 1 + 16] = 96;
models[width * 1 + 17] = 97;
models[width * 2 + 15] = 98;
models[width * 2 + 16] = 99;
models[width * 2 + 17] = 100;
} else {
models[width * 1 + 15] = 89;
models[width * 1 + 16] = 90;
models[width * 1 + 17] = 91;
models[width * 2 + 15] = 92;
models[width * 2 + 16] = 93;
models[width * 2 + 17] = 94;
}
}
void PlaceSafariZoneAreas(MAPMATRIX *map_matrix, SaveData *save) {
u16 *models = map_matrix->data.maps.models;
s32 width = map_matrix->width;
if (map_matrix->matrix_id != NARC_map_matrix_map_matrix_0212_D47R0102_bin) { // Safari Zone
return;
}
SafariZone *safari_zone = Save_SafariZone_Get(save);
SAFARIZONE_AREASET *sz_area_set = SafariZone_GetAreaSet(safari_zone, 3);
for (s32 y = 0; y < SAFARI_ZONE_AREA_SET_ROWS; y++) {
for (s32 x = 0; x < SAFARI_ZONE_AREA_SET_COLS; x++) {
u8 area_no = sz_area_set->areas[(y * SAFARI_ZONE_AREA_SET_COLS) + x].area_no;
models[width * (y + 1) + x + 1] = 652 + area_no;
}
}
}