C/C++ code from a mini project I made for myself not long ago.
Code: Select all
struct FLD
{
unsigned short width;
unsigned short height;
unsigned char* block;
};
struct GAT
{
unsigned char magic[6]; // 0
unsigned short width; // 6
short garbageone;
unsigned short height; // 10
short garbagetwo;
struct GATblock* block; //14
};
struct GATblock
{ // Offset
float ulHeight; // 0
float urHeight; // 4
float llHeight; // 8
float lrHeight; // 12
unsigned char type; // 16
unsigned char unknown[3]; // 17
};
Note that width/height are actually unsigned integer values, but I have them as unsigned short because RO maps don't get bigger than 400x400.
The following code is terrible and you shouldn't reuse it. At the same time it gives an idea of how to load structures from a file. You said you are using C# so you probably can't reuse it any way.
Code: Select all
bool GenFld(char* gatName, FLDtwo* fldReturn)
{
FLD fldInfo;
char rswName[255];
strcpy(rswName, gatName);
ChangeFileType((char*)rswName, ".rsw");
unsigned int waterDepth;
waterDepth=GetWaterDepth((char*)rswName);
FILE* gat=fopen(gatName, "r");
if (!gat)
return 0;
GAT gatInfo;
fread(&gatInfo, 14, 1, gat);
unsigned int maxIndex=gatInfo.height*gatInfo.width;
GATblock* blocks=(GATblock*)malloc(sizeof(GATblock)*maxIndex+1);
gatInfo.block=blocks;
fread(blocks, sizeof(GATblock), maxIndex, gat);
FILE* debug=fopen("debug.txt", "w+");
fwrite(&gatInfo, sizeof(gatInfo), 1, debug);
fclose(debug);
fclose(gat);
fldInfo.height=gatInfo.height;
fldInfo.width=gatInfo.width;
fldInfo.block=(unsigned char*)malloc(sizeof(char)*maxIndex+1);
for (unsigned int i=0; i<maxIndex; i++)
{
GATblock thisBlock=gatInfo.block[i];
char type=0;
type=thisBlock.type;
unsigned short y=i/fldInfo.width;
unsigned short x=i- (y*fldInfo.width);
if (x == (fldInfo.width-1) || y == (fldInfo.height-1))
{
type=1;
}
else
{
unsigned int tileDepth=(unsigned int)(thisBlock.ulHeight + thisBlock.urHeight + thisBlock.llHeight + thisBlock.lrHeight) >> 2;
if (tileDepth > waterDepth) //Below ater level
{
if (type == 0 || type == 3)
{
type=3; //Walkable water
}
else if (type == 1 || type == 6)
{
type=2; //Non-walkable water
}
else if (type == 5)
{
type=4;
}
else
{
type=7;
}
}
}
fldInfo.block[i]=type;
}
char fldName[255];
strcpy(fldName, gatName);
ChangeFileType((char*)fldName, ".fld");
SaveFld((char*)fldName, &fldInfo);
return 1;
}
bool LoadFld(char* fldName, FLDtwo* fldReturn)
{
FLD fldInfo;
FILE* fld=fopen(fldName, "r");
if (!fld)
return 0;
fread((void*)&fldInfo, 4, 1, fld);
unsigned int maxIndex=fldInfo.height*fldInfo.width;
unsigned char* blocks=(unsigned char*)malloc(sizeof(char)*maxIndex+1);
fldInfo.block=blocks;
fread(blocks, sizeof(char), maxIndex, fld);
//Fix edge tiles, OpenKore fld marks them as walkable because the gat does - oh hell no
for (unsigned int i=0; i<maxIndex; i++)
{
unsigned short y=i/fldInfo.width;
unsigned short x=i- (y*fldInfo.width);
if (x == (fldInfo.width-1) || y == (fldInfo.height-1))
{
fldInfo.block[i]=1;
}
}
fclose(fld);
return 1;
}
unsigned int GetWaterDepth(char* rswName)
{
FILE* rsw=fopen(rswName, "r");
if (!rsw)
return 0;
char buffer[255];
unsigned int depth;
fread(buffer, 1, 166, rsw);
fread(&depth, 4, 1, rsw);
fclose(rsw);
return depth;
}