Mercurial > mm7
annotate Engine/Graphics/Outdoor.cpp @ 2563:65c97624c047
Saving & loading works from both main menu and game
author | a.parshin |
---|---|
date | Tue, 19 May 2015 22:00:56 +0200 |
parents | b8a56afc6ba1 |
children | 30eb6dcac768 |
rev | line source |
---|---|
2496 | 1 #define _CRTDBG_MAP_ALLOC |
2545 | 2 #define _CRT_SECURE_NO_WARNINGS |
2496 | 3 #include <stdlib.h> |
4 #include <crtdbg.h> | |
5 | |
2541 | 6 #include "Engine/Engine.h" |
2545 | 7 #include "Engine/Party.h" |
8 #include "Engine/Objects/SpriteObject.h" | |
9 #include "Engine/LOD.h" | |
10 #include "Engine/OurMath.h" | |
11 #include "Engine/Objects/ObjectList.h" | |
12 #include "Engine/Objects/Actor.h" | |
13 #include "Engine/Objects/Chest.h" | |
14 #include "Engine/stru123.h" | |
15 #include "Engine/Timer.h" | |
16 #include "Engine/TurnEngine/TurnEngine.h" | |
17 #include "Engine/Events.h" | |
18 #include "Engine/ZlibWrapper.h" | |
19 #include "Engine/MMT.h" | |
2496 | 20 |
21 #include "stru6.h" | |
22 #include "Weather.h" | |
23 #include "Sprites.h" | |
24 #include "LightmapBuilder.h" | |
25 #include "Outdoor.h" | |
26 #include "PaletteManager.h" | |
27 #include "DecorationList.h" | |
28 #include "Viewport.h" | |
29 #include "ParticleEngine.h" | |
30 #include "Lights.h" | |
2545 | 31 #include "Level/Decoration.h" |
2496 | 32 |
2502 | 33 #include "GUI/GUIWindow.h" |
2545 | 34 #include "GUI/GUIProgressBar.h" |
35 #include "GUI/UI/UITransition.h" | |
36 | |
37 #include "Media/Audio/AudioPlayer.h" | |
38 | |
39 MapStartPoint uLevel_StartingPointType; | |
2496 | 40 |
41 OutdoorLocation *pOutdoor = new OutdoorLocation; | |
42 ODMRenderParams *pODMRenderParams; | |
43 | |
44 | |
45 stru149 stru_8019C8; | |
46 std::array<struct Polygon, 2000 + 18000> array_77EC08; | |
47 | |
48 | |
49 struct FogProbabilityTableEntry | |
50 { | |
51 unsigned char small_fog_chance; | |
52 unsigned char average_fog_chance; | |
53 unsigned char dense_fog_chance; | |
54 unsigned char __unused; | |
55 } fog_probability_table[15] = | |
56 { | |
57 { 20, 10, 5, 0}, // MAP_EMERALD_ISLE | |
58 { 20, 10, 5, 0}, // MAP_HARMONDALE | |
59 { 20, 10, 5, 0}, // MAP_STEADWICK | |
60 { 20, 10, 5, 0}, // MAP_PIERPONT | |
61 { 20, 10, 5, 0}, // MAP_DEYJA | |
62 { 10, 5, 0, 0}, // MAP_BRAKADA_DESERT | |
63 { 0, 0, 0, 0}, // MAP_CELESTIA | |
64 { 0, 0, 0, 0}, // MAP_THE_PIT | |
65 { 20, 30, 50, 0}, // MAP_EVENMORN_ISLE | |
66 { 30, 20, 10, 0}, // MAP_MOUNT_NIGHON | |
67 { 10, 5, 0, 0}, // MAP_BARROW_DOWNS | |
68 { 20, 10, 5, 0}, // MAP_LAND_OF_GIANTS | |
69 { 20, 10, 5, 0}, // MAP_TATALIA | |
70 { 20, 10, 5, 0}, // MAP_AVLEE | |
71 { 0, 100, 0, 0} // MAP_SHOALS | |
72 }; | |
73 | |
74 //for future sky textures? | |
75 std::array<int, 9> dword_4EC268={{3,3,3,3,3,3,3,3,3}}; // weak | |
76 std::array<int, 7> dword_4EC28C={{3,3,3,3,3,3,3}}; // weak | |
77 int dword_4EC2A8=9; // weak | |
78 int dword_4EC2AC=7; // weak | |
79 | |
80 | |
81 | |
82 //----- (0047A59E) -------------------------------------------------------- | |
83 void OutdoorLocation::ExecDraw(unsigned int bRedraw) | |
84 { | |
85 | |
2543 | 86 pIndoorCameraD3D->debug_flags = 0; |
2496 | 87 if (viewparams->draw_d3d_outlines) |
2543 | 88 pIndoorCameraD3D->debug_flags |= ODM_RENDER_DRAW_D3D_OUTLINES; |
2496 | 89 |
90 if (bRedraw || true/*pRenderer->pRenderD3D*/) | |
91 { | |
92 //pODMRenderParams->RotationToInts(); | |
93 sub_481ED9_MessWithODMRenderParams(); | |
94 } | |
95 | |
96 pODMRenderParams->uMapGridCellX = WorldPosToGridCellX(pParty->vPosition.x); | |
97 pODMRenderParams->uMapGridCellZ = WorldPosToGridCellZ(pParty->vPosition.y); | |
98 assert(pODMRenderParams->uMapGridCellX <= 127 && pODMRenderParams->uMapGridCellZ <= 127); | |
99 | |
100 if (bRedraw) | |
101 { | |
102 sub_487DA9(); | |
103 } | |
104 if ( pParty->uCurrentMinute != pOutdoor->uLastSunlightUpdateMinute ) | |
105 pOutdoor->UpdateSunlightVectors(); | |
106 pOutdoor->UpdateFog(); | |
2543 | 107 //pIndoorCameraD3D->sr_Reset_list_0037C(); |
2496 | 108 |
109 //if (pRenderer->pRenderD3D) // d3d - redraw always | |
110 { | |
111 pRenderer->DrawOutdoorSkyD3D(); | |
112 pRenderer->DrawBuildingsD3D(); | |
113 pRenderer->RenderTerrainD3D(); | |
114 //pRenderer->DrawBezierTerrain(); | |
115 } | |
116 /*else | |
117 { | |
118 if (!bRedraw) | |
119 pRenderer->OnOutdoorRedrawSW(); | |
120 else | |
121 { | |
122 pRenderer->DrawBuildingsSW(); | |
123 pRenderer->DrawBezierTerrain(); | |
124 sr_sub_486F92_MessWithEdgesAndSpans(); | |
125 pODMRenderParams->ApplyLightmapsSW(); | |
126 } | |
127 }*/ | |
128 | |
129 | |
130 pMobileLightsStack->uNumLightsActive = 0; | |
131 pStationaryLightsStack->uNumLightsActive = 0; | |
132 /*if ( !pRenderer->pRenderD3D ) | |
133 { | |
134 pRenderer->ExecOutdoorDrawSW(); | |
2543 | 135 pIndoorCameraD3D->sr_438240_draw_lits(); |
2496 | 136 }*/ |
2541 | 137 pEngine->PushStationaryLights(-1); |
138 pEngine->PrepareBloodsplats(); | |
2496 | 139 if (bRedraw) |
140 pOutdoor->UpdateDiscoveredArea(WorldPosToGridCellX(pParty->vPosition.x), WorldPosToGridCellZ(pParty->vPosition.y), 1); | |
2541 | 141 pEngine->uFlags2 &= 0xFFFFFFFEu;//~0x00000001 |
2496 | 142 if (/*pRenderer->pRenderD3D*/true && pRenderer->bUsingSpecular) |
2541 | 143 pEngine->pLightmapBuilder->uFlags |= 1; |
2496 | 144 else |
2541 | 145 pEngine->pLightmapBuilder->uFlags &= 0xFFFFFFFEu;//~0x00000001 |
2496 | 146 |
147 uNumDecorationsDrawnThisFrame = 0; | |
148 uNumSpritesDrawnThisFrame = 0; | |
149 uNumBillboardsToDraw = 0; | |
150 | |
151 PrepareActorsDrawList(); | |
152 if (!pODMRenderParams->bDoNotRenderDecorations) | |
153 pRenderer->PrepareDecorationsRenderList_ODM(); | |
154 | |
155 pRenderer->DrawSpriteObjects_ODM(); | |
156 pRenderer->TransformBillboardsAndSetPalettesODM(); | |
157 } | |
158 | |
159 | |
160 //----- (00441CFF) -------------------------------------------------------- | |
161 void OutdoorLocation::Draw() | |
162 { | |
163 bool redrawWorld = true; | |
2541 | 164 if ( !(pParty->uFlags & 2) && !(pEngine->uFlags2 & 1) ) |
2496 | 165 redrawWorld = false; |
166 pOutdoor->ExecDraw(redrawWorld); | |
167 | |
2541 | 168 pEngine->DrawParticles(); |
2496 | 169 //pWeather->Draw();//если раскомментировать скорость снега быстрее |
170 trail_particle_generator.UpdateParticles(); | |
171 } | |
172 | |
173 //----- (00488E23) -------------------------------------------------------- | |
174 double OutdoorLocation::GetFogDensityByTime() | |
175 { | |
176 if ( pParty->uCurrentHour < 5 )//ночь | |
177 { | |
178 pWeather->bNight = true; | |
179 return 60.0 * 0.016666668; | |
180 } | |
181 else if ( pParty->uCurrentHour >= 5 && pParty->uCurrentHour < 6 )//рассвет | |
182 { | |
183 pWeather->bNight = false; | |
184 return (60.0 - (double)(60 * pParty->uCurrentHour + pParty->uCurrentMinute - 300)) * 0.016666668; | |
185 } | |
186 else if ( pParty->uCurrentHour >= 6 && pParty->uCurrentHour < 20 )//день | |
187 { | |
188 pWeather->bNight = false; | |
189 return 0.0; | |
190 } | |
191 else if ( pParty->uCurrentHour >= 20 && pParty->uCurrentHour < 21 )//сумерки | |
192 { | |
193 pWeather->bNight = false; | |
194 return ((double)(pParty->uCurrentHour - 20) * 60.0 + (double)(signed int)pParty->uCurrentMinute) * 0.016666668; | |
195 } | |
196 else//ночь | |
197 { | |
198 pWeather->bNight = true; | |
199 return 60.0 * 0.016666668; | |
200 } | |
201 } | |
202 | |
203 //----- (00488EB1) -------------------------------------------------------- | |
204 int OutdoorLocation::GetSomeOtherTileInfo(int sX, int sY) | |
205 { | |
206 //OutdoorLocation *v3; // esi@1 | |
207 unsigned int v4; // edi@1 | |
208 unsigned int v5; // eax@1 | |
209 // int result; // eax@5 | |
210 | |
211 /* v3 = this; | |
212 v4 = WorldPosToGridCellZ(sY); | |
213 v5 = WorldPosToGridCellX(sX); | |
214 if ( (v5 & 0x80000000u) != 0 || (signed int)v5 > 127 || (v4 & 0x80000000u) != 0 || (signed int)v4 > 127 ) | |
215 result = 0; | |
216 else | |
217 result = ActuallyGetSomeOtherTileInfo(v5, v4); | |
218 return result;*/ | |
219 v4 = WorldPosToGridCellZ(sY); | |
220 v5 = WorldPosToGridCellX(sX); | |
221 if ( v5 < 0 || v5 > 127 || v4 < 0 || v4 > 127 ) | |
222 return 0; | |
223 return ActuallyGetSomeOtherTileInfo(v5, v4); | |
224 } | |
225 // 47F44B: using guessed type int __stdcall WorldPosToGridCellX(int); | |
226 // 47F458: using guessed type int __stdcall WorldPosToGridCellZ(int); | |
227 | |
228 //----- (00488EEF) -------------------------------------------------------- | |
229 unsigned int OutdoorLocation::GetTileTexture(signed int sX, signed int sY) | |
230 { | |
231 //OutdoorLocation *v3; // esi@1 | |
232 signed int v4; // edi@1 | |
233 signed int v5; // eax@1 | |
234 // unsigned int result; // eax@5 | |
235 | |
236 /*v3 = this; | |
237 v4 = WorldPosToGridCellZ(sZ); | |
238 v5 = WorldPosToGridCellX(sX); | |
239 if ( v5< 0 || (signed int)v5 > 127 || v4 < 0 || (signed int)v4 > 127 )//if ( (v5 & 0x80000000u) != 0 || (signed int)v5 > 127 || (v4 & 0x80000000u) != 0 || (signed int)v4 > 127 ) | |
240 result = -1; | |
241 else | |
242 result = DoGetTileTexture(v5, v4); | |
243 return result;*/ | |
244 v4 = WorldPosToGridCellZ(sY); | |
245 v5 = WorldPosToGridCellX(sX); | |
246 if ( v5 < 0 || v5 > 127 || v4 < 0 || v4 > 127 ) | |
247 return -1; | |
248 return DoGetTileTexture(v5, v4); | |
249 } | |
250 // 47F44B: using guessed type int __stdcall WorldPosToGridCellX(int); | |
251 // 47F458: using guessed type int __stdcall WorldPosToGridCellZ(int); | |
252 | |
253 //----- (00488F2E) -------------------------------------------------------- | |
254 int OutdoorLocation::GetHeightOnTerrain(int sX, int sZ) | |
255 /* Функция предоставляет возможность перемещать камеру таким образом, чтобы она имитировала ходьбу по ландшафту. | |
256 То есть нам надо менять высоту камеры (координату Y) в зависимости от того, в каком месте ландшафта мы находимся. | |
257 Для этого мы сначала должны определить по координатам X и Z камеры квадрат ландшафта в котором мы находимся. | |
258 Все это делает функция Terrain::getHeight; в своих параметрах она получает координаты X и Z камеры и возвращает высоту, | |
259 на которой должна быть расположена камера, чтобы она оказалась над ландшафтом.*/ | |
260 { | |
261 int result; // eax@5 | |
262 | |
263 if ( sX < 0 || sX > 127 || sZ < 0 || sZ > 127 ) | |
264 result = 0; | |
265 else | |
266 result = DoGetHeightOnTerrain(sX, sZ); | |
267 return result; | |
268 } | |
269 | |
270 //----- (00488F5C) -------------------------------------------------------- | |
271 bool OutdoorLocation::Initialize(const char *pFilename, int File, size_t uRespawnInterval, int *thisa) | |
272 { | |
273 OutdoorLocation *v5; // esi@1 | |
274 bool result; // eax@2 | |
275 | |
276 v5 = this; | |
277 if ( pFilename ) | |
278 { | |
279 Release(); | |
280 pBitmaps_LOD->ReleaseAll2(); | |
281 pSprites_LOD->DeleteSomeOtherSprites(); | |
282 pSpriteFrameTable->ResetSomeSpriteFlags(); | |
283 pIcons_LOD->ReleaseAll2(); | |
284 | |
285 if ( !Load(pFilename, (ODMFace *)File, uRespawnInterval, thisa) ) | |
286 { | |
287 MessageBoxA(0, "Error!", "Couldn't Load Map!", 0); | |
288 CreateDebugLocation(); | |
289 } | |
290 ::day_attrib = v5->loc_time.day_attrib; | |
291 ::day_fogrange_1 = v5->loc_time.day_fogrange_1; | |
292 ::day_fogrange_2 = v5->loc_time.day_fogrange_2; | |
293 if ( Is_out15odm_underwater() ) | |
294 SetUnderwaterFog(); | |
295 _6BE134_odm_main_tile_group = v5->pTileTypes[0].tileset; | |
296 result = 1; | |
297 } | |
298 else | |
299 { | |
300 result = 0; | |
301 } | |
302 return result; | |
303 } | |
304 | |
305 | |
306 | |
307 char foot_travel_destinations[15][4] = | |
308 { | |
309 // north south east west from | |
310 {MAP_INVALID, MAP_INVALID, MAP_INVALID, MAP_INVALID}, // MAP_EMERALD_ISLE | |
311 {MAP_PIERPONT, MAP_BARROW_DOWNS, MAP_PIERPONT, MAP_STEADWICK}, // MAP_HARMONDALE | |
312 {MAP_DEYJA, MAP_BRAKADA_DESERT, MAP_HARMONDALE, MAP_TATALIA}, // MAP_STEADWICK | |
313 {MAP_AVLEE, MAP_HARMONDALE, MAP_INVALID, MAP_DEYJA}, // MAP_PIERPONT | |
314 {MAP_PIERPONT, MAP_STEADWICK, MAP_PIERPONT, MAP_STEADWICK}, // MAP_DEYJA | |
315 {MAP_STEADWICK, MAP_INVALID, MAP_BARROW_DOWNS, MAP_INVALID}, // MAP_BRAKADA_DESERT | |
316 {MAP_INVALID, MAP_INVALID, MAP_INVALID, MAP_INVALID}, // MAP_CELESTIA | |
317 {MAP_INVALID, MAP_INVALID, MAP_INVALID, MAP_INVALID}, // MAP_THE_PIT | |
318 {MAP_INVALID, MAP_INVALID, MAP_INVALID, MAP_INVALID}, // MAP_EVENMORN_ISLE | |
319 {MAP_INVALID, MAP_INVALID, MAP_INVALID, MAP_INVALID}, // MAP_MOUNT_NIGHON | |
320 {MAP_HARMONDALE, MAP_BRAKADA_DESERT, MAP_HARMONDALE, MAP_BRAKADA_DESERT}, // MAP_BARROW_DOWNS | |
321 {MAP_INVALID, MAP_INVALID, MAP_INVALID, MAP_INVALID}, // MAP_LAND_OF_GIANTS | |
322 {MAP_INVALID, MAP_INVALID, MAP_STEADWICK, MAP_INVALID}, // MAP_TATALIA | |
323 {MAP_INVALID, MAP_PIERPONT, MAP_PIERPONT, MAP_INVALID}, // MAP_AVLEE | |
324 {MAP_INVALID, MAP_INVALID, MAP_INVALID, MAP_INVALID} // MAP_SHOALS | |
325 }; | |
326 unsigned char foot_travel_times[15][4] = | |
327 { | |
328 // north south east west from | |
329 {0, 0, 0, 0}, // MAP_EMERALD_ISLE | |
330 {5, 5, 7, 5}, // MAP_HARMONDALE | |
331 {5, 5, 5, 5}, // MAP_STEADWICK | |
332 {5, 5, 0, 5}, // MAP_PIERPONT | |
333 {7, 5, 5, 4}, // MAP_DEYJA | |
334 {5, 0, 5, 0}, // MAP_BRAKADA_DESERT | |
335 {0, 0, 0, 0}, // MAP_CELESTIA | |
336 {0, 0, 0, 0}, // MAP_THE_PIT | |
337 {0, 0, 0, 0}, // MAP_EVENMORN_ISLE | |
338 {0, 0, 0, 0}, // MAP_MOUNT_NIGHON | |
339 {5, 7, 7, 5}, // MAP_BARROW_DOWNS | |
340 {0, 0, 0, 0}, // MAP_LAND_OF_GIANTS | |
341 {0, 0, 5, 0}, // MAP_TATALIA | |
342 {0, 7, 5, 0}, // MAP_AVLEE | |
343 {0, 0, 0, 0}, // MAP_SHOALS | |
344 }; | |
345 | |
346 | |
347 MapStartPoint foot_travel_arrival_points[15][4] = | |
348 { | |
349 // north south east west from | |
350 {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party}, // MAP_EMERALD_ISLE | |
351 {MapStartPoint_South, MapStartPoint_North, MapStartPoint_South, MapStartPoint_East}, // MAP_HARMONDALE | |
352 {MapStartPoint_South, MapStartPoint_North, MapStartPoint_West, MapStartPoint_East}, // MAP_STEADWICK | |
353 {MapStartPoint_East, MapStartPoint_North, MapStartPoint_Party, MapStartPoint_East}, // MAP_PIERPONT | |
354 {MapStartPoint_West, MapStartPoint_North, MapStartPoint_West, MapStartPoint_North}, // MAP_DEYJA | |
355 {MapStartPoint_South, MapStartPoint_Party, MapStartPoint_West, MapStartPoint_Party}, // MAP_BRAKADA_DESERT | |
356 {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party}, // MAP_CELESTIA | |
357 {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party}, // MAP_THE_PIT | |
358 {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party}, // MAP_EVENMORN_ISLE | |
359 {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party}, // MAP_MOUNT_NIGHON | |
360 {MapStartPoint_South, MapStartPoint_East, MapStartPoint_South, MapStartPoint_East}, // MAP_BARROW_DOWNS | |
361 {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party}, // MAP_LAND_OF_GIANTS | |
362 {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_West, MapStartPoint_Party}, // MAP_TATALIA | |
363 {MapStartPoint_Party, MapStartPoint_North, MapStartPoint_North, MapStartPoint_Party}, // MAP_AVLEE | |
364 {MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party, MapStartPoint_Party}, // MAP_SHOALS | |
365 }; | |
366 | |
367 | |
368 //----- (0048902E) -------------------------------------------------------- | |
369 bool OutdoorLocation::GetTravelDestination(signed int sPartyX, signed int sPartyZ, char *pOut, signed int a5) | |
370 { | |
371 char *mapNumberAsStr; // eax@3 | |
372 int mapNumberAsInt; // eax@3 | |
373 signed int direction; // esi@7 | |
374 signed int destinationMap; // eax@23 | |
375 char Str[140]; // [sp+8h] [bp-78h]@3 | |
376 | |
377 strcpy(Str, this->pLevelFilename);//настоящая локация | |
378 _strlwr(Str); | |
379 mapNumberAsStr = strtok(Str, "out"); | |
380 mapNumberAsStr[2] = 0; | |
381 mapNumberAsInt = atoi(mapNumberAsStr); | |
382 if ( a5 < 10 || strlen(this->pLevelFilename) != 9 || mapNumberAsInt < 1 || mapNumberAsInt > 15 ) //длина .odm и количество локаций | |
383 return 0; | |
384 if ( sPartyX < -22528 )//граница карты | |
385 direction = 4; | |
386 else if ( sPartyX > 22528 ) | |
387 direction = 3; | |
388 else if ( sPartyZ < -22528 ) | |
389 direction = 2; | |
390 else if ( sPartyZ > 22528 ) | |
391 direction = 1; | |
392 else | |
393 return false; | |
394 | |
395 if ( mapNumberAsInt == MAP_AVLEE && direction == 4) // to Shoals | |
396 { | |
397 if ( pPlayers[1]->HasUnderwaterSuitEquipped() && | |
398 pPlayers[2]->HasUnderwaterSuitEquipped() && | |
399 pPlayers[3]->HasUnderwaterSuitEquipped() && | |
400 pPlayers[4]->HasUnderwaterSuitEquipped()) | |
401 { | |
402 uDefaultTravelTime_ByFoot = 1; | |
403 strcpy(pOut, "out15.odm"); | |
404 uLevel_StartingPointType = MapStartPoint_East; | |
405 LOWORD(pParty->uFlags) &= 0xFD7Bu; | |
406 return true; | |
407 } | |
408 } | |
409 else if ( mapNumberAsInt == MAP_SHOALS && direction == 3 ) //from Shoals | |
410 { | |
411 uDefaultTravelTime_ByFoot = 1; | |
412 strcpy(pOut, "out14.odm");//Авли | |
413 uLevel_StartingPointType = MapStartPoint_West; | |
414 LOWORD(pParty->uFlags) &= 0xFD7Bu; | |
415 return true; | |
416 } | |
417 destinationMap = foot_travel_destinations[mapNumberAsInt - 1][direction - 1]; | |
418 if (destinationMap == MAP_INVALID) | |
419 return false; | |
420 | |
421 assert(destinationMap <= MAP_SHOALS); | |
422 | |
423 uDefaultTravelTime_ByFoot = foot_travel_times[mapNumberAsInt - 1][direction - 1]; | |
424 uLevel_StartingPointType = foot_travel_arrival_points[mapNumberAsInt - 1][direction - 1]; | |
425 sprintf(pOut, "out%02d.odm", destinationMap); //локация направления | |
426 return true; | |
427 } | |
428 // 6BD07C: using guessed type int uDefaultTravelTime_ByFoot; | |
429 // 6BE35C: using guessed type int uLevel_StartingPointType; | |
430 | |
431 //----- (0048917E) -------------------------------------------------------- | |
432 void OutdoorLocation::MessWithLUN() | |
433 { | |
434 this->pSpriteIDs_LUN[0] = -1; | |
435 this->pSpriteIDs_LUN[1] = 0; | |
436 this->pSpriteIDs_LUN[2] = pSpriteFrameTable->FastFindSprite("LUN1-4"); | |
437 this->pSpriteIDs_LUN[3] = 0; | |
438 this->pSpriteIDs_LUN[4] = pSpriteFrameTable->FastFindSprite("LUN1-2"); | |
439 this->pSpriteIDs_LUN[5] = 0; | |
440 this->pSpriteIDs_LUN[6] = pSpriteFrameTable->FastFindSprite("LUN3-4"); | |
441 this->pSpriteIDs_LUN[7] = 0; | |
442 this->uSpriteID_LUNFULL = pSpriteFrameTable->FastFindSprite("LUNFULL"); | |
443 this->uSpriteID_LUN1_2_cp = pSpriteFrameTable->FastFindSprite("LUN1-2"); | |
444 this->uSpriteID_LUN1_4_cp = pSpriteFrameTable->FastFindSprite("LUN1-4"); | |
445 this->uSpriteID_LUN3_4_cp = pSpriteFrameTable->FastFindSprite("LUN3-4"); | |
446 this->field_D60 = -1; | |
447 this->field_CF0 = 4; | |
448 this->field_CF8 = 4; | |
449 this->field_D00 = 4; | |
450 this->field_CE8 = 0; | |
451 this->field_D3C = (int)this->pSpriteIDs_LUN; | |
452 this->field_D40 = 0; | |
453 this->field_D44 = 0; | |
454 this->field_D48 = 0; | |
455 this->field_D4C = 131072; | |
456 this->field_D5C = 0; | |
457 this->field_D64 = 0; | |
458 this->field_D28 = -1; | |
459 this->field_D08 = 0; | |
460 this->field_D0C = 0; | |
461 this->field_D10 = 0; | |
462 this->field_D24 = 0; | |
463 this->field_D2C = 0; | |
464 this->uSpriteID_LUN_SUN = pSpriteFrameTable->FastFindSprite("LUN-SUN"); | |
465 this->field_D14 = -131072; | |
466 for ( uint i = 0; i < 8; i++ ) | |
467 pSpriteFrameTable->InitializeSprite(this->pSpriteIDs_LUN[i]);//v2 += 2; | |
468 pSpriteFrameTable->InitializeSprite(this->uSpriteID_LUN_SUN); | |
469 } | |
470 | |
471 //----- (004892E6) -------------------------------------------------------- | |
472 void OutdoorLocation::UpdateSunlightVectors() | |
473 { | |
474 unsigned int v3; // edi@3 | |
475 double v8; // st7@4 | |
476 | |
477 if ( pParty->uCurrentHour >= 5 && pParty->uCurrentHour < 21 ) | |
478 { | |
479 v3 = pParty->uCurrentMinute + 60 * (pParty->uCurrentHour - 5); | |
480 this->inv_sunlight_y = 0; | |
481 this->inv_sunlight_x = stru_5C6E00->Cos((v3 * stru_5C6E00->uIntegerPi) / 960); | |
482 this->inv_sunlight_z = stru_5C6E00->Sin((v3 * stru_5C6E00->uIntegerPi) / 960); | |
483 this->vSunlight.x = -this->inv_sunlight_x; | |
484 this->vSunlight.y = -this->inv_sunlight_y; | |
485 this->vSunlight.z = -this->inv_sunlight_z; | |
486 if ( v3 >= 480 ) | |
487 v8 = 960 - v3; | |
488 else | |
489 v8 = v3; | |
490 this->max_terrain_dimming_level = (int)(20.0 - v8 / 480.0 * 20.0); | |
491 this->uLastSunlightUpdateMinute = pParty->uCurrentMinute; | |
492 } | |
493 } | |
494 | |
495 //----- (004893C1) -------------------------------------------------------- | |
496 void OutdoorLocation::UpdateFog() | |
497 { | |
498 fFogDensity = GetFogDensityByTime(); | |
499 } | |
500 | |
501 //----- (004893CF) -------------------------------------------------------- | |
502 int OutdoorLocation::GetNumFoodRequiredToRestInCurrentPos(int x, signed int y, int z) | |
503 { | |
504 int v7; // eax@4 | |
505 int is_on_water; // [sp+8h] [bp-8h]@2 | |
506 int bmodel_standing_on_pid; // [sp+Ch] [bp-4h]@2 | |
507 | |
508 is_on_water = 0; | |
509 bmodel_standing_on_pid = 0; | |
510 ODM_GetFloorLevel(x, y, z, pParty->uDefaultPartyHeight, &is_on_water, &bmodel_standing_on_pid, 0); | |
511 if ( pParty->uFlags & 8 || bmodel_standing_on_pid || is_on_water )//на bmodel,и или на воде | |
512 return 2; | |
513 v7 = _47ED83(WorldPosToGridCellX(pParty->vPosition.x), WorldPosToGridCellZ(pParty->vPosition.y) - 1); | |
514 switch ( pTileTable->pTiles[GetTileIdByTileMapId(v7)].tileset ) | |
515 { | |
516 case Tileset_Grass://на траве | |
517 return 1; | |
518 case Tileset_Snow://на снегу | |
519 return 3; | |
520 case Tilset_Desert://на песке | |
521 return 5; | |
2534 | 522 case Tileset_CooledLava: |
2496 | 523 case Tileset_Dirt:// на грязи |
524 return 4; | |
525 case Tileset_Water:// on water(на воде) | |
526 return 3;//еденицы еды | |
527 default: | |
528 return 2; | |
529 } | |
530 } | |
531 | |
532 //----- (00489487) -------------------------------------------------------- | |
533 void OutdoorLocation::SetFog() | |
534 { | |
535 strcpy(pOutdoor->pLevelFilename, pCurrentMapName); | |
536 | |
537 MAP_TYPE map_id = pMapStats->GetMapInfo(pCurrentMapName); | |
538 if (map_id == MAP_INVALID || map_id == MAP_CELESTIA || map_id == MAP_THE_PIT || map_id > MAP_SHOALS) | |
539 return; | |
540 | |
541 uint chance = rand() % 100; | |
542 | |
543 if (chance < fog_probability_table[map_id - 1].small_fog_chance) | |
544 { | |
545 ::day_fogrange_1 = 4096; | |
546 ::day_fogrange_2 = 8192; | |
547 ::day_attrib |= DAY_ATTRIB_FOG; | |
548 } | |
549 else if (chance < fog_probability_table[map_id - 1].small_fog_chance + | |
550 fog_probability_table[map_id - 1].average_fog_chance) | |
551 { | |
552 ::day_fogrange_2 = 4096; | |
553 ::day_fogrange_1 = 0; | |
554 ::day_attrib |= DAY_ATTRIB_FOG; | |
555 } | |
556 else if (fog_probability_table[map_id - 1].dense_fog_chance && | |
557 chance < fog_probability_table[map_id - 1].small_fog_chance + | |
558 fog_probability_table[map_id - 1].average_fog_chance + | |
559 fog_probability_table[map_id - 1].dense_fog_chance) | |
560 { | |
561 ::day_fogrange_2 = 2048; | |
562 ::day_fogrange_1 = 0; | |
563 ::day_attrib |= DAY_ATTRIB_FOG; | |
564 } | |
565 else | |
566 ::day_attrib &= ~DAY_ATTRIB_FOG; | |
567 | |
568 if ( Is_out15odm_underwater() ) | |
569 SetUnderwaterFog(); | |
570 pOutdoor->loc_time.day_fogrange_1 = ::day_fogrange_1; | |
571 pOutdoor->loc_time.day_fogrange_2 = ::day_fogrange_2; | |
572 pOutdoor->loc_time.day_attrib = ::day_attrib; | |
573 } | |
574 | |
575 //----- (00482170) -------------------------------------------------------- | |
576 bool ODMFace::IsBackfaceNotCulled(RenderVertexSoft *a2, struct Polygon *polygon) | |
577 { | |
578 unsigned int numOfVertices; // edx@1 | |
579 RenderVertexSoft *currVertex; // ecx@2 | |
580 double v7; // st7@5 | |
581 double v8; // st6@5 | |
582 double v9; // st5@5 | |
583 float v18; // [sp+8h] [bp-38h]@5 | |
584 float v19; // [sp+10h] [bp-30h]@5 | |
585 float v20; // [sp+14h] [bp-2Ch]@5 | |
586 float v21; // [sp+18h] [bp-28h]@5 | |
587 float v22; // [sp+1Ch] [bp-24h]@5 | |
588 float v23; // [sp+24h] [bp-1Ch]@5 | |
589 float v24; // [sp+28h] [bp-18h]@5 | |
590 float v25; // [sp+30h] [bp-10h]@5 | |
591 float v26; // [sp+34h] [bp-Ch]@5 | |
592 float v27; // [sp+38h] [bp-8h]@5 | |
593 float v28; // [sp+3Ch] [bp-4h]@5 | |
594 float a3a; // [sp+48h] [bp+8h]@5 | |
595 float a3b; // [sp+48h] [bp+8h]@17 | |
596 float a3c; // [sp+48h] [bp+8h]@17 | |
597 float a3d; // [sp+48h] [bp+8h]@17 | |
598 float a3e; // [sp+48h] [bp+8h]@17 | |
599 | |
600 numOfVertices = polygon->uNumVertices; | |
601 if ( numOfVertices < 3 ) | |
602 return false; | |
603 currVertex = &a2[numOfVertices - 1]; | |
604 if ( a2->vWorldPosition.z == a2[1].vWorldPosition.z && a2[1].vWorldPosition.z == currVertex->vWorldPosition.z ) | |
605 polygon->flags |= 0x10u; | |
606 | |
607 v28 = a2[1].vWorldPosition.x - a2->vWorldPosition.x; | |
608 v27 = a2[1].vWorldPosition.y - a2->vWorldPosition.y; | |
609 a3a = a2[1].vWorldPosition.z - a2->vWorldPosition.z; | |
610 | |
611 | |
612 for (int i = 0; i < numOfVertices; i++) | |
613 { | |
614 v7 = currVertex->vWorldPosition.x - a2->vWorldPosition.x; | |
615 v8 = currVertex->vWorldPosition.y - a2->vWorldPosition.y; | |
616 v9 = currVertex->vWorldPosition.z - a2->vWorldPosition.z; | |
617 v26 = v27 * v9 - v8 * a3a; | |
618 v24 = v7 * a3a - v9 * v28; | |
619 v25 = v8 * v28 - v7 * v27; | |
620 if ( v24 != 0.0 || v25 != 0.0 || v26 != 0.0 ) | |
621 break; | |
622 currVertex--; | |
623 } | |
624 | |
2543 | 625 if ( ((double)pIndoorCameraD3D->vPartyPos.x - a2->vWorldPosition.x) * v26 |
626 + ((double)pIndoorCameraD3D->vPartyPos.z - a2->vWorldPosition.z) * v25 | |
627 + ((double)pIndoorCameraD3D->vPartyPos.y - a2->vWorldPosition.y) * v24 > 0.0 ) | |
2496 | 628 { |
629 | |
630 v19 = a2[1].vWorldViewPosition.x - a2->vWorldViewPosition.x; | |
631 v18 = a2[1].vWorldViewPosition.y - a2->vWorldViewPosition.y; | |
632 v20 = a2[1].vWorldViewPosition.z - a2->vWorldViewPosition.z; | |
633 v21 = currVertex->vWorldViewPosition.x - a2->vWorldViewPosition.x; | |
634 v22 = currVertex->vWorldViewPosition.y - a2->vWorldViewPosition.y; | |
635 v23 = currVertex->vWorldViewPosition.z - a2->vWorldViewPosition.z; | |
636 | |
637 a3b = v23 * v18 - v22 * v20; | |
638 polygon->v_18.x = bankersRounding(a3b); | |
639 a3c = v21 * v20 - v23 * v19; | |
640 polygon->v_18.y = bankersRounding(a3c); | |
641 a3d = v22 * v19 - v21 * v18; | |
642 polygon->v_18.z = bankersRounding(a3d); | |
643 polygon->_normalize_v_18(); | |
644 a3e = -((double)polygon->v_18.x * a2->vWorldViewPosition.x) | |
645 - (double)polygon->v_18.y * a2->vWorldViewPosition.y | |
646 - (double)polygon->v_18.z * a2->vWorldViewPosition.z; | |
647 polygon->field_24 = bankersRounding(a3e); | |
648 return true; | |
649 } | |
650 else | |
651 return false; | |
652 } | |
653 | |
654 //----- (0047C7A9) -------------------------------------------------------- | |
655 void OutdoorLocationTerrain::_47C7A9() | |
656 { | |
657 this->field_10 = 0; | |
658 this->field_12 = 0; | |
659 this->field_16 = 0; | |
660 this->field_14 = 0; | |
661 this->field_1C = 0; | |
662 this->field_18 = 0; | |
663 } | |
664 | |
665 //----- (0047C7C2) -------------------------------------------------------- | |
666 void OutdoorLocationTerrain::Release()//очистить локацию | |
667 { | |
668 free(this->pHeightmap); | |
669 pHeightmap = nullptr; | |
670 free(pTilemap); | |
671 pTilemap = nullptr; | |
672 free(pAttributemap); | |
673 pAttributemap = nullptr; | |
674 free(pDmap); | |
675 pDmap = nullptr; | |
676 | |
677 _47C7A9(); | |
678 } | |
679 | |
680 //----- (0047C80A) -------------------------------------------------------- | |
681 void OutdoorLocationTerrain::FillDMap( int X, int Y, int W, int Z ) | |
682 { | |
683 double v6; // st7@1 | |
684 double v7; // st7@2 | |
685 double v8; // st7@2 | |
686 int result; // eax@3 | |
687 int v10; // eax@4 | |
688 int v11; // ecx@5 | |
689 int v12; // ecx@6 | |
690 int v13; // edi@7 | |
691 int v14; // edx@9 | |
692 // int v15; // eax@15 | |
693 unsigned __int8 *pMapHeight; // ebx@15 | |
694 int v17; // eax@15 | |
695 int v18; // ecx@15 | |
696 int v19; // esi@15 | |
697 int v20; // edi@15 | |
698 int v21; // edx@15 | |
699 int v22; // ecx@15 | |
700 int v23; // ebx@15 | |
701 int v24; // ecx@15 | |
702 int v25; // ST28_4@15 | |
703 double v26; // st7@15 | |
704 double v27; // st6@15 | |
705 double v28; // st5@15 | |
706 double v29; // st7@15 | |
707 double v30; // st7@16 | |
708 double v31; // st7@17 | |
709 int v32; // eax@21 | |
710 double v33; // st7@21 | |
711 double v34; // st6@21 | |
712 double v35; // st5@21 | |
713 double v36; // st7@21 | |
714 double v37; // st7@22 | |
715 double v38; // st7@23 | |
716 int v39; // [sp+14h] [bp-34h]@8 | |
717 int v40; // [sp+18h] [bp-30h]@15 | |
718 int v41; // [sp+1Ch] [bp-2Ch]@15 | |
719 int v42; // [sp+20h] [bp-28h]@15 | |
720 int v44; // [sp+28h] [bp-20h]@21 | |
721 float v45; // [sp+2Ch] [bp-1Ch]@1 | |
722 float v46; // [sp+30h] [bp-18h]@1 | |
723 float v47; // [sp+34h] [bp-14h]@1 | |
724 //int v48; // [sp+38h] [bp-10h]@7 | |
725 int v49; // [sp+3Ch] [bp-Ch]@10 | |
726 int v50; // [sp+40h] [bp-8h]@9 | |
727 float v51; // [sp+44h] [bp-4h]@15 | |
728 float v52; // [sp+44h] [bp-4h]@21 | |
729 float v53; // [sp+50h] [bp+8h]@15 | |
730 float v54; // [sp+50h] [bp+8h]@21 | |
731 // int v55; // [sp+54h] [bp+Ch]@15 | |
732 float v56; // [sp+54h] [bp+Ch]@15 | |
733 float v57; // [sp+54h] [bp+Ch]@21 | |
734 | |
735 v46 = -64.0; | |
736 v47 = -64.0; | |
737 v45 = 64.0; | |
738 v6 = sqrt(12288.0); | |
739 if ( v6 != 0.0 ) | |
740 { | |
741 v7 = 1.0 / v6; | |
742 v45 = 64.0 * v7; | |
743 v8 = v7 * -64.0; | |
744 v46 = v8; | |
745 v47 = v8; | |
746 } | |
747 result = Y; | |
748 if ( Y > Z ) | |
749 { | |
750 v10 = Z ^ Y; | |
751 Z ^= Y ^ Z; | |
752 result = Z ^ v10; | |
753 } | |
754 v11 = X; | |
755 if ( X > W ) | |
756 { | |
757 v12 = W ^ X; | |
758 W ^= X ^ W; | |
759 v11 = W ^ v12; | |
760 } | |
761 //v48 = result - 1; | |
762 if ( result - 1 <= Z ) | |
763 { | |
764 v39 = v11 - 1; | |
765 for ( v13 = result - 1; v13 <= Z; v13++ ) | |
766 { | |
767 v50 = v39; | |
768 if ( v39 <= W ) | |
769 { | |
770 result = (v39 - 63) << 9; | |
771 v49 = (v39 - 63) << 9; | |
772 for ( v14 = v39; v14 <= W; v14++ ) | |
773 { | |
774 if ( v13 >= 0 && result >= -32256 && v13 <= 127 && result <= 32768 ) | |
775 { | |
776 //v15 = pOutLocTerrain->field_10; | |
777 //v55 = pOutLocTerrain->field_10; | |
778 pMapHeight = this->pHeightmap; | |
779 v17 = (int)(&pMapHeight[v13 * this->field_10] + v14); | |
780 v18 = -v13; | |
781 v19 = (64 - v13) << 9; | |
782 v20 = 32 * *(char *)v17; | |
783 v21 = 32 * *(char *)(v17 + 1); | |
784 | |
785 v22 = (v18 + 63) << 9; | |
786 v41 = v22; | |
787 v23 = (int)(&pMapHeight[this->field_10 * (v13 + 1)] + v14); | |
788 v24 = v22 - v19; | |
789 v40 = 32 * *(char *)v23; | |
790 v42 = 32 * *(char *)(v23 + 1); | |
791 | |
792 v25 = v49 - 512 - v49; | |
793 v26 = (double)-((v20 - v21) * v24); | |
794 v51 = v26; | |
795 v27 = (double)-(v25 * (v42 - v21)); | |
796 v53 = v27; | |
797 v28 = (double)(v25 * v24); | |
798 v56 = v28; | |
799 v29 = sqrt(v28 * v28 + v27 * v27 + v26 * v26); | |
800 if ( v29 != 0.0 ) | |
801 { | |
802 v30 = 1.0 / v29; | |
803 v51 = v51 * v30; | |
804 v53 = v53 * v30; | |
805 v56 = v30 * v56; | |
806 } | |
807 v31 = (v56 * v47 + v53 * v46 + v51 * v45) * 31.0; | |
808 if ( v31 < 0.0 ) | |
809 v31 = 0.0; | |
810 if ( v31 > 31.0 ) | |
811 v31 = 31.0; | |
812 v44 = 2 * (v14 + v13 * this->field_10); | |
813 //pOutLocTerrain = pOutLocTerrain2; | |
814 *((char *)this->pDmap + v44 + 1) = (signed __int64)v31; | |
815 | |
816 v32 = v49 - (v49 - 512); | |
817 v33 = (double)-((v42 - v40) * (v19 - v41)); | |
818 v52 = v33; | |
819 v34 = (double)-(v32 * (v20 - v40)); | |
820 v54 = v34; | |
821 v35 = (double)(v32 * (v19 - v41)); | |
822 v57 = v35; | |
823 v36 = sqrt(v35 * v35 + v34 * v34 + v33 * v33); | |
824 if ( v36 != 0.0 ) | |
825 { | |
826 v37 = 1.0 / v36; | |
827 v52 = v52 * v37; | |
828 v54 = v54 * v37; | |
829 v57 = v37 * v57; | |
830 } | |
831 v38 = (v57 * v47 + v54 * v46 + v52 * v45) * 31.0; | |
832 if ( v38 < 0.0 ) | |
833 v38 = 0.0; | |
834 if ( v38 > 31.0 ) | |
835 v38 = 31.0; | |
836 //v13 = v48; | |
837 *((char *)this->pDmap + v44) = (signed __int64)v38; | |
838 //v14 = v50; | |
839 result = v49; | |
840 } | |
841 //++v14; | |
842 result += 512; | |
843 //v50 = v14; | |
844 v49 = result; | |
845 } | |
846 } | |
847 //++v13; | |
848 //v48 = v13; | |
849 } | |
850 //while ( v13 <= Z ); | |
851 } | |
852 } | |
853 | |
854 //----- (0047CB57) -------------------------------------------------------- | |
855 int OutdoorLocationTerrain::_47CB57(int a1, int a2, int a3) | |
856 { | |
857 signed int result; // eax@2 | |
858 // unsigned __int16 *v5; // edx@3 | |
859 // double v6; // st7@3 | |
860 // int v8; // eax@3 | |
861 // int v9; // eax@4 | |
862 // int v10; // eax@5 | |
863 // double v11; // st6@7 | |
864 // signed int v12; // edi@7 | |
865 // int v13; // esi@9 | |
866 // char *v14; // esi@10 | |
867 // signed int v15; // ecx@10 | |
868 // char v16[256]; // [sp+4h] [bp-124h]@9 | |
869 // unsigned __int16 *v17; // [sp+104h] [bp-24h]@3 | |
870 // float v22; // [sp+118h] [bp-10h]@3 | |
871 // float v23; // [sp+11Ch] [bp-Ch]@3 | |
872 // int i; // [sp+120h] [bp-8h]@3 | |
873 // unsigned int v25; // [sp+124h] [bp-4h]@5 | |
874 // signed int a2a; // [sp+134h] [bp+Ch]@3 | |
875 // unsigned int a2b; // [sp+134h] [bp+Ch]@7 | |
876 // float a3a; // [sp+138h] [bp+10h]@7 | |
877 // int a3b; // [sp+138h] [bp+10h]@9 | |
878 | |
879 int num_r_bits = 5; | |
880 int num_g_bits = 6; | |
881 int num_b_bits = 5; | |
882 | |
883 int r_mask = 0xF800; | |
884 int g_mask = 0x7E0; | |
885 int b_mask = 0x1F; | |
886 | |
887 //if ( pRenderer->pRenderD3D ) | |
888 result = 0; | |
889 /*else | |
890 { | |
891 __debugbreak(); | |
892 v5 = PaletteManager::Get_Dark_or_Red_LUT(a2, 0, 1); | |
893 v6 = 0.0; | |
894 v22 = 0.0; | |
895 v8 = 0; | |
896 v17 = v5; | |
897 v23 = 0.0; | |
898 a2a = 0; | |
899 for ( i = 0; i < a3; ++i ) | |
900 { | |
901 v9 = *(char *)(v8 + a1); | |
902 if ( v9 ) | |
903 { | |
904 v10 = v5[v9]; | |
905 v6 = v6 + (double)((signed int)(r_mask & v10) >> (num_b_bits + num_g_bits)); | |
906 ++a2a; | |
907 v25 = b_mask & v10; | |
908 v22 = (double)((signed int)(g_mask & v10) >> num_b_bits) + v22; | |
909 v23 = (double)(signed int)(b_mask & v10) + v23; | |
910 } | |
911 v8 = i + 1; | |
912 } | |
913 v11 = 1.0 / (double)a2a; | |
914 a3a = v11; | |
915 v25 = (signed __int64)(a3a * v22); | |
916 i = (signed __int64)(a3a * v23); | |
917 v12 = 0; | |
918 a2b = num_b_bits + num_g_bits; | |
919 while ( 1 ) | |
920 { | |
921 v13 = v17[v12]; | |
922 a3b = abs((__int64)(signed __int64)(v11 * v6) - ((signed int)(r_mask & v17[v12]) >> a2b)); | |
923 BYTE3(a3b) = abs((signed)v25 - ((signed int)(g_mask & v13) >> num_b_bits)) + a3b; | |
924 v16[v12++] = abs((signed)i - (signed)(b_mask & v13)) + BYTE3(a3b); | |
925 if ( v12 >= 256 ) | |
926 break; | |
927 } | |
928 result = 0; | |
929 v14 = (char *)&pPaletteManager->field_D1600[42][23][116]; | |
930 v15 = 0; | |
931 do | |
932 { | |
933 if ( (unsigned __int8)v16[v15] < (signed int)v14 ) | |
934 { | |
935 v14 = (char *)(unsigned __int8)v16[v15]; | |
936 result = v15; | |
937 } | |
938 ++v15; | |
939 } | |
940 while ( v15 < 256 ); | |
941 }*/ | |
942 return result; | |
943 } | |
944 | |
945 //----- (0047CCE2) -------------------------------------------------------- | |
946 bool OutdoorLocationTerrain::ZeroLandscape() | |
947 { | |
948 memset(this->pHeightmap, 0, 0x4000u); | |
949 memset(this->pTilemap, 90, 0x4000u); | |
950 memset(this->pAttributemap, 0, 0x4000u); | |
951 memset(this->pDmap, 0, 0x8000u); | |
952 this->field_12 = 128; | |
953 this->field_10 = 128; | |
954 this->field_16 = 7; | |
955 this->field_14 = 7; | |
956 this->field_1C = 127; | |
957 this->field_18 = 127; | |
958 return true; | |
959 } | |
960 | |
961 //----- (0047CD44) -------------------------------------------------------- | |
962 bool OutdoorLocationTerrain::Initialize() | |
963 { | |
2534 | 964 pHeightmap = (unsigned __int8 *)malloc(0x4000);//height map |
965 pTilemap = (unsigned __int8 *)malloc(0x4000);//tile map | |
966 pAttributemap = (unsigned __int8 *)malloc(0x4000);//карта атрибутов | |
967 pDmap = (struct DMap *)malloc(0x8000); | |
2496 | 968 if (pHeightmap && pTilemap && pAttributemap && pDmap ) |
969 return true; | |
970 else | |
971 return false; | |
972 } | |
973 | |
974 //----- (0047CDE2) -------------------------------------------------------- | |
975 void OutdoorLocation::CreateDebugLocation() | |
976 { | |
977 //OutdoorLocation *v1; // esi@1 | |
978 void *v2; // eax@1 | |
979 void *v3; // ST14_4@1 | |
980 void *v4; // eax@1 | |
981 void *v5; // ST14_4@1 | |
982 void *v6; // eax@1 | |
983 //unsigned int v7; // eax@1 | |
984 //char v8; // zf@1 | |
985 | |
986 //v1 = this; | |
987 strcpy(this->pLevelFilename, "blank"); | |
988 strcpy(this->pLocationFileName, "i6.odm"); | |
989 strcpy(this->pLocationFileDescription, "MM6 Outdoor v1.00"); | |
990 this->uNumBModels = 0; | |
991 this->pTileTypes[0].tileset = Tileset_Grass; | |
992 this->pTileTypes[1].tileset = Tileset_Water; | |
2534 | 993 this->pTileTypes[2].tileset = Tileset_Badlands; |
2496 | 994 this->pTileTypes[3].tileset = Tileset_RoadGrassCobble; |
995 this->LoadTileGroupIds(); | |
996 this->LoadRoadTileset(); | |
997 free(this->pBModels); | |
998 free(this->pSpawnPoints); | |
999 this->pBModels = 0; | |
1000 this->pSpawnPoints = 0; | |
1001 this->pTerrain.Initialize(); | |
1002 this->pTerrain.ZeroLandscape(); | |
1003 this->pTerrain.FillDMap(0, 0, 128, 128); | |
1004 free(this->pCmap); | |
1005 this->pCmap = 0; | |
1006 v2 = malloc(0x8000u); | |
1007 v3 = this->pOMAP; | |
1008 this->pCmap = v2; | |
1009 free(v3); | |
1010 this->pOMAP = 0; | |
1011 v4 = malloc(0x10000u); | |
1012 this->pOMAP = (unsigned int *)v4; | |
1013 memset(v4, 0, 0x10000u); | |
1014 v5 = this->pFaceIDLIST; | |
1015 this->numFaceIDListElems = 0; | |
1016 free(v5); | |
1017 this->pFaceIDLIST = 0; | |
1018 v6 = malloc(2); | |
1019 this->pFaceIDLIST = (unsigned __int16 *)v6; | |
1020 *(short *)v6 = 0; | |
1021 strcpy(this->pSkyTextureName, pDefaultSkyTexture.data()); | |
1022 this->sSky_TextureID = pBitmaps_LOD->LoadTexture(this->pSkyTextureName); | |
1023 strcpy(this->pGroundTileset, byte_6BE124_cfg_textures_DefaultGroundTexture.data()); | |
1024 //v7 = pBitmaps_LOD->LoadTexture(this->pGroundTileset); | |
1025 this->sMainTile_BitmapID = pBitmaps_LOD->LoadTexture(this->pGroundTileset); | |
1026 | |
1027 if ( this->sSky_TextureID == -1 ) | |
1028 Error("Invalid Sky Tex Handle"); | |
1029 | |
1030 if ( this->sMainTile_BitmapID == -1 ) | |
1031 Error("Invalid Ground Tex Handle"); | |
1032 } | |
1033 | |
1034 //----- (0047CF9C) -------------------------------------------------------- | |
1035 void OutdoorLocation::Release() | |
1036 { | |
1037 strcpy(pLevelFilename, "blank"); | |
1038 strcpy(pLocationFileName, "default.odm"); | |
1039 strcpy(pLocationFileDescription, "MM6 Outdoor v1.00"); | |
1040 strcpy(pSkyTextureName, "sky043"); | |
1041 strcpy(pGroundTileset, "hm005"); | |
1042 | |
1043 if (pBModels) | |
1044 { | |
1045 for (uint i = 0; i < uNumBModels; ++i) | |
1046 pBModels[i].Release(); | |
1047 | |
1048 free(pBModels); | |
1049 pBModels = nullptr; | |
1050 uNumBModels = 0; | |
1051 } | |
1052 | |
1053 free(pSpawnPoints); | |
1054 pSpawnPoints = nullptr; | |
1055 uNumSpawnPoints = 0; | |
1056 | |
1057 pTerrain.Release(); | |
1058 | |
1059 free(pCmap); | |
1060 pCmap = nullptr; | |
1061 free(pOMAP); | |
1062 pOMAP = nullptr; | |
1063 free(pFaceIDLIST); | |
1064 pFaceIDLIST = nullptr; | |
1065 free(pTerrainNormals); | |
1066 pTerrainNormals = nullptr; | |
1067 } | |
1068 | |
1069 //----- (0047D0A6) -------------------------------------------------------- | |
1070 bool OutdoorLocation::Load(const char *pFilename, ODMFace *File, size_t pNumItems, int *thisa)//загрузка локации | |
1071 { | |
2534 | 1072 FILE *pFile; // eax@50 |
2496 | 1073 unsigned __int16 v62; // ax@65 |
1074 int v108; // [sp+0h] [bp-B80h]@10 | |
1075 char Src[968]; // [sp+10h] [bp-B70h]@110 | |
1076 char Dst[968]; // [sp+3D8h] [bp-7A8h]@50 | |
1077 char Str[256]; // [sp+7A0h] [bp-3E0h]@50 | |
1078 ODMHeader header; // [sp+B58h] [bp-28h]@50 | |
1079 char *Str2; // [sp+B74h] [bp-Ch]@12 | |
1080 | |
1081 //pOutdoorLocation = this; | |
1082 //strcpy(pContainer, pFilename); | |
1083 | |
1084 if (bUnderwater) | |
1085 { | |
1086 pPaletteManager->pPalette_tintColor[0] = 0x10; | |
1087 pPaletteManager->pPalette_tintColor[1] = 0xC2; | |
1088 pPaletteManager->pPalette_tintColor[2] = 0x99; | |
1089 pPaletteManager->SetMistColor(37, 143, 92); | |
1090 } | |
1091 else | |
1092 { | |
1093 pPaletteManager->pPalette_tintColor[0] = 0; | |
1094 pPaletteManager->pPalette_tintColor[1] = 0; | |
1095 pPaletteManager->pPalette_tintColor[2] = 0; | |
1096 if (pPaletteManager->pPalette_mistColor[0] != 0x80 || | |
1097 pPaletteManager->pPalette_mistColor[1] != 0x80 || | |
1098 pPaletteManager->pPalette_mistColor[2] != 0x80) | |
1099 { | |
1100 pPaletteManager->SetMistColor(128, 128, 128); | |
1101 pPaletteManager->RecalculateAll(); | |
1102 } | |
1103 } | |
1104 | |
1105 _6807E0_num_decorations_with_sounds_6807B8 = 0; | |
1106 /*sprintf(FileName, "levels\\%s", pContainer); | |
1107 if ( GetFileAttributesA(FileName) != -1 ) | |
1108 { | |
1109 result = (bool)fopen(FileName, "rb"); | |
1110 v7 = result; | |
1111 File = (ODMFace *)result; | |
1112 if ( !result ) | |
1113 return result; | |
1114 *(int *)thisa = 1; | |
1115 v8 = strlen(pContainer); | |
1116 v108 = 2; | |
1117 *((char *)&v139 + v8) = 0; | |
1118 viewparams->uTextureID_LocationMap = pIcons_LOD->LoadTexture(pContainer, (enum TEXTURE_TYPE)v108); | |
1119 fread(&DstBuf, 0x180u, 1u, (FILE *)v7); | |
1120 fseek((FILE *)v7, Offset, 0); | |
1121 fread(this, 0xB0u, 1u, (FILE *)v7); | |
1122 LoadTileGroupIds(); | |
1123 LoadRoadTileset(); | |
1124 strcpy(pGroundTileset, "grastyl"); | |
1125 fseek((FILE *)v7, v114, 0); | |
1126 fread(&uNumBModels, 4u, 1u, (FILE *)v7); | |
1127 fseek((FILE *)v7, v115, 0); | |
1128 fread(&uNumSpriteObjects, 4u, 1u, (FILE *)v7); | |
1129 fseek((FILE *)v7, v116, 0); | |
1130 fread(&uNumLevelDecorations, 4u, 1u, (FILE *)v7); | |
1131 fseek((FILE *)v7, v117, 0); | |
1132 fread(&uNumActors, 4u, 1u, (FILE *)v7); | |
1133 fseek((FILE *)v7, v118, 0); | |
1134 fread(&uNumChests, 4u, 1u, (FILE *)v7); | |
1135 pTerrain.Initialize(); | |
1136 fseek((FILE *)v7, v119, 0); | |
1137 fread(pTerrain.pHeightmap, 1u, 0x4000u, (FILE *)v7); | |
1138 fseek((FILE *)v7, v120, 0); | |
1139 fread(pTerrain.pTilemap, 1u, 0x4000u, (FILE *)v7); | |
1140 fseek((FILE *)v7, v121, 0); | |
1141 fread(pTerrain.pAttributemap, 1u, 0x4000u, (FILE *)v7); | |
1142 pTerrain._47C80A(0, 0, 128, 128); | |
1143 free(ptr_D4); | |
1144 ptr_D4 = 0; | |
1145 v9 = malloc(0, 0x8000u, "CMAP"); | |
1146 v108 = (int)pOMAP; | |
1147 ptr_D4 = v9; | |
1148 free((void *)v108); | |
1149 pOMAP = 0; | |
1150 v10 = malloc(0, 0x10000u, "OMAP"); | |
1151 v108 = 0; | |
1152 pOMAP = (unsigned int *)v10; | |
1153 fseek((FILE *)v7, v136, v108); | |
1154 fread(&uNumTerrainNormals, 4u, 1u, (FILE *)v7); | |
1155 fread(pTerrainSomeOtherData, 1u, 0x20000u, (FILE *)v7); | |
1156 fread(pTerrainNormalIndices, 1u, 0x10000u, (FILE *)v7); | |
1157 pTerrainNormals = (Vec3_float_ *)malloc(pTerrainNormals, 12 * uNumTerrainNormals, "TerNorm"); | |
1158 fread(pTerrainNormals, 1u, 12 * uNumTerrainNormals, (FILE *)v7); | |
1159 v11 = malloc(pBModels, 188 * uNumBModels, "BDdata"); | |
1160 v108 = 0; | |
1161 pBModels = (BSPModel *)v11; | |
1162 fseek((FILE *)v7, v122, v108); | |
1163 fread(pBModels, 0xBCu, uNumBModels, (FILE *)v7); | |
1164 fseek((FILE *)v7, v123, 0); | |
1165 pNumItems = 0; | |
1166 if ( (signed int)uNumBModels > 0 ) | |
1167 { | |
1168 v12 = 0; | |
1169 while ( 1 ) | |
1170 { | |
1171 pBModels[v12].pVertices.pVertices = 0; | |
1172 pBModels[v12].pFaces = 0; | |
1173 pBModels[v12].pFacesOrdering = 0; | |
1174 pBModels[v12].pNodes = 0; | |
1175 FileName[0] = 0; | |
1176 v108 = (int)&pBModels[v12]; | |
1177 sprintfex(FileName, "%s", v108); | |
1178 v13 = pBModels; | |
1179 v138 = 0; | |
1180 pBModels[v12].pVertices.pVertices = (Vec3_int_ *)malloc(v13[v12].pVertices.pVertices, 12 * v13[v12].pVertices.uNumVertices, | |
1181 FileName); | |
1182 pBModels[v12].pFaces = (ODMFace *)malloc(pBModels[v12].pFaces, 308 * pBModels[v12].uNumFaces, | |
1183 FileName); | |
1184 pBModels[v12].pFacesOrdering = (unsigned __int16 *)malloc(pBModels[v12].pFacesOrdering, | |
1185 2 * pBModels[v12].uNumFaces, FileName); | |
1186 v14 = malloc(pBModels[v12].pNodes, 8 * pBModels[v12].uNumNodes, FileName); | |
1187 v15 = pBModels; | |
1188 v108 = (int)File; | |
1189 v15[v12].pNodes = (BSPNode *)v14; | |
1190 fread(pBModels[v12].pVertices.pVertices, 0xCu, pBModels[v12].pVertices.uNumVertices, (FILE *)v108); | |
1191 fread(pBModels[v12].pFaces, 0x134u, pBModels[v12].uNumFaces, (FILE *)File); | |
1192 fread(pBModels[v12].pFacesOrdering, 2u, pBModels[v12].uNumFaces, (FILE *)File); | |
1193 fread(pBModels[v12].pNodes, 8u, pBModels[v12].uNumNodes, (FILE *)File); | |
1194 v16 = malloc(10 * pBModels[v12].uNumFaces); | |
1195 v107 = (int)File; | |
1196 v17 = pBModels; | |
1197 ptr = (FILE *)v16; | |
1198 fread(v16, 0xAu, v17[v12].uNumFaces, (FILE *)File); | |
1199 v18 = pBModels; | |
1200 Str2 = 0; | |
1201 if ( (signed int)v18[v12].uNumFaces > 0 ) | |
1202 break; | |
1203 LABEL_25: | |
1204 free(ptr); | |
1205 ++pNumItems; | |
1206 ++v12; | |
1207 if ( (signed int)pNumItems >= (signed int)uNumBModels ) | |
1208 goto LABEL_26; | |
1209 } | |
1210 pDestLen = 0; | |
1211 pFilename = (char *)ptr; | |
1212 while ( 1 ) | |
1213 { | |
1214 thisa = (int)((char *)v18[v12].pFaces + pDestLen); | |
1215 if ( !(*(char *)(thisa + 29) & 0x40) ) | |
1216 break; | |
1217 v19 = pTextureFrameTable->FindTextureByName(pFilename); | |
1218 *(short *)(thisa + 272) = v19; | |
1219 if ( !v19 ) | |
1220 { | |
1221 v20 = pBitmaps_LOD->LoadTexture(pFilename); | |
1222 v21 = thisa; | |
1223 *(char *)(v21 + 29) &= 0xBFu; | |
1224 LABEL_19: | |
1225 *(short *)(v21 + 272) = v20; | |
1226 v149 = (void *)(v20 != -1 ? &pBitmaps_LOD->pTextures[v20] : 0); | |
1227 auto pTex = (Texture *)v149; | |
1228 if (pTex) | |
1229 pTex->palette_id2 = pPaletteManager->LoadPalette(pTex->palette_id1); | |
1230 goto LABEL_20; | |
1231 } | |
1232 pTextureFrameTable->LoadAnimationSequenceAndPalettes(*(unsigned __int16 *)((char *)&pBModels[v12].pFaces->uTextureID + pDestLen)); | |
1233 LABEL_20: | |
1234 if ( *(short *)(thisa + 292) ) | |
1235 { | |
1236 if ( ((ODMFace *)thisa)->HasEventHint() ) | |
1237 *(char *)(thisa + 30) |= 0x10u; | |
1238 else | |
1239 *(char *)(thisa + 30) &= 0xEFu; | |
1240 } | |
1241 ++Str2; | |
1242 v18 = pBModels; | |
1243 pDestLen += 308; | |
1244 pFilename += 10; | |
1245 if ( (signed int)Str2 >= (signed int)v18[v12].uNumFaces ) | |
1246 goto LABEL_25; | |
1247 } | |
1248 v20 = pBitmaps_LOD->LoadTexture(pFilename); | |
1249 v21 = thisa; | |
1250 goto LABEL_19; | |
1251 } | |
1252 LABEL_26: | |
1253 v22 = File; | |
1254 fseek((FILE *)File, v124, 0); | |
1255 fread(pSpriteObjects, 0x70u, uNumSpriteObjects, (FILE *)v22); | |
1256 if ( (signed int)uNumSpriteObjects > 0 ) | |
1257 { | |
1258 pItems = pSpriteObjects; | |
1259 pNumItems = uNumSpriteObjects; | |
1260 do | |
1261 { | |
1262 v24 = pItems->stru_24.uItemID; | |
1263 thisa = 0; | |
1264 v27 = (ODMFace *)(48 * v24); | |
1265 v25 = pObjectList->uNumObjects == 0; | |
1266 v26 = (pObjectList->uNumObjects & 0x80000000u) != 0; | |
1267 LOWORD(v27) = *(short *)((char *)&v27->pFacePlane.vNormal.x + (int)((char *)&pItemsTable + 24)); | |
1268 File = v27; | |
1269 pItems->uItemType = (unsigned __int16)v27; | |
1270 if ( v26 | v25 ) | |
1271 { | |
1272 LABEL_33: | |
1273 v29 = 0; | |
1274 } | |
1275 else | |
1276 { | |
1277 for ( i = (const char *)&pObjectList->pObjects->uObjectID; (short)v27 != *(short *)i; i = pFilename ) | |
1278 { | |
1279 ++thisa; | |
1280 pFilename = (char *)i + 56; | |
1281 if ( thisa >= (signed int)pObjectList->uNumObjects ) | |
1282 goto LABEL_33; | |
1283 LOWORD(v27) = (short)File; | |
1284 } | |
1285 v29 = thisa; | |
1286 } | |
1287 pItems->uObjectDescID = v29; | |
1288 ++pItems; | |
1289 --pNumItems; | |
1290 } | |
1291 while ( pNumItems ); | |
1292 } | |
1293 fseek((FILE *)v22, v125, 0); | |
1294 fread(pLevelDecorations, 0x20u, uNumLevelDecorations, (FILE *)v22); | |
1295 pNumItems = 0; | |
1296 if ( (signed int)uNumLevelDecorations > 0 ) | |
1297 { | |
1298 thisa = (int)pLevelDecorations; | |
1299 do | |
1300 { | |
1301 fread(FileName, 1u, 0x20u, (FILE *)v22); | |
1302 v30 = pDecorationList->GetDecorIdByName(FileName); | |
1303 v31 = thisa; | |
1304 ++pNumItems; | |
1305 thisa += 32; | |
1306 *(short *)v31 = v30; | |
1307 } | |
1308 while ( (signed int)pNumItems < (signed int)uNumLevelDecorations ); | |
1309 } | |
1310 fseek((FILE *)v22, v126, 0); | |
1311 fread(pActors, 0x344u, uNumActors, (FILE *)v22); | |
1312 fseek((FILE *)v22, v127, 0); | |
1313 fread(pChests, 0x14CCu, uNumChests, (FILE *)v22); | |
1314 fseek((FILE *)v22, v128, 0); | |
1315 fread(&field_DC, 4u, 1u, (FILE *)v22); | |
1316 free(pFaceIDLIST); | |
1317 v32 = field_DC; | |
1318 pFaceIDLIST = 0; | |
1319 v33 = malloc(0, 2 * v32, "IDLIST"); | |
1320 v108 = (int)v22; | |
1321 pFaceIDLIST = (unsigned __int16 *)v33; | |
1322 fread(v33, 2u, field_DC, (FILE *)v108); | |
1323 fseek((FILE *)v22, v129, 0); | |
1324 fread(pOMAP, 4u, 0x4000u, (FILE *)v22); | |
1325 fseek((FILE *)v22, v130, 0); | |
1326 fread(&uNumSpawnPoints, 4u, 1u, (FILE *)v22); | |
1327 pSpawnPoints = (SpawnPointMM7 *)malloc(pSpawnPoints, 24 * uNumSpawnPoints, "Spawn"); | |
1328 fseek((FILE *)v22, v131, 0); | |
1329 fread(pSpawnPoints, 0x18u, uNumSpawnPoints, (FILE *)v22); | |
1330 fseek((FILE *)v22, v132, 0); | |
1331 fread(&ddm, 0x28u, 1u, (FILE *)v22); | |
1332 fseek((FILE *)v22, v133, 0); | |
1333 fread(&stru_5E4C90, 1u, 0xC8u, (FILE *)v22); | |
1334 fseek((FILE *)v22, v134, 0); | |
1335 fread(&uLastVisitDay, 1u, 0x38u, (FILE *)v22); | |
1336 fseek((FILE *)v22, v135, 0); | |
1337 fread(&uLastVisitDay, 1u, 4u, (FILE *)v22); | |
1338 thisa = (int)pTileTypes; | |
1339 pTileTable->InitializeTileset(4); | |
1340 pTileTable->InitializeTileset(pTileTypes[0].uTileGroup); | |
1341 pTileTable->InitializeTileset(pTileTypes[1].uTileGroup); | |
1342 pTileTable->InitializeTileset(pTileTypes[2].uTileGroup); | |
1343 pTileTable->InitializeTileset(pTileTypes[3].uTileGroup); | |
1344 if ( this != (OutdoorLocation *)-96 && pSkyTextureName[0] ) | |
1345 { | |
1346 v108 = 0; | |
1347 v107 = (int)pSkyTextureName; | |
1348 } | |
1349 else | |
1350 { | |
1351 v108 = 0; | |
1352 v107 = (int)pDefaultSkyTexture; | |
1353 } | |
1354 sSky_TextureID = pBitmaps_LOD->LoadTexture((const char *)v107, (enum TEXTURE_TYPE)v108); | |
1355 strcpy(pGroundTileset, byte_6BE124_cfg_textures_DefaultGroundTexture); | |
1356 v34 = pTileTable->GetTileById(pTileTypes[0].uTileID); | |
1357 v35 = pBitmaps_LOD->LoadTexture(v34->pTileName); | |
1358 v36 = sSky_TextureID; | |
1359 sMainTile_BitmapID = v35; | |
1360 if ( v36 != -1 ) | |
1361 pBitmaps_LOD->pTextures[v36].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[v36].palette_id1); | |
1362 | |
1363 v37 = sMainTile_BitmapID; | |
1364 if ( v37 != -1 ) | |
1365 pBitmaps_LOD->pTextures[v37].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[v37].palette_id1); | |
1366 | |
1367 _47F0E2(); | |
1368 pGameLoadingUI_ProgressBar->Progress(); | |
1369 fclose((FILE *)v22); | |
1370 goto LABEL_150; | |
1371 }*/ | |
1372 | |
1373 assert(sizeof(BSPModel) == 188); | |
1374 | |
1375 if (!pGames_LOD->DoesContainerExist(pFilename)) | |
1376 Error("Unable to find %s in Games.LOD", pFilename); | |
1377 | |
1378 | |
1379 char pMinimapTextureFilename[1024]; | |
1380 strcpy(pMinimapTextureFilename, pFilename); | |
1381 pMinimapTextureFilename[strlen(pMinimapTextureFilename) - 4] = 0; | |
1382 viewparams->uTextureID_LocationMap = pIcons_LOD->LoadTexture(pMinimapTextureFilename, TEXTURE_16BIT_PALETTE); | |
1383 | |
1384 //strcpy(FileName, pContainer); | |
1385 strcpy(Str, pFilename); | |
1386 strcpy(Str + strlen(Str) - 4, ".odm"); | |
1387 //v141 = &v139; | |
1388 //v38 = strlen(pFilename); | |
1389 //strcpy((char *)&v139 + v38, ".odm"); | |
2534 | 1390 pFile = pGames_LOD->FindContainer(Str, true); |
2496 | 1391 //Str[strlen(Str) - 4] = 0; |
1392 | |
1393 header.uCompressedSize = 0; | |
1394 header.uDecompressedSize = 0; | |
1395 //ptr = v39; | |
1396 header.uVersion = 91969; | |
1397 header.pMagic[0] = 'm'; | |
1398 header.pMagic[1] = 'v'; | |
1399 header.pMagic[2] = 'i'; | |
1400 header.pMagic[3] = 'i'; | |
2534 | 1401 fread(&header, 0x10, 1, pFile); |
2496 | 1402 if (header.uVersion != 91969 || |
1403 header.pMagic[0] != 'm' || | |
1404 header.pMagic[1] != 'v' || | |
1405 header.pMagic[2] != 'i' || | |
1406 header.pMagic[3] != 'i') | |
1407 { | |
1408 MessageBoxW(nullptr, L"Can't load file!", | |
1409 L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odmap.cpp:507", 0); | |
1410 } | |
1411 //v40 = header.uCompressedSize; | |
1412 //pSource = header.uDecompressedSize; | |
1413 //v41 = malloc(header.uDecompressedSize); | |
1414 uchar* pSrcMem = (unsigned char *)malloc(header.uDecompressedSize); | |
1415 uchar* pSrc = pSrcMem; | |
1416 //v42 = v41; | |
1417 //HIDWORD(v142) = (uint32)pSrc; | |
1418 if (header.uCompressedSize < header.uDecompressedSize) | |
1419 { | |
1420 char* pComressedSrc = (char *)malloc(header.uCompressedSize); | |
2534 | 1421 fread(pComressedSrc, header.uCompressedSize, 1, pFile); |
2496 | 1422 |
1423 uint actualDecompressedSize = header.uDecompressedSize; | |
1424 zlib::MemUnzip(pSrc, &actualDecompressedSize, pComressedSrc, header.uCompressedSize); | |
1425 free(pComressedSrc); | |
1426 } | |
1427 else | |
1428 { | |
2534 | 1429 fread(pSrc, header.uDecompressedSize, 1, pFile); |
2496 | 1430 } |
1431 | |
1432 memcpy(pLevelFilename, pSrc, 0x20); | |
1433 memcpy(pLocationFileName, pSrc + 0x20, 0x20); | |
1434 memcpy(pLocationFileDescription, pSrc + 0x40, 0x20); | |
1435 memcpy(pSkyTextureName, pSrc + 3 * 32, 32); | |
1436 memcpy(pGroundTileset, pSrc + 0x80, 0x20); | |
1437 memcpy(pTileTypes, pSrc + 0xA0, 0x10); | |
1438 pSrc += 0xB0; | |
1439 | |
1440 //v43 = (char *)pSrc + 176; | |
1441 LoadTileGroupIds(); | |
1442 LoadRoadTileset(); | |
1443 strcpy(pGroundTileset, "grastyl"); | |
2534 | 1444 |
1445 pGameLoadingUI_ProgressBar->Progress(); //прогресс загрузки | |
1446 | |
1447 //*******************Terrain**************************// | |
2496 | 1448 pTerrain.Initialize(); |
2534 | 1449 memcpy(pTerrain.pHeightmap, pSrc, 0x4000); //карта высот |
2496 | 1450 pSrc += 0x4000; |
1451 | |
2534 | 1452 memcpy(pTerrain.pTilemap, pSrc, 0x4000); //карта тайлов |
2496 | 1453 pSrc += 0x4000; |
1454 | |
2534 | 1455 memcpy(pTerrain.pAttributemap, pSrc, 0x4000); // карта аттрибутов |
2496 | 1456 pSrc += 0x4000; |
1457 | |
1458 //v43 = (char *)v43 + 16384; | |
1459 //v108 = (int)ptr_D4; | |
1460 free(pCmap); | |
1461 pCmap = malloc(0x8000); | |
2534 | 1462 pTerrain.FillDMap(0, 0, 128, 128); // |
1463 | |
1464 pGameLoadingUI_ProgressBar->Progress(); //прогресс загрузки | |
1465 | |
1466 memcpy(&uNumTerrainNormals, pSrc, 4); // количество нормалей | |
2496 | 1467 memcpy(pTerrainSomeOtherData.data(), pSrc + 4, 0x20000); |
1468 pSrc += 4 + 0x20000; | |
1469 //v43 = (char *)v43 + 131072; | |
2534 | 1470 memcpy(pTerrainNormalIndices.data(), pSrc, 0x10000); //индексы нормалей |
2496 | 1471 pSrc += 0x10000; |
1472 //v43 = (char *)v43 + 65536; | |
1473 | |
1474 //pFilename = (char *)(12 * uNumTerrainNormals); | |
2534 | 1475 pTerrainNormals = (Vec3_float_ *)malloc(sizeof(Vec3_float_) * uNumTerrainNormals);//карта нормалей |
2496 | 1476 memcpy(pTerrainNormals, pSrc, 12 * uNumTerrainNormals); |
1477 pSrc += 12 * uNumTerrainNormals; | |
1478 //v44 = (char *)v43 + (int)pFilename; | |
1479 //v44 = (char *)v44 + 4; | |
1480 //v45 = uNumBModels; | |
1481 //v108 = (int)"BDdata"; | |
1482 | |
2534 | 1483 pGameLoadingUI_ProgressBar->Progress(); //прогресс загрузки |
1484 | |
1485 //************BModels************************// | |
2496 | 1486 //v107 = 188 * v45; |
1487 //v106 = (char *)pBModels; | |
1488 //v46 = (BSPModel *)malloc(v106, 188 * v45, "BDdata"); | |
1489 //v47 = uNumBModels; | |
2534 | 1490 memcpy(&uNumBModels, pSrc, 4); //количество BModel'ей |
2496 | 1491 pBModels = (BSPModel *)malloc(188 * uNumBModels); |
2534 | 1492 memcpy(pBModels, pSrc + 4, 188 * uNumBModels); //BModel'и |
2496 | 1493 pSrc += 4 + 188 * uNumBModels; |
1494 | |
2534 | 1495 pGameLoadingUI_ProgressBar->Progress(); //прогресс загрузки |
2496 | 1496 |
1497 //uSourceLen = (char *)v44 + (int)pFilename; | |
1498 //v151 = 0; | |
1499 for (uint i = 0; i < uNumBModels; ++i) | |
1500 { | |
1501 //v48 = 0; | |
1502 //BSPModel* model = &pBModels[i]; | |
1503 | |
1504 pBModels[i].pVertices.pVertices = nullptr; | |
1505 pBModels[i].pFaces = nullptr; | |
1506 pBModels[i].pFacesOrdering = nullptr; | |
1507 pBModels[i].pNodes = nullptr; | |
1508 //FileName[0] = 0; | |
1509 //v108 = (int)&pBModels[i]; | |
1510 //sprintf(FileName, "%s", v108); | |
1511 //v49 = pBModels; | |
1512 //v138 = 0; | |
1513 //v50 = &pBModels[v48]; | |
1514 //v108 = (int)FileName; | |
1515 //v107 = 12 * v50->pVertices.uNumVertices; | |
1516 //v106 = (char *)v50->pVertices.pVertices; | |
1517 assert(sizeof(Vec3_int_) == 12); | |
1518 uint verticesSize = pBModels[i].pVertices.uNumVertices * sizeof(Vec3_int_); | |
1519 pBModels[i].pVertices.pVertices = (Vec3_int_ *)malloc(verticesSize); | |
1520 memcpy(pBModels[i].pVertices.pVertices, pSrc, verticesSize); | |
1521 pSrc += verticesSize; | |
1522 //v51 = &pBModels[v48]; | |
1523 //v108 = (int)FileName; | |
1524 //v107 = 308 * v51->uNumFaces; | |
1525 //v106 = (char *)v51->pFaces; | |
1526 assert(sizeof(ODMFace) == 308); | |
1527 uint facesSize = pBModels[i].uNumFaces * sizeof(ODMFace); | |
1528 pBModels[i].pFaces = (ODMFace *)malloc(facesSize); | |
1529 memcpy(pBModels[i].pFaces, pSrc, facesSize); | |
1530 pSrc += facesSize; | |
1531 //v52 = &pBModels[v48]; | |
1532 //v108 = (int)FileName; | |
1533 //v107 = 2 * v52->uNumFaces; | |
1534 //v106 = (char *)v52->pFacesOrdering; | |
1535 uint facesOrderingSize = pBModels[i].uNumFaces * sizeof(short); | |
1536 pBModels[i].pFacesOrdering = (unsigned __int16 *)malloc(facesOrderingSize); | |
1537 memcpy(pBModels[i].pFacesOrdering, pSrc, facesOrderingSize); | |
1538 pSrc += facesOrderingSize; | |
1539 //v53 = &pBModels[v48]; | |
1540 //v108 = (int)FileName; | |
1541 //v107 = 8 * v53->uNumNodes; | |
1542 //v106 = (char *)v53->pNodes; | |
1543 assert(sizeof(BSPNode) == 8); | |
1544 uint nodesSize = pBModels[i].uNumNodes * sizeof(BSPNode); | |
1545 pBModels[i].pNodes = (BSPNode *)malloc(nodesSize); | |
1546 memcpy(pBModels[i].pNodes, pSrc, nodesSize); | |
1547 pSrc += nodesSize; | |
1548 //v54 = &pBModels[v48]; | |
1549 //v108 = 12 * v54->pVertices.uNumVertices; | |
1550 //pFilename = (char *)v108; | |
1551 //v107 = (int)uSourceLen; | |
1552 //v106 = (char *)v54->pVertices.pVertices; | |
1553 //memcpy(v106, uSourceLen, v108); | |
1554 //uSourceLen = (char *)uSourceLen + (int)pFilename; | |
1555 //v55 = &pBModels[v48]; | |
1556 //v105 = 308 * v55->uNumFaces; | |
1557 //v104 = uSourceLen; | |
1558 //v103 = v55->pFaces; | |
1559 //pFilename = (char *)v105; | |
1560 //memcpy(v103, uSourceLen, v105); | |
1561 //v56 = &pBModels[v48]; | |
1562 //uSourceLen = (char *)uSourceLen + (int)pFilename; | |
1563 //v57 = v56->pFacesOrdering; | |
1564 //pFilename = (char *)(2 * v56->uNumFaces); | |
1565 //memcpy(v57, uSourceLen, (size_t)pFilename); | |
1566 //v58 = &pBModels[v48]; | |
1567 //uSourceLen = (char *)uSourceLen + (int)pFilename; | |
1568 //v59 = v58->pNodes; | |
1569 //pFilename = (char *)(8 * v58->uNumNodes); | |
1570 //memcpy(v59, uSourceLen, (size_t)pFilename); | |
1571 //uSourceLen = (char *)uSourceLen + (int)pFilename; | |
1572 //ptr = (FILE *)malloc(10 * model->uNumFaces); | |
1573 const char* textureFilenames = (const char *)malloc(10 * pBModels[i].uNumFaces); | |
1574 //pFilename = (char *)(10 * pBModels[v48].uNumFaces); | |
1575 memcpy((char *)textureFilenames, pSrc, 10 * pBModels[i].uNumFaces); | |
1576 pSrc += 10 * pBModels[i].uNumFaces; | |
1577 //v144 = 0; | |
1578 //uSourceLen = (char *)uSourceLen + (int)pFilename; | |
1579 //v60 = pBModels; | |
1580 for (uint j = 0; j < pBModels[i].uNumFaces; ++j) | |
1581 { | |
1582 const char* texFilename = &textureFilenames[j * 10]; | |
1583 //v149 = 0; | |
1584 //Str2 = (char *)ptr; | |
1585 | |
1586 //ODMFace* face = &pBModels[i].pFaces[j]; | |
1587 //pFilename = (char *)v149 + (unsigned int)v60[v48].pFaces; | |
1588 if ( !(pBModels[i].pFaces[j].uAttributes & FACE_DONT_CACHE_TEXTURE)) | |
1589 { | |
1590 v62 = pBitmaps_LOD->LoadTexture(texFilename); | |
1591 // v63 = (ODMFace *)pFilename; | |
1592 pBModels[i].pFaces[j].uTextureID = v62; | |
1593 //v145 = (signed __int16)v62 != -1 ? &pBitmaps_LOD->pTextures[(signed __int16)v62] : 0; | |
1594 //v108 = ((signed __int16)v62 != -1 ? pBitmaps_LOD->pTextures[(signed __int16)v62].palette_id1 : 36); | |
1595 if ((signed __int16)v62 != -1) | |
1596 pBitmaps_LOD->pTextures[v62].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[v62].palette_id1); | |
1597 //goto LABEL_69; | |
1598 //goto LABEL_68; | |
1599 } | |
1600 else | |
1601 { | |
1602 //v61 = pTextureFrameTable->FindTextureByName(texFilename); | |
1603 pBModels[i].pFaces[j].uTextureID = pTextureFrameTable->FindTextureByName(texFilename); | |
1604 if (!pBModels[i].pFaces[j].uTextureID) | |
1605 { | |
1606 v62 = pBitmaps_LOD->LoadTexture(texFilename); | |
1607 //v63 = (ODMFace *)pFilename; | |
1608 pBModels[i].pFaces[j].uAttributes &= ~FACE_DONT_CACHE_TEXTURE; | |
1609 //LABEL_68: | |
1610 pBModels[i].pFaces[j].uTextureID = v62; | |
1611 //v145 = (signed __int16)v62 != -1 ? &pBitmaps_LOD->pTextures[(signed __int16)v62] : 0; | |
1612 //v108 = ((signed __int16)v62 != -1 ? pBitmaps_LOD->pTextures[(signed __int16)v62].palette_id1 : 36); | |
1613 if ((signed __int16)v62 != -1) | |
1614 pBitmaps_LOD->pTextures[v62].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[v62].palette_id1); | |
1615 //goto LABEL_69; | |
1616 } | |
1617 else | |
1618 pTextureFrameTable->LoadAnimationSequenceAndPalettes(pBModels[i].pFaces[j].uTextureID); | |
1619 } | |
1620 //LABEL_69: | |
1621 if (pBModels[i].pFaces[j].sCogTriggeredID) | |
1622 { | |
1623 if (pBModels[i].pFaces[j].HasEventHint()) | |
1624 pBModels[i].pFaces[j].uAttributes |= FACE_HAS_EVENT; | |
1625 else | |
1626 pBModels[i].pFaces[j].uAttributes &= ~FACE_HAS_EVENT; | |
1627 } | |
1628 //++v144; | |
1629 //v60 = pBModels; | |
1630 //v149 = (char *)v149 + 308; | |
1631 //Str2 += 10; | |
1632 //if ( v144 >= (signed int)v60[v48].uNumFaces ) | |
1633 //goto LABEL_74; | |
1634 } | |
1635 | |
1636 //LABEL_74: | |
1637 free((void *)textureFilenames); | |
1638 // ++v151; | |
1639 // ++v48; | |
1640 // if ( v151 >= (signed int)uNumBModels ) | |
1641 // goto LABEL_75; | |
1642 } | |
1643 //LABEL_75: | |
2534 | 1644 pGameLoadingUI_ProgressBar->Progress(); //прогресс загрузки |
1645 | |
1646 //******************Decorations**********************// | |
2496 | 1647 memcpy(&uNumLevelDecorations, pSrc, 4); |
1648 //uSourceLen = (char *)uSourceLen + 4; | |
1649 if (uNumLevelDecorations > 3000) | |
1650 MessageBoxW(nullptr, L"Can't load file!", | |
1651 L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odmap.cpp:678", 0); | |
1652 | |
1653 assert(sizeof(LevelDecoration) == 32); | |
1654 //pFilename = (char *)(32 * uNumLevelDecorations); | |
1655 memcpy(pLevelDecorations.data(), pSrc + 4, uNumLevelDecorations * sizeof(LevelDecoration)); | |
1656 pSrc += 4 + sizeof(LevelDecoration) * uNumLevelDecorations; | |
1657 | |
1658 pGameLoadingUI_ProgressBar->Progress(); | |
1659 | |
1660 //v151 = 0; | |
1661 //uSourceLen = (char *)uSourceLen + (int)pFilename; | |
1662 for (uint i = 0; i < uNumLevelDecorations; ++i) | |
1663 { | |
1664 char name[256]; | |
1665 memcpy(name, pSrc, sizeof(LevelDecoration)); | |
1666 pSrc += sizeof(LevelDecoration); | |
1667 | |
1668 pLevelDecorations[i].uDecorationDescID = pDecorationList->GetDecorIdByName(name); | |
1669 } | |
1670 | |
2534 | 1671 pGameLoadingUI_ProgressBar->Progress(); //прогресс загрузки |
2496 | 1672 |
1673 memcpy(&numFaceIDListElems, pSrc, 4); | |
1674 | |
1675 //uSourceLen = (char *)uSourceLen + 4; | |
1676 //v108 = (int)pFaceIDLIST; | |
1677 free(pFaceIDLIST); | |
1678 pFaceIDLIST = nullptr; | |
1679 //v66 = field_DC; | |
1680 //pFaceIDLIST = 0; | |
1681 //v67 = malloc(0, 2 * v66, "IDLIST"); | |
1682 uint faceIDListSize = 2 * numFaceIDListElems; | |
1683 pFaceIDLIST = (unsigned short *)malloc(faceIDListSize); | |
1684 //v68 = field_DC; | |
1685 //pFaceIDLIST = (unsigned __int16 *)v67; | |
1686 //pFilename = (char *)(2 * v68); | |
1687 memcpy(pFaceIDLIST, pSrc + 4, faceIDListSize); | |
1688 pSrc += 4 + faceIDListSize; | |
1689 | |
1690 //uSourceLen = (char *)uSourceLen + (int)pFilename; | |
2534 | 1691 pGameLoadingUI_ProgressBar->Progress(); //прогресс загрузки |
2496 | 1692 |
1693 //v108 = (int)pOMAP; | |
1694 //free((void *)v108); | |
1695 //pOMAP = 0; | |
1696 free(pOMAP); | |
1697 //v69 = malloc(0, 0x10000u, "OMAP"); | |
1698 pOMAP = (unsigned int *)malloc(0x10000); | |
1699 //v108 = 65536; | |
1700 //pOMAP = (unsigned int *)v69; | |
1701 memcpy(pOMAP, pSrc, 65536); | |
1702 pSrc += 65536; | |
1703 | |
1704 //uSourceLen = (char *)uSourceLen + 65536; | |
1705 pGameLoadingUI_ProgressBar->Progress(); | |
1706 | |
1707 memcpy(&uNumSpawnPoints, pSrc, 4); | |
1708 //uSourceLen = (char *)uSourceLen + 4; | |
2534 | 1709 pGameLoadingUI_ProgressBar->Progress(); //прогресс загрузки |
2496 | 1710 //v70 = uNumSpawnPoints; |
1711 //v108 = (int)"Spawn"; | |
1712 //v107 = 24 * v70; | |
1713 //v106 = (char *)pSpawnPoints; | |
1714 assert(sizeof(SpawnPointMM7) == 24); | |
1715 uint spawnPointsSize = uNumSpawnPoints * sizeof(SpawnPointMM7); | |
1716 pSpawnPoints = (SpawnPointMM7 *)malloc(spawnPointsSize); | |
1717 //v72 = uNumSpawnPoints; | |
1718 //pSpawnPoints = v71; | |
1719 memcpy(pSpawnPoints, pSrc + 4, spawnPointsSize); | |
1720 pSrc += 4 + spawnPointsSize; | |
1721 | |
2534 | 1722 pGameLoadingUI_ProgressBar->Progress(); //прогресс загрузки |
1723 | |
1724 //****************.ddm file*********************// | |
2496 | 1725 free(pSrcMem); |
1726 strcpy(Str + strlen(Str) - 4, ".ddm"); | |
2534 | 1727 pFile = pNew_LOD->FindContainer(Str, 1); |
1728 fread(&header, 0x10, 1, pFile); | |
2496 | 1729 Str2 = 0; |
1730 if (header.uVersion != 91969 || | |
1731 header.pMagic[0] != 'm' || | |
1732 header.pMagic[1] != 'v' || | |
1733 header.pMagic[2] != 'i' || | |
1734 header.pMagic[3] != 'i' ) | |
1735 { | |
1736 MessageBoxW(nullptr, L"Can't load file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odmap.cpp:746", 0); | |
1737 Str2 = (char *)1; | |
1738 } | |
1739 //v74 = 0; | |
1740 //pFilename = (char *)header.uCompressedSize; | |
1741 //v149 = 0; | |
1742 //pDestLen = header.uDecompressedSize; | |
1743 if ( !Str2 ) | |
1744 { | |
1745 pSrcMem = (unsigned char *)malloc(header.uDecompressedSize); | |
1746 pSrc = pSrcMem; | |
1747 //v149 = v75; | |
1748 if (header.uCompressedSize == header.uDecompressedSize) | |
2534 | 1749 fread(pSrc, header.uDecompressedSize, 1, pFile); |
2496 | 1750 else if (header.uCompressedSize < header.uDecompressedSize) |
1751 { | |
1752 void* compressedMem = malloc(header.uCompressedSize); | |
2534 | 1753 fread(compressedMem, header.uCompressedSize, 1, pFile); |
2496 | 1754 |
1755 uint actualDecompressedSize = header.uDecompressedSize; | |
1756 zlib::MemUnzip(pSrc, &actualDecompressedSize, compressedMem, header.uCompressedSize); | |
1757 free(compressedMem); | |
1758 } | |
1759 else | |
2534 | 1760 MessageBoxW(nullptr, L"Can't load file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odmap.cpp:765", 0); |
2496 | 1761 |
1762 assert(sizeof(DDM_DLV_Header) == 0x28); | |
1763 memcpy(&ddm, pSrc, sizeof(DDM_DLV_Header)); | |
1764 pSrc += sizeof(DDM_DLV_Header); | |
1765 //v74 = (int)((char *)v75 + 40); | |
1766 } | |
1767 uint actualNumFacesInLevel = 0; | |
1768 for (uint i = 0; i < uNumBModels; ++i) | |
1769 actualNumFacesInLevel += pBModels[i].uNumFaces; | |
1770 | |
1771 if (ddm.uNumFacesInBModels) | |
1772 { | |
1773 if ( ddm.uNumBModels ) | |
1774 { | |
1775 if (ddm.uNumDecorations) | |
1776 { | |
1777 if (ddm.uNumFacesInBModels != actualNumFacesInLevel || | |
1778 ddm.uNumBModels != uNumBModels || | |
1779 ddm.uNumDecorations != uNumLevelDecorations ) | |
1780 Str2 = (char *)1; | |
1781 } | |
1782 } | |
1783 } | |
1784 | |
1785 if (dword_6BE364_game_settings_1 & GAME_SETTINGS_2000) | |
1786 pNumItems = 0x1BAF800; | |
1787 | |
1788 if (Str2 || ((unsigned int)((char *)File - ddm.uLastRepawnDay) >= pNumItems || !ddm.uLastRepawnDay)) | |
1789 { | |
1790 | |
1791 if (Str2) | |
1792 { | |
2534 | 1793 memset(Dst, 0, 0x3C8); |
1794 memset(Src, 0, 0x3C8); | |
2496 | 1795 } |
1796 if ((unsigned int)((char *)File - ddm.uLastRepawnDay) >= pNumItems || !ddm.uLastRepawnDay) | |
1797 { | |
2534 | 1798 memcpy(Dst, pSrc, 968); |
1799 memcpy(Src, pSrc + 968, 968); | |
2496 | 1800 } |
1801 free(pSrcMem); | |
1802 | |
1803 ddm.uLastRepawnDay = (int)File; | |
1804 if (Str2 == 0) | |
1805 ++ddm.uNumRespawns; | |
1806 v108 = 0; | |
1807 *thisa = 1; | |
2534 | 1808 pFile = pGames_LOD->FindContainer(Str, 0); |
1809 fread(&header, 0x10, 1, pFile); | |
2496 | 1810 //pFilename = (char *)header.uCompressedSize; |
1811 //pDestLen = header.uDecompressedSize; | |
1812 //v82 = malloc(header.uDecompressedSize); | |
1813 pSrcMem = (unsigned char *)malloc(header.uDecompressedSize); | |
1814 //v149 = v82; | |
1815 if (header.uCompressedSize == header.uDecompressedSize) | |
2534 | 1816 fread(pSrcMem, header.uDecompressedSize, 1, pFile); |
2496 | 1817 else if (header.uCompressedSize < header.uDecompressedSize) |
1818 { | |
1819 void* compressedMem = malloc(header.uCompressedSize); | |
2534 | 1820 fread(compressedMem, header.uCompressedSize, 1, pFile); |
2496 | 1821 |
1822 uint actualDecompressedSize = header.uDecompressedSize; | |
1823 zlib::MemUnzip(pSrcMem, &actualDecompressedSize, compressedMem, header.uCompressedSize); | |
1824 free(compressedMem); | |
1825 } | |
1826 else | |
1827 MessageBoxW(nullptr, L"Can't load file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odmap.cpp:857", 0); | |
1828 | |
1829 pSrc = pSrcMem + 40; | |
1830 } | |
1831 else | |
1832 *thisa = 0; | |
2534 | 1833 memcpy(uFullyRevealedCellOnMap, pSrc, 968); |
1834 memcpy(uPartiallyRevealedCellOnMap, pSrc + 968, 968); | |
1835 pSrc += 2 * 968; | |
1836 | |
1837 pGameLoadingUI_ProgressBar->Progress(); //прогресс загрузки | |
2496 | 1838 |
1839 if ( *thisa ) | |
1840 { | |
2534 | 1841 memcpy(uFullyRevealedCellOnMap, Dst, 968); |
1842 memcpy(uPartiallyRevealedCellOnMap, Src, 968); | |
2496 | 1843 } |
1844 | |
1845 for (uint i = 0; i < uNumBModels; ++i) | |
1846 { | |
1847 BSPModel model = pBModels[i]; | |
1848 for (uint j = 0; j < model.uNumFaces; ++j) | |
1849 { | |
1850 ODMFace face = model.pFaces[j]; | |
1851 memcpy(&face.uAttributes, pSrc, 4); | |
1852 pSrc += 4; | |
1853 } | |
1854 | |
1855 for (uint j = 0; j < model.uNumFaces; ++j) | |
1856 { | |
1857 ODMFace face = model.pFaces[j]; | |
1858 if (face.sCogTriggeredID) | |
1859 { | |
1860 if (face.HasEventHint()) | |
1861 face.uAttributes |= FACE_HAS_EVENT_HINT; | |
1862 else | |
1863 face.uAttributes &= ~FACE_HAS_EVENT_HINT;//~0x00001000 | |
1864 } | |
1865 } | |
1866 } | |
1867 | |
2534 | 1868 pGameLoadingUI_ProgressBar->Progress(); //прогресс загрузки |
2496 | 1869 |
1870 for (uint i = 0; i < uNumLevelDecorations; ++i) | |
1871 { | |
1872 memcpy(&pLevelDecorations[i].uFlags, pSrc, 2); | |
1873 pSrc += 2; | |
1874 } | |
1875 | |
2534 | 1876 pGameLoadingUI_ProgressBar->Progress(); //прогресс загрузки |
2496 | 1877 |
1878 memcpy(&uNumActors, pSrc, 4); | |
1879 if (uNumActors > 500) | |
2534 | 1880 MessageBoxW(nullptr, L"Can't load file!", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odmap.cpp:939", 0); |
1881 | |
1882 pGameLoadingUI_ProgressBar->Progress(); //прогресс загрузки | |
2496 | 1883 |
1884 assert(sizeof(Actor) == 836); | |
1885 //pFilename = (char *)(836 * uNumActors); | |
1886 memcpy(pActors.data(), pSrc + 4, uNumActors * sizeof(Actor)); | |
1887 pSrc += 4 + uNumActors * sizeof(Actor); | |
1888 //v92 = (char *)v91 + (int)pFilename; | |
2534 | 1889 pGameLoadingUI_ProgressBar->Progress(); //прогресс загрузки |
2496 | 1890 |
1891 memcpy(&uNumSpriteObjects, pSrc, 4); | |
1892 assert(uNumSpriteObjects <= 1000 && "Too many objects"); | |
1893 assert(sizeof(SpriteObject) == 112); | |
1894 | |
2534 | 1895 pGameLoadingUI_ProgressBar->Progress(); //прогресс загрузки |
2496 | 1896 |
1897 //pFilename = (char *)(112 * uNumSpriteObjects); | |
1898 memcpy(pSpriteObjects.data(), pSrc + 4, uNumSpriteObjects * sizeof(SpriteObject)); | |
1899 pSrc += 4 + uNumSpriteObjects * sizeof(SpriteObject); | |
1900 | |
1901 //v94 = (char *)v93 + (int)pFilename; | |
2534 | 1902 pGameLoadingUI_ProgressBar->Progress(); //прогресс загрузки |
2496 | 1903 |
1904 memcpy(&uNumChests, pSrc, 4); | |
1905 //v95 = (char *)v94 + 4; | |
1906 if (uNumChests > 20) | |
1907 MessageBoxW(nullptr, L"Can't load file!", | |
1908 L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Odmap.cpp:968", 0); | |
1909 | |
2534 | 1910 pGameLoadingUI_ProgressBar->Progress(); //прогресс загрузки |
2496 | 1911 |
1912 assert(sizeof(Chest) == 5324); | |
1913 //pFilename = (char *)(5324 * uNumChests); | |
1914 memcpy(pChests.data(), pSrc + 4 , uNumChests * sizeof(Chest)); | |
1915 pSrc += 4 + uNumChests * sizeof(Chest); | |
1916 //v96 = (char *)v95 + (int)pFilename; | |
2534 | 1917 pGameLoadingUI_ProgressBar->Progress(); //прогресс загрузки |
2496 | 1918 |
1919 memcpy(&stru_5E4C90_MapPersistVars, pSrc, 0xC8); | |
1920 pSrc += 0xC8; | |
1921 | |
2534 | 1922 pGameLoadingUI_ProgressBar->Progress(); //прогресс загрузки |
2496 | 1923 memcpy(&loc_time, pSrc, 0x38u); |
1924 | |
1925 free(pSrcMem); | |
1926 | |
1927 pTileTable->InitializeTileset(Tileset_Dirt); | |
1928 pTileTable->InitializeTileset(Tileset_Snow); | |
1929 pTileTable->InitializeTileset(pTileTypes[0].tileset); | |
1930 pTileTable->InitializeTileset(pTileTypes[1].tileset); | |
1931 pTileTable->InitializeTileset(pTileTypes[2].tileset); | |
1932 pTileTable->InitializeTileset(pTileTypes[3].tileset); | |
1933 strcpy(pGroundTileset, byte_6BE124_cfg_textures_DefaultGroundTexture.data()); | |
1934 TileDesc* v98 = pTileTable->GetTileById(pTileTypes[0].uTileID); | |
1935 sMainTile_BitmapID = pBitmaps_LOD->LoadTexture(v98->pTileName, TEXTURE_DEFAULT); | |
1936 if (sMainTile_BitmapID != -1) | |
1937 pBitmaps_LOD->pTextures[sMainTile_BitmapID].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[sMainTile_BitmapID].palette_id1); | |
1938 | |
1939 _47F0E2(); | |
1940 | |
1941 //LABEL_150: | |
1942 if ( pWeather->bRenderSnow ) //Ritor1: it's include for snow | |
1943 strcpy(loc_time.sky_texture_name, "sky19"); | |
1944 else if (loc_time.uLastVisitDay) | |
1945 { | |
1946 if ( (signed int)((signed int)(signed __int64)((double)loc_time.uLastVisitDay * 0.234375) / 60 / 60 / 24) % 28 != pParty->uDaysPlayed ) | |
1947 { | |
1948 if ( rand() % 100 >= 20 ) | |
1949 v108 = dword_4EC268[rand() % dword_4EC2A8]; | |
1950 else | |
1951 v108 = dword_4EC28C[rand() % dword_4EC2AC]; | |
1952 sprintf(loc_time.sky_texture_name, "plansky%d", v108); | |
1953 } | |
1954 } | |
1955 else | |
1956 strcpy(loc_time.sky_texture_name, "plansky3"); | |
1957 | |
2534 | 1958 //New_SKY_NIGHT_ID = pBitmaps_LOD->LoadTexture("SKY13"); |
1959 //if (New_SKY_NIGHT_ID != -1) | |
1960 // pBitmaps_LOD->pTextures[New_SKY_NIGHT_ID].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[New_SKY_NIGHT_ID].palette_id1); | |
1961 | |
2496 | 1962 //v101 = pBitmaps_LOD->LoadTexture(field_4F8); |
1963 sSky_TextureID = pBitmaps_LOD->LoadTexture(loc_time.sky_texture_name); | |
1964 if (sSky_TextureID != -1) | |
1965 pBitmaps_LOD->pTextures[sSky_TextureID].palette_id2 = pPaletteManager->LoadPalette(pBitmaps_LOD->pTextures[sSky_TextureID].palette_id1); | |
1966 | |
1967 pPaletteManager->RecalculateAll(); | |
2534 | 1968 pSoundList->LoadSound(SOUND_RunDirt, 0); //For Dirt tyle(для звука хождения по грязи) |
1969 pSoundList->LoadSound(SOUND_WalkDirt, 0); //для бега | |
1970 pSoundList->LoadSound(SOUND_RunRoad, 0); //для звука хождения по дороге | |
1971 pSoundList->LoadSound(SOUND_WalkRoad, 0); | |
1972 pSoundList->LoadSound(SOUND_RunWood, 0); //для звука хождения по дереву | |
1973 pSoundList->LoadSound(SOUND_WalkWood, 0); | |
2496 | 1974 for (int i=0; i < 3;++i) |
1975 { | |
1976 switch ( pTileTypes[i].tileset ) | |
1977 { | |
1978 case Tileset_Grass: | |
2534 | 1979 pSoundList->LoadSound(SOUND_RunGrass, 0); //для звука хождения по траве |
1980 pSoundList->LoadSound(SOUND_WalkGrass, 0); | |
2496 | 1981 break; |
1982 case Tileset_Snow: | |
2534 | 1983 pSoundList->LoadSound(SOUND_RunSnow, 0); //по снегу |
1984 pSoundList->LoadSound(SOUND_WalkSnow, 0); | |
2496 | 1985 break; |
1986 case Tilset_Desert: | |
2534 | 1987 pSoundList->LoadSound(SOUND_RunDesert, 0); //по пустыне |
1988 pSoundList->LoadSound(SOUND_WalkDesert, 0); | |
2496 | 1989 break; |
2534 | 1990 case Tileset_CooledLava: |
1991 pSoundList->LoadSound(SOUND_RunCooledLava, 0);//по лаве | |
1992 pSoundList->LoadSound(SOUND_WalkCooledLava, 0); | |
2496 | 1993 break; |
1994 case Tileset_Water: | |
2534 | 1995 pSoundList->LoadSound(SOUND_RunWater, 0); //по воде |
1996 pSoundList->LoadSound(SOUND_WalkWater, 0); | |
2496 | 1997 break; |
2534 | 1998 case Tileset_Badlands: |
1999 pSoundList->LoadSound(SOUND_RunBadlands, 0); //для звука ходьбы по бесплодным землям | |
2000 pSoundList->LoadSound(SOUND_WalkBadlands, 0); | |
2496 | 2001 break; |
2002 case Tileset_Swamp: | |
2534 | 2003 pSoundList->LoadSound(SOUND_RunSwamp, 0); //по болоту |
2004 pSoundList->LoadSound(SOUND_WalkSwamp, 0); | |
2496 | 2005 break; |
2006 } | |
2007 } | |
2008 return true; | |
2009 } | |
2010 | |
2011 //----- (0047ECC1) -------------------------------------------------------- | |
2012 int OutdoorLocation::GetTileIdByTileMapId(signed int a2) | |
2013 { | |
2014 signed int result; // eax@2 | |
2015 int v3; // eax@3 | |
2016 | |
2017 if ( a2 >= 90 ) | |
2018 { | |
2019 v3 = (a2 - 90) / 36; | |
2020 if ( v3 && v3 != 1 && v3 != 2 ) | |
2021 { | |
2534 | 2022 if ( v3 == Tileset_CooledLava ) |
2496 | 2023 result = this->pTileTypes[3].uTileID; |
2024 else | |
2025 result = a2; | |
2026 } | |
2027 else | |
2028 result = this->pTileTypes[v3].uTileID; | |
2029 } | |
2030 else | |
2031 result = 0; | |
2032 return result; | |
2033 } | |
2034 | |
2035 //----- (0047ED08) -------------------------------------------------------- | |
2036 unsigned int OutdoorLocation::DoGetTileTexture(signed int sX, signed int sY) | |
2037 { | |
2038 int v3; // esi@5 | |
2039 // unsigned int result; // eax@9 | |
2040 | |
2041 assert(sX < 128 && sY < 128); | |
2042 | |
2043 v3 = this->pTerrain.pTilemap[sY * 128 + sX]; | |
2044 if (v3 < 198) // < Tileset_3 | |
2045 { | |
2046 if (v3 >= 90) | |
2047 v3 = v3 + this->pTileTypes[(v3 - 90) / 36].uTileID - 36 * ((v3 - 90) / 36) - 90; | |
2048 } | |
2049 else | |
2050 v3 = v3 + this->pTileTypes[3].uTileID - 198; | |
2051 | |
2052 #pragma region "New: seasons change" | |
2053 | |
2054 if (change_seasons) | |
2055 switch (pParty->uCurrentMonth) | |
2056 { | |
2057 case 11: case 0: case 1: // winter | |
2058 if (v3 >= 90) // Tileset_Grass begins at TileID = 90 | |
2059 { | |
2060 if (v3 <= 95) // some grastyl entries | |
2061 v3 = 348; | |
2062 else if (v3 <= 113) // rest of grastyl & all grdrt* | |
2063 v3 = 348 + (v3 - 96); | |
2064 } | |
2065 /*switch (v3) | |
2066 { | |
2067 case 102: v3 = 354; break; // grdrtNE -> SNdrtne | |
2068 case 104: v3 = 356; break; // grdrtNW -> SNdrtnw | |
2069 case 108: v3 = 360; break; // grdrtN -> SNdrtn | |
2070 }*/ | |
2071 break; | |
2072 | |
2073 case 2: case 3: case 4: // spring | |
2074 case 8: case 9: case 10: // autumn | |
2075 if (v3 >= 90 && v3 <= 113) // just convert all Tileset_Grass to dirt | |
2076 v3 = 1; | |
2077 break; | |
2078 | |
2079 case 5: case 6: case 7: // summer | |
2080 //all tiles are green grass by default | |
2081 break; | |
2082 | |
2083 default: assert(pParty->uCurrentMonth >= 0 && pParty->uCurrentMonth < 12); | |
2084 } | |
2085 #pragma endregion | |
2086 | |
2087 return pTileTable->pTiles[v3].uBitmapID; | |
2088 } | |
2089 | |
2090 //----- (0047ED83) -------------------------------------------------------- | |
2091 int OutdoorLocation::_47ED83(signed int a2, signed int a3) | |
2092 { | |
2093 assert(a2 < 128 && a3 < 128); | |
2094 | |
2095 return *(&this->pTerrain.pTilemap[128 * a3] + a2); | |
2096 } | |
2097 | |
2098 //----- (0047EDB3) -------------------------------------------------------- | |
2099 int OutdoorLocation::ActuallyGetSomeOtherTileInfo(signed int sX, signed int sY) | |
2100 { | |
2101 assert(sX < 128 && sY < 128); | |
2102 int v3; // esi@5 | |
2103 | |
2104 v3 = this->pTerrain.pTilemap[sY * 128 + sX]; | |
2105 if ( v3 >= 90 ) | |
2106 v3 = v3 + this->pTileTypes[(v3 - 90) / 36].uTileID - 36 * ((v3 - 90) / 36) - 90; | |
2107 return pTileTable->pTiles[v3].uAttributes; | |
2108 } | |
2109 | |
2110 //----- (0047EE16) -------------------------------------------------------- | |
2111 int OutdoorLocation::DoGetHeightOnTerrain(signed int sX, signed int sZ) | |
2112 { | |
2113 assert(sX < 128 && sZ < 128); | |
2114 | |
2115 return 32 * pTerrain.pHeightmap[sZ * 128 + sX]; | |
2116 } | |
2117 | |
2118 //----- (0047EE49) -------------------------------------------------------- | |
2119 int OutdoorLocation::GetSoundIdByPosition( signed int X_pos, signed int Y_pos, int running ) | |
2120 { | |
2121 signed int v4; // eax@5 | |
2122 signed int v5; // eax@7 | |
2123 // int v6; // eax@8 | |
2124 signed int v8; // eax@9 | |
2125 int modif=0; | |
2126 | |
2127 if ( X_pos < 0 || X_pos > 127 || Y_pos < 0 || Y_pos > 127 ) | |
2128 v4 = 0; | |
2129 else | |
2130 v4 = this->pTerrain.pTilemap[128 * Y_pos + X_pos]; | |
2131 v5 = GetTileIdByTileMapId(v4); | |
2132 if (running) | |
2133 modif=-39; | |
2134 if ( !v5 ) | |
2135 return 92+modif; | |
2136 | |
2137 switch (pTileTable->pTiles[v5].tileset) | |
2138 { | |
2139 case 0: return 93+ modif; | |
2140 case 1: return 97+ modif; | |
2141 case 2: return 91+ modif; | |
2142 case 3: return 90+ modif; | |
2143 case 4: return 101+ modif; | |
2144 case 5: return 95+ modif; | |
2145 case 6: return 88+ modif; | |
2146 case 7: return 100+ modif; | |
2147 case 8: return 93+ modif; | |
2148 default: | |
2149 v8=pTileTable->pTiles[v5].tileset; | |
2150 if ( (v8 > 9 && v8 <= 17) || (v8 > 21 && v8 <= 27) ) | |
2151 return 96+ modif; | |
2152 else | |
2153 return 95+ modif; | |
2154 } | |
2155 | |
2156 } | |
2157 | |
2158 //----- (0047EF60) -------------------------------------------------------- | |
2159 int OutdoorLocation::UpdateDiscoveredArea(int X_grid_pos, int Y_grid_poa, int a4) | |
2160 { | |
2161 for (int i = -10; i < 10; i++) | |
2162 { | |
2163 int currYpos = Y_grid_poa + i - 20; | |
2164 for (int j = -10; j < 10; j++) | |
2165 { | |
2166 int currXpos = X_grid_pos + j - 20; | |
2167 int distanceSquared = i * i + j * j; | |
2168 if ( distanceSquared <= 100 && currYpos >= 0 && currYpos <= 87 && currXpos >= 0 && currXpos <= 87 ) | |
2169 { | |
2170 unsigned char v13 = 1 << (7 - currXpos % 8); | |
2171 this->uPartiallyRevealedCellOnMap[currYpos][currXpos / 8] |= v13; | |
2172 if ( distanceSquared <= 49 ) | |
2173 this->uFullyRevealedCellOnMap[currYpos][currXpos / 8] |= v13; | |
2174 } | |
2175 } | |
2176 } | |
2177 return 1; | |
2178 } | |
2179 | |
2180 | |
2181 //----- (0047F04C) -------------------------------------------------------- | |
2182 bool OutdoorLocation::IsMapCellFullyRevealed(signed int x_pos, signed int y_pos) | |
2183 { | |
2184 if ( x_pos < 0 || x_pos >= 88 || y_pos < 0 || y_pos >= 88 ) | |
2185 return false; | |
2186 else | |
2187 return (uFullyRevealedCellOnMap[y_pos][x_pos/8] & (1 << (7 - (x_pos) % 8))) != 0; | |
2188 } | |
2189 | |
2190 //----- (0047F097) -------------------------------------------------------- | |
2191 bool OutdoorLocation::IsMapCellPartiallyRevealed(signed int x_pos, signed int y_pos) | |
2192 { | |
2193 if ( x_pos < 0 || x_pos >= 88 || y_pos < 0 || y_pos >= 88 ) | |
2194 return false; | |
2195 else | |
2196 return (uPartiallyRevealedCellOnMap[y_pos][x_pos/8] & (1 << (7 - (x_pos) % 8))) != 0; | |
2197 } | |
2198 | |
2199 //----- (0047F0E2) -------------------------------------------------------- | |
2200 bool OutdoorLocation::_47F0E2() | |
2201 { | |
2202 for ( uint i = 0; i < (signed int)pBitmaps_LOD->uNumLoadedFiles; ++i ) | |
2203 { | |
2204 //if ( i != -1 ? (int)&pBitmaps_LOD->pTextures[i] : 0 ) | |
2205 pBitmaps_LOD->pTextures[i].uDecompressedSize = this->pTerrain._47CB57((int)pBitmaps_LOD->pTextures[i].pLevelOfDetail0_prolly_alpha_mask, | |
2206 pBitmaps_LOD->pTextures[i].palette_id2, | |
2207 pBitmaps_LOD->pTextures[i].uTextureWidth * pBitmaps_LOD->pTextures[i].uTextureHeight); | |
2208 } | |
2209 return 1; | |
2210 } | |
2211 | |
2212 //----- (0047F138) -------------------------------------------------------- | |
2213 bool OutdoorLocation::PrepareDecorations() | |
2214 { | |
2215 signed int v1; // ebx@1 | |
2216 signed int v8; // [sp+Ch] [bp-4h]@1 | |
2217 | |
2218 v1 = 0; | |
2219 v8 = 0; | |
2220 if ( !_stricmp(pCurrentMapName, "out09.odm") ) | |
2221 v8 = 1; | |
2222 | |
2223 for (uint i = 0; i < uNumLevelDecorations; ++i) | |
2224 { | |
2225 LevelDecoration* decor = &pLevelDecorations[i]; | |
2226 | |
2227 pDecorationList->InitializeDecorationSprite(decor->uDecorationDescID); | |
2228 if ( pDecorationList->pDecorations[decor->uDecorationDescID].uSoundID && _6807E0_num_decorations_with_sounds_6807B8 < 9 ) | |
2229 { | |
2230 pSoundList->LoadSound(pDecorationList->pDecorations[decor->uDecorationDescID].uSoundID, 0); | |
2231 _6807B8_level_decorations_ids[_6807E0_num_decorations_with_sounds_6807B8++] = i; | |
2232 } | |
2233 if ( v8 && decor->uCog == 20 ) | |
2234 decor->uFlags |= LEVEL_DECORATION_OBELISK_CHEST; | |
2235 if ( !decor->uEventID ) | |
2236 { | |
2237 if ( decor->IsInteractive() ) | |
2238 { | |
2239 if ( v1 < 124 ) | |
2240 { | |
2241 decor->_idx_in_stru123 = v1 + 75; | |
2242 if ( !stru_5E4C90_MapPersistVars._decor_events[v1++] ) | |
2243 decor->uFlags |= LEVEL_DECORATION_INVISIBLE; | |
2244 } | |
2245 } | |
2246 } | |
2247 } | |
2248 | |
2249 pGameLoadingUI_ProgressBar->Progress(); | |
2250 return true; | |
2251 } | |
2252 // 6807E0: using guessed type int _6807E0_num_decorations_6807B8; | |
2253 | |
2254 //----- (0047F223) -------------------------------------------------------- | |
2255 void OutdoorLocation::ArrangeSpriteObjects() | |
2256 { | |
2257 OutdoorLocation *v5; // [sp+0h] [bp-4h]@1 | |
2258 | |
2259 v5 = this; | |
2260 if ( (signed int)uNumSpriteObjects > 0 ) | |
2261 { | |
2262 for ( int i = 0; i < (signed int)uNumSpriteObjects; ++i ) | |
2263 { | |
2264 if ( pSpriteObjects[i].uObjectDescID ) | |
2265 { | |
2266 if ( !(pSpriteObjects[i].uAttributes & 8) && !(pObjectList->pObjects[pSpriteObjects[i].uObjectDescID].uFlags & 0x10) ) | |
2267 pSpriteObjects[i].vPosition.z = GetTerrainHeightsAroundParty2(pSpriteObjects[i].vPosition.x, pSpriteObjects[i].vPosition.y, (int *)&v5, 0); | |
2268 if ( pSpriteObjects[i].stru_24.uItemID ) | |
2269 { | |
2270 if ( pSpriteObjects[i].stru_24.uItemID != 220 | |
2271 && pItemsTable->pItems[pSpriteObjects[i].stru_24.uItemID].uEquipType == EQUIP_POTION | |
2272 && !pSpriteObjects[i].stru_24.uEnchantmentType ) | |
2273 pSpriteObjects[i].stru_24.uEnchantmentType = rand() % 15 + 5; | |
2274 pItemsTable->SetSpecialBonus(&pSpriteObjects[i].stru_24); | |
2275 } | |
2276 } | |
2277 } | |
2278 } | |
2279 pGameLoadingUI_ProgressBar->Progress(); | |
2280 } | |
2281 | |
2282 //----- (0047F2D3) -------------------------------------------------------- | |
2283 bool OutdoorLocation::InitalizeActors(int a1) | |
2284 { | |
2285 int alert_status; // [sp+348h] [bp-8h]@1 | |
2286 // int v9; // [sp+34Ch] [bp-4h]@1 | |
2287 | |
2288 alert_status = 0; | |
2289 for( int i = 0; i < uNumActors; ++i ) | |
2290 { | |
2291 if ( !(pActors[i].uAttributes & ACTOR_UNKNOW7) ) | |
2292 { | |
2293 if ( alert_status != 1 ) | |
2294 { | |
2295 pActors[i].uCurrentActionTime = 0; | |
2296 pActors[i].uCurrentActionLength = 0; | |
2297 if ( pActors[i].uAttributes & ACTOR_UNKNOW11 ) | |
2298 pActors[i].uAIState = AIState::Disabled; | |
2299 if ( pActors[i].uAIState != AIState::Removed && pActors[i].uAIState != AIState::Disabled && | |
2300 (pActors[i].sCurrentHP == 0 || pActors[i].pMonsterInfo.uHP == 0) ) | |
2301 pActors[i].uAIState = AIState::Dead; | |
2302 pActors[i].vVelocity.x = 0; | |
2303 pActors[i].vVelocity.y = 0; | |
2304 pActors[i].vVelocity.z = 0; | |
2305 pActors[i].UpdateAnimation(); | |
2306 pActors[i].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly; | |
2307 pActors[i].PrepareSprites(0); | |
2308 } | |
2309 else | |
2310 { | |
2311 pActors[i].uAIState = AIState::Disabled; | |
2312 pActors[i].uAttributes |= ACTOR_UNKNOW11; | |
2313 } | |
2314 } | |
2315 else if ( a1 == 0 ) | |
2316 { | |
2317 pActors[i].uAIState = AIState::Disabled; | |
2318 pActors[i].uAttributes |= ACTOR_UNKNOW11; | |
2319 } | |
2320 else if ( alert_status != 0 ) | |
2321 { | |
2322 pActors[i].uCurrentActionTime = 0; | |
2323 pActors[i].uCurrentActionLength = 0; | |
2324 if ( pActors[i].uAttributes & ACTOR_UNKNOW11 ) | |
2325 pActors[i].uAIState = AIState::Disabled; | |
2326 if ( pActors[i].uAIState != AIState::Removed && pActors[i].uAIState != AIState::Disabled && | |
2327 (pActors[i].sCurrentHP == 0 || pActors[i].pMonsterInfo.uHP == 0) ) | |
2328 pActors[i].uAIState = AIState::Dead; | |
2329 pActors[i].vVelocity.x = 0; | |
2330 pActors[i].vVelocity.y = 0; | |
2331 pActors[i].vVelocity.z = 0; | |
2332 pActors[i].UpdateAnimation(); | |
2333 pActors[i].pMonsterInfo.uHostilityType = MonsterInfo::Hostility_Friendly; | |
2334 pActors[i].PrepareSprites(0); | |
2335 } | |
2336 else | |
2337 { | |
2338 pActors[i].uAIState = AIState::Disabled; | |
2339 pActors[i].uAttributes |= ACTOR_UNKNOW11; | |
2340 alert_status = GetAlertStatus(); | |
2341 } | |
2342 } | |
2343 | |
2344 pGameLoadingUI_ProgressBar->Progress(); | |
2345 //no use for this | |
2346 // Actor thisa; | |
2347 // thisa.pMonsterInfo.uID = 45; | |
2348 // thisa.PrepareSprites(0); | |
2349 return 1; | |
2350 } | |
2351 | |
2352 //----- (0047F3EA) -------------------------------------------------------- | |
2353 bool OutdoorLocation::LoadRoadTileset() | |
2354 { | |
2355 pTileTypes[3].uTileID = pTileTable->GetTileForTerrainType(pTileTypes[3].tileset, 1); | |
2356 pTileTable->InitializeTileset(pTileTypes[3].tileset); | |
2357 return 1; | |
2358 } | |
2359 | |
2360 //----- (0047F420) -------------------------------------------------------- | |
2361 bool OutdoorLocation::LoadTileGroupIds() | |
2362 { | |
2363 for (uint i = 0; i < 3; ++i) | |
2364 pTileTypes[i].uTileID = pTileTable->GetTileForTerrainType(pTileTypes[i].tileset, 1); | |
2365 | |
2366 return true; | |
2367 } | |
2368 | |
2369 //----- (0047B42C) -------------------------------------------------------- | |
2370 void OutdoorLocation::PrepareActorsDrawList() | |
2371 { | |
2372 unsigned int result; // eax@1 | |
2373 int z; // esi@5 | |
2374 float v4; // ST48_4@8 | |
2375 unsigned int v8; // eax@11 | |
2376 int v9; // edx@11 | |
2377 signed int v12; // eax@16 | |
2378 SpriteFrame *v14; // eax@24 | |
2379 SpriteFrame *v15; // ebx@25 | |
2380 int v17; // eax@35 | |
2381 int v18; // ST78_4@36 | |
2382 int v19; // eax@36 | |
2383 int v20; // ecx@38 | |
2384 int v21; // eax@38 | |
2385 int v22; // ecx@41 | |
2386 int v23; // ST5C_4@43 | |
2387 int v24; // esi@44 | |
2388 signed __int64 v25; // qtt@45 | |
2389 int v26; // ST54_4@45 | |
2390 int v27; // ecx@45 | |
2391 int v34; // ecx@54 | |
2392 int v41; // [sp+24h] [bp-3Ch]@11 | |
2393 int v42; // [sp+28h] [bp-38h]@38 | |
2394 int v43; // [sp+28h] [bp-38h]@45 | |
2395 int v44; // [sp+2Ch] [bp-34h]@36 | |
2396 int v45; // [sp+2Ch] [bp-34h]@44 | |
2397 int v46; // [sp+2Ch] [bp-34h]@45 | |
2398 int v47; // [sp+30h] [bp-30h]@36 | |
2399 int v48; // [sp+30h] [bp-30h]@41 | |
2400 signed int v49; // [sp+34h] [bp-2Ch]@5 | |
2401 int v50; // [sp+34h] [bp-2Ch]@36 | |
2402 int v51; // [sp+34h] [bp-2Ch]@41 | |
2403 int v53; // [sp+38h] [bp-28h]@36 | |
2404 int y; // [sp+40h] [bp-20h]@5 | |
2405 int x; // [sp+44h] [bp-1Ch]@5 | |
2406 int v57; // [sp+48h] [bp-18h]@45 | |
2407 int v58; // [sp+4Ch] [bp-14h]@45 | |
2408 int X; // [sp+54h] [bp-Ch]@36 | |
2409 signed __int16 v62; // [sp+5Ch] [bp-4h]@25 | |
2410 | |
2411 //result = 0; | |
2412 //v59 = 0; | |
2413 for (int i = 0; i < uNumActors; ++i) | |
2414 { | |
2415 //v54 = 0; | |
2416 //v1 = pActors;//[0].vPosition.z; | |
2417 //do | |
2418 //{ | |
2419 //Actor* actor = &pActors[i]; | |
2420 //v2 = actor->uAIState; | |
2421 | |
2422 pActors[i].uAttributes &= 0xFFFFFFF7;//~0x8 | |
2423 if (pActors[i].uAIState == Removed || pActors[i].uAIState == Disabled) | |
2424 continue; | |
2425 | |
2426 z = pActors[i].vPosition.z; | |
2427 v49 = 0; | |
2428 x = pActors[i].vPosition.x; | |
2429 y = pActors[i].vPosition.y; | |
2430 if (pActors[i].uAIState == Summoned) | |
2431 { | |
2432 if (PID_TYPE(pActors[i].uSummonerID) != OBJECT_Actor || | |
2433 pActors[PID_ID(pActors[i].uSummonerID)].pMonsterInfo.uSpecialAbilityDamageDiceSides != 1 ) | |
2434 { | |
2435 z += floorf(pActors[i].uActorHeight * 0.5f + 0.5f); | |
2436 } | |
2437 else | |
2438 { | |
2439 v49 = 1; | |
2541 | 2440 pEngine->pStru6Instance->_4A7F74(pActors[i].vPosition.x, pActors[i].vPosition.y, z); |
2496 | 2441 v4 = (1.0 - (double)pActors[i].uCurrentActionTime / (double)pActors[i].uCurrentActionLength) * |
2442 (double)(2 * pActors[i].uActorHeight); | |
2443 z -= floorf(v4 + 0.5f); | |
2444 if ( z > pActors[i].vPosition.z ) | |
2445 z = pActors[i].vPosition.z; | |
2446 } | |
2447 } | |
2543 | 2448 v8 = stru_5C6E00->Atan2(pActors[i].vPosition.x - pIndoorCameraD3D->vPartyPos.x, |
2449 pActors[i].vPosition.y - pIndoorCameraD3D->vPartyPos.y); | |
2496 | 2450 LOWORD(v9) = pActors[i].uYawAngle; |
2451 v41 = ((signed int)(stru_5C6E00->uIntegerPi + ((signed int)stru_5C6E00->uIntegerPi >> 3) + v9 - v8) >> 8) & 7; | |
2452 if ( pParty->bTurnBasedModeOn ) | |
2453 { | |
2454 v12 = pActors[i].uCurrentActionTime; | |
2455 if ( pActors[i].uCurrentActionAnimation == 1 ) | |
2456 v12 = 32 * i + pMiscTimer->uTotalGameTimeElapsed; | |
2457 } | |
2458 else | |
2459 { | |
2460 v12 = pActors[i].uCurrentActionTime; | |
2461 if ( pActors[i].uCurrentActionAnimation == 1 ) | |
2462 v12 = 32 * i + pEventTimer->uTotalGameTimeElapsed; | |
2463 } | |
2464 if ( (signed __int64)pActors[i].pActorBuffs[ACTOR_BUFF_STONED].uExpireTime > 0 || (signed __int64)pActors[i].pActorBuffs[ACTOR_BUFF_PARALYZED].uExpireTime > 0 ) | |
2465 v12 = 0; | |
2466 if ( pActors[i].uAIState == 17 && !v49 ) | |
2467 v14 = pSpriteFrameTable->GetFrame(uSpriteID_Spell11, v12); | |
2468 else if ( pActors[i].uAIState == 16 ) | |
2469 v14 = pSpriteFrameTable->GetFrameBy_x(pActors[i].pSpriteIDs[pActors[i].uCurrentActionAnimation], v12); | |
2470 else | |
2471 v14 = pSpriteFrameTable->GetFrame(pActors[i].pSpriteIDs[pActors[i].uCurrentActionAnimation], v12); | |
2472 v62 = 0; | |
2473 v15 = v14; | |
2474 //v16 = (int *)v14->uFlags; | |
2475 if (v14->uFlags & 2) | |
2476 v62 = 2; | |
2477 if (v14->uFlags & 0x40000) | |
2478 v62 |= 0x40; | |
2479 if (v14->uFlags & 0x20000) | |
2480 LOBYTE(v62) = v62 | 0x80; | |
2481 if ((256 << v41) & v14->uFlags) | |
2482 v62 |= 4; | |
2483 if ( v15->uGlowRadius ) | |
2484 { | |
2485 //LOBYTE(v16) = _4E94D3_light_type; | |
2486 pMobileLightsStack->AddLight(x, y, z, 0, v15->uGlowRadius, 0xFFu, 0xFFu, 0xFFu, _4E94D3_light_type); | |
2487 } | |
2543 | 2488 v17 = (x - pIndoorCameraD3D->vPartyPos.x) << 16; |
2489 if (pIndoorCameraD3D->sRotationX) | |
2496 | 2490 { |
2543 | 2491 v18 = (y - pIndoorCameraD3D->vPartyPos.y) << 16; |
2492 v47 = (fixpoint_mul(v17, pIndoorCameraD3D->int_cosine_y) + fixpoint_mul(v18, pIndoorCameraD3D->int_sine_y)); | |
2493 v50 = fixpoint_mul(v17, pIndoorCameraD3D->int_sine_y); | |
2494 v53 = fixpoint_mul(v18, pIndoorCameraD3D->int_cosine_y); | |
2495 v44 = (z - pIndoorCameraD3D->vPartyPos.z) << 16; | |
2496 v19 = (fixpoint_mul(v44, pIndoorCameraD3D->int_sine_x) + fixpoint_mul(v47, pIndoorCameraD3D->int_cosine_x)); | |
2497 X = fixpoint_mul(v44, pIndoorCameraD3D->int_sine_x) + fixpoint_mul(v47, pIndoorCameraD3D->int_cosine_x); | |
2496 | 2498 if ( v19 < 262144 || v19 > pODMRenderParams->shading_dist_mist << 16 ) |
2499 continue; | |
2500 v20 = v53 - v50; | |
2501 v42 = v53 - v50; | |
2543 | 2502 v21 = (fixpoint_mul(v44, pIndoorCameraD3D->int_cosine_x) - fixpoint_mul(v47, pIndoorCameraD3D->int_sine_x)); |
2496 | 2503 } |
2504 else | |
2505 { | |
2543 | 2506 v48 = (y - pIndoorCameraD3D->vPartyPos.y) << 16; |
2507 v51 = fixpoint_mul(v17, pIndoorCameraD3D->int_cosine_y); | |
2508 v22 = fixpoint_mul(v48, pIndoorCameraD3D->int_sine_y); | |
2496 | 2509 X = v22 + v51; |
2510 if ( v22 + v51 < 262144 || v22 + v51 > pODMRenderParams->shading_dist_mist << 16 ) | |
2511 continue; | |
2543 | 2512 v23 = fixpoint_mul(((x - pIndoorCameraD3D->vPartyPos.x) << 16), pIndoorCameraD3D->int_sine_y); |
2513 v20 = fixpoint_mul(v48, pIndoorCameraD3D->int_cosine_y) - v23; | |
2514 v42 = fixpoint_mul(v48, pIndoorCameraD3D->int_cosine_y) - v23; | |
2515 v21 = (z - pIndoorCameraD3D->vPartyPos.z) << 16; | |
2496 | 2516 } |
2517 v45 = v21; | |
2518 v24 = abs(v20); | |
2519 if ( abs(X) >= v24 ) | |
2520 { | |
2521 LODWORD(v25) = 0; | |
2522 HIDWORD(v25) = SLOWORD(pODMRenderParams->int_fov_rad); | |
2523 v58 = v25 / X; | |
2524 v26 = v25 / X; | |
2525 LODWORD(v25) = 0; | |
2526 HIDWORD(v25) = SLOWORD(pODMRenderParams->int_fov_rad); | |
2527 v57 = v25 / X; | |
2528 v27 = pViewport->uScreenCenterX - ((signed int)(fixpoint_mul(v26, v42) + 0x8000) >> 16); | |
2529 v43 = pViewport->uScreenCenterX - ((signed int)(fixpoint_mul(v26, v42) + 0x8000) >> 16); | |
2530 v46 = pViewport->uScreenCenterY - ((signed int)(fixpoint_mul(v25 / X, v45) + 0x8000) >> 16); | |
2531 result = uNumBillboardsToDraw; | |
2532 //v28 = &pBillboardRenderList[uNumBillboardsToDraw]; | |
2533 if (uNumBillboardsToDraw >= 500) | |
2534 return; | |
2535 ++uNumBillboardsToDraw; | |
2536 ++uNumSpritesDrawnThisFrame; | |
2537 pActors[i].uAttributes |= ACTOR_UNKNOW2; | |
2538 pBillboardRenderList[uNumBillboardsToDraw - 1].HwSpriteID = v15->pHwSpriteIDs[v41]; | |
2539 pBillboardRenderList[uNumBillboardsToDraw - 1].uIndoorSectorID = 0; | |
2540 pBillboardRenderList[uNumBillboardsToDraw - 1].uPalette = v15->uPaletteIndex; | |
2541 pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_x_scaler_packedfloat = fixpoint_mul(v15->scale, v58); | |
2542 pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat = fixpoint_mul(v15->scale, v57); | |
2543 if ( pActors[i].pActorBuffs[ACTOR_BUFF_SHRINK].uExpireTime <= 0 ) | |
2544 { | |
2545 if ( pActors[i].pActorBuffs[ACTOR_BUFF_MASS_DISTORTION].uExpireTime > 0 ) | |
2546 { | |
2541 | 2547 pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat = fixpoint_mul(pEngine->pStru6Instance->_4A806F(&pActors[i]), |
2496 | 2548 pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat); |
2549 LOWORD(v27) = v43; | |
2550 } | |
2551 } | |
2552 else | |
2553 { | |
2554 if ( pActors[i].pActorBuffs[ACTOR_BUFF_SHRINK].uPower ) | |
2555 { | |
2556 pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat = fixpoint_mul(65536 / pActors[i].pActorBuffs[ACTOR_BUFF_SHRINK].uPower, | |
2557 pBillboardRenderList[uNumBillboardsToDraw - 1]._screenspace_y_scaler_packedfloat); | |
2558 LOWORD(v27) = v43; | |
2559 } | |
2560 } | |
2561 pBillboardRenderList[uNumBillboardsToDraw - 1].uScreenSpaceX = v27; | |
2562 pBillboardRenderList[uNumBillboardsToDraw - 1].uScreenSpaceY = v46; | |
2563 pBillboardRenderList[uNumBillboardsToDraw - 1].world_x = x; | |
2564 pBillboardRenderList[uNumBillboardsToDraw - 1].world_y = y; | |
2565 pBillboardRenderList[uNumBillboardsToDraw - 1].world_z = z; | |
2566 HIWORD(v34) = HIWORD(X); | |
2567 LOWORD(v34) = 0; | |
2568 pBillboardRenderList[uNumBillboardsToDraw - 1].dimming_level = 0; | |
2569 pBillboardRenderList[uNumBillboardsToDraw - 1].sZValue = v34 + PID(OBJECT_Actor, i); | |
2570 pBillboardRenderList[uNumBillboardsToDraw - 1].field_14_actor_id = i; | |
2571 //v35 = pMonsterList->pMonsters; | |
2572 //v36 = pActors[i].pMonsterInfo.uID; | |
2573 pBillboardRenderList[uNumBillboardsToDraw - 1].field_1E = v62 | 0x200; | |
2574 pBillboardRenderList[uNumBillboardsToDraw - 1].pSpriteFrame = v15; | |
2575 pBillboardRenderList[uNumBillboardsToDraw - 1].sTintColor = pMonsterList->pMonsters[pActors[i].pMonsterInfo.uID - 1].sTintColor;//*((int *)&v35[v36] - 36); | |
2576 if (pActors[i].pActorBuffs[ACTOR_BUFF_STONED].uExpireTime) | |
2577 pBillboardRenderList[uNumBillboardsToDraw - 1].field_1E = v62 | 0x200; | |
2578 } | |
2579 //LABEL_58: | |
2580 //++v59; | |
2581 //v54 += 32; | |
2582 //result = v59; | |
2583 //++v1; | |
2584 //} | |
2585 //while ( v59 < (signed int)uNumActors ); | |
2586 } | |
2587 //return result; | |
2588 } | |
2589 | |
2590 //----- (0044C1E8) -------------------------------------------------------- | |
2591 bool ODMFace::HasEventHint() | |
2592 { | |
2593 signed int event_index; // eax@1 | |
2594 _evt_raw* start_evt; | |
2595 _evt_raw* end_evt; | |
2596 | |
2597 event_index = 0; | |
2598 if ( (uLevelEVT_NumEvents - 1) <= 0 ) | |
2599 return false; | |
2600 while ( pLevelEVT_Index[event_index].uEventID != this->sCogTriggeredID ) | |
2601 { | |
2602 ++event_index; | |
2603 if ( event_index >= (signed int)(uLevelEVT_NumEvents - 1) ) | |
2604 return false; | |
2605 } | |
2606 end_evt=(_evt_raw*)&pLevelEVT[pLevelEVT_Index[event_index+1].uEventOffsetInEVT]; | |
2607 start_evt=(_evt_raw*)&pLevelEVT[pLevelEVT_Index[event_index].uEventOffsetInEVT]; | |
2608 if ( (end_evt->_e_type != EVENT_Exit) || (start_evt->_e_type!= EVENT_MouseOver) ) | |
2609 return false; | |
2610 else | |
2611 return true; | |
2612 } | |
2613 //----- (0046D49E) -------------------------------------------------------- | |
2614 int ODM_GetFloorLevel(int X, signed int Y, int Z, int __unused, int *pIsOnWater, int *bmodel_pid, int bWaterWalk) | |
2615 { | |
2616 BSPModel *pBModel; // esi@4 | |
2617 ODMFace *pFace; // ecx@11 | |
2618 // int v14; // edx@20 | |
2619 signed int v18; // edx@26 | |
2620 int v19; // eax@28 | |
2621 // int v20; // edx@30 | |
2622 // int v21; // ST1C_4@30 | |
2623 signed int v22; // edx@30 | |
2624 signed __int64 v23; // qtt@30 | |
2625 int v24; // eax@36 | |
2626 signed int v25; // ecx@38 | |
2627 // int result; // eax@42 | |
2628 signed int current_floor_level; // ecx@43 | |
2629 // int v28; // edi@44 | |
2630 signed int v29; // edx@44 | |
2631 // int v30; // esi@45 | |
2632 // int v31; // eax@45 | |
2633 // int v33; // ecx@59 | |
2634 // int v36; // [sp+14h] [bp-2Ch]@24 | |
2635 // int v38; // [sp+1Ch] [bp-24h]@2 | |
2636 int v39; // [sp+20h] [bp-20h]@9 | |
2637 signed int pBModelNum; // [sp+28h] [bp-18h]@1 | |
2638 int pFaceNum; // [sp+2Ch] [bp-14h]@8 | |
2639 bool current_vertices_Y; // [sp+30h] [bp-10h]@22 | |
2640 bool next_vertices_Y; // [sp+34h] [bp-Ch]@24 | |
2641 signed int v46; // [sp+3Ch] [bp-4h]@1 | |
2642 signed int number_hits; // [sp+58h] [bp+18h]@22 | |
2643 signed int next_floor_level; // [sp+58h] [bp+18h]@43 | |
2644 | |
2645 v46 = 1; | |
2646 current_BModel_id[0] = -1; | |
2647 current_Face_id[0] = -1; | |
2648 odm_floor_level[0] = GetTerrainHeightsAroundParty2(X, Y, pIsOnWater, bWaterWalk); | |
2649 | |
2650 for ( pBModelNum = 0; pBModelNum < pOutdoor->uNumBModels; ++pBModelNum ) | |
2651 { | |
2652 pBModel = &pOutdoor->pBModels[pBModelNum]; | |
2653 if ( X <= pBModel->sMaxX && X >= pBModel->sMinX && | |
2654 Y <= pBModel->sMaxY && Y >= pBModel->sMinY ) | |
2655 { | |
2656 if ( pBModel->uNumFaces > 0 ) | |
2657 { | |
2658 v39 = 0; | |
2659 for ( pFaceNum = 0; pFaceNum < pBModel->uNumFaces; ++pFaceNum ) | |
2660 { | |
2661 pFace = &pBModel->pFaces[pFaceNum]; | |
2662 if ( pFace->Ethereal() ) | |
2663 continue; | |
2664 if ( (pFace->uPolygonType == POLYGON_Floor || pFace->uPolygonType == POLYGON_InBetweenFloorAndWall) | |
2665 && X <= pFace->pBoundingBox.x2 && X >= pFace->pBoundingBox.x1 | |
2666 && Y <= pFace->pBoundingBox.y2 && Y >= pFace->pBoundingBox.y1 ) | |
2667 { | |
2668 for ( uint i = 0; i < pFace->uNumVertices; ++i) | |
2669 { | |
2670 odm_floor_face_vert_coord_X[2 * i] = pFace->pXInterceptDisplacements[i] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i]].x; | |
2671 odm_floor_face_vert_coord_Y[2 * i] = pFace->pYInterceptDisplacements[i] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i]].y; | |
2672 odm_floor_face_vert_coord_X[2 * i + 1] = pFace->pXInterceptDisplacements[i] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i + 1]].x; | |
2673 odm_floor_face_vert_coord_Y[2 * i + 1] = pFace->pYInterceptDisplacements[i] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i + 1]].y; | |
2674 } | |
2675 odm_floor_face_vert_coord_X[2 * pFace->uNumVertices] = odm_floor_face_vert_coord_X[0]; | |
2676 odm_floor_face_vert_coord_Y[2 * pFace->uNumVertices] = odm_floor_face_vert_coord_Y[0]; | |
2677 | |
2678 current_vertices_Y = odm_floor_face_vert_coord_Y[0] >= Y; | |
2679 number_hits = 0; | |
2680 if ( 2 * pFace->uNumVertices > 0 ) | |
2681 { | |
2682 for ( int i = 0; i < 2 * pFace->uNumVertices; ++i ) | |
2683 { | |
2684 if ( number_hits >= 2 ) | |
2685 break; | |
2686 //v36 = odm_floor_face_vert_coord_Y[i + 1]; | |
2687 next_vertices_Y = odm_floor_face_vert_coord_Y[i + 1] >= Y; | |
2688 if ( current_vertices_Y != next_vertices_Y )//проверка по Y | |
2689 { | |
2690 v18 = odm_floor_face_vert_coord_X[i + 1] >= X ? 0 : 2; | |
2691 v19 = v18 | (odm_floor_face_vert_coord_X[i] < X); | |
2692 if ( v19 != 3 ) | |
2693 { | |
2694 if ( !v19 ) | |
2695 ++number_hits; | |
2696 else | |
2697 { | |
2698 LODWORD(v23) = (Y - odm_floor_face_vert_coord_Y[i]) << 16; | |
2699 HIDWORD(v23) = (Y - odm_floor_face_vert_coord_Y[i]) >> 16; | |
2700 v22 = ((((odm_floor_face_vert_coord_X[i + 1] - odm_floor_face_vert_coord_X[i]) * v23 / (odm_floor_face_vert_coord_Y[i + 1] | |
2701 - odm_floor_face_vert_coord_Y[i])) >> 16) + odm_floor_face_vert_coord_X[i]); | |
2702 if ( v22 >= X) | |
2703 ++number_hits; | |
2704 } | |
2705 } | |
2706 } | |
2707 current_vertices_Y = next_vertices_Y; | |
2708 } | |
2709 if ( number_hits == 1 ) | |
2710 { | |
2711 if ( v46 >= 20 ) | |
2712 break; | |
2713 if ( pFace->uPolygonType == POLYGON_Floor ) | |
2714 v24 = pBModel->pVertices.pVertices[pFace->pVertexIDs[0]].z; | |
2715 else | |
2716 { | |
2717 int a = fixpoint_mul(pFace->zCalc1, X); | |
2718 int b = fixpoint_mul(pFace->zCalc2, Y); | |
2719 int c = ((signed __int64)pFace->zCalc3 >> 16); | |
2720 v24 = a + b + c; | |
2721 } | |
2722 v25 = v46++; | |
2723 odm_floor_level[v25] = v24; | |
2724 current_BModel_id[v25] = pBModelNum; | |
2725 current_Face_id[v25] = pFaceNum; | |
2726 } | |
2727 } | |
2728 } | |
2729 | |
2730 } | |
2731 } | |
2732 } | |
2733 } | |
2734 if ( v46 == 1 ) | |
2735 { | |
2736 *bmodel_pid = 0; | |
2737 return odm_floor_level[0]; | |
2738 } | |
2739 current_floor_level = 0; | |
2740 v29 = 0; | |
2741 if ( v46 <= 1 ) | |
2742 *bmodel_pid = 0; | |
2743 else | |
2744 { | |
2745 current_floor_level = odm_floor_level[0]; | |
2746 for ( uint i = 1; i < v46; ++i ) | |
2747 { | |
2748 next_floor_level = odm_floor_level[i]; | |
2749 if ( current_floor_level <= Z + 5 ) | |
2750 { | |
2751 if ( next_floor_level > current_floor_level && next_floor_level <= Z + 5 ) | |
2752 { | |
2753 current_floor_level = next_floor_level; | |
2754 v29 = i; | |
2755 } | |
2756 } | |
2757 else if ( next_floor_level < current_floor_level ) | |
2758 { | |
2759 current_floor_level = next_floor_level; | |
2760 v29 = i; | |
2761 } | |
2762 } | |
2763 if ( !v29 ) | |
2764 *bmodel_pid = 0; | |
2765 else | |
2766 *bmodel_pid = current_Face_id[v29] | (current_BModel_id[v29] << 6); | |
2767 } | |
2768 if ( v29 ) | |
2769 { | |
2770 *pIsOnWater = false; | |
2771 if ( pOutdoor->pBModels[current_BModel_id[v29]].pFaces[current_Face_id[v29]].Fluid()) | |
2772 *pIsOnWater = true; | |
2773 } | |
2774 if ( odm_floor_level[v29] >= odm_floor_level[0] ) | |
2775 odm_floor_level[0] = odm_floor_level[v29]; | |
2776 return odm_floor_level[0]; | |
2777 } | |
2778 | |
2779 //not sure if right- or left-handed coordinate space assumed, so this could be normal of inverse normal | |
2780 // for a right-handed system, that would be an inverse normal | |
2781 //----- (0046DCC8) -------------------------------------------------------- | |
2782 void ODM_GetTerrainNormalAt(int pos_x, int pos_z, Vec3_int_ *out) | |
2783 { | |
2784 uint grid_x = WorldPosToGridCellX(pos_x); | |
2785 uint grid_z = WorldPosToGridCellZ(pos_z) - 1; | |
2786 | |
2787 int grid_pos_x1 = GridCellToWorldPosX(grid_x); | |
2788 int grid_pos_x2 = GridCellToWorldPosX(grid_x + 1); | |
2789 int grid_pos_z1 = GridCellToWorldPosZ(grid_z); | |
2790 int grid_pos_z2 = GridCellToWorldPosZ(grid_z + 1); | |
2791 | |
2792 int x1z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z); | |
2793 int x2z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z); | |
2794 int x2z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1); | |
2795 int x1z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1); | |
2796 | |
2797 float side1_dx, side1_dy, side1_dz, | |
2798 side2_dx, side2_dy, side2_dz; | |
2799 | |
2800 int dx = abs(pos_x - grid_pos_x1), | |
2801 dz = abs(grid_pos_z1 - pos_z); | |
2802 if (dz >= dx) | |
2803 { | |
2804 side2_dx = (double)(grid_pos_x2 - grid_pos_x1); | |
2805 side2_dz = 0.0;//(double)(grid_pos_z2 - grid_pos_z2); // bug? z2 - z2 | |
2806 side2_dy = (double)(x2z2_y - x1z2_y); | |
2807 | |
2808 side1_dx = 0.0;//(double)(grid_pos_x1 - grid_pos_x1); | |
2809 side1_dz = (double)(grid_pos_z1 - grid_pos_z2); // z1 - z2 yes | |
2810 side1_dy = (double)(x1z1_y - x1z2_y); | |
2811 //Log::Warning(L"%S %S %u\n", __FILE__, __FUNCTION__, __LINE__); | |
2812 /* |\ | |
2813 side1 | \ | |
2814 |____\ | |
2815 side 2 */ | |
2816 } | |
2817 else | |
2818 { | |
2819 side2_dx = (double)(grid_pos_x1 - grid_pos_x2); | |
2820 side2_dz = 0.0;//(double)(grid_pos_z1 - grid_pos_z1); | |
2821 side2_dy = (double)(x1z1_y - x2z1_y); | |
2822 | |
2823 side1_dx = 0.0;//(double)(grid_pos_x2 - grid_pos_x1); | |
2824 side1_dz = (double)(grid_pos_z2 - grid_pos_z1); | |
2825 side1_dy = (double)(x2z2_y - x2z1_y); | |
2826 /* side 2 | |
2827 _____ | |
2828 \ | | |
2829 \ | side 1 | |
2830 \| */ | |
2831 } | |
2832 | |
2833 float nx = side1_dy * side2_dz - side1_dz * side2_dy; | |
2834 float ny = side1_dx * side2_dy - side1_dy * side2_dx; | |
2835 float nz = side1_dz * side2_dx - side1_dx * side2_dz; | |
2836 | |
2837 float mag = sqrt(nx * nx + ny * ny + nz * nz); | |
2838 if (fabsf(mag) < 1e-6f) | |
2839 { | |
2840 out->y = 0; | |
2841 out->x = 0; | |
2842 out->z = 65536; | |
2843 } | |
2844 else | |
2845 { | |
2846 float invmag = 1.0 / mag; | |
2847 out->x = invmag * nx * 65536.0; | |
2848 out->y = invmag * ny * 65536.0; | |
2849 out->z = invmag * nz * 65536.0; | |
2850 } | |
2851 } | |
2852 //----- (0046BE0A) -------------------------------------------------------- | |
2853 void ODM_UpdateUserInputAndOther() | |
2854 { | |
2855 bool v0; // eax@5 | |
2856 char pOut[32]; // [sp+8h] [bp-20h]@5 | |
2857 | |
2858 UpdateObjects(); | |
2859 ODM_ProcessPartyActions(); | |
2860 if ( pParty->vPosition.x < -22528 | |
2861 || pParty->vPosition.x > 22528 | |
2862 || pParty->vPosition.y < -22528 | |
2863 || pParty->vPosition.y > 22528 ) | |
2864 { | |
2865 strcpy(pOutdoor->pLevelFilename, pCurrentMapName); | |
2866 v0 = pOutdoor->GetTravelDestination(pParty->vPosition.x, pParty->vPosition.y, pOut, 32); | |
2867 if ( !bUnderwater && (pParty->uFlags & (PARTY_FLAGS_1_STANDING_ON_WATER | PARTY_FLAGS_1_FALLING | 0x04) || pParty->uFlags & 0x0200 || pParty->bFlying) || !v0 ) | |
2868 { | |
2869 if ( pParty->vPosition.x < -22528 ) | |
2870 pParty->vPosition.x = -22528; | |
2871 if ( pParty->vPosition.x > 22528 ) | |
2872 pParty->vPosition.x = 22528; | |
2873 if ( pParty->vPosition.y < -22528 ) | |
2874 pParty->vPosition.y = -22528; | |
2875 if ( pParty->vPosition.y > 22528 ) | |
2876 pParty->vPosition.y = 22528; | |
2877 } | |
2878 else | |
2879 { | |
2880 pAudioPlayer->StopChannels(-1, -1); | |
2545 | 2881 pDialogueWindow = new GUIWindow_Travel();//TravelUI_Load(); |
2496 | 2882 } |
2883 } | |
2884 UpdateActors_ODM(); | |
2885 check_event_triggers(); | |
2886 } | |
2887 //----- (0041F54A) -------------------------------------------------------- | |
2888 void OutdoorLocation::LoadActualSkyFrame() | |
2889 { | |
2890 if ( pTexture_RestUI_CurrentSkyFrame ) | |
2891 pTexture_RestUI_CurrentSkyFrame->Release(); | |
2892 if ( pTexture_RestUI_CurrentHourglassFrame ) | |
2893 pTexture_RestUI_CurrentHourglassFrame->Release(); | |
2894 pIcons_LOD->SyncLoadedFilesCount(); | |
2895 sprintf(pTmpBuf.data(), "TERRA%03d", pParty->uCurrentMinute / 6 + 10 * pParty->uCurrentHour); | |
2896 pTexture_RestUI_CurrentSkyFrame = pIcons_LOD->LoadTexturePtr(pTmpBuf.data(), TEXTURE_16BIT_PALETTE); | |
2897 } | |
2898 | |
2899 | |
2900 //----- (004626BA) -------------------------------------------------------- | |
2901 OutdoorLocation::OutdoorLocation() | |
2902 { | |
2903 subconstuctor(); | |
2904 uLastSunlightUpdateMinute = 0; | |
2905 | |
2906 uNumBModels = 0; | |
2907 pBModels = nullptr; | |
2908 } | |
2909 | |
2910 //----- (004626CD) -------------------------------------------------------- | |
2911 void OutdoorLocation::subconstuctor() | |
2912 { | |
2913 //OutdoorLocationTerrain::OutdoorLocationTerrain(&this->pTerrain); | |
2914 field_F0 = 0; | |
2915 field_F4 = 0x40000000u; | |
2916 //DLVHeader::DLVHeader(&v1->ddm); | |
2917 pSpawnPoints = 0; | |
2918 pBModels = 0; | |
2919 pCmap = 0; | |
2920 pFaceIDLIST = 0; | |
2921 pOMAP = 0; | |
2922 } | |
2923 | |
2924 //----- (00481E55) -------------------------------------------------------- | |
2925 void ODM_Project(unsigned int uNumVertices) | |
2926 { | |
2927 for ( uint i = 0; i < uNumVertices; i++ ) | |
2928 { | |
2562
b8a56afc6ba1
new var no_actors, lights_flag, debug_lights, StationaryLights and MobileLights
Ritor1
parents:
2545
diff
changeset
|
2929 memcpy(&VertexRenderList[i], &array_507D30[i], sizeof(VertexRenderList[i])); |
b8a56afc6ba1
new var no_actors, lights_flag, debug_lights, StationaryLights and MobileLights
Ritor1
parents:
2545
diff
changeset
|
2930 VertexRenderList[i].vWorldViewProjX = (double)pViewport->uScreenCenterX |
2496 | 2931 - ((double)pODMRenderParams->int_fov_rad * array_507D30[i]._rhw) * array_507D30[i].vWorldViewPosition.y; |
2562
b8a56afc6ba1
new var no_actors, lights_flag, debug_lights, StationaryLights and MobileLights
Ritor1
parents:
2545
diff
changeset
|
2932 VertexRenderList[i].vWorldViewProjY = (double)pViewport->uScreenCenterY |
2496 | 2933 - ((double)pODMRenderParams->int_fov_rad * array_507D30[i]._rhw) * array_507D30[i].vWorldViewPosition.z; |
2934 } | |
2935 } | |
2936 //----- (00485F64) -------------------------------------------------------- | |
2937 void ODMRenderParams::Initialize() | |
2938 { | |
2939 int v1; // eax@1 | |
2940 int v2; // eax@2 | |
2941 signed __int64 v3; // qtt@4 | |
2942 int v4; // eax@4 | |
2943 | |
2944 this->uCameraFovInDegrees = 75; | |
2945 v1 = stru_5C6E00->uPiMask & 0xD5; | |
2946 if ( v1 >= (signed int)stru_5C6E00->uIntegerHalfPi ) | |
2947 v2 = -stru_5C6E00->pTanTable[stru_5C6E00->uIntegerPi - v1]; | |
2948 else | |
2949 v2 = stru_5C6E00->pTanTable[v1]; | |
2950 LODWORD(v3) = (viewparams->uSomeZ - viewparams->uSomeX) << 31; | |
2951 HIDWORD(v3) = (viewparams->uSomeZ - viewparams->uSomeX) << 15 >> 16; | |
2952 v4 = (signed int)(v3 / v2) >> 16; | |
2953 this->int_fov_rad = v4; | |
2954 this->field_4C = 360000; | |
2955 this->int_fov_rad_inv = 65536 / v4; | |
2956 this->field_50 = 115; | |
2957 //sr_6BE060[1] = 1; | |
2958 //RotationToInts(); | |
2959 } | |
2960 //----- (00473893) -------------------------------------------------------- | |
2961 void ODM_ProcessPartyActions() | |
2962 { | |
2963 int v1; // edi@1 | |
2964 int v2; // ebx@1 | |
2965 int floor_level; // eax@14 | |
2966 ODMFace *face; // ecx@45 | |
2967 int v34; // esi@143 | |
2968 int v35; // esi@147 | |
2969 int v36; // eax@155 | |
2970 int v40; // esi@162 | |
2971 bool v42; // eax@180 | |
2972 signed int v43; // ecx@184 | |
2973 signed int v44; // edx@184 | |
2974 int v45; // ecx@200 | |
2975 BSPModel *pModel; // eax@203 | |
2976 bool pModel_; | |
2977 ODMFace *pODMFace; // esi@203 | |
2978 int v48; // eax@203 | |
2979 int v54; // eax@215 | |
2980 int v55; // eax@217 | |
2981 unsigned int v66; // esi@263 | |
2982 signed int v68; // ecx@263 | |
2983 int v69; // eax@263 | |
2984 bool v77; // edx@297 | |
2985 bool v78; // ecx@303 | |
2986 int v79; // ecx@314 | |
2987 __int16 v80; // dx@317 | |
2988 int pTerrainHeight; // eax@321 | |
2989 int v87; // [sp-20h] [bp-B4h]@248 | |
2990 int v97; // [sp+Ch] [bp-88h]@180 | |
2991 Vec3_int_ v98; | |
2992 bool not_high_fall; // [sp+1Ch] [bp-78h]@33 | |
2993 int v102; // [sp+20h] [bp-74h]@1 | |
2994 int trigger_id; // [sp+24h] [bp-70h]@1 | |
2995 bool bFeatherFall; // [sp+28h] [bp-6Ch]@4 | |
2996 int bonus; | |
2997 int on_ground; // [sp+2Ch] [bp-68h]@24 | |
2998 bool bWaterWalk; // [sp+30h] [bp-64h]@1 | |
2999 int ceiling_height; // [sp+3Ch] [bp-58h]@28 | |
3000 int v110; // [sp+40h] [bp-54h]@180 | |
3001 int v111; // [sp+44h] [bp-50h]@14 | |
3002 bool hovering; // [sp+48h] [bp-4Ch]@1 | |
3003 int v113; // [sp+4Ch] [bp-48h]@1 | |
3004 bool party_running_flag; // [sp+50h] [bp-44h]@1 | |
3005 int _walk_speed; // [sp+54h] [bp-40h]@48 | |
3006 int pX; // [sp+58h] [bp-3Ch]@1 | |
3007 int pY; // [sp+5Ch] [bp-38h]@1 | |
2534 | 3008 int party_new_Z; // [sp+74h] [bp-20h]@1 |
2496 | 3009 int v118; // [sp+60h] [bp-34h]@1 |
3010 int _angle_x; // [sp+68h] [bp-2Ch]@48 | |
3011 unsigned int v122; // [sp+70h] [bp-24h]@180 | |
2534 | 3012 |
2496 | 3013 bool party_walking_flag; // [sp+78h] [bp-1Ch]@1 |
3014 int _angle_y; // [sp+7Ch] [bp-18h]@48 | |
3015 int v128; // [sp+88h] [bp-Ch]@1 | |
3016 int v129; // [sp+8Ch] [bp-8h]@92 | |
3017 | |
3018 v1 = 0; | |
3019 trigger_id = 0; | |
3020 v2 = 0; | |
3021 //*(float *)&v128 = 0.0; | |
3022 int fall_speed = pParty->uFallSpeed; | |
3023 v128 = 0; | |
3024 v129 = 0; | |
2534 | 3025 |
2496 | 3026 pX = pParty->vPosition.x; |
3027 pY = pParty->vPosition.y; | |
2534 | 3028 party_new_Z = pParty->vPosition.z; |
3029 | |
2496 | 3030 v113 = pParty->field_6F0; |
3031 hovering = false; | |
3032 bool partyAtHighSlope = IsTerrainSlopeTooHigh(pParty->vPosition.x, pParty->vPosition.y); | |
3033 party_running_flag = false; | |
3034 party_walking_flag = false; | |
3035 v102 = 0; | |
3036 pModel_ = false; | |
3037 bWaterWalk = false; | |
2534 | 3038 //************************************ |
3039 //Проверка падение пера | |
3040 if (!pParty->FeatherFallActive()) | |
2496 | 3041 { |
3042 bFeatherFall = false; | |
3043 for (int i = 0; i < 4; ++i) | |
3044 if (pParty->pPlayers[i].WearsItemAnyWhere(ITEM_ARTIFACT_LADYS_ESCORT)) // seems like flying boots | |
3045 { | |
3046 bFeatherFall = true; | |
3047 break; | |
3048 } | |
3049 } | |
3050 else | |
3051 bFeatherFall = true; | |
2534 | 3052 //************************************ |
3053 //Проверка хождения по воде | |
2496 | 3054 pParty->uFlags &= ~PARTY_FLAGS_1_STANDING_ON_WATER; |
2534 | 3055 if (pParty->WaterWalkActive()) |
2496 | 3056 { |
3057 //LOBYTE(pParty->uFlags) &= 0x7Fu; | |
3058 bWaterWalk = true; | |
2508 | 3059 *(short *)&stru_5E4C90_MapPersistVars._decor_events[20 * pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uOverlayID + 119] |= 1; |
2496 | 3060 if (!(pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uFlags & 1) && |
3061 pParty->pPlayers[pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uCaster - 1].sMana <= 0 ) | |
3062 bWaterWalk = false; | |
3063 } | |
2534 | 3064 //************************************* |
3065 //определение уровня пола | |
3066 int bmodel_standing_on_pid; //данные 3D model'и | |
3067 int is_on_water = false; //на воду | |
3068 floor_level = ODM_GetFloorLevel(pX, pY, party_new_Z, pParty->uPartyHeight, &is_on_water, &bmodel_standing_on_pid, bWaterWalk); | |
3069 int is_not_on_bmodel = bmodel_standing_on_pid == 0; //не на 3D model | |
3070 | |
3071 v111 = floor_level; //??? | |
3072 //************************************ | |
3073 //определение высоты падения | |
3074 if ( bFeatherFall ) //падение пера | |
2496 | 3075 pParty->uFallStartY = floor_level; |
3076 else | |
3077 floor_level = pParty->uFallStartY; | |
2534 | 3078 //************************************* |
3079 //падение на 3D Model | |
3080 if ( floor_level - party_new_Z > 512 && !bFeatherFall && party_new_Z <= v111 + 1 ) | |
2496 | 3081 { |
3082 if (pParty->uFlags & PARTY_FLAGS_1_LANDING) | |
3083 pParty->uFlags &= ~PARTY_FLAGS_1_LANDING; | |
3084 else for (int i = 0; i < 4; ++i) // receive falling damage | |
3085 { | |
3086 if ( !pParty->pPlayers[i].HasEnchantedItemEquipped(72) && !pParty->pPlayers[i].WearsItem(ITEM_ARTIFACT_HERMES_SANDALS, EQUIP_BOOTS) ) | |
3087 { | |
3088 pParty->pPlayers[i].ReceiveDamage( | |
2534 | 3089 (signed int)((pParty->uFallStartY - party_new_Z) * (unsigned __int64)(pParty->pPlayers[i].GetMaxHealth() / 10)) / 256, DMGT_PHISYCAL); |
2496 | 3090 bonus = 20 - pParty->pPlayers[i].GetParameterBonus(pParty->pPlayers[i].GetActualEndurance()); |
3091 pParty->pPlayers[i].SetRecoveryTime((signed __int64)((double)bonus * flt_6BE3A4_debug_recmod1 * 2.133333333333333)); | |
3092 } | |
3093 } | |
3094 } | |
2534 | 3095 //********************************* |
3096 //определение высоты потолка | |
2496 | 3097 ceiling_height = -1; |
2534 | 3098 if ( pParty->bFlying ) //в полёте |
3099 ceiling_height = GetCeilingHeight(pX, pY, party_new_Z + pParty->uPartyHeight, (int)&v102);//высота потолка | |
2496 | 3100 //v107 = bmodel_standing_on_pid == 0; |
2534 | 3101 on_ground = v111 + 1; //на земле |
3102 //************************************** | |
3103 | |
3104 if ( party_new_Z <= on_ground )//полёт: посадка | |
2496 | 3105 { |
3106 ceiling_height = -1; | |
3107 pParty->bFlying = false; | |
3108 } | |
3109 else | |
3110 hovering = true; | |
2534 | 3111 not_high_fall = party_new_Z - v111 <= 32; |
3112 //**************************************** | |
3113 //timer update(обновить таймер звука ходьбы) | |
3114 if ( bWalkSound && pParty->walk_sound_timer) | |
2496 | 3115 { |
3116 if (pParty->walk_sound_timer >= pEventTimer->uTimeElapsed) | |
3117 pParty->walk_sound_timer -= pEventTimer->uTimeElapsed; | |
3118 else | |
3119 pParty->walk_sound_timer = 0; | |
3120 } | |
2534 | 3121 //**************************************** |
3122 // конец действия полёта | |
3123 if (!bUnderwater && pParty->pPartyBuffs[PARTY_BUFF_FLY].uExpireTime <= 0)//не под водой и время закла полёта закончилось | |
2496 | 3124 pParty->bFlying = false; |
2534 | 3125 //***************************************** |
3126 // установить на чём стоит группа | |
3127 if (!hovering)//не в воздухе | |
2496 | 3128 { |
3129 if ( pParty->floor_face_pid != PID(OBJECT_BModel, bmodel_standing_on_pid) ) | |
3130 { | |
3131 if (bmodel_standing_on_pid) | |
3132 { | |
2534 | 3133 int BModel_id = bmodel_standing_on_pid >> 6; |
3134 if ( BModel_id < pOutdoor->uNumBModels ) | |
2496 | 3135 { |
2534 | 3136 face = pOutdoor->pBModels[BModel_id].pFaces; |
3137 int face_id = bmodel_standing_on_pid & 0x3F; | |
2496 | 3138 /*if ( *(char *)(v7->pFacePlane.vNormal.x + 308 * v6 + 31) & 4 ) |
3139 { | |
3140 pParty->field_6F4_packedid = PID(OBJECT_BModel,v108); | |
3141 v103 = *(short *)(v7->pFacePlane.vNormal.x + 308 * v6 + 292); | |
3142 }*/ | |
2534 | 3143 if ( face[face_id].uAttributes & FACE_PRESSURE_PLATE ) |
2496 | 3144 { |
3145 pParty->floor_face_pid = PID(OBJECT_BModel, bmodel_standing_on_pid); | |
2534 | 3146 trigger_id = face[face_id].sCogTriggeredID; //EVT, панель имеет событие |
2496 | 3147 } |
3148 } | |
3149 } | |
3150 } | |
2534 | 3151 pParty->floor_face_pid = PID(OBJECT_BModel, bmodel_standing_on_pid);//6 - на земле |
2496 | 3152 } |
2534 | 3153 //*********************************************** |
2496 | 3154 _walk_speed = pParty->uWalkSpeed; |
3155 _angle_y = pParty->sRotationY; | |
3156 _angle_x = pParty->sRotationX; | |
3157 //v126 = pEventTimer->dt_in_some_format; | |
3158 /*v119 = (Player **)((unsigned __int64)(pEventTimer->dt_in_some_format | |
3159 * (signed __int64)((signed int)(pParty->field_20_prolly_turn_speed | |
3160 * stru_5C6E00->uIntegerPi) | |
3161 / 180)) >> 16);*/ | |
3162 __int64 dturn = (unsigned __int64)(pEventTimer->dt_in_some_format * (signed __int64)((signed int)(pParty->y_rotation_speed * stru_5C6E00->uIntegerPi) / 180)) >> 16; | |
3163 while (pPartyActionQueue->uNumActions) | |
3164 { | |
3165 switch (pPartyActionQueue->Next()) | |
3166 { | |
3167 case PARTY_FlyUp://полёт вверх | |
3168 { | |
3169 if (!pParty->FlyActive() && !bUnderwater) | |
3170 break; | |
3171 | |
3172 pParty->bFlying = false; | |
3173 if (bUnderwater || | |
3174 pParty->pPartyBuffs[PARTY_BUFF_FLY].uFlags & 1 || | |
3175 pParty->pPlayers[pParty->pPartyBuffs[PARTY_BUFF_FLY].uCaster - 1].sMana > 0 ) | |
3176 { | |
3177 extern int max_flight_height; | |
3178 if ( pParty->vPosition.z < max_flight_height || hovering ) | |
3179 { | |
2534 | 3180 party_new_Z += 30; |
2496 | 3181 v113 += 30; |
3182 pParty->bFlying = true; | |
2534 | 3183 if ( party_new_Z > max_flight_height ) |
2496 | 3184 { |
2534 | 3185 party_new_Z = max_flight_height; |
2496 | 3186 v113 = max_flight_height; |
3187 } | |
3188 v1 = 0; | |
3189 v2 = 0; | |
3190 fall_speed = 0; | |
3191 *(float *)&v128 = 0.0; | |
2534 | 3192 if ( v102 && party_new_Z < ceiling_height && (signed int)(pParty->uPartyHeight + party_new_Z) >= ceiling_height )//столкновение с потолком |
2496 | 3193 { |
3194 pParty->field_6E0 = 0; | |
3195 pParty->field_6E4 = 0; | |
3196 pPartyActionQueue->uNumActions = 0; | |
3197 pParty->uFlags |= PARTY_FLAGS_1_LANDING; | |
3198 pParty->vPosition.z = ceiling_height - pParty->uPartyHeight - 31; | |
2534 | 3199 pParty->field_6F0 = party_new_Z; |
2496 | 3200 pParty->bFlying = false; |
2534 | 3201 party_new_Z = ceiling_height - pParty->uPartyHeight - 31; |
2496 | 3202 v113 = pParty->field_6F0; |
3203 } | |
3204 pParty->uFallSpeed = 0; | |
3205 pModel_ = true; | |
3206 } | |
3207 } | |
3208 } | |
3209 break; | |
3210 | |
3211 case PARTY_FlyDown://полёт вниз | |
3212 if (pParty->FlyActive() || bUnderwater) | |
3213 { | |
3214 pParty->bFlying = false; | |
3215 if ( bUnderwater | |
3216 || pParty->pPartyBuffs[PARTY_BUFF_FLY].uFlags & 1 | |
3217 || pParty->pPlayers[pParty->pPartyBuffs[PARTY_BUFF_FLY].uCaster - 1].sMana > 0 )//*(int *)&pParty->pArtifactsFound[6972 * pParty->pPartyBuffs[PARTY_BUFF_FLY].uCaster + 10] > 0 ) | |
3218 { | |
2534 | 3219 party_new_Z -= 30; |
2496 | 3220 v113 -= 30; |
3221 pParty->uFallSpeed = 0; | |
3222 fall_speed = 0; | |
3223 pParty->bFlying = true; | |
3224 pModel_ = true; | |
2534 | 3225 if ( party_new_Z <= v111 ) |
2496 | 3226 { |
3227 pParty->bFlying = false; | |
3228 pPartyActionQueue->uNumActions = 0; | |
3229 } | |
3230 } | |
3231 } | |
3232 break; | |
3233 | |
2534 | 3234 case PARTY_TurnLeft://поворот влево |
2496 | 3235 if (uTurnSpeed) |
3236 _angle_y += uTurnSpeed; //descrete turn | |
3237 else | |
3238 _angle_y += dturn * fTurnSpeedMultiplier; // time-based smooth turn | |
3239 | |
3240 _angle_y &= stru_5C6E00->uDoublePiMask; | |
3241 break; | |
3242 | |
2534 | 3243 case PARTY_TurnRight://поворот вправо |
2496 | 3244 if (uTurnSpeed) |
3245 _angle_y -= uTurnSpeed; | |
3246 else | |
3247 _angle_y -= dturn * fTurnSpeedMultiplier; | |
3248 | |
3249 _angle_y &= stru_5C6E00->uDoublePiMask; | |
3250 break; | |
3251 | |
2534 | 3252 case PARTY_FastTurnLeft://быстрый поворот влево |
2496 | 3253 if (uTurnSpeed) |
3254 _angle_y += uTurnSpeed; | |
3255 else | |
3256 _angle_y += 2.0f * fTurnSpeedMultiplier * (double)dturn; | |
3257 | |
3258 _angle_y &= stru_5C6E00->uDoublePiMask; | |
3259 break; | |
3260 | |
2534 | 3261 case PARTY_FastTurnRight://быстрый поворот вправо |
2496 | 3262 if (!uTurnSpeed) |
3263 _angle_y -= 2.0f * fTurnSpeedMultiplier * (double)dturn; | |
3264 else | |
3265 _angle_y -= uTurnSpeed; | |
3266 | |
3267 _angle_y &= stru_5C6E00->uDoublePiMask; | |
3268 break; | |
3269 | |
3270 case PARTY_StrafeLeft://хождение боком в влево | |
3271 { | |
3272 *(float *)&v128 = pParty->uWalkSpeed; | |
3273 | |
2534 | 3274 float sin_y = sinf(2 * pi_double * _angle_y / 2048.0); |
2496 | 3275 int dx = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; |
3276 v2 -= 3 * dx / 4; | |
3277 | |
2534 | 3278 float cos_y = cosf(2 * pi_double * _angle_y / 2048.0); |
2496 | 3279 int dy = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; |
3280 v1 += 3 * dy / 4; | |
3281 | |
3282 v128 = v1; | |
3283 party_walking_flag = true; | |
3284 } | |
3285 break; | |
3286 | |
3287 case PARTY_StrafeRight://хождение боком в вправо | |
3288 { | |
3289 *(float *)&v128 = pParty->uWalkSpeed; | |
3290 | |
2534 | 3291 float sin_y = sinf(2 * pi_double * _angle_y / 2048.0); |
2496 | 3292 int dx = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; |
3293 v2 += 3 * dx / 4; | |
3294 | |
2534 | 3295 float cos_y = cosf(2 * pi_double * _angle_y / 2048.0); |
2496 | 3296 int dy = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; |
3297 v1 -= 3 * dy / 4; | |
3298 | |
3299 v128 = v1; | |
3300 party_walking_flag = true; | |
3301 } | |
3302 break; | |
3303 | |
3304 case PARTY_WalkForward:// идти вперёд | |
3305 { | |
3306 *(float *)&v128 = _walk_speed; | |
3307 | |
2534 | 3308 float sin_y = sinf(2 * pi_double * _angle_y / 2048.0), |
3309 cos_y = cosf(2 * pi_double * _angle_y / 2048.0); | |
2496 | 3310 |
3311 int dx = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; | |
3312 int dy = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; | |
3313 | |
3314 if ( new_speed ) | |
3315 { | |
3316 v2 += dx * 12; | |
3317 v1 += dy * 12; | |
3318 } | |
3319 else | |
3320 { | |
3321 v2 += dx; | |
3322 v1 += dy; | |
3323 } | |
3324 | |
3325 v128 = v1; | |
3326 party_walking_flag = true; | |
3327 } | |
3328 break; | |
3329 | |
3330 case PARTY_RunForward://бежать вперёд | |
3331 { | |
3332 *(float *)&v128 = _walk_speed; | |
3333 | |
2534 | 3334 float sin_y = sinf(2 * pi_double * _angle_y / 2048.0); |
3335 float cos_y = cosf(2 * pi_double * _angle_y / 2048.0); | |
2496 | 3336 |
3337 int dx = cos_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; | |
3338 int dy = sin_y * pParty->uWalkSpeed * fWalkSpeedMultiplier; | |
3339 | |
3340 if (pParty->bFlying)//лететь вперёд | |
3341 { | |
3342 v2 += 4 * dx; | |
3343 v1 += 4 * dy; | |
3344 | |
3345 v128 = v1; | |
3346 } | |
3347 else if (partyAtHighSlope && !bmodel_standing_on_pid)//сбегание со склона | |
3348 { | |
3349 v2 += dx; | |
3350 v1 += dy; | |
3351 | |
3352 v128 = v1; | |
3353 party_walking_flag = true; | |
3354 } | |
3355 else | |
3356 { | |
3357 /*v2 += (unsigned __int64)(stru_5C6E00->Cos(_angle_y) | |
3358 * (signed __int64)(signed int)(2 * (unsigned __int64)(signed __int64)((double)_walk_speed * fWalkSpeedMultiplier))) >> 16; | |
3359 v1 += (unsigned __int64)((signed int)stru_5C6E00->Sin(_angle_y) | |
3360 * (signed __int64)(signed int)(2 * (unsigned __int64)(signed __int64)((double)_walk_speed * fWalkSpeedMultiplier))) >> 16;*/ | |
3361 | |
3362 v2 += 2 * dx; | |
3363 v1 += 2 * dy; | |
3364 | |
3365 v128 = v1; | |
3366 party_running_flag = true; | |
3367 } | |
3368 } | |
3369 break; | |
3370 | |
3371 | |
3372 case PARTY_WalkBackward://идти назад | |
3373 { | |
3374 *(float *)&v128 = _walk_speed; | |
3375 | |
3376 float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0), | |
3377 cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0); | |
3378 | |
3379 int dx = cos_y * pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier; | |
3380 v2 -= dx; | |
3381 | |
3382 int dy = sin_y * pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier; | |
3383 v1 -= dy; | |
3384 | |
3385 v128 = v1; | |
3386 party_walking_flag = true; | |
3387 } | |
3388 break; | |
3389 | |
3390 | |
3391 case PARTY_RunBackward://бежать назад | |
3392 { | |
3393 float sin_y = sinf(2 * 3.141592653589 * _angle_y / 2048.0), | |
3394 cos_y = cosf(2 * 3.141592653589 * _angle_y / 2048.0); | |
3395 | |
3396 int dx = cos_y * pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier; | |
3397 int dy = sin_y * pParty->uWalkSpeed * fBackwardWalkSpeedMultiplier; | |
3398 | |
3399 if (pParty->bFlying) | |
3400 { | |
3401 v2 -= 4 * dx; | |
3402 v1 -= 4 * dy; | |
3403 v128 = v1; | |
3404 } | |
3405 else | |
3406 { | |
3407 v2 -= dx; | |
3408 v1 -= dy; | |
3409 | |
3410 v128 = v1; | |
3411 party_walking_flag = true; | |
3412 } | |
3413 } | |
3414 break; | |
3415 | |
3416 case PARTY_CenterView://смотреть прямо | |
3417 _angle_x = 0; | |
3418 break; | |
3419 | |
3420 case PARTY_LookUp://смотреть вверх | |
3421 _angle_x += (signed __int64)(flt_6BE150_look_up_down_dangle * 25.0); | |
3422 if ( _angle_x > 128 ) | |
3423 _angle_x = 128; | |
3424 if (uActiveCharacter) | |
3425 pPlayers[uActiveCharacter]->PlaySound(SPEECH_63, 0); | |
3426 break; | |
3427 | |
3428 case PARTY_LookDown://смотреть вниз | |
3429 _angle_x += (signed __int64)(flt_6BE150_look_up_down_dangle * -25.0); | |
3430 if ( _angle_x < -128 ) | |
3431 _angle_x = -128; | |
3432 if (uActiveCharacter) | |
3433 pPlayers[uActiveCharacter]->PlaySound(SPEECH_64, 0); | |
3434 break; | |
3435 | |
3436 case PARTY_Jump://прыжок | |
3437 if ( (!partyAtHighSlope || bmodel_standing_on_pid) && !hovering && pParty->field_24 && !(pParty->uFlags & 4) && !(pParty->uFlags & 0x200) ) | |
3438 { | |
3439 //v126 = pParty->field_24 << 6; | |
3440 hovering = true; | |
3441 fall_speed = (signed __int64)((double)(pParty->field_24 << 6) * 1.5 + (double)fall_speed); | |
3442 } | |
3443 break; | |
3444 | |
3445 case PARTY_Land://приземление(клавиша Home) | |
3446 if (pParty->bFlying) | |
3447 { | |
3448 pParty->uFlags |= PARTY_FLAGS_1_LANDING; | |
3449 pParty->uFallSpeed = 0; | |
3450 } | |
3451 pParty->bFlying = false; | |
3452 pPartyActionQueue->uNumActions = 0; | |
3453 break; | |
3454 | |
3455 default: | |
3456 assert(false); | |
3457 | |
3458 | |
3459 } | |
3460 } | |
3461 | |
3462 pParty->sRotationY = _angle_y; | |
3463 pParty->sRotationX = _angle_x; | |
3464 //------------------------------------------- | |
3465 if ( pParty->bFlying ) | |
3466 { | |
3467 v129 = fixpoint_mul(4, stru_5C6E00->Cos(GetTickCount())); | |
2534 | 3468 party_new_Z = v113 + v129; |
2496 | 3469 if ( pModel_ ) |
2534 | 3470 party_new_Z = v113; |
2496 | 3471 if (pParty->FlyActive()) |
3472 stru_5E4C90_MapPersistVars._decor_events[20 * pParty->pPartyBuffs[PARTY_BUFF_FLY].uOverlayID + 119] &= 0xFE; | |
2534 | 3473 pParty->uFallStartY = party_new_Z; |
2496 | 3474 } |
2534 | 3475 else if ( party_new_Z < v111 ) |
2496 | 3476 { |
3477 if ( is_on_water && fall_speed ) | |
3478 SpriteObject::sub_42F960_create_object(pX, pY, v111); | |
3479 fall_speed = 0; | |
2534 | 3480 party_new_Z = v111; |
2496 | 3481 pParty->uFallStartY = v111; |
2534 | 3482 v113 = party_new_Z; |
2496 | 3483 if (pParty->FlyActive()) |
3484 stru_5E4C90_MapPersistVars._decor_events[20 * pParty->pPartyBuffs[PARTY_BUFF_FLY].uOverlayID + 119] |= 1; | |
3485 } | |
3486 else | |
3487 { | |
2534 | 3488 v113 = party_new_Z; |
2496 | 3489 if (pParty->FlyActive()) |
3490 stru_5E4C90_MapPersistVars._decor_events[20 * pParty->pPartyBuffs[PARTY_BUFF_FLY].uOverlayID + 119] |= 1; | |
3491 } | |
3492 //------------------------------------------ | |
3493 if (hovering && !pParty->bFlying)//расчёт скорости падения | |
3494 { | |
3495 //v33 = -(pEventTimer->uTimeElapsed * GetGravityStrength()); | |
3496 v34 = fall_speed + (-(pEventTimer->uTimeElapsed * GetGravityStrength()) << 1); | |
3497 fall_speed += (-(pEventTimer->uTimeElapsed * GetGravityStrength()) << 1 ); //y(t) = 2*gt | |
3498 } | |
3499 else if (!partyAtHighSlope) | |
3500 v34 = fall_speed; | |
3501 else if (!hovering) | |
3502 { | |
3503 if ( !bmodel_standing_on_pid ) | |
3504 { | |
3505 // rolling down the hill | |
3506 // how it's done: you get a little bit pushed in the air along terrain normal, getting in the air | |
3507 // and falling to the gravity, gradually sliding downwards. nice trick | |
2534 | 3508 party_new_Z = v111; |
2496 | 3509 ODM_GetTerrainNormalAt(pX, pY, &v98); |
3510 v35 = fall_speed + (8 * -(pEventTimer->uTimeElapsed * GetGravityStrength())); | |
3511 v129 = abs(v2 * v98.x + v1 * v98.y + v35 * v98.z) >> 16; | |
3512 v2 += fixpoint_mul(v129, v98.x); | |
3513 v1 += fixpoint_mul(v129, v98.y); | |
3514 v34 = v35 + fixpoint_mul(v129, v98.z); | |
3515 v128 = v1; | |
3516 fall_speed = v34; | |
3517 } | |
3518 } | |
3519 else | |
3520 v34 = fall_speed; | |
3521 | |
3522 if ( hovering )//блок для крика падения | |
3523 { | |
3524 if ( !bUnderwater && v34 <= 0) | |
3525 { | |
3526 if ( v34 < -500 && !pParty->bFlying && pParty->vPosition.z - v111 > 1000 && !pParty->FeatherFallActive()) | |
3527 { // falling scream | |
3528 for (int i = 0; i < 4; ++i) | |
3529 { | |
3530 if (!pParty->pPlayers[i].HasEnchantedItemEquipped(72) | |
3531 && !pParty->pPlayers[i].WearsItem(ITEM_ARTIFACT_HERMES_SANDALS, EQUIP_BOOTS) | |
3532 && pParty->pPlayers[i].CanAct()) | |
3533 pParty->pPlayers[i].PlaySound(SPEECH_Falling_scream, 0);//крик падения | |
3534 } | |
3535 } | |
3536 } | |
3537 } | |
3538 else | |
2534 | 3539 pParty->uFallStartY = party_new_Z; |
2496 | 3540 |
3541 if ( v2 * v2 + v1 * v1 < 400 && !partyAtHighSlope ) | |
3542 { | |
3543 *(float *)&v128 = 0.0; | |
3544 v2 = 0; | |
3545 } | |
3546 //--(столкновения)------------------------------------------------------------------- | |
3547 stru_721530.field_84 = -1; | |
3548 stru_721530.field_70 = 0; | |
3549 stru_721530.prolly_normal_d = pParty->field_14_radius; | |
3550 stru_721530.field_8_radius = pParty->field_14_radius / 2; | |
3551 stru_721530.field_0 = 1; | |
3552 stru_721530.height = pParty->uPartyHeight - 32; | |
3553 for ( uint i = 0; i < 100; i++ ) | |
3554 { | |
3555 stru_721530.position.x = pX; | |
3556 stru_721530.position.y = pY; | |
2534 | 3557 stru_721530.position.z = stru_721530.height + party_new_Z + 1; |
2496 | 3558 |
3559 stru_721530.normal.x = pX; | |
3560 stru_721530.normal.y = pY; | |
2534 | 3561 stru_721530.normal.z = stru_721530.prolly_normal_d + party_new_Z + 1; |
2496 | 3562 |
3563 stru_721530.velocity.x = v2; | |
3564 stru_721530.velocity.y = v128; | |
3565 stru_721530.velocity.z = fall_speed; | |
3566 | |
3567 stru_721530.uSectorID = 0; | |
3568 v36 = 0; | |
3569 if ( pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_MOVEMENT ) | |
3570 v36 = 13312; | |
3571 if ( stru_721530._47050A(v36) ) | |
3572 break; | |
3573 _46E889_collide_against_bmodels(1); | |
3574 //v37 = WorldPosToGridCellZ(pParty->vPosition.y); | |
3575 //v38 = WorldPosToGridCellX(pParty->vPosition.x); | |
3576 _46E26D_collide_against_sprites(WorldPosToGridCellX(pParty->vPosition.x), WorldPosToGridCellZ(pParty->vPosition.y)); | |
3577 _46ED8A_collide_against_sprite_objects(4); | |
3578 for ( uint actor_id = 0; actor_id < (signed int)uNumActors; ++actor_id ) | |
3579 Actor::_46DF1A_collide_against_actor(actor_id, 0); | |
3580 if ( stru_721530.field_7C >= stru_721530.field_6C ) | |
3581 { | |
3582 _angle_x = stru_721530.normal2.x; | |
3583 _angle_y = stru_721530.normal2.y; | |
3584 v40 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1; | |
3585 } | |
3586 else | |
3587 { | |
3588 _angle_x = pX + fixpoint_mul(stru_721530.field_7C, stru_721530.direction.x); | |
3589 _angle_y = pY + fixpoint_mul(stru_721530.field_7C, stru_721530.direction.y); | |
3590 //pModel = (BSPModel *)fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z); | |
2534 | 3591 v40 = fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z) + party_new_Z; |
2496 | 3592 } |
3593 v122 = v40; | |
3594 ODM_GetFloorLevel(_angle_x, _angle_y, v40, pParty->uPartyHeight, &is_on_water, &bmodel_standing_on_pid, 0); | |
3595 v129 = ODM_GetFloorLevel(_angle_x, pY, v40, pParty->uPartyHeight, &is_on_water, &v97, 0); | |
3596 int v119 = ODM_GetFloorLevel(pX, _angle_y, v40, pParty->uPartyHeight, &is_on_water, &v110, 0); | |
3597 bool v42_ = (BSPModel *)IsTerrainSlopeTooHigh(_angle_x, pY); | |
3598 v42 = IsTerrainSlopeTooHigh(pX, _angle_y); | |
3599 is_not_on_bmodel = false; | |
3600 //v118 = v42; | |
3601 if ( !v97 && !v110 && !bmodel_standing_on_pid ) | |
3602 is_not_on_bmodel = true; | |
3603 v43 = 1; | |
3604 v44 = 1; | |
3605 if ( bUnderwater || !is_not_on_bmodel ) | |
3606 { | |
3607 pX = _angle_x; | |
3608 if ( v43 ) | |
3609 pY = _angle_y; | |
3610 } | |
3611 else | |
3612 { | |
2534 | 3613 if ( v42_ && v129 > party_new_Z ) |
2496 | 3614 v44 = 0; |
2534 | 3615 if ( v42 && v119 > party_new_Z ) |
2496 | 3616 v43 = 0; |
3617 if ( v44 ) | |
3618 { | |
3619 pX = _angle_x; | |
3620 if ( v43 ) | |
3621 pY = _angle_y; | |
3622 } | |
3623 else if ( v43 ) | |
3624 pY = _angle_y; | |
3625 else | |
3626 { | |
3627 int new_ = ODM_GetFloorLevel(_angle_x, _angle_y, v40, pParty->uPartyHeight, &is_on_water, &bmodel_standing_on_pid, 0); | |
2534 | 3628 if ( IsTerrainSlopeTooHigh(_angle_x, _angle_y) && new_ <= party_new_Z ) |
2496 | 3629 { |
3630 v43 = 1; | |
3631 pX = _angle_x; | |
3632 if ( v43 ) | |
3633 pY = _angle_y; | |
3634 } | |
3635 } | |
3636 } | |
3637 if ( stru_721530.field_7C >= stru_721530.field_6C ) | |
3638 { | |
3639 if ( !is_not_on_bmodel ) | |
3640 { | |
3641 pX = stru_721530.normal2.x; | |
3642 pY = stru_721530.normal2.y; | |
3643 } | |
2534 | 3644 party_new_Z = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1; |
2496 | 3645 break; |
3646 } | |
3647 stru_721530.field_70 += stru_721530.field_7C; | |
3648 pX = _angle_x; | |
3649 pY = _angle_y; | |
3650 v45 = stru_721530.uFaceID; | |
2534 | 3651 party_new_Z = v40; |
2496 | 3652 |
3653 if ( PID_TYPE(stru_721530.uFaceID) == OBJECT_Actor) | |
3654 { | |
3655 if (pParty->Invisible()) | |
3656 pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset(); | |
3657 viewparams->bRedrawGameUI = true; | |
3658 } | |
3659 | |
3660 if ( PID_TYPE(stru_721530.uFaceID) == OBJECT_Decoration) | |
3661 { | |
3662 v129 = stru_5C6E00->Atan2(_angle_x - pLevelDecorations[(signed int)stru_721530.uFaceID >> 3].vPosition.x, | |
3663 _angle_y - pLevelDecorations[(signed int)stru_721530.uFaceID >> 3].vPosition.y); | |
3664 v2 = fixpoint_mul(stru_5C6E00->Cos(v129), integer_sqrt(v2 * v2 + v128 * v128)); | |
3665 v122 = fixpoint_mul(stru_5C6E00->Sin(v129), integer_sqrt(v2 * v2 + v128 * v128)); | |
3666 v128 = fixpoint_mul(stru_5C6E00->Sin(v129), integer_sqrt(v2 * v2 + v128 * v128)); | |
3667 } | |
3668 | |
3669 if ( PID_TYPE(stru_721530.uFaceID) == OBJECT_BModel) | |
3670 { | |
3671 pParty->bFlying = false; | |
3672 pModel = &pOutdoor->pBModels[(signed int)stru_721530.uFaceID >> 9]; | |
3673 pODMFace = &pModel->pFaces[((signed int)stru_721530.uFaceID >> 3) & 0x3F]; | |
3674 v48 = pODMFace->pBoundingBox.z2 - pODMFace->pBoundingBox.z1; | |
3675 v129 = v48 <= 32; | |
3676 v119 = pODMFace->pFacePlane.vNormal.z < 46378; | |
3677 if ( bUnderwater == 1 ) | |
3678 v119 = 0; | |
3679 if ( pODMFace->uPolygonType == POLYGON_Floor ) | |
3680 { | |
3681 if ( fall_speed < 0 ) | |
3682 fall_speed = 0; | |
2534 | 3683 party_new_Z = pModel->pVertices.pVertices[pODMFace->pVertexIDs[0]].z + 1; |
2496 | 3684 if ( v2 * v2 + v128 * v128 < 400 ) |
3685 { | |
3686 v2 = 0; | |
3687 *(float *)&v128 = 0.0; | |
3688 } | |
3689 if ( pParty->floor_face_pid != v45 && pODMFace->Pressure_Plate() ) | |
3690 { | |
3691 pParty->floor_face_pid = v45; | |
3692 trigger_id = pODMFace->sCogTriggeredID; | |
3693 } | |
3694 } | |
3695 if ( !v129 && (pODMFace->uPolygonType != POLYGON_InBetweenFloorAndWall || v119) )// упёрся в столб | |
3696 { | |
3697 v118 = abs(v128 * pODMFace->pFacePlane.vNormal.y + fall_speed * pODMFace->pFacePlane.vNormal.z | |
3698 + v2 * pODMFace->pFacePlane.vNormal.x) >> 16; | |
3699 if ((stru_721530.speed >> 3) > v118 ) | |
3700 v118 = stru_721530.speed >> 3; | |
3701 v2 += fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.x); | |
3702 v128 += fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.y); | |
3703 v54 = 0; | |
3704 if ( !v119 ) | |
3705 v54 = fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.z); | |
3706 pParty->uFallSpeed += v54; | |
3707 v55 = stru_721530.prolly_normal_d - ((signed int)(pODMFace->pFacePlane.dist + v122 * pODMFace->pFacePlane.vNormal.z | |
3708 + _angle_y * pODMFace->pFacePlane.vNormal.y + _angle_x * pODMFace->pFacePlane.vNormal.x) >> 16); | |
3709 if ( v55 > 0 ) | |
3710 { | |
3711 pX = _angle_x + fixpoint_mul(pODMFace->pFacePlane.vNormal.x, v55); | |
3712 pY = _angle_y + fixpoint_mul(pODMFace->pFacePlane.vNormal.y, v55); | |
3713 if ( !v119 ) | |
2534 | 3714 party_new_Z = v122 + fixpoint_mul(pODMFace->pFacePlane.vNormal.z, v55); |
2496 | 3715 } |
3716 if ( pParty->floor_face_pid != stru_721530.uFaceID && pODMFace->Pressure_Plate() ) | |
3717 { | |
3718 pParty->floor_face_pid = stru_721530.uFaceID; | |
3719 trigger_id = pODMFace->sCogTriggeredID; // | |
3720 } | |
3721 } | |
3722 if ( pODMFace->uPolygonType == POLYGON_InBetweenFloorAndWall ) | |
3723 { | |
3724 v118 = abs(v128 * pODMFace->pFacePlane.vNormal.y | |
3725 + fall_speed * pODMFace->pFacePlane.vNormal.z + v2 * pODMFace->pFacePlane.vNormal.x) >> 16; | |
3726 if ((stru_721530.speed >> 3) > v118 ) | |
3727 v118 = stru_721530.speed >> 3; | |
3728 v2 += fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.x); | |
3729 v128 += fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.y); | |
3730 fall_speed += fixpoint_mul(v118, pODMFace->pFacePlane.vNormal.z); | |
3731 if ( v2 * v2 + v128 * v128 >= 400 ) | |
3732 { | |
3733 if ( pParty->floor_face_pid != stru_721530.uFaceID && pODMFace->Pressure_Plate() ) | |
3734 { | |
3735 pParty->floor_face_pid = stru_721530.uFaceID; | |
3736 trigger_id = pODMFace->sCogTriggeredID; // | |
3737 } | |
3738 } | |
3739 else | |
3740 { | |
3741 v2 = 0; | |
3742 fall_speed = 0; | |
3743 *(float *)&v128 = 0.0; | |
3744 } | |
3745 } | |
3746 } | |
3747 v2 = fixpoint_mul(58500, v2); | |
3748 v128 = fixpoint_mul(58500, v128); | |
3749 v122 = fixpoint_mul(58500, v122); | |
3750 fall_speed = fixpoint_mul(58500, fall_speed); | |
3751 } | |
3752 | |
3753 //Воспроизведение звуков ходьбы/бега------------------------ | |
3754 uint pX_ = abs(pParty->vPosition.x - pX); | |
3755 uint pY_ = abs(pParty->vPosition.y - pY); | |
2534 | 3756 uint pZ_ = abs(pParty->vPosition.z - party_new_Z); |
2496 | 3757 if ( bWalkSound && pParty->walk_sound_timer <= 0 ) |
3758 { | |
3759 pAudioPlayer->_4AA258(804);//stop sound | |
3760 if ( party_running_flag && (!hovering || not_high_fall) ) | |
3761 { | |
3762 if ( integer_sqrt(pX_ * pX_ + pY_ * pY_ + pZ_ * pZ_) >= 16 ) | |
3763 { | |
3764 if ( !is_not_on_bmodel && pOutdoor->pBModels[pParty->floor_face_pid >> 9].pFaces[(pParty->floor_face_pid >> 3) & 0x3F].Visible() ) | |
2534 | 3765 pAudioPlayer->PlaySound(SOUND_RunWood, 804, 1, -1, 0, 0, 0, 0);//бег на 3D Modelи |
2496 | 3766 else |
3767 { | |
3768 v87 = pOutdoor->GetSoundIdByPosition(WorldPosToGridCellX(pParty->vPosition.x), WorldPosToGridCellZ(pParty->vPosition.y) - 1, 1); | |
3769 pAudioPlayer->PlaySound((SoundID)v87, 804, 1, -1, 0, 0, 0, 0);//бег по земле 56 | |
3770 } | |
3771 pParty->walk_sound_timer = 96;//таймер для бега | |
3772 } | |
3773 } | |
3774 else if( party_walking_flag && (!hovering || not_high_fall) ) | |
3775 { | |
3776 if ( integer_sqrt(pX_ * pX_ + pY_ * pY_ + pZ_ * pZ_) >= 8 ) | |
3777 { | |
3778 if ( !is_not_on_bmodel && pOutdoor->pBModels[pParty->floor_face_pid >> 9].pFaces[(pParty->floor_face_pid >> 3) & 0x3F].Visible() ) | |
2534 | 3779 pAudioPlayer->PlaySound(SOUND_WalkWood, 804, 1, -1, 0, 0, 0, 0);// хождение на 3D Modelи |
2496 | 3780 else |
3781 { | |
3782 v87 = pOutdoor->GetSoundIdByPosition(WorldPosToGridCellX(pParty->vPosition.x), WorldPosToGridCellZ(pParty->vPosition.y) - 1, 0); | |
3783 pAudioPlayer->PlaySound((SoundID)v87, 804, 1, -1, 0, 0, 0, 0);// хождение по земле | |
3784 } | |
3785 pParty->walk_sound_timer = 144;//таймер для ходьбы | |
3786 } | |
3787 } | |
3788 } | |
3789 if ( integer_sqrt(pX_ * pX_ + pY_ * pY_ + pZ_ * pZ_) < 8 )//отключить звук ходьбы при остановке | |
3790 pAudioPlayer->_4AA258(804); | |
3791 //------------------------------------------------------------------------ | |
3792 if ( !hovering || !not_high_fall )// или не высокое падение | |
3793 pParty->uFlags &= ~PARTY_FLAGS_1_FALLING; | |
3794 else | |
3795 pParty->uFlags |= PARTY_FLAGS_1_FALLING; | |
3796 int pMap_X = WorldPosToGridCellX(pParty->vPosition.x); | |
3797 int pMap_Y = WorldPosToGridCellZ(pParty->vPosition.y) - 1; | |
3798 unsigned int v114_a = WorldPosToGridCellX(pX); | |
3799 v66 = WorldPosToGridCellZ(pY) - 1; | |
3800 unsigned int v122_a = (~(unsigned int)pOutdoor->ActuallyGetSomeOtherTileInfo(pMap_X, pMap_Y) / 2) & 1; | |
3801 v122 = (~(unsigned int)pOutdoor->ActuallyGetSomeOtherTileInfo(v114_a, pMap_Y) / 2) & 1; | |
3802 v69 = (~(unsigned int)pOutdoor->ActuallyGetSomeOtherTileInfo(pMap_X, v66) / 2) & 1; | |
3803 | |
3804 //-(обновление координат группы)--------------------------------------- | |
3805 v68 = 0; | |
3806 if ( v114_a == pMap_X && v66 == pMap_Y && v122 && v69 ) | |
3807 v68 = 1; | |
3808 if ( !is_not_on_bmodel ) // на bmodel,и | |
3809 v68 = 1; | |
3810 if ( v68 ) | |
3811 { | |
3812 pParty->vPosition.x = pX; | |
3813 pParty->vPosition.y = pY; | |
2534 | 3814 pParty->vPosition.z = party_new_Z; |
2496 | 3815 pParty->field_6F0 = v113; |
3816 pParty->uFallSpeed = fall_speed; | |
2534 | 3817 if ( party_new_Z > 8160 ) //ограничение высоты |
2496 | 3818 { |
2534 | 3819 party_new_Z = 8160; |
2496 | 3820 pParty->uFallStartY = 8160; |
3821 pParty->vPosition.z = 8160; | |
3822 } | |
3823 | |
3824 if ( !trigger_id //падение на землю | |
3825 || (EventProcessor(trigger_id, 0, 1), | |
3826 pParty->vPosition.x == pX) | |
3827 && pParty->vPosition.y == pY | |
2534 | 3828 && pParty->vPosition.z == party_new_Z ) |
2496 | 3829 { |
3830 if ( pParty->vPosition.z < v111 ) | |
3831 { | |
3832 pParty->uFallSpeed = 0; | |
3833 //v73 = v105; | |
3834 pParty->vPosition.z = on_ground; | |
2534 | 3835 if ( pParty->uFallStartY - party_new_Z > 512 && !bFeatherFall |
3836 && party_new_Z <= on_ground && !bUnderwater )//Fall to the ground(падение на землю с высоты) | |
2496 | 3837 { |
3838 if ( pParty->uFlags & PARTY_FLAGS_1_LANDING ) | |
3839 pParty->uFlags &= ~PARTY_FLAGS_1_LANDING; | |
3840 else | |
3841 { | |
3842 for ( uint i = 1; i <= 4; ++i ) | |
3843 { | |
2534 | 3844 pPlayers[i]->ReceiveDamage((signed int)((pParty->uFallStartY - party_new_Z) * (unsigned __int64)(signed __int64)((double)pPlayers[i]->GetMaxHealth() * 0.1)) / 256, |
2496 | 3845 DMGT_PHISYCAL); |
3846 v110 = 20 - pPlayers[i]->GetParameterBonus(pPlayers[i]->GetActualEndurance()); | |
3847 pPlayers[i]->SetRecoveryTime((signed __int64)((double)v110 * flt_6BE3A4_debug_recmod1 * 2.133333333333333)); | |
3848 } | |
3849 //v73 = pParty->vPosition.z; | |
3850 } | |
3851 } | |
2534 | 3852 pParty->uFallStartY = party_new_Z; |
2496 | 3853 } |
3854 if ( v102 && pParty->vPosition.z < ceiling_height ) | |
3855 { | |
3856 if ( (signed int)(pParty->uPartyHeight + pParty->vPosition.z) >= ceiling_height ) | |
3857 { | |
3858 pParty->vPosition.z = ceiling_height - pParty->uPartyHeight - 1; | |
3859 pParty->field_6F0 = ceiling_height - pParty->uPartyHeight - 1; | |
3860 } | |
3861 } | |
3862 pParty->uFlags &= ~0x204; | |
3863 } | |
3864 return; | |
3865 } | |
3866 //----------------------------------------------------------------- | |
3867 //v76 = pParty->bFlying; | |
3868 if ( pParty->bFlying || !not_high_fall || bWaterWalk || !v122_a )// полёт или высокое падение или хождение по воде или | |
3869 v77 = 1; | |
3870 else | |
3871 v77 = v122 != 0; | |
3872 bool party_drowning_flag = false; | |
3873 if ( !pParty->bFlying && not_high_fall && !bWaterWalk ) //не полёт и не высокое падение и не хождение по воде | |
3874 { | |
3875 if ( v122_a ) | |
3876 v78 = v69 != 0; | |
3877 else | |
3878 { | |
3879 party_drowning_flag = true;//утопление | |
3880 v78 = true; | |
3881 } | |
3882 } | |
3883 else | |
3884 v78 = true; | |
3885 | |
3886 if ( v77 ) | |
3887 pParty->vPosition.x = pX; | |
3888 if ( v78 ) | |
3889 pParty->vPosition.y = pY; | |
3890 | |
3891 if ( v78 || v77) | |
3892 { | |
3893 if ( bWaterWalk ) | |
3894 { | |
3895 pParty->uFlags &= ~PARTY_FLAGS_1_STANDING_ON_WATER; | |
3896 //v79 = 20 * pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uOverlayID + 6180178; | |
3897 //*(short *)&stru_5E4C90._decor_events[20 * pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uOverlayID + 119] |= 1u; | |
3898 v79 = (int)&stru_5E4C90_MapPersistVars._decor_events[20 * pParty->pPartyBuffs[PARTY_BUFF_WATER_WALK].uOverlayID + 119]; | |
3899 *(short *)v79 |= 1; | |
3900 if ( !v122 || !v69 ) | |
3901 { | |
3902 if ( !pParty->bFlying ) | |
3903 { | |
3904 v80 = *(short *)v79; | |
3905 pParty->uFlags |= PARTY_FLAGS_1_STANDING_ON_WATER; | |
3906 *(short *)v79 = v80 & 0xFFFE; | |
3907 } | |
3908 } | |
3909 } | |
3910 } | |
3911 else if ( bWalkSound && pParty->walk_sound_timer <= 0 ) | |
3912 { | |
3913 pAudioPlayer->_4AA258(804); | |
3914 pParty->walk_sound_timer = 64; | |
3915 } | |
3916 | |
3917 //v81 = pZ; | |
3918 //v82 = pZ; | |
2534 | 3919 pParty->vPosition.z = party_new_Z; |
3920 if ( party_new_Z > 8160 )//опять ограничение высоты | |
2496 | 3921 { |
3922 //v82 = 8160; | |
3923 pParty->uFallStartY = 8160; | |
3924 pParty->vPosition.z = 8160; | |
3925 } | |
3926 LOWORD(pParty->uFlags) &= 0xFDFBu; | |
3927 pParty->uFallSpeed = fall_speed; | |
3928 pParty->field_6F0 = v113; | |
3929 if ( party_drowning_flag )//группа тонет | |
3930 { | |
3931 pTerrainHeight = GetTerrainHeightsAroundParty2(pParty->vPosition.x, pParty->vPosition.y, &v110, 1); | |
3932 if ( pParty->vPosition.z <= pTerrainHeight + 1 )//положение группы всегда +1 | |
3933 pParty->uFlags |= PARTY_FLAGS_1_WATER_DAMAGE; | |
3934 } | |
3935 | |
3936 if ( !trigger_id//падение на воду | |
3937 || (EventProcessor(trigger_id, 0, 1), | |
3938 pParty->vPosition.x == pX) | |
3939 && pParty->vPosition.y == pY | |
2534 | 3940 && pParty->vPosition.z == party_new_Z ) |
2496 | 3941 { |
3942 if ( pParty->vPosition.z < v111 ) | |
3943 { | |
3944 //v82 = on_ground; | |
3945 pParty->uFallSpeed = 0; | |
3946 pParty->vPosition.z = on_ground; | |
2534 | 3947 if ( pParty->uFallStartY - party_new_Z > 512 |
3948 && !bFeatherFall && party_new_Z <= on_ground && !bUnderwater )//Fall to the water(падение на воду с высоты) | |
2496 | 3949 { |
3950 if ( pParty->uFlags & PARTY_FLAGS_1_LANDING ) | |
3951 pParty->uFlags &= ~PARTY_FLAGS_1_LANDING; | |
3952 else | |
3953 { | |
3954 for ( uint i = 1; i <= 4; ++i ) | |
3955 { | |
3956 v110 = pPlayers[i]->GetMaxHealth(); | |
2534 | 3957 pPlayers[i]->ReceiveDamage((signed int)((pParty->uFallStartY - party_new_Z) * (unsigned __int64)(signed __int64)((double)v110 * 0.1)) / 256, |
2496 | 3958 DMGT_PHISYCAL); |
3959 v110 = 20 - pPlayers[i]->GetParameterBonus(pPlayers[i]->GetActualEndurance()); | |
3960 pPlayers[i]->SetRecoveryTime((signed __int64)((double)v110 * flt_6BE3A4_debug_recmod1 * 2.133333333333333)); | |
3961 } | |
3962 //v82 = pParty->vPosition.z; | |
3963 } | |
3964 } | |
2534 | 3965 pParty->uFallStartY = party_new_Z; |
2496 | 3966 } |
3967 if ( v102 && pParty->vPosition.z < ceiling_height && (signed int)(pParty->uPartyHeight + pParty->vPosition.z) >= ceiling_height ) | |
3968 { | |
3969 pParty->vPosition.z = pParty->vPosition.z + pParty->uPartyHeight - ceiling_height + 1; | |
3970 pParty->field_6F0 = pParty->vPosition.z + pParty->uPartyHeight - ceiling_height + 1; | |
3971 } | |
3972 } | |
3973 } | |
3974 | |
3975 //----- (0046D8E3) -------------------------------------------------------- | |
3976 int GetCeilingHeight(int Party_X, signed int Party_Y, int Party_ZHeight, int pFaceID) | |
3977 { | |
3978 signed int v13; // eax@25 | |
3979 int v14; // edx@27 | |
3980 int v16; // ST18_4@29 | |
3981 signed int v17; // edx@29 | |
3982 signed __int64 v18; // qtt@29 | |
3983 int v19; // eax@35 | |
3984 signed int v20; // ecx@37 | |
3985 signed int v22; // ebx@42 | |
3986 // int v24; // edx@44 | |
3987 // int v25; // eax@44 | |
3988 int v27; // [sp+10h] [bp-34h]@21 | |
3989 bool v34; // [sp+30h] [bp-14h]@21 | |
3990 bool v35; // [sp+34h] [bp-10h]@23 | |
3991 signed int v37; // [sp+38h] [bp-Ch]@21 | |
3992 signed int v38; // [sp+38h] [bp-Ch]@42 | |
3993 signed int v39; // [sp+3Ch] [bp-8h]@1 | |
3994 | |
3995 dword_720ED0[0] = -1; | |
3996 dword_720E80[0] = -1; | |
3997 v39 = 1; | |
3998 ceiling_height_level[0] = 10000;//нет потолка | |
3999 for ( uint i = 0; i < (signed int)pOutdoor->uNumBModels; ++i ) | |
4000 { | |
4001 if ( Party_X <= pOutdoor->pBModels[i].sMaxX && Party_X >= pOutdoor->pBModels[i].sMinX | |
4002 && Party_Y <= pOutdoor->pBModels[i].sMaxY && Party_Y >= pOutdoor->pBModels[i].sMinY ) | |
4003 { | |
4004 for ( uint j = 0; j < pOutdoor->pBModels[i].uNumFaces; ++j ) | |
4005 { | |
4006 if ( (pOutdoor->pBModels[i].pFaces[j].uPolygonType == POLYGON_Ceiling | |
4007 || pOutdoor->pBModels[i].pFaces[j].uPolygonType == POLYGON_InBetweenCeilingAndWall) | |
4008 && !pOutdoor->pBModels[i].pFaces[j].Ethereal() | |
4009 && Party_X <= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x2 && Party_X >= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.x1 | |
4010 && Party_Y <= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y2 && Party_Y >= pOutdoor->pBModels[i].pFaces[j].pBoundingBox.y1 ) | |
4011 { | |
4012 for ( uint v = 0; v < pOutdoor->pBModels[i].pFaces[j].uNumVertices; v++ ) | |
4013 { | |
4014 word_720DB0_xs[2 * v] = pOutdoor->pBModels[i].pFaces[j].pXInterceptDisplacements[v] + LOWORD(pOutdoor->pBModels[i].pVertices.pVertices[pOutdoor->pBModels[i].pFaces[j].pVertexIDs[v]].x); | |
4015 word_720CE0_ys[2 * v] = pOutdoor->pBModels[i].pFaces[j].pXInterceptDisplacements[v] + LOWORD(pOutdoor->pBModels[i].pVertices.pVertices[pOutdoor->pBModels[i].pFaces[j].pVertexIDs[v]].y); | |
4016 word_720DB0_xs[2 * v + 1] = pOutdoor->pBModels[i].pFaces[j].pXInterceptDisplacements[v] + LOWORD(pOutdoor->pBModels[i].pVertices.pVertices[pOutdoor->pBModels[i].pFaces[j].pVertexIDs[v + 1]].x); | |
4017 word_720CE0_ys[2 * v + 1] = pOutdoor->pBModels[i].pFaces[j].pXInterceptDisplacements[v] + LOWORD(pOutdoor->pBModels[i].pVertices.pVertices[pOutdoor->pBModels[i].pFaces[j].pVertexIDs[v + 1]].y); | |
4018 } | |
4019 v27 = 2 * pOutdoor->pBModels[i].pFaces[j].uNumVertices; | |
4020 word_720DB0_xs[2 * pOutdoor->pBModels[i].pFaces[j].uNumVertices] = word_720DB0_xs[0]; | |
4021 word_720CE0_ys[2 * pOutdoor->pBModels[i].pFaces[j].uNumVertices] = word_720CE0_ys[0]; | |
4022 v34 = word_720CE0_ys[0] >= Party_Y; | |
4023 v37 = 0; | |
4024 for ( uint v = 0; v < v27; ++v ) | |
4025 { | |
4026 if ( v37 >= 2 ) | |
4027 break; | |
4028 v35 = word_720CE0_ys[v + 1] >= Party_Y; | |
4029 if ( v34 != v35 ) | |
4030 { | |
4031 v13 = word_720DB0_xs[v + 1] >= Party_X ? 0 : 2; | |
4032 v14 = v13 | (word_720DB0_xs[v] < Party_X); | |
4033 if ( v14 != 3 ) | |
4034 { | |
4035 if ( !v14 || ( v16 = word_720CE0_ys[v + 1] - word_720CE0_ys[v], | |
4036 v17 = Party_Y - word_720CE0_ys[v], | |
4037 LODWORD(v18) = v17 << 16, | |
4038 HIDWORD(v18) = v17 >> 16, | |
4039 (signed int)(((unsigned __int64)(((signed int)word_720DB0_xs[v + 1] | |
4040 - (signed int)word_720DB0_xs[v]) * v18 / v16) >> 16) + word_720DB0_xs[v]) >= Party_X) ) | |
4041 ++v37; | |
4042 } | |
4043 } | |
4044 v34 = v35; | |
4045 } | |
4046 if ( v37 == 1 ) | |
4047 { | |
4048 if ( v39 >= 20 ) | |
4049 break; | |
4050 if ( pOutdoor->pBModels[i].pFaces[j].uPolygonType == POLYGON_Ceiling ) | |
4051 v19 = pOutdoor->pBModels[i].pVertices.pVertices[pOutdoor->pBModels[i].pFaces[j].pVertexIDs[0]].z; | |
4052 else | |
4053 v19 = fixpoint_mul(pOutdoor->pBModels[i].pFaces[j].zCalc1, Party_X) + fixpoint_mul(pOutdoor->pBModels[i].pFaces[j].zCalc2, Party_Y) | |
4054 + HIWORD(pOutdoor->pBModels[i].pFaces[j].zCalc3); | |
4055 v20 = v39++; | |
4056 ceiling_height_level[v20] = v19; | |
4057 dword_720ED0[v20] = i; | |
4058 dword_720E80[v20] = j; | |
4059 } | |
4060 } | |
4061 } | |
4062 } | |
4063 } | |
4064 if ( !v39 ) | |
4065 { | |
4066 pFaceID = 0; | |
4067 return ceiling_height_level[0]; | |
4068 } | |
4069 v22 = 0; | |
4070 for ( v38 = 0; v38 < v39; ++v38 ) | |
4071 { | |
4072 if ( ceiling_height_level[v38] == ceiling_height_level[0] ) | |
4073 v22 = v38; | |
4074 else if ( ceiling_height_level[v38] < ceiling_height_level[0] && ceiling_height_level[0] > Party_ZHeight + 15 ) | |
4075 v22 = v38; | |
4076 else if ( ceiling_height_level[v38] > ceiling_height_level[0] && ceiling_height_level[v38] <= Party_ZHeight + 15 ) | |
4077 v22 = v38; | |
4078 } | |
4079 if ( v22 ) | |
4080 { | |
4081 *(int *)pFaceID = dword_720E80[v22] | (dword_720ED0[v22] << 6); | |
4082 return ceiling_height_level[v22];//если есть преграда | |
4083 } | |
4084 pFaceID = 0; | |
4085 return ceiling_height_level[v22];// нет никакой преграды | |
4086 } | |
4087 | |
4088 | |
4089 //----- (00464839) -------------------------------------------------------- | |
4090 char Is_out15odm_underwater() | |
4091 { | |
4092 return _stricmp(pCurrentMapName, "out15.odm") == 0; | |
4093 } | |
4094 | |
4095 //----- (00464851) -------------------------------------------------------- | |
4096 void SetUnderwaterFog() | |
4097 { | |
4098 day_fogrange_1 = 50; | |
4099 day_fogrange_2 = 5000; | |
4100 } | |
4101 | |
4102 //----- (00487DA9) -------------------------------------------------------- | |
4103 void sub_487DA9() | |
4104 { | |
4105 for (int i = 0; i < 20000; ++i) | |
4106 array_77EC08[i].field_108 = 0; | |
4107 } | |
4108 | |
4109 //----- (004706C6) -------------------------------------------------------- | |
4110 void UpdateActors_ODM() | |
4111 { | |
4112 int v3; // ebx@6 | |
4113 int v5; // eax@10 | |
4114 //int v6; // ecx@10 | |
4115 signed int v8; // ebx@17 | |
4116 // unsigned __int8 v10; // sf@17 | |
4117 // unsigned __int16 v11; // ax@21 | |
4118 __int16 v20; // ax@42 | |
4119 int v25; // eax@45 | |
4120 signed int v26; // ecx@50 | |
4121 int v28; // eax@54 | |
4122 signed int v29; // ebx@57 | |
4123 signed int v30; // eax@57 | |
4124 int v31; // edi@57 | |
4125 signed int i; // ebx@57 | |
4126 unsigned int v33; // ecx@58 | |
4127 int v35; // edi@64 | |
4128 int v36; // eax@64 | |
4129 unsigned int v39; // edi@71 | |
4130 ODMFace *face; // edi@75 | |
4131 int v46; // ecx@82 | |
4132 signed int v47; // ebx@85 | |
4133 int v48; // edi@85 | |
4134 // int v55; // eax@107 | |
4135 // unsigned int v56; // edi@107 | |
4136 // int v57; // ST10_4@107 | |
4137 unsigned int v58; // edi@107 | |
4138 unsigned int v59; // ebx@107 | |
4139 // signed int v60; // eax@107 | |
4140 int v61; // eax@124 | |
4141 Vec3_int_ v62; // [sp+Ch] [bp-44h]@42 | |
4142 int v63; // [sp+18h] [bp-38h]@64 | |
4143 int v64; // [sp+1Ch] [bp-34h]@64 | |
4144 bool v67; // [sp+28h] [bp-28h]@10 | |
4145 unsigned int v69; // [sp+30h] [bp-20h]@6 | |
4146 unsigned int v70; // [sp+34h] [bp-1Ch]@10 | |
4147 int v71; // [sp+38h] [bp-18h]@62 | |
4148 int uIsAboveFloor; // [sp+3Ch] [bp-14h]@10 | |
4149 int v72b; | |
4150 int uIsFlying; // [sp+44h] [bp-Ch]@8 | |
4151 unsigned int v75; // [sp+48h] [bp-8h]@1 | |
4152 int uIsOnWater; // [sp+4Ch] [bp-4h]@10 | |
4153 | |
2562
b8a56afc6ba1
new var no_actors, lights_flag, debug_lights, StationaryLights and MobileLights
Ritor1
parents:
2545
diff
changeset
|
4154 if(no_actors) |
b8a56afc6ba1
new var no_actors, lights_flag, debug_lights, StationaryLights and MobileLights
Ritor1
parents:
2545
diff
changeset
|
4155 uNumActors = 0; |
b8a56afc6ba1
new var no_actors, lights_flag, debug_lights, StationaryLights and MobileLights
Ritor1
parents:
2545
diff
changeset
|
4156 |
2496 | 4157 for (v75 = 0; v75 < uNumActors; ++v75) |
4158 { | |
4159 if (pActors[v75].uAIState == Removed | |
4160 || pActors[v75].uAIState == Disabled | |
4161 || pActors[v75].uAIState == Summoned | |
4162 || !pActors[v75].uMovementSpeed) | |
4163 continue; | |
4164 v3 = 0; | |
4165 v69 = 0; | |
4166 if (MonsterStats::BelongsToSupertype(pActors[v75].pMonsterInfo.uID, MONSTER_SUPERTYPE_WATER_ELEMENTAL)) | |
4167 v3 = 1; | |
4168 pActors[v75].uSectorID = 0; | |
4169 uIsFlying = pActors[v75].pMonsterInfo.uFlying; | |
4170 if (!pActors[v75].CanAct()) | |
4171 uIsFlying = 0; | |
4172 v70 = IsTerrainSlopeTooHigh(pActors[v75].vPosition.x, pActors[v75].vPosition.y); | |
4173 v5 = ODM_GetFloorLevel(pActors[v75].vPosition.x, pActors[v75].vPosition.y, pActors[v75].vPosition.z, | |
4174 pActors[v75].uActorHeight, &uIsOnWater, (int *)&v69, v3); | |
4175 //v6 = pActors[v75].vPosition.z; | |
4176 uIsAboveFloor = 0; | |
4177 v67 = v69 == 0; | |
4178 if (pActors[v75].vPosition.z > v5 + 1) | |
4179 uIsAboveFloor = 1; | |
4180 if (pActors[v75].uAIState == Dead && uIsOnWater && !uIsAboveFloor) | |
4181 { | |
4182 pActors[v75].uAIState = Removed; | |
4183 continue; | |
4184 } | |
4185 if (pActors[v75].uCurrentActionAnimation == ANIM_Walking) | |
4186 { | |
4187 v8 = pActors[v75].uMovementSpeed; | |
4188 if ((signed __int64)pActors[v75].pActorBuffs[ACTOR_BUFF_SLOWED].uExpireTime > 0) | |
4189 v8 = (signed __int64)((double)v8 * 0.5); | |
4190 if (pActors[v75].uAIState == Fleeing || pActors[v75].uAIState == Pursuing) | |
4191 v8 *= 2; | |
4192 if (pParty->bTurnBasedModeOn == true && pTurnEngine->turn_stage == TE_WAIT) | |
4193 v8 *= flt_6BE3AC_debug_recmod1_x_1_6; | |
4194 if (v8 > 1000) | |
4195 v8 = 1000; | |
4196 | |
4197 pActors[v75].vVelocity.x = fixpoint_mul(stru_5C6E00->Cos(pActors[v75].uYawAngle), v8); | |
4198 pActors[v75].vVelocity.y = fixpoint_mul(stru_5C6E00->Sin(pActors[v75].uYawAngle), v8); | |
4199 if (uIsFlying) | |
4200 { | |
4201 pActors[v75].vVelocity.z = fixpoint_mul(stru_5C6E00->Sin(pActors[v75].uPitchAngle), v8); | |
4202 } | |
4203 //v7 = v68; | |
4204 } | |
4205 else | |
4206 { | |
4207 pActors[v75].vVelocity.x = fixpoint_mul(55000, pActors[v75].vVelocity.x); | |
4208 pActors[v75].vVelocity.y = fixpoint_mul(55000, pActors[v75].vVelocity.y); | |
4209 if (uIsFlying) | |
4210 pActors[v75].vVelocity.z = fixpoint_mul(55000, pActors[v75].vVelocity.z); | |
4211 } | |
4212 if (pActors[v75].vPosition.z < v5) | |
4213 { | |
4214 pActors[v75].vPosition.z = v5; | |
4215 pActors[v75].vVelocity.z = uIsFlying != 0 ? 0x14 : 0; | |
4216 } | |
4217 //v17 = 0; | |
4218 if (!uIsAboveFloor || uIsFlying) | |
4219 { | |
4220 if (v70 && !uIsAboveFloor && v67) | |
4221 { | |
4222 pActors[v75].vPosition.z = v5; | |
4223 ODM_GetTerrainNormalAt(pActors[v75].vPosition.x, pActors[v75].vPosition.y, &v62); | |
4224 v20 = GetGravityStrength(); | |
4225 //v21 = v62.y; | |
4226 //v22 = v62.z; | |
4227 //v23 = v62.y * v0->vVelocity.y; | |
4228 pActors[v75].vVelocity.z += -8 * LOWORD(pEventTimer->uTimeElapsed) * v20; | |
4229 int v73 = abs(v62.x * pActors[v75].vVelocity.x + v62.z * pActors[v75].vVelocity.z + v62.y * pActors[v75].vVelocity.y) >> 16; | |
4230 //v72b = v21; | |
4231 pActors[v75].vVelocity.x += fixpoint_mul(v73, v62.x); | |
4232 pActors[v75].vVelocity.y += fixpoint_mul(v73, v62.y); | |
4233 pActors[v75].vVelocity.z += fixpoint_mul(v73, v62.z); | |
4234 //v17 = 0; | |
4235 } | |
4236 } | |
4237 else | |
4238 { | |
4239 pActors[v75].vVelocity.z -= LOWORD(pEventTimer->uTimeElapsed) * GetGravityStrength(); | |
4240 } | |
4241 if (pParty->armageddon_timer != 0 && pActors[v75].CanAct()) | |
4242 { | |
4243 pActors[v75].vVelocity.x += rand() % 100 - 50; | |
4244 pActors[v75].vVelocity.y += rand() % 100 - 50; | |
4245 pActors[v75].vVelocity.z += rand() % 100 - 20; | |
4246 v25 = rand(); | |
4247 pActors[v75].uAIState = Stunned; | |
4248 pActors[v75].uYawAngle += v25 % 32 - 16; | |
4249 pActors[v75].UpdateAnimation(); | |
4250 } | |
4251 if (pActors[v75].vVelocity.x * pActors[v75].vVelocity.x + pActors[v75].vVelocity.y * pActors[v75].vVelocity.y < 400 && v70 == 0) | |
4252 { | |
4253 pActors[v75].vVelocity.y = 0; | |
4254 pActors[v75].vVelocity.x = 0; | |
4255 } | |
4256 stru_721530.field_0 = 1; | |
4257 if (!uIsFlying) | |
4258 v26 = 40; | |
4259 else | |
4260 v26 = pActors[v75].uActorRadius; | |
4261 | |
4262 stru_721530.field_84 = -1; | |
4263 stru_721530.field_8_radius = v26; | |
4264 stru_721530.prolly_normal_d = v26; | |
4265 stru_721530.height = pActors[v75].uActorHeight; | |
4266 stru_721530.field_70 = 0; | |
4267 | |
4268 for (v69 = 0; v69 < 100; ++v69) | |
4269 { | |
4270 stru_721530.position.x = pActors[v75].vPosition.x; | |
4271 stru_721530.normal.x = stru_721530.position.x; | |
4272 stru_721530.position.y = pActors[v75].vPosition.y; | |
4273 stru_721530.normal.y = stru_721530.position.y; | |
4274 v28 = pActors[v75].vPosition.z; | |
4275 stru_721530.normal.z = v28 + v26 + 1; | |
4276 stru_721530.position.z = v28 - v26 + stru_721530.height - 1; | |
4277 if (stru_721530.position.z < stru_721530.normal.z) | |
4278 stru_721530.position.z = v28 + v26 + 1; | |
4279 stru_721530.velocity.x = pActors[v75].vVelocity.x; | |
4280 stru_721530.uSectorID = 0; | |
4281 stru_721530.velocity.y = pActors[v75].vVelocity.y; | |
4282 stru_721530.velocity.z = pActors[v75].vVelocity.z; | |
4283 if (stru_721530._47050A(0)) | |
4284 break; | |
4285 _46E889_collide_against_bmodels(1); | |
4286 v29 = WorldPosToGridCellZ(pActors[v75].vPosition.y); | |
4287 v30 = WorldPosToGridCellX(pActors[v75].vPosition.x); | |
4288 _46E26D_collide_against_sprites(v30, v29); | |
4289 _46EF01_collision_chech_player(0); | |
4290 _46ED8A_collide_against_sprite_objects(PID(OBJECT_Actor, v75)); | |
4291 v31 = 0; | |
4292 for (i = 0; v31 < ai_arrays_size; ++v31) | |
4293 { | |
4294 v33 = ai_near_actors_ids[v31]; | |
4295 if (v33 != v75 && Actor::_46DF1A_collide_against_actor(v33, 40)) | |
4296 ++i; | |
4297 } | |
4298 v71 = i > 1; | |
4299 if (stru_721530.field_7C < stru_721530.field_6C) | |
4300 v70 = fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z); | |
4301 //v34 = 0; | |
4302 v35 = stru_721530.normal2.z - stru_721530.prolly_normal_d - 1; | |
4303 v36 = ODM_GetFloorLevel(stru_721530.normal2.x, stru_721530.normal2.y, | |
4304 stru_721530.normal2.z - stru_721530.prolly_normal_d - 1, | |
4305 pActors[v75].uActorHeight, (int *)&v63, &v64, 0); | |
4306 if (uIsOnWater) | |
4307 { | |
4308 if (v35 < v36 + 60) | |
4309 { | |
4310 if (pActors[v75].uAIState == Dead || pActors[v75].uAIState == Dying || pActors[v75].uAIState == Removed | |
4311 || pActors[v75].uAIState == Disabled) | |
4312 { | |
4313 if (v64) | |
4314 v61 = v36 + 30; | |
4315 else | |
4316 v61 = v5 + 60; | |
4317 SpriteObject::sub_42F960_create_object(pActors[v75].vPosition.x, pActors[v75].vPosition.y, v61); | |
4318 pActors[v75].uAIState = Removed; | |
4319 return; | |
4320 } | |
4321 } | |
4322 } | |
4323 if (stru_721530.field_7C >= stru_721530.field_6C) | |
4324 { | |
4325 pActors[v75].vPosition.x = LOWORD(stru_721530.normal2.x); | |
4326 pActors[v75].vPosition.y = LOWORD(stru_721530.normal2.y); | |
4327 pActors[v75].vPosition.z = LOWORD(stru_721530.normal2.z) - LOWORD(stru_721530.prolly_normal_d) - 1; | |
4328 break; | |
4329 } | |
4330 //v72b = fixpoint_mul(stru_721530.field_7C, stru_721530.field_58.x); | |
4331 pActors[v75].vPosition.x += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.x); | |
4332 //v72b = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.y) >> 16; | |
4333 pActors[v75].vPosition.y += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.y); | |
4334 //v72b = (unsigned __int64)(stru_721530.field_7C * (signed __int64)stru_721530.field_58.z) >> 16; | |
4335 pActors[v75].vPosition.z += fixpoint_mul(stru_721530.field_7C, stru_721530.direction.z); | |
4336 stru_721530.field_70 += stru_721530.field_7C; | |
4337 v39 = PID_ID(stru_721530.uFaceID); | |
4338 switch (PID_TYPE(stru_721530.uFaceID)) | |
4339 { | |
4340 case OBJECT_Actor: | |
4341 if (pTurnEngine->turn_stage != TE_ATTACK && pTurnEngine->turn_stage != TE_MOVEMENT || pParty->bTurnBasedModeOn != TE_WAIT) | |
4342 { | |
4343 //if(pParty->bTurnBasedModeOn == 1) | |
4344 //v34 = 0; | |
4345 if (pActors[v75].pMonsterInfo.uHostilityType) | |
4346 { | |
4347 if (v71 == 0) | |
4348 Actor::AI_Flee(v75, stru_721530.uFaceID, 0, (AIDirection *)0); | |
4349 else | |
4350 Actor::AI_StandOrBored(v75, 4, 0, (AIDirection *)0); | |
4351 } | |
4352 else if (v71) | |
4353 Actor::AI_StandOrBored(v75, 4, 0, (AIDirection *)0); | |
4354 else if (pActors[v39].pMonsterInfo.uHostilityType == MonsterInfo::Hostility_Friendly) | |
4355 Actor::AI_Flee(v75, stru_721530.uFaceID, 0, (AIDirection *)0); | |
4356 else | |
4357 Actor::AI_FaceObject(v75, stru_721530.uFaceID, 0, (AIDirection *)0); | |
4358 } | |
4359 break; | |
4360 case OBJECT_Player: | |
4361 if (!pActors[v75].GetActorsRelation(0)) | |
4362 { | |
4363 Actor::AI_FaceObject(v75, stru_721530.uFaceID, 0, (AIDirection *)0); | |
4364 break; | |
4365 } | |
4366 //v52 = HIDWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime) == 0; | |
4367 //v53 = SHIDWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime) < 0; | |
4368 pActors[v75].vVelocity.y = 0; | |
4369 pActors[v75].vVelocity.x = 0; | |
4370 //if ( !v53 && (!(v53 | v52) || LODWORD(pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime) > 0) ) | |
4371 if ((signed __int64)pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].uExpireTime < 0) | |
4372 pParty->pPartyBuffs[PARTY_BUFF_INVISIBILITY].Reset(); | |
4373 viewparams->bRedrawGameUI = 1; | |
4374 break; | |
4375 case OBJECT_Decoration: | |
4376 v47 = integer_sqrt(pActors[v75].vVelocity.x * pActors[v75].vVelocity.x + pActors[v75].vVelocity.y * pActors[v75].vVelocity.y); | |
4377 v48 = stru_5C6E00->Atan2(pActors[v75].vPosition.x - pLevelDecorations[v39].vPosition.x, | |
4378 pActors[v75].vPosition.y - pLevelDecorations[v39].vPosition.y); | |
4379 //v49 = v48; | |
4380 pActors[v75].vVelocity.x = fixpoint_mul(stru_5C6E00->Cos(v48), v47); | |
4381 pActors[v75].vVelocity.y = fixpoint_mul(stru_5C6E00->Sin(v48), v47); | |
4382 break; | |
4383 case OBJECT_BModel: | |
4384 face = &pOutdoor->pBModels[stru_721530.uFaceID >> 9].pFaces[v39 & 0x3F]; | |
4385 if (!face->Ethereal()) | |
4386 { | |
4387 if (face->uPolygonType == 3) | |
4388 { | |
4389 pActors[v75].vVelocity.z = 0; | |
4390 pActors[v75].vPosition.z = LOWORD(pOutdoor->pBModels[stru_721530.uFaceID >> 9].pVertices.pVertices[face->pVertexIDs[0]].z) + 1; | |
4391 if (pActors[v75].vVelocity.x * pActors[v75].vVelocity.x | |
4392 + pActors[v75].vVelocity.y * pActors[v75].vVelocity.y < 400) | |
4393 { | |
4394 pActors[v75].vVelocity.y = 0; | |
4395 pActors[v75].vVelocity.x = 0; | |
4396 } | |
4397 } | |
4398 else | |
4399 { | |
4400 v72b = abs(face->pFacePlane.vNormal.y * pActors[v75].vVelocity.y + face->pFacePlane.vNormal.z * pActors[v75].vVelocity.z | |
4401 + face->pFacePlane.vNormal.x * pActors[v75].vVelocity.x) >> 16; | |
4402 if ((stru_721530.speed >> 3) > v72b) | |
4403 v72b = stru_721530.speed >> 3; | |
4404 | |
4405 pActors[v75].vVelocity.x += fixpoint_mul(v72b, face->pFacePlane.vNormal.x); | |
4406 pActors[v75].vVelocity.y += fixpoint_mul(v72b, face->pFacePlane.vNormal.y); | |
4407 pActors[v75].vVelocity.z += fixpoint_mul(v72b, face->pFacePlane.vNormal.z); | |
4408 if (face->uPolygonType != 4) | |
4409 { | |
4410 v46 = stru_721530.prolly_normal_d | |
4411 - ((face->pFacePlane.dist | |
4412 + face->pFacePlane.vNormal.x * pActors[v75].vPosition.x | |
4413 + face->pFacePlane.vNormal.y * pActors[v75].vPosition.y | |
4414 + face->pFacePlane.vNormal.z * pActors[v75].vPosition.z) >> 16); | |
4415 if (v46 > 0) | |
4416 { | |
4417 pActors[v75].vPosition.x += fixpoint_mul(v46, face->pFacePlane.vNormal.x); | |
4418 pActors[v75].vPosition.y += fixpoint_mul(v46, face->pFacePlane.vNormal.y); | |
4419 pActors[v75].vPosition.z += fixpoint_mul(v46, face->pFacePlane.vNormal.z); | |
4420 } | |
4421 pActors[v75].uYawAngle = stru_5C6E00->Atan2(pActors[v75].vVelocity.x, pActors[v75].vVelocity.y); | |
4422 } | |
4423 } | |
4424 } | |
4425 break; | |
4426 } | |
4427 | |
4428 pActors[v75].vVelocity.x = fixpoint_mul(58500, pActors[v75].vVelocity.x); | |
4429 pActors[v75].vVelocity.y = fixpoint_mul(58500, pActors[v75].vVelocity.y); | |
4430 pActors[v75].vVelocity.z = fixpoint_mul(58500, pActors[v75].vVelocity.z); | |
4431 | |
4432 v26 = stru_721530.prolly_normal_d; | |
4433 } | |
4434 | |
4435 v58 = ((unsigned int)~pOutdoor->ActuallyGetSomeOtherTileInfo(WorldPosToGridCellX(pActors[v75].vPosition.x), WorldPosToGridCellZ(pActors[v75].vPosition.y) - 1) >> 1) & 1; | |
4436 v59 = ((unsigned int)~pOutdoor->ActuallyGetSomeOtherTileInfo(WorldPosToGridCellX(pActors[v75].vPosition.x), WorldPosToGridCellZ(pActors[v75].vPosition.y) - 1) >> 1) & 1; | |
4437 if (WorldPosToGridCellX(pActors[v75].vPosition.x) == WorldPosToGridCellX(pActors[v75].vPosition.x) | |
4438 && WorldPosToGridCellZ(pActors[v75].vPosition.y) == WorldPosToGridCellZ(pActors[v75].vPosition.y) | |
4439 && v58 || v67 != 0) | |
4440 { | |
4441 if (MonsterStats::BelongsToSupertype(pActors[v75].pMonsterInfo.uID, MONSTER_SUPERTYPE_WATER_ELEMENTAL)) | |
4442 { | |
4443 v58 = v58 == 0; | |
4444 v59 = v59 == 0; | |
4445 } | |
4446 if (!uIsFlying && v58 && !v59) | |
4447 { | |
4448 pActors[v75].vPosition.x = pActors[v75].vPosition.x; | |
4449 pActors[v75].vPosition.y = pActors[v75].vPosition.y; | |
4450 if (pActors[v75].CanAct()) | |
4451 { | |
4452 pActors[v75].uYawAngle -= 32; | |
4453 pActors[v75].uCurrentActionTime = 0; | |
4454 pActors[v75].uCurrentActionLength = 128; | |
4455 pActors[v75].uAIState = Fleeing; | |
4456 } | |
4457 } | |
4458 } | |
4459 } | |
4460 } | |
4461 | |
4462 //----- (0047A384) -------------------------------------------------------- | |
4463 void ODM_LoadAndInitialize(const char *pLevelFilename, ODMRenderParams *thisa) | |
4464 { | |
4465 int v2; // ebx@3 | |
4466 unsigned int v3; // eax@3 | |
4467 MapInfo *v4; // edi@4 | |
4468 //int v5; // eax@8 | |
4469 //SpawnPointMM7 *v6; // edx@14 | |
4470 size_t v7; // eax@19 | |
4471 //char *v8; // eax@19 | |
4472 //char *v9; // eax@21 | |
4473 char Source[120]; // [sp+Ch] [bp-84h]@19 | |
4474 const char *pFilename; // [sp+84h] [bp-Ch]@1 | |
4475 //unsigned int v12; // [sp+88h] [bp-8h]@12 | |
4476 //int v13; // [sp+8Ch] [bp-4h]@11 | |
4477 int v; | |
4478 | |
4479 pFilename = pLevelFilename; | |
4480 //thisa->AllocSoftwareDrawBuffers(); | |
4481 pODMRenderParams->Initialize(); | |
4482 pWeather->bRenderSnow = false; | |
4483 pRenderer->ClearZBuffer(0, 479); | |
4484 //thisa = (ODMRenderParams *)1; | |
4485 GetAlertStatus(); | |
4486 if (_A750D8_player_speech_timer) | |
4487 _A750D8_player_speech_timer = 0; | |
4488 v2 = pMapStats->GetMapInfo(pCurrentMapName); | |
4489 v3 = 0; | |
4490 if (v2) | |
4491 { | |
4492 v4 = &pMapStats->pInfos[v2]; | |
4493 v3 = v4->uRespawnIntervalDays; | |
4494 } | |
4495 else | |
4496 v4 = (MapInfo *)1; | |
4497 day_attrib &= ~DAY_ATTRIB_FOG; | |
4498 dword_6BE13C_uCurrentlyLoadedLocationID = v2; | |
4499 pOutdoor->Initialize( | |
4500 pFilename, | |
4501 (unsigned int)(signed __int64)((double)(signed __int64)pParty->uTimePlayed * 0.234375) / 0x3C / 0x3C / 0x18 + 1, | |
4502 v3, | |
4503 &v); | |
4504 if (!(dword_6BE364_game_settings_1 & GAME_SETTINGS_2000)) | |
4505 { | |
4506 Actor::InitializeActors(); | |
4507 SpriteObject::InitializeSpriteObjects(); | |
4508 } | |
4509 dword_6BE364_game_settings_1 &= ~GAME_SETTINGS_2000; | |
4510 //v5 = 0; | |
4511 if (!v2) | |
4512 v = 0; | |
4513 if (v == 1) | |
4514 { | |
4515 //v13 = 0; | |
4516 for (uint i = 0; i < pOutdoor->uNumSpawnPoints; ++i) | |
4517 { | |
4518 //v12 = 0; | |
4519 //while ( 1 ) | |
4520 //{ | |
4521 SpawnPointMM7* spawn = pOutdoor->pSpawnPoints + i; | |
4522 //v6 = &pOutdoor->pSpawnPoints[v12 / 0x18]; | |
4523 if (spawn->uKind == 3) | |
4524 SpawnEncounter(v4, spawn, 0, 0, 0); | |
4525 else | |
4526 v4->SpawnRandomTreasure(spawn); | |
4527 //++v13; | |
4528 //v12 += 24; | |
4529 //if ( v13 >= (signed int)pOutdoor->uNumSpawnPoints ) | |
4530 // break; | |
4531 //v5 = 0; | |
4532 //} | |
4533 } | |
4534 RespawnGlobalDecorations(); | |
4535 } | |
4536 pOutdoor->PrepareDecorations(); | |
4537 pOutdoor->ArrangeSpriteObjects(); | |
4538 pOutdoor->InitalizeActors(v2); | |
4539 pOutdoor->MessWithLUN(); | |
4540 v7 = strlen("levels\\"); | |
4541 strcpy(Source, &pFilename[v7]); | |
4542 strcpy(pOutdoor->pLevelFilename, Source); | |
4543 pWeather->Initialize(); | |
2543 | 4544 pIndoorCameraD3D->sRotationY = pParty->sRotationY; |
4545 pIndoorCameraD3D->sRotationX = pParty->sRotationX; | |
2496 | 4546 //pODMRenderParams->RotationToInts(); |
4547 pOutdoor->UpdateSunlightVectors(); | |
4548 | |
4549 float fov_rad; | |
4550 float fov_rad_inv; | |
4551 //----- (0042394D) -------------------------------------------------------- | |
4552 //void IndoorCamera::Initialize(int degFov, unsigned int uViewportWidth, unsigned int uViewportHeight) | |
4553 { | |
4554 //pIndoorCamera->Initialize(65, viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X + 1, | |
4555 // viewparams->uScreen_BttmR_Y - viewparams->uScreen_topL_Y + 1); | |
4556 | |
4557 int uViewportWidth = viewparams->uScreen_BttmR_X - viewparams->uScreen_topL_X + 1; | |
4558 | |
4559 extern float _calc_fov(int viewport_width, int angle_degree); | |
4560 fov_rad = _calc_fov(uViewportWidth, 65); | |
4561 fov_rad_inv = 65536.0 / fov_rad; | |
4562 } | |
4563 pODMRenderParams->int_fov_rad = (signed __int64)fov_rad; | |
4564 pODMRenderParams->int_fov_rad_inv = (signed __int64)fov_rad_inv; | |
4565 | |
4566 for (int i = 0; i < 20000; ++i) | |
4567 { | |
4568 array_77EC08[i].ptr_38 = &stru_8019C8; | |
4569 | |
4570 array_77EC08[i].ptr_48 = nullptr; | |
4571 } | |
4572 | |
4573 MM7Initialization(); | |
4574 } | |
4575 | |
4576 //----- (0047C370) -------------------------------------------------------- | |
4577 unsigned int GetLevelFogColor() | |
4578 { | |
4579 signed __int64 v1; // qax@5 | |
4580 int v2; // eax@6 | |
4581 | |
4582 if (bUnderwater) | |
4583 return 0xFF258F5C; | |
4584 | |
4585 if (day_attrib & DAY_ATTRIB_FOG) | |
4586 { | |
4587 if (pWeather->bNight) // night-time fog | |
4588 { | |
4589 if (for_refactoring) | |
4590 { | |
4591 MessageBoxA(nullptr, "Nomad: decompilation can be inaccurate, please send savegame to Nomad", "", 0); | |
4592 __debugbreak(); | |
4593 } | |
4594 v2 = -(pWeather->bNight != 1); | |
4595 return (v2 & 0xE0E0E1) - 0xE0E0E1; | |
4596 } | |
4597 else | |
4598 { | |
4599 v1 = (signed __int64)((1.0 - pOutdoor->fFogDensity) * 200.0 + pOutdoor->fFogDensity * 31.0); | |
4600 return v1 | (((unsigned int)v1 | (((unsigned int)v1 | 0xFFFFFF00) << 8)) << 8); | |
4601 } | |
4602 } | |
4603 | |
4604 return 0; | |
4605 } | |
4606 | |
4607 //----- (0047C3D7) -------------------------------------------------------- | |
4608 int __fastcall sub_47C3D7_get_fog_specular(int a1, int a2, float a3) | |
4609 { | |
4610 int v3; // ecx@1 | |
4611 signed int v7; // ecx@11 | |
4612 | |
4613 v3 = pWeather->bNight; | |
4614 if (bUnderwater == 1) | |
4615 v3 = 0; | |
4616 if (pParty->armageddon_timer || !(day_attrib & DAY_ATTRIB_FOG) && !bUnderwater) | |
4617 return 0xFF000000; | |
4618 if (v3) | |
4619 { | |
4620 if (a3 < (double)day_fogrange_1) | |
4621 { | |
4622 v7 = 0; | |
4623 if (a3 == 0.0) | |
4624 v7 = 216; | |
4625 if (a2) | |
4626 v7 = 248; | |
4627 return (-1 - v7) << 24; | |
4628 } | |
4629 else | |
4630 { | |
4631 if (a3 > (double)day_fogrange_2) | |
4632 { | |
4633 v7 = 216; | |
4634 if (a3 == 0.0) | |
4635 v7 = 216; | |
4636 if (a2) | |
4637 v7 = 248; | |
4638 return (-1 - v7) << 24; | |
4639 } | |
4640 v7 = (signed __int64)((a3 - (double)day_fogrange_1) / ((double)day_fogrange_2 - (double)day_fogrange_1) * 216.0); | |
4641 } | |
4642 } | |
4643 else | |
4644 { | |
4645 if (a3 < (double)day_fogrange_1) | |
4646 { | |
4647 v7 = 0; | |
4648 if (a3 == 0.0) | |
4649 v7 = 216; | |
4650 if (a2) | |
4651 v7 = 248; | |
4652 return (-1 - v7) << 24; | |
4653 } | |
4654 else | |
4655 { | |
4656 if (a3 > (double)day_fogrange_2) | |
4657 { | |
4658 v7 = 216; | |
4659 if (a3 == 0.0) | |
4660 v7 = 216; | |
4661 if (a2) | |
4662 v7 = 248; | |
4663 return (-1 - v7) << 24; | |
4664 } | |
4665 else | |
4666 v7 = floorf(((a3 - (double)day_fogrange_1) * 216.0 / ((double)day_fogrange_2 - (double)day_fogrange_1)) + 0.5f); | |
4667 } | |
4668 } | |
4669 if (v7 > 216) | |
4670 v7 = 216; | |
4671 else | |
4672 { | |
4673 if (a3 == 0.0) | |
4674 v7 = 216; | |
4675 } | |
4676 if (a2) | |
4677 v7 = 248; | |
4678 return (-1 - v7) << 24; | |
4679 } | |
4680 | |
4681 | |
4682 //----- (0047F44B) -------------------------------------------------------- | |
4683 unsigned int WorldPosToGridCellX(int sWorldPosX) | |
4684 { | |
4685 return (sWorldPosX >> 9) + 64; // sar is in original exe, resulting -880 / 512 = -1 | |
4686 // and -880 sar 9 = -2 | |
4687 } | |
4688 | |
4689 //----- (0047F458) -------------------------------------------------------- | |
4690 unsigned int WorldPosToGridCellZ(int sWorldPosZ) | |
4691 { | |
4692 return 64 - (sWorldPosZ >> 9); // sar is in original exe, resulting -880 / 512 = -1 | |
4693 // and -880 sar 9 = -2 | |
4694 } | |
4695 | |
4696 //----- (0047F469) -------------------------------------------------------- | |
4697 int GridCellToWorldPosX(int a1) | |
4698 { | |
4699 return (a1 - 64) << 9; | |
4700 } | |
4701 | |
4702 //----- (0047F476) -------------------------------------------------------- | |
4703 int GridCellToWorldPosZ(int a1) | |
4704 { | |
4705 return (64 - a1) << 9; | |
4706 } | |
4707 | |
4708 | |
4709 | |
4710 //----- (00481ED9) -------------------------------------------------------- | |
4711 void sub_481ED9_MessWithODMRenderParams() | |
4712 { | |
4713 stru_8019C8._48616B_frustum_odm(65536, 0, 0, 0, 65536, 0); | |
4714 pODMRenderParams->uNumPolygons = 0; | |
4715 //pODMRenderParams->uNumEdges = 0; | |
4716 //pODMRenderParams->uNumSpans = 0; | |
4717 //pODMRenderParams->uNumSurfs = 0; | |
4718 pODMRenderParams->uNumBillboards = 0; | |
4719 pODMRenderParams->field_44 = 0; | |
4720 } | |
4721 | |
4722 //----- (004823F4) -------------------------------------------------------- | |
4723 bool IsTerrainSlopeTooHigh(int pos_x, int pos_z) | |
4724 { | |
4725 //unsigned int v2; // ebx@1 | |
4726 //unsigned int v3; // edi@1 | |
4727 //int v4; // eax@1 | |
4728 //int v6; // esi@5 | |
4729 //int v7; // ecx@6 | |
4730 //int v8; // edx@6 | |
4731 //int v9; // eax@6 | |
4732 //int y_min; // esi@10 | |
4733 //int v11; // [sp+14h] [bp-8h]@1 | |
4734 //int v12; // [sp+18h] [bp-4h]@1 | |
4735 | |
4736 //v12 = a1; | |
4737 //v11 = a2; | |
4738 unsigned int grid_x = WorldPosToGridCellX(pos_x); | |
4739 unsigned int grid_z = WorldPosToGridCellZ(pos_z) - 1; | |
4740 | |
4741 int party_grid_x1 = GridCellToWorldPosX(grid_x); | |
4742 //dword_76D56C_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x + 1); | |
4743 //dword_76D570_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x + 1); | |
4744 //dword_76D574_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x); | |
4745 int party_grid_z1 = GridCellToWorldPosZ(grid_z); | |
4746 //dword_76D55C_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z); | |
4747 //dword_76D560_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z + 1); | |
4748 //dword_76D564_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z + 1); | |
4749 int party_x1z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z); | |
4750 int party_x2z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z); | |
4751 int party_x2z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1); | |
4752 int party_x1z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1); | |
4753 //dword_76D554_terrain_cell_world_pos_around_party_y = v4; | |
4754 if (party_x1z1_y == party_x2z1_y && | |
4755 party_x2z1_y == party_x2z2_y && | |
4756 party_x2z2_y == party_x1z2_y) | |
4757 return false; | |
4758 | |
4759 int dx = abs(pos_x - party_grid_x1), | |
4760 dz = abs(party_grid_z1 - pos_z); | |
4761 | |
4762 int y1, y2, y3; | |
4763 if (dz >= dx) | |
4764 { | |
4765 y1 = party_x1z2_y; // lower-left triangle | |
4766 y2 = party_x2z2_y; // y3 | \ | |
4767 y3 = party_x1z1_y; // | \ | |
4768 /* | \ | |
4769 |______ \ | |
4770 y1 y2 */ | |
4771 } | |
4772 else | |
4773 { | |
4774 y1 = party_x2z1_y; // upper-right | |
4775 y2 = party_x1z1_y; // y2_______ y1 | |
4776 y3 = party_x2z2_y; // \ | | |
4777 /* \ | | |
4778 \ | | |
4779 y3 */ | |
4780 } | |
4781 | |
4782 int y_min = min(y1, min(y2, y3));// не верно при подъёме на склон | |
4783 int y_max = max(y1, max(y2, y3)); | |
4784 return (y_max - y_min) > 512; | |
4785 } | |
4786 | |
4787 //----- (0048257A) -------------------------------------------------------- | |
4788 int __fastcall GetTerrainHeightsAroundParty2(int a1, int a2, int *pIsOnWater, int bFloatAboveWater) | |
4789 { | |
4790 // int result; // eax@9 | |
4791 int v8; // ebx@11 | |
4792 int v9; // eax@11 | |
4793 int v10; // ecx@11 | |
4794 int v13; // [sp+10h] [bp-8h]@11 | |
4795 signed int v14; // [sp+14h] [bp-4h]@3 | |
4796 int v15; // [sp+24h] [bp+Ch]@11 | |
4797 | |
4798 unsigned int grid_x = WorldPosToGridCellX(a1); | |
4799 unsigned int grid_z = WorldPosToGridCellZ(a2) - 1; | |
4800 | |
4801 int grid_x1 = GridCellToWorldPosX(grid_x), | |
4802 grid_x2 = GridCellToWorldPosX(grid_x + 1); | |
4803 int grid_z1 = GridCellToWorldPosZ(grid_z), | |
4804 grid_z2 = GridCellToWorldPosZ(grid_z + 1); | |
4805 | |
4806 int y_x1z1 = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z), | |
4807 y_x2z1 = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z), | |
4808 y_x2z2 = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1), | |
4809 y_x1z2 = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1); | |
4810 //v4 = WorldPosToGridCellX(a1); | |
4811 //v5 = WorldPosToGridCellZ(v12) - 1; | |
4812 //dword_76D538_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4); | |
4813 //dword_76D53C_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4 + 1); | |
4814 //dword_76D540_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4 + 1); | |
4815 //dword_76D544_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v4); | |
4816 //dword_76D528_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5); | |
4817 //dword_76D52C_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5); | |
4818 //dword_76D530_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5 + 1); | |
4819 //dword_76D534_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v5 + 1); | |
4820 //dword_76D518_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4, v5); | |
4821 //dword_76D51C_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4 + 1, v5); | |
4822 //dword_76D520_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4 + 1, v5 + 1); | |
4823 //dword_76D524_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v4, v5 + 1); | |
4824 *pIsOnWater = false; | |
4825 if (pOutdoor->ActuallyGetSomeOtherTileInfo(grid_x, grid_z) & 2) | |
4826 *pIsOnWater = true; | |
4827 v14 = 0; | |
4828 if (!bFloatAboveWater && *pIsOnWater) | |
4829 v14 = -60; | |
4830 if (y_x1z1 != y_x2z1 || | |
4831 y_x2z1 != y_x2z2 || | |
4832 y_x2z2 != y_x1z2) | |
4833 { | |
4834 if (abs(grid_z1 - a2) >= abs(a1 - grid_x1)) | |
4835 { | |
4836 v8 = y_x1z2; | |
4837 v9 = y_x2z2; | |
4838 v10 = y_x1z1; | |
4839 v15 = a1 - grid_x1; | |
4840 v13 = a2 - grid_z2; | |
4841 } | |
4842 else | |
4843 { | |
4844 v8 = y_x2z1; | |
4845 v9 = y_x1z1; | |
4846 v10 = y_x2z2; | |
4847 v15 = grid_x2 - a1; | |
4848 v13 = grid_z1 - a2; | |
4849 } | |
4850 return v14 + v8 + fixpoint_mul(v13, (v10 - v8) * 128) + fixpoint_mul(v15, (v9 - v8) * 128); | |
4851 } | |
4852 else | |
4853 return y_x1z1; | |
4854 } |