Files
source/TileEngine/tiledef.cpp
T
MaddMugsy 49a590ed34 1. PItems are now variable, from 3-20 and can be set in JA2Options.ini via NUM_P_ITEMS
2. USE_XML_TILESETS moved from JA2.ini to JA2Options.ini
3. New Feature - Ctrl+Click on an item with an item in hand to auto-attach/merge them.  Attach works with stacks.  Merge only works on single items, for now at least.
4. New Feature - To accompany Quiet Training, there are now Quiet Repairing and Quiet Doctoring options.
5. Bugfix - inseparable attachments of attachments were getting lost again when using ctrl+f/the map screen button to remove attachments
6. Bugfix - INT8 overflow error causing vehicle repair to actually lower its status
7. GasMask tag in items.xml can now be applied to helmets as well as face items.
8. Bugfix - AI code was referencing hard coded GASMASK item number instead of looking for the tag
9. Bugfix - "break;" was removed in Explosion Control.cpp, thereby causing mustard gas to deal out fire damage. (Not sure if this was deliberate?  But the new implementation differs from the JA2 standard, so it should be added to JA2Options.ini at least)

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@5320 3b4a5df2-a311-0410-b5c6-a8a6f20db521
2012-05-30 10:19:53 +00:00

1346 lines
30 KiB
C++

#ifdef PRECOMPILEDHEADERS
#include "TileEngine All.h"
#else
#include "tiledef.h"
#include "worlddef.h"
#include <stdio.h>
#include <string.h>
#include "wcheck.h"
#include "stdlib.h"
#include "time.h"
#include "video.h"
#include "debug.h"
#include "worldman.h"
#include "gameloop.h"
#include "edit_sys.h"
#include "pathai.h"
#include "tile surface.h"
#include "Tactical Save.h"
#endif
//#include "editscreen.h"
// GLobals
TILE_ELEMENT gTileDatabase[ NUMBEROFTILES ];
UINT16 gTileDatabaseSize;
UINT16 gusNumAnimatedTiles = 0;
UINT16 gusAnimatedTiles[ MAX_ANIMATED_TILES ];
UINT16 gTileTypeStartIndex[ NUMBEROFTILETYPES ];
UINT8 gubEncryptionArray2[ BASE_NUMBER_OF_ROTATION_ARRAYS * 3 ][ NEW_ROTATION_ARRAY_SIZE ] =
{
{
81,168,102,49,61,70,172,
127,7,148,115,179,10,117,
253,35,30,218,76,63,116,
210,241,65,169,157,4,9,
29,205,160,111,41,213,193,
190,86,19,207,133,25,190,
187,131,66,196,253,227,163
},
{
236,81,128,26,96,137,92,
120,243,71,33,141,55,2,
185,185,187,33,230,72,146,
143,226,21,110,155,226,150,
111,124,165,242,4,76,201,
34,223,227,29,202,119,86,
172,219,8,121,183,148,142
},
{
73,81,249,189,120,220,96,
79,28,37,30,199,170,56,
1,10,70,215,151,190,146,
156,233,11,251,146,195,134,
188,140,23,233,137,204,150,
116,36,97,40,119,204,194,
55,9,193,18,143,76,209
},
{
143,200,80,50,154,231,247,
140,225,72,226,136,2,99,
209,182,82,146,128,49,3,
98,101,196,95,136,85,3,
81,37,131,9,251,79,209,
101,128,157,238,229,205,178,
49,161,141,101,175,48,2
},
{
171,145,70,2,204,252,166,
194,2,182,182,189,17,205,
141,80,12,104,215,96,174,
11,106,181,150,113,213,71,
209,89,219,35,229,63,18,
64,237,140,153,224,215,31,
48,198,108,180,139,233,39
},
{
31,60,240,131,203,6,32,
206,137,249,244,36,8,39,
38,142,11,77,76,18,200,
76,210,138,106,198,130,22,
37,178,76,18,233,77,149,
77,28,47,186,126,72,234,
254,158,97,10,162,58,93
},
{
181,91,80,208,248,218,224,
90,219,176,181,120,63,35,
132,167,206,85,6,76,223,
90,15,100,142,121,79,111,
255,88,196,134,19,72,133,
40,95,98,232,153,217,182,
186,109,241,66,128,26,140
},
{
225,112,22,157,253,52,123,
209,31,7,165,18,48,83,
190,53,154,87,188,199,251,
248,185,48,164,93,44,22,
165,77,239,88,148,21,155,
115,203,231,20,170,83,100,
222,204,57,83,39,241,126
},
{
51,228,1,96,176,54,89,
49,157,66,125,113,124,187,
15,110,70,101,246,16,108,
156,20,32,200,96,70,170,
120,198,42,199,79,93,100,
115,246,113,213,187,66,169,
129,241,230,251,145,23,29
},
{
101,67,67,78,108,22,58,
97,212,30,230,190,142,195,
243,169,75,210,61,248,180,
47,75,218,191,5,154,172,
19,204,224,123,244,251,1,
94,192,187,249,33,79,120,
115,109,88,173,40,7,61
},
{
178,239,46,52,245,141,192,
77,114,7,54,78,179,195,
12,213,79,16,184,192,27,
100,195,74,5,1,15,226,
223,50,245,39,244,230,85,
8,196,217,18,128,187,251,
52,225,65,96,62,49,239
},
{
94,190,122,81,36,204,171,
249,104,120,214,89,133,203,
103,19,163,117,53,59,48,
182,240,91,101,160,234,121,
1,78,151,26,3,28,228,
130,138,137,188,21,167,198,
197,34,63,165,195,11,206
},
{
220,164,4,55,94,159,83,
86,186,109,101,150,60,4,
146,58,195,221,221,148,11,
50,155,232,95,39,71,37,
106,104,102,59,34,41,206,
61,129,242,45,11,12,85,
27,184,210,214,165,106,238
},
{
44,151,227,47,39,93,122,
237,91,225,164,198,235,53,
226,36,124,86,57,94,185,
251,231,101,120,178,168,162,
218,38,34,33,126,235,196,
151,30,175,212,103,170,17,
208,48,75,16,231,10,66
},
{
90,201,253,44,89,120,222,
145,82,80,6,63,114,22,
37,106,33,40,177,4,112,
152,9,70,250,103,229,235,
22,147,65,5,164,55,48,
233,103,112,216,69,34,63,
31,159,108,38,14,111,132
},
{
170,177,43,7,140,86,71,
207,205,235,155,239,88,129,
53,6,111,139,249,208,172,
252,34,88,175,213,251,129,
86,54,242,107,142,144,79,
96,161,29,171,196,16,17,
143,205,207,201,47,88,10
},
{
112,203,199,48,59,153,46,
130,221,189,166,213,63,67,
50,190,21,148,242,238,113,
94,28,228,234,100,103,187,
95,53,124,69,6,55,6,
39,204,11,231,64,176,183,
86,248,21,152,62,205,200
},
{
133,189,180,176,46,27,167,
213,33,253,7,209,112,92,
8,60,122,206,229,50,184,
207,25,142,34,149,64,234,
16,252,247,255,22,70,90,
126,212,16,93,248,50,89,
194,248,244,230,224,203,62
},
{
234,231,52,206,57,230,130,
158,240,79,58,175,226,31,
213,160,154,113,199,241,84,
178,66,108,201,41,240,188,
24,9,50,145,172,208,226,
100,127,42,93,55,123,245,
197,102,110,206,48,234,81
},
{
176,193,13,70,253,101,15,
39,156,34,168,239,92,185,
235,239,109,151,115,6,12,
184,92,210,40,152,12,36,
57,183,30,136,247,232,152,
77,59,225,190,208,165,59,
133,118,100,111,45,20,177
},
{
242,224,56,94,247,232,26,
5,5,92,145,57,226,205,
229,79,2,235,214,16,252,
135,176,247,51,4,190,78,
45,155,6,184,220,121,136,
151,66,29,253,210,166,255,
75,82,234,246,152,230,26
},
{
71,92,199,196,224,54,108,
71,191,224,240,145,231,54,
198,135,241,115,219,139,162,
178,253,95,131,237,175,212,
251,85,23,132,211,92,89,
14,166,88,5,254,58,254,
204,5,41,160,72,105,230
},
{
122,240,140,138,243,30,90,
95,32,36,108,168,91,94,
223,161,93,96,118,32,153,
235,41,222,65,8,181,221,
196,207,70,218,41,74,198,
79,6,240,9,240,142,41,
69,48,113,102,15,168,239
},
{
33,100,248,1,115,220,254,
216,113,156,238,175,27,36,
61,20,255,131,209,181,91,
40,126,238,227,186,46,228,
253,64,201,169,138,5,71,
30,20,119,212,255,127,121,
170,240,13,84,96,212,210
},
{
213,91,87,107,184,54,252,
30,240,165,139,29,230,205,
42,49,78,136,10,113,160,
132,246,82,211,200,164,178,
112,128,15,43,150,157,197,
88,7,48,126,75,210,2,
196,228,191,100,25,80,254
},
{
161,100,85,71,23,7,176,
250,104,108,62,88,195,110,
27,102,177,102,127,163,105,
65,133,21,24,117,155,208,
39,37,206,154,225,85,176,
161,128,129,8,6,18,114,
12,53,53,165,90,177,26
},
{
36,101,106,199,26,144,50,
33,13,177,101,149,6,56,
112,251,141,157,46,152,191,
112,214,180,104,160,119,202,
112,75,167,190,116,185,126,
27,229,214,110,194,128,191,
19,24,123,193,148,15,69
},
{
94,179,36,34,168,18,167,
136,168,214,94,144,245,66,
241,83,82,74,25,138,106,
213,7,78,133,181,254,75,
73,230,160,60,93,65,204,
19,24,42,169,150,246,86,
182,211,11,68,108,69,44
},
{
127,97,243,9,60,97,125,
234,114,130,69,83,11,157,
186,44,46,37,4,205,85,
226,218,134,60,127,11,227,
55,80,85,109,26,120,25,
19,60,173,155,255,182,196,
64,12,112,91,145,131,23
},
{
166,108,127,147,227,40,125,
27,76,18,129,108,39,24,
100,92,205,245,147,59,47,
190,251,54,204,28,72,76,
151,24,71,228,181,206,140,
172,161,216,38,201,154,203,
141,252,226,169,135,208,183
},
{
143,63,98,145,133,62,237,
139,191,134,154,119,47,128,
196,154,179,252,48,125,206,
245,106,207,37,87,203,218,
175,115,73,116,243,111,167,
231,22,81,34,216,26,234,
36,136,62,97,46,137,172
},
{
125,118,61,116,135,101,54,
15,215,129,210,84,238,226,
43,56,40,197,174,30,226,
95,117,34,65,115,192,53,
67,222,155,83,103,157,18,
188,158,107,3,133,177,144,
242,76,231,253,233,120,19
},
{
65,199,211,202,123,9,216,
255,223,125,141,168,222,211,
71,184,143,146,32,40,117,
82,140,45,50,203,212,115,
70,166,219,132,100,127,245,
11,146,38,66,68,135,130,
71,59,123,29,51,25,249
},
{
190,161,56,194,42,46,58,
104,89,177,209,173,64,141,
117,68,136,202,201,9,67,
112,209,78,255,233,204,77,
72,199,213,85,252,204,10,
221,117,125,115,252,250,46,
101,111,125,194,139,186,255
},
{
31,86,139,193,121,21,227,
136,133,87,49,18,190,230,
224,29,177,1,149,9,151,
24,129,123,31,191,15,12,
186,16,109,103,75,43,16,
233,124,37,188,28,178,253,
78,27,215,234,165,87,234
},
{
170,4,161,157,18,78,11,
223,148,86,130,184,244,199,
171,43,229,209,235,160,189,
23,30,145,9,19,238,221,
41,113,74,156,184,137,226,
186,241,135,67,86,193,87,
95,11,215,251,31,39,80
},
{
85,223,21,67,248,93,201,
234,55,255,161,143,221,252,
110,10,206,90,36,240,21,
39,237,78,109,10,6,248,
7,125,44,88,104,198,17,
195,47,15,140,61,184,167,
251,182,72,224,147,159,196
},
{
123,19,239,168,30,154,104,
60,207,7,69,172,234,176,
23,31,137,211,242,79,208,
145,194,222,40,205,220,218,
202,197,167,163,162,203,119,
188,250,215,100,172,230,115,
79,119,241,177,204,213,247
},
{
164,47,183,166,25,101,55,
173,255,232,132,251,73,117,
235,22,152,184,146,245,171,
192,242,110,184,81,188,135,
183,224,50,201,210,124,141,
254,235,54,153,73,133,105,
251,27,228,131,103,255,205
},
{
141,53,177,160,37,136,109,
76,46,150,5,207,226,32,
160,180,136,191,175,88,111,
36,245,86,149,192,56,237,
119,37,117,196,117,115,54,
203,93,49,208,170,113,233,
46,143,140,211,5,170,166
},
{
2,245,56,116,61,150,114,
76,28,201,61,29,126,115,
226,153,233,246,200,95,246,
112,88,77,97,48,22,186,
203,102,27,213,211,119,235,
204,147,244,229,21,29,175,
52,103,21,222,146,203,247
},
{
203,187,75,44,10,228,157,
113,156,9,120,202,29,117,
184,122,64,90,44,31,194,
191,30,155,50,190,115,208,
130,69,132,201,246,81,100,
108,67,226,228,85,112,150,
243,222,107,49,158,2,199
},
{
243,107,29,155,25,62,54,
254,77,132,226,20,121,227,
78,33,189,27,153,172,240,
78,17,13,117,133,92,119,
205,123,66,233,177,141,20,
2,21,244,85,47,218,7,
194,47,175,180,65,92,188
},
{
3,223,186,179,171,112,64,
226,172,223,83,208,235,215,
235,20,187,212,96,218,104,
41,66,233,141,50,89,115,
102,35,34,147,219,175,203,
216,121,7,60,166,18,77,
246,202,53,41,124,33,72
},
{
115,8,155,105,168,30,132,
213,57,253,89,18,62,83,
13,138,197,40,21,218,47,
156,13,133,209,66,82,67,
99,176,107,172,80,52,146,
108,148,19,61,193,41,114,
250,121,164,57,125,29,35
},
{
252,37,152,15,100,236,254,
226,253,7,172,123,6,10,
139,17,7,254,146,114,216,
45,95,154,241,252,4,47,
134,193,201,19,97,207,39,
144,254,165,157,60,218,144,
173,48,97,157,173,165,139
},
{
43,160,148,141,246,225,109,
162,9,196,127,84,62,238,
41,82,224,161,103,65,28,
169,227,113,157,43,7,17,
78,6,67,179,102,7,16,
186,197,164,203,143,211,114,
255,34,222,17,63,184,47
},
{
202,17,101,190,148,37,65,
227,178,78,200,202,174,105,
90,13,220,198,78,74,44,
37,172,23,111,225,219,23,
223,119,96,149,12,206,14,
131,243,148,179,37,120,26,
168,77,232,223,65,125,224
},
{
95,160,190,37,50,215,151,
196,31,209,227,48,62,1,
249,123,173,73,232,137,16,
25,39,88,73,51,149,31,
178,19,34,120,74,112,230,
97,243,213,31,34,121,189,
200,255,68,57,75,208,129
},
{
135,244,60,186,169,184,217,
128,88,234,225,59,98,108,
180,189,228,11,222,179,81,
129,225,122,192,210,117,133,
142,124,112,228,166,55,29,
3,133,178,40,47,107,31,
237,22,170,212,75,186,142
},
{
254,191,1,222,153,4,115,
100,149,222,68,112,139,102,
61,231,195,98,156,181,242,
24,137,44,136,34,43,76,
219,155,8,100,28,81,181,
252,75,50,126,154,46,177,
11,53,126,99,180,248,57
},
{
109,132,42,96,40,141,189,
8,138,168,147,13,172,54,
196,69,7,241,14,128,187,
124,187,63,140,172,27,97,
195,63,235,191,196,254,187,
234,123,1,174,6,88,6,
177,247,45,156,120,226,125
},
{
30,95,46,155,25,137,245,
52,68,72,74,137,152,60,
3,26,152,42,137,223,113,
244,114,229,1,192,53,115,
90,174,232,119,234,38,77,
114,195,46,6,151,52,203,
85,96,69,205,58,68,39
},
{
30,59,201,53,236,197,180,
160,196,103,128,88,254,209,
225,82,124,227,135,183,59,
172,203,39,154,168,155,144,
235,35,68,198,41,8,87,
105,92,255,110,51,167,55,
248,69,103,157,208,146,105
},
{
249,205,245,168,172,15,16,
148,112,53,141,74,5,64,
218,194,253,75,243,113,168,
228,80,59,85,44,153,81,
216,126,55,215,165,220,72,
217,83,199,41,128,227,208,
24,3,173,137,18,75,53
},
{
21,130,191,209,19,213,58,
123,18,147,139,147,81,14,
156,255,245,64,150,115,131,
244,12,61,185,211,155,114,
151,96,11,203,200,138,71,
17,26,234,71,106,73,60,
76,106,210,50,115,45,2
},
{
55,17,107,248,62,204,196,
224,45,253,50,10,2,51,
233,34,73,107,137,68,253,
235,235,24,99,52,125,184,
3,3,88,146,80,226,29,
5,25,66,196,226,87,125,
83,169,124,218,190,135,197
},
};
#if 0
// These values coorespond to TerrainTypeDefines order
UINT8 gTileTypeMovementCost[ NUM_TERRAIN_TYPES ] =
{
TRAVELCOST_FLAT, // NO_TERRAIN
TRAVELCOST_FLAT, // FLAT GROUND
TRAVELCOST_FLATFLOOR, // FLAT FLOOR
TRAVELCOST_PAVEDROAD, // PAVED ROAD
TRAVELCOST_DIRTROAD, // DIRT ROAD
TRAVELCOST_GRASS, // LOW_GRASS
TRAVELCOST_THICK, // HIGH GRASS
TRAVELCOST_TRAINTRACKS, // TRAIN TRACKS
TRAVELCOST_SHORE, // LOW WATER
TRAVELCOST_KNEEDEEP, // MED WATER
TRAVELCOST_DEEPWATER, // DEEP WATER
};
#else
// These values coorespond to TerrainTypeDefines order
UINT8 gTileTypeMovementCost[ NUM_TERRAIN_TYPES ] =
{
TRAVELCOST_FLAT, // NO_TERRAIN
TRAVELCOST_FLAT, // FLAT GROUND
TRAVELCOST_FLATFLOOR, // FLAT FLOOR
TRAVELCOST_PAVEDROAD, // PAVED ROAD
TRAVELCOST_DIRTROAD, // DIRT ROAD
TRAVELCOST_FLAT, // LOW_GRASS
TRAVELCOST_FLAT, // HIGH GRASS
TRAVELCOST_TRAINTRACKS, // TRAIN TRACKS
TRAVELCOST_SHORE, // LOW WATER
TRAVELCOST_SHORE, // MED WATER
TRAVELCOST_SHORE, // DEEP WATER
};
#endif
void CreateTileDatabase( )
{
UINT32 cnt1, cnt2;
UINT8 ubLoop;
UINT32 NumRegions;
PTILE_IMAGERY TileSurf;
TILE_ELEMENT TileElement;
// Loop through all surfaces and tiles and build database
for( cnt1 = 0; cnt1 < giNumberOfTileTypes; cnt1++ )
{
// Get number of regions
TileSurf = gTileSurfaceArray[ cnt1 ];
if ( TileSurf != NULL )
{
// Build start index list
gTileTypeStartIndex[ cnt1 ] = (UINT16)gTileDatabaseSize;
NumRegions = TileSurf->vo->usNumberOfObjects;
// Check for overflow
if ( NumRegions > gNumTilesPerType[ cnt1 ] )
{
#ifdef JA2EDITOR
// Display warning
gfWarning = (UINT8)cnt1;
#endif
// Cutof
NumRegions = gNumTilesPerType[ cnt1 ];
}
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Type: %s Size: %d Index: %d", gTileSurfaceName[cnt1], gNumTilesPerType[ cnt1 ], gTileDatabaseSize ) );
for( cnt2 = 0; cnt2 < NumRegions; cnt2++ )
{
memset( &TileElement, 0, sizeof( TileElement ) );
TileElement.usRegionIndex = (UINT16)cnt2;
TileElement.hTileSurface = TileSurf->vo;
TileElement.sBuddyNum = -1;
// Check for multi-z stuff
if ( TileSurf->vo->ppZStripInfo != NULL )
{
// Only do this if we are within the # of video objects
if ( cnt2 < TileSurf->vo->usNumberOfObjects )
{
if ( TileSurf->vo->ppZStripInfo[ cnt2 ] != NULL )
{
TileElement.uiFlags |= MULTI_Z_TILE;
}
}
}
// Structure database stuff!
if (TileSurf->pStructureFileRef != NULL && TileSurf->pStructureFileRef->pubStructureData != NULL)
{
if (TileSurf->pStructureFileRef->pDBStructureRef[cnt2].pDBStructure != NULL)
{
TileElement.pDBStructureRef = &(TileSurf->pStructureFileRef->pDBStructureRef[cnt2]);
if ( TileElement.pDBStructureRef->pDBStructure->fFlags & STRUCTURE_HIDDEN )
{
// ATE: These are ignored!
//TileElement.uiFlags |= HIDDEN_TILE;
}
}
}
TileElement.fType = (UINT16)TileSurf->fType;
TileElement.ubTerrainID = TileSurf->ubTerrainID;
TileElement.usWallOrientation = NO_ORIENTATION;
if (TileSurf->pAuxData != NULL)
{
if (TileSurf->pAuxData[cnt2].fFlags & AUX_FULL_TILE)
{
TileElement.ubFullTile = 1;
}
if (TileSurf->pAuxData[cnt2].fFlags & AUX_ANIMATED_TILE)
{
// Allocate Animated tile data
AllocateAnimTileData( &TileElement, TileSurf->pAuxData[cnt2].ubNumberOfFrames );
// Set values into tile element
TileElement.pAnimData->bCurrentFrame = TileSurf->pAuxData[cnt2].ubCurrentFrame;
for (ubLoop = 0; ubLoop < TileElement.pAnimData->ubNumFrames; ubLoop++)
{
TileElement.pAnimData->pusFrames[ ubLoop ] = gTileDatabaseSize - TileElement.pAnimData->bCurrentFrame + ubLoop;
}
/*
for (ubLoop = TileElement.pAnimData->bCurrentFrame; ubLoop < TileElement.pAnimData->ubNumFrames; ubLoop++)
{
TileElement.pAnimData->pusFrames[ ubLoop ] = gTileDatabaseSize - TileElement.pAnimData->bCurrentFrame + ubLoop;
}
for (ubLoop = 0; ubLoop < TileElement.pAnimData->bCurrentFrame; ubLoop++)
{
TileElement.pAnimData->pusFrames[ ubLoop ] = gTileDatabaseSize - TileElement.pAnimData->bCurrentFrame + ubLoop;
}
*/
// set into animation controller array
gusAnimatedTiles[ gusNumAnimatedTiles ] = gTileDatabaseSize;
gusNumAnimatedTiles++;
Assert( gusNumAnimatedTiles <= MAX_ANIMATED_TILES );
TileElement.uiFlags |= ANIMATED_TILE;
}
TileElement.usWallOrientation = TileSurf->pAuxData[cnt2].ubWallOrientation;
if (TileSurf->pAuxData[cnt2].ubNumberOfTiles > 0)
{
TileElement.ubNumberOfTiles = TileSurf->pAuxData[cnt2].ubNumberOfTiles;
TileElement.pTileLocData = TileSurf->pTileLocData + TileSurf->pAuxData[cnt2].usTileLocIndex;
}
}
SetSpecificDatabaseValues( (UINT16)cnt1, gTileDatabaseSize, &TileElement, TileSurf->bRaisedObjectType );
gTileDatabase[ gTileDatabaseSize ] = TileElement;
gTileDatabaseSize++;
}
// Check if data matches what should be there
if ( NumRegions < gNumTilesPerType[ cnt1 ] )
{
#ifdef JA2EDITOR
// Display warning here
gfWarning = (UINT8)cnt1;
#endif
// Do underflows here
for ( cnt2 = NumRegions; cnt2 < gNumTilesPerType[ cnt1 ]; cnt2++ )
{
memset( &TileElement, 0, sizeof( TileElement ) );
TileElement.usRegionIndex = 0;
TileElement.hTileSurface = TileSurf->vo;
TileElement.fType = (UINT16)TileSurf->fType;
TileElement.ubFullTile = FALSE;
TileElement.sOffsetHeight = 0;
TileElement.ubFullTile = 0;
TileElement.uiFlags |= UNDERFLOW_FILLER;
gTileDatabase[ gTileDatabaseSize ] = TileElement;
gTileDatabaseSize++;
}
}
}
}
//Calculate mem usgae
gSurfaceMemUsage = guiMemTotal - gSurfaceMemUsage;
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Database Sizes: %d vs %d", gTileDatabaseSize, NUMBEROFTILES ) );
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Database Types: %d", NUMBEROFTILETYPES ) );
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Database Item Mem: %d", gTileDatabaseSize * sizeof( TILE_ELEMENT ) ) );
DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("Database Item Total Mem: %d", gSurfaceMemUsage ) );
}
void DeallocateTileDatabase( )
{
INT32 cnt;
for( cnt = 0; cnt < giNumberOfTiles; cnt++ )
{
// Check if an existing set of animated tiles are in place, remove if found
if ( gTileDatabase[ cnt ].pAnimData != NULL )
{
FreeAnimTileData( &gTileDatabase[ cnt ] );
}
}
gTileDatabaseSize = 0;
gSurfaceMemUsage = 0;
gusNumAnimatedTiles = 0;
}
BOOLEAN GetLandHeadType( INT32 iMapIndex, UINT32 *puiType )
{
UINT16 usIndex;
Assert( puiType != NULL );
CHECKF( gpWorldLevelData[ iMapIndex ].pLandHead != NULL );
usIndex = gpWorldLevelData[ iMapIndex ].pLandHead->usIndex;
GetTileType( usIndex, puiType );
return( TRUE );
}
BOOLEAN SetLandIndex( INT32 iMapIndex, UINT16 usIndex, UINT32 uiNewType, BOOLEAN fDelete )
{
UINT16 usTempIndex;
UINT8 ubLastHighLevel=0;
if ( fDelete )
{
RemoveLand( iMapIndex, usIndex );
return( TRUE );
}
if ( AnyHeigherLand( iMapIndex, uiNewType, &ubLastHighLevel ) )
{
// Check if type exists and get it's index if so
if ( TypeExistsInLandLayer( iMapIndex, uiNewType, &usTempIndex ) )
{
// Replace with new index
return( ReplaceLandIndex( iMapIndex, usTempIndex, usIndex ) );
}
else
{
return( InsertLandIndexAtLevel( iMapIndex, usIndex, (UINT8)(ubLastHighLevel+1) ) );
}
}
else
{
// Check if type exists and get it's index if so
if ( TypeExistsInLandLayer( iMapIndex, uiNewType, &usTempIndex ) )
{
// Replace with new index
return( ReplaceLandIndex( iMapIndex, usTempIndex, usIndex ) );
}
else
{
// Otherwise, add to head
return( AddLandToHead( iMapIndex, usIndex ) );
}
}
}
BOOLEAN SetLandIndexWithRadius( INT32 iMapIndex, UINT16 usIndex, UINT32 uiNewType, UINT8 ubRadius, BOOLEAN fReplace )
{
UINT16 usTempIndex;
INT16 sTop, sBottom;
INT16 sLeft, sRight;
INT16 cnt1, cnt2;
INT32 iNewIndex;
BOOLEAN fDoPaste = FALSE;
INT32 leftmost;
//BOOLEAN fNewCommand;
UINT16 Dummy;
// Determine start end end indicies and num rows
sTop = ubRadius;
sBottom = -ubRadius;
sLeft = - ubRadius;
sRight = ubRadius;
//fNewCommand = fFirstDrawMode; //NEW_UNDO_COMMAND;
for( cnt1 = sBottom; cnt1 <= sTop; cnt1++ )
{
leftmost = ( ( iMapIndex + ( WORLD_COLS * cnt1 ) )/ WORLD_COLS ) * WORLD_COLS;
for( cnt2 = sLeft; cnt2 <= sRight; cnt2++ )
{
iNewIndex = iMapIndex + ( WORLD_COLS * cnt1 ) + cnt2;
if ( iNewIndex >=0 && iNewIndex < WORLD_MAX &&
iNewIndex >= leftmost && iNewIndex < ( leftmost + WORLD_COLS ) )
{
if ( fReplace )
{
fDoPaste = TRUE;
}
else
{
if ( !TypeExistsInLandLayer( iNewIndex, uiNewType, &usTempIndex ) )
{
fDoPaste = TRUE;
}
}
if ( fDoPaste && ((uiNewType >= FIRSTFLOOR && uiNewType <= LASTFLOOR) ||
((uiNewType < FIRSTFLOOR || uiNewType > LASTFLOOR) &&
!TypeRangeExistsInLandLayer( iNewIndex, FIRSTFLOOR, LASTFLOOR, &Dummy ))) )
{
SetLandIndex( iNewIndex, usIndex, uiNewType, FALSE );
}
}
}
}
return( TRUE );
}
BOOLEAN GetTypeLandLevel( UINT32 iMapIndex, UINT32 uiNewType, UINT8 *pubLevel )
{
UINT8 level = 0;
LEVELNODE *pLand;
UINT32 fTileType=0;
pLand = gpWorldLevelData[ iMapIndex ].pLandHead;
while( pLand != NULL )
{
if ( pLand->usIndex != NO_TILE )
{
GetTileType( pLand->usIndex, &fTileType );
if ( fTileType == uiNewType )
{
*pubLevel = level;
return( TRUE );
}
}
level++;
pLand = pLand->pNext;
}
return( FALSE );
}
UINT8 GetLandLevelDepth( UINT32 iMapIndex )
{
UINT8 level = 0;
LEVELNODE *pLand;
pLand = gpWorldLevelData[ iMapIndex ].pLandHead;
while( pLand != NULL )
{
level++;
pLand = pLand->pNext;
}
return( level );
}
BOOLEAN GetSubIndexFromTileIndex( UINT16 usTileIndex, UINT16 *pusSubIndex )
{
UINT32 uiType=0;
*pusSubIndex = 0xffff;
if( GetTileType( usTileIndex, &uiType ) )
{
*pusSubIndex = usTileIndex - gTileTypeStartIndex[ uiType ] + 1;
return TRUE;
}
return FALSE;
}
BOOLEAN GetTypeSubIndexFromTileIndex( UINT32 uiCheckType, UINT16 usIndex, UINT16 *pusSubIndex )
{
// Tile database is zero-based, Type indecies are 1-based!
*pusSubIndex = 0xffff;
CHECKF ( uiCheckType < giNumberOfTileTypes );
*pusSubIndex = usIndex - gTileTypeStartIndex[ uiCheckType ] + 1;
return( TRUE );
}
BOOLEAN GetTypeSubIndexFromTileIndexChar( UINT32 uiCheckType, UINT16 usIndex, UINT8 *pubSubIndex )
{
*pubSubIndex = 0xff;
// Tile database is zero-based, Type indecies are 1-based!
CHECKF ( uiCheckType < giNumberOfTileTypes );
*pubSubIndex = (UINT8)(usIndex - gTileTypeStartIndex[ uiCheckType ] + 1);
return( TRUE );
}
BOOLEAN GetTileIndexFromTypeSubIndex( UINT32 uiCheckType, UINT16 usSubIndex, UINT16 *pusTileIndex )
{
// Tile database is zero-based, Type indecies are 1-based!
*pusTileIndex = 0xffff;
CHECKF ( uiCheckType < giNumberOfTileTypes );
*pusTileIndex = usSubIndex + gTileTypeStartIndex[ uiCheckType ] - 1;
return( TRUE );
}
BOOLEAN MoveLandIndexToTop( UINT32 iMapIndex, UINT16 usIndex )
{
// Remove, then add again
RemoveLand( iMapIndex, usIndex );
AddLandToHead( iMapIndex, usIndex );
return( TRUE );
}
// Database access functions
BOOLEAN GetTileType( UINT16 usIndex, UINT32 *puiType )
{
TILE_ELEMENT TileElem;
*puiType = 0xffffffff;
CHECKF( usIndex != NO_TILE );
CHECKF( usIndex < giNumberOfTiles ); //lal bugfix
// Get tile element
TileElem = gTileDatabase[ usIndex ];
*puiType = TileElem.fType;
return( TRUE );
}
BOOLEAN GetTileFlags( UINT16 usIndex, UINT32 *puiFlags )
{
TILE_ELEMENT TileElem;
*puiFlags = 0;
CHECKF( usIndex != NO_TILE );
CHECKF( usIndex < giNumberOfTiles );
// Get tile element
TileElem = gTileDatabase[ usIndex ];
*puiFlags = TileElem.uiFlags;
return( TRUE );
}
BOOLEAN GetTileTypeLogicalHeight( UINT32 fType, UINT8 *pubLogHeight )
{
*pubLogHeight = gTileTypeLogicalHeight[ fType ];
return( TRUE );
}
BOOLEAN LandTypeHeigher( UINT32 uiDestType, UINT32 uiSrcType )
{
UINT8 ubDestLogHeight;
UINT8 ubSrcLogHeight;
// Get logical height of type at head and type we wish to paste
GetTileTypeLogicalHeight( uiDestType, &ubDestLogHeight );
GetTileTypeLogicalHeight( uiSrcType, &ubSrcLogHeight );
return( ubDestLogHeight > ubSrcLogHeight );
}
BOOLEAN AnyHeigherLand( UINT32 iMapIndex, UINT32 uiSrcType, UINT8 *pubLastLevel )
{
LEVELNODE *pLand = NULL;
UINT8 ubSrcLogHeight=0;
UINT32 fTileType=0;
UINT8 level = 0;
UINT8 ubSrcTypeLevel=0;
BOOLEAN fFound = FALSE;
pLand = gpWorldLevelData[ iMapIndex ].pLandHead;
GetTileTypeLogicalHeight( uiSrcType, &ubSrcLogHeight );
// Check that src type is not head
if ( GetTypeLandLevel( iMapIndex, uiSrcType, &ubSrcTypeLevel ) )
{
if ( ubSrcTypeLevel == LANDHEAD )
{
return( FALSE );
}
}
// Look through all objects and Search for type
while( pLand != NULL )
{
// Get type and height
GetTileType( pLand->usIndex, &fTileType );
if ( gTileTypeLogicalHeight[ fTileType ] > ubSrcLogHeight )
{
*pubLastLevel = level;
fFound = TRUE;
}
// Advance to next
pLand = pLand->pNext;
level++;
}
// Could not find it, return FALSE
return( fFound );
}
BOOLEAN AnyLowerLand( UINT32 iMapIndex, UINT32 uiSrcType, UINT8 *pubLastLevel )
{
LEVELNODE *pLand = NULL;
UINT8 ubSrcLogHeight;
UINT32 fTileType=0;
UINT8 level = 0;
UINT8 ubSrcTypeLevel;
TILE_ELEMENT TileElem;
pLand = gpWorldLevelData[ iMapIndex ].pLandHead;
GetTileTypeLogicalHeight( uiSrcType, &ubSrcLogHeight );
GetTypeLandLevel( iMapIndex, uiSrcType, &ubSrcTypeLevel );
// Look through all objects and Search for type
while( pLand != NULL )
{
// Get type and height
GetTileType( pLand->usIndex, &fTileType );
if ( gTileTypeLogicalHeight[ fTileType ] < ubSrcLogHeight )
{
*pubLastLevel = level;
return( TRUE );
}
// Get tile element
TileElem = gTileDatabase[ pLand->usIndex ];
// Get full tile flag
if ( TileElem.ubFullTile && fTileType != uiSrcType )
{
return( FALSE );
}
// Advance to next
pLand = pLand->pNext;
level++;
}
// Could not find it, return FALSE
return( FALSE );
}
BOOLEAN GetWallOrientation( UINT16 usIndex, UINT16 *pusWallOrientation )
{
TILE_ELEMENT TileElem;
*pusWallOrientation = 0xffff;
CHECKF( usIndex != NO_TILE );
CHECKF( usIndex < giNumberOfTiles ); //lal bugfix
// Get tile element
TileElem = gTileDatabase[ usIndex ];
*pusWallOrientation = TileElem.usWallOrientation;
return( TRUE );
}
BOOLEAN ContainsWallOrientation( INT32 iMapIndex, UINT32 uiType, UINT16 usWallOrientation, UINT8 *pubLevel )
{
LEVELNODE *pStruct = NULL;
UINT8 level = 0;
UINT16 usCheckWallOrient=0;
pStruct = gpWorldLevelData[ iMapIndex ].pStructHead;
// Look through all objects and Search for type
while( pStruct != NULL )
{
GetWallOrientation( pStruct->usIndex, &usCheckWallOrient );
if ( usCheckWallOrient == usWallOrientation )
{
*pubLevel = level;
return( TRUE );
}
// Advance to next
pStruct = pStruct->pNext;
level++;
}
// Could not find it, return FALSE
return( FALSE );
}
//Kris: This function returns two special types if there are two walls
//sharing the same tile. This case only happens with the exterior and
//interior bottom corners. Otherwise, it returns the orientation of the
//first wall encountered -- not that there should be duplicate walls...
UINT8 CalculateWallOrientationsAtGridNo( INT32 iMapIndex )
{
UINT16 usCheckWallOrientation=0;
LEVELNODE *pStruct = NULL;
UINT8 ubFinalWallOrientation = NO_ORIENTATION;
pStruct = gpWorldLevelData[ iMapIndex ].pStructHead;
//Traverse all of the pStructs
while( pStruct != NULL )
{
GetWallOrientation( pStruct->usIndex, &usCheckWallOrientation );
if( ubFinalWallOrientation == NO_ORIENTATION )
{ //Get the first valid orientation.
ubFinalWallOrientation = (UINT8)usCheckWallOrientation;
}
else switch( ubFinalWallOrientation )
{ //If the first valid orientation has the key counterpart orientation,
//return the special corner orientations.
case INSIDE_TOP_LEFT:
if( usCheckWallOrientation == INSIDE_TOP_RIGHT )
return INSIDE_BOTTOM_CORNER;
break;
case INSIDE_TOP_RIGHT:
if( usCheckWallOrientation == INSIDE_TOP_LEFT )
return INSIDE_BOTTOM_CORNER;
break;
case OUTSIDE_TOP_LEFT:
if( usCheckWallOrientation == OUTSIDE_TOP_RIGHT )
return OUTSIDE_BOTTOM_CORNER;
break;
case OUTSIDE_TOP_RIGHT:
if( usCheckWallOrientation == OUTSIDE_TOP_LEFT )
return OUTSIDE_BOTTOM_CORNER;
break;
}
// Advance to next
pStruct = pStruct->pNext;
}
// Only one wall, so return it's orienation.
return ubFinalWallOrientation;
}
BOOLEAN AllocateAnimTileData( TILE_ELEMENT *pTileElem, UINT8 ubNumFrames )
{
pTileElem->pAnimData = (TILE_ANIMATION_DATA *)MemAlloc( sizeof( TILE_ANIMATION_DATA ) );
CHECKF( pTileElem->pAnimData != NULL );
pTileElem->pAnimData->pusFrames = (UINT16 *)MemAlloc( sizeof( UINT16 ) * ubNumFrames );
CHECKF( pTileElem->pAnimData->pusFrames != NULL );
// Set # if frames!
pTileElem->pAnimData->ubNumFrames = ubNumFrames;
return( TRUE );
}
void FreeAnimTileData( TILE_ELEMENT *pTileElem )
{
if ( pTileElem->pAnimData != NULL )
{
// Free frames list
MemFree( pTileElem->pAnimData->pusFrames );
// Free frames
MemFree( pTileElem->pAnimData );
}
}