Mercurial > mm7
annotate Engine/Objects/Chest.cpp @ 2546:4087cbc62706
GameMenu logic moved to GUIWindow_GameMenu
the same for game menu options
author | a.parshin |
---|---|
date | Mon, 11 May 2015 17:45:02 +0200 |
parents | c674d547cc7c |
children | fb42e2662c38 |
rev | line source |
---|---|
2497 | 1 #define _CRTDBG_MAP_ALLOC |
2 #include <stdlib.h> | |
3 #include <crtdbg.h> | |
4 | |
5 #define _CRT_SECURE_NO_WARNINGS | |
6 #include <stdio.h> | |
7 | |
2541 | 8 #include "Engine/Engine.h" |
2497 | 9 |
10 #include "Items.h" | |
11 #include "Chest.h" | |
2499 | 12 #include "../Tables/FrameTableInc.h" |
13 #include "../LOD.h" | |
14 #include "../MapInfo.h" | |
2497 | 15 #include "Actor.h" |
2499 | 16 #include "../Graphics/Outdoor.h" |
17 #include "../Graphics/DecorationList.h" | |
18 #include "../Party.h" | |
2502 | 19 #include "Media/Audio/AudioPlayer.h" |
2499 | 20 #include "../OurMath.h" |
21 #include "../Texts.h" | |
2497 | 22 #include "ObjectList.h" |
2502 | 23 #include "GUI/GUIWindow.h" |
2499 | 24 #include "../Timer.h" |
2497 | 25 #include "SpriteObject.h" |
2502 | 26 #include "IO/Mouse.h" |
2499 | 27 #include "../Graphics/Viewport.h" |
28 #include "../Graphics/Level/Decoration.h" | |
2497 | 29 |
30 size_t uNumChests; // idb | |
31 struct ChestList *pChestList; | |
32 std::array<Chest, 20> pChests; | |
33 | |
34 | |
35 const int pChestPixelOffsetX[8] = {42, 18, 18, 42, 42, 42, 18, 42}; | |
36 const int pChestPixelOffsetY[8] = {34, 30, 30, 34, 34, 34, 30, 34}; | |
37 const int pChestWidthsByType[8] = {9, 9, 9, 9, 9, 9, 9, 9}; | |
38 const int pChestHeightsByType[8] = {9, 9, 9, 9, 9, 9, 9, 9}; | |
39 | |
40 | |
41 //----- (0042041E) -------------------------------------------------------- | |
42 bool Chest::Open( signed int uChestID ) | |
43 { | |
44 unsigned int pMapID; // eax@8 | |
45 int pRandom; // edx@16 | |
46 int v6; // eax@16 | |
47 ODMFace *pODMFace; // eax@19 | |
48 BLVFace *pBLVFace; // eax@20 | |
49 int pObjectX; // ebx@21 | |
50 int pObjectZ; // edi@21 | |
51 double dir_x; // st7@23 | |
52 double dir_y; // st6@23 | |
53 double length_vector; // st7@23 | |
54 int pDepth; // ecx@26 | |
55 Vec3_int_ v; // ST4C_12@28 | |
56 bool flag_shout; // edi@28 | |
57 int pSpriteID[4]; // [sp+84h] [bp-40h]@16 | |
58 Vec3_int_ pOut; // [sp+A0h] [bp-24h]@28 | |
59 int pObjectY; // [sp+B0h] [bp-14h]@21 | |
60 int sRotX; // [sp+B4h] [bp-10h]@23 | |
61 float dir_z; // [sp+BCh] [bp-8h]@23 | |
62 int sRotY; // [sp+C0h] [bp-4h]@8 | |
63 SpriteObject pSpellObject; // [sp+14h] [bp-B0h]@28 | |
64 | |
65 assert( uChestID < 20 ); | |
66 if ( ( uChestID < 0 ) && ( uChestID >= 20 ) ) | |
67 return false; | |
68 Chest* chest = &pChests[uChestID]; | |
69 | |
70 ++pIcons_LOD->uTexturePacksCount; | |
71 if (!pIcons_LOD->uNumPrevLoadedFiles) | |
72 pIcons_LOD->uNumPrevLoadedFiles = pIcons_LOD->uNumLoadedFiles; | |
73 | |
74 if (!chest->Initialized()) | |
75 Chest::PlaceItems(uChestID); | |
76 | |
77 if ( !uActiveCharacter ) | |
78 return false; | |
79 flag_shout = false; | |
80 pMapID = pMapStats->GetMapInfo(pCurrentMapName); | |
81 if ( chest->Trapped() && pMapID ) | |
82 { | |
83 if ( pPlayers[uActiveCharacter]->GetDisarmTrap() < 2 * pMapStats->pInfos[pMapID].LockX5 ) | |
84 { | |
85 pSpriteID[0] = 811; | |
86 pSpriteID[1] = 812; | |
87 pSpriteID[2] = 813; | |
88 pSpriteID[3] = 814; | |
89 pRandom = rand() % 4; | |
90 v6 = PID_ID(EvtTargetObj); | |
91 if ( PID_TYPE(EvtTargetObj) == OBJECT_Decoration) | |
92 { | |
93 pObjectX = pLevelDecorations[v6].vPosition.x; | |
94 pObjectY = pLevelDecorations[v6].vPosition.y; | |
95 pObjectZ = pLevelDecorations[v6].vPosition.z + ( pDecorationList->pDecorations[pLevelDecorations[v6].uDecorationDescID].uDecorationHeight / 2 ); | |
96 } | |
97 if ( PID_TYPE(EvtTargetObj) == OBJECT_BModel) | |
98 { | |
99 if ( uCurrentlyLoadedLevelType == LEVEL_Outdoor) | |
100 { | |
101 pODMFace = &pOutdoor->pBModels[EvtTargetObj >> 9].pFaces[(EvtTargetObj >> 3) & 0x3F]; | |
102 pObjectX = ( pODMFace->pBoundingBox.x1 + pODMFace->pBoundingBox.x2 ) / 2; | |
103 pObjectY = ( pODMFace->pBoundingBox.y1 + pODMFace->pBoundingBox.y2 ) / 2; | |
104 pObjectZ = ( pODMFace->pBoundingBox.z1 + pODMFace->pBoundingBox.z2 ) / 2; | |
105 } | |
106 else//Indoor | |
107 { | |
108 pBLVFace = &pIndoor->pFaces[v6]; | |
109 pObjectX = ( pBLVFace->pBounding.x1 + pBLVFace->pBounding.x2 ) / 2; | |
110 pObjectY = ( pBLVFace->pBounding.y1 + pBLVFace->pBounding.y2 ) / 2; | |
111 pObjectZ = ( pBLVFace->pBounding.z1 + pBLVFace->pBounding.z2 ) / 2; | |
112 } | |
113 } | |
114 dir_x = (double)pParty->vPosition.x - (double)pObjectX; | |
115 dir_y = (double)pParty->vPosition.y - (double)pObjectY; | |
116 dir_z = ( (double)pParty->sEyelevel + (double)pParty->vPosition.z ) - (double)pObjectZ; | |
117 length_vector = sqrt( (dir_x * dir_x) + (dir_y * dir_y) + (dir_z * dir_z) ); | |
118 if ( length_vector <= 1.0 ) | |
119 { | |
120 *(float *)&sRotX = 0.0; | |
121 *(float *)&sRotY = 0.0; | |
122 } | |
123 else | |
124 { | |
125 sRotY = (signed __int64)sqrt(dir_x * dir_x + dir_y * dir_y); | |
126 sRotX = stru_5C6E00->Atan2((signed __int64)dir_x, (signed __int64)dir_y); | |
127 sRotY = stru_5C6E00->Atan2(dir_y * dir_y, (signed __int64)dir_z); | |
128 } | |
129 pDepth = 256; | |
130 if ( length_vector < 256.0 ) | |
131 pDepth = (signed __int64)length_vector / 4; | |
132 v.x = pObjectX; | |
133 v.y = pObjectY; | |
134 v.z = pObjectZ; | |
135 Vec3_int_::Rotate(pDepth, sRotX, sRotY, v, &pOut.x, &pOut.z, &pOut.y); | |
136 SpriteObject::sub_42F7EB_DropItemAt(pSpriteID[pRandom], pOut.x, pOut.z, pOut.y, 0, 1, 0, 48, 0); | |
137 | |
138 pSpellObject.stru_24.Reset(); | |
139 pSpellObject.spell_skill = 0; | |
140 pSpellObject.spell_level = 0; | |
141 pSpellObject.spell_id = 0; | |
142 pSpellObject.field_54 = 0; | |
143 pSpellObject.uType = pSpriteID[pRandom]; | |
144 pSpellObject.uObjectDescID = 0; | |
145 if ( pObjectList->uNumObjects ) | |
146 { | |
147 for ( uint i = 0; i < (signed int)pObjectList->uNumObjects; ++i ) | |
148 { | |
149 if ( pSpriteID[pRandom] == pObjectList->pObjects[i].uObjectID ) | |
150 pSpellObject.uObjectDescID = i; | |
151 } | |
152 } | |
153 pSpellObject.vPosition.y = pOut.z; | |
154 pSpellObject.vPosition.x = pOut.x; | |
155 pSpellObject.vPosition.z = pOut.y; | |
156 pSpellObject.uSoundID = 0; | |
157 pSpellObject.uAttributes = 48; | |
158 pSpellObject.uSectorID = pIndoor->GetSector(pOut.x, pOut.z, pOut.y); | |
159 pSpellObject.uSpriteFrameID = 0; | |
160 pSpellObject.spell_caster_pid = 0; | |
161 pSpellObject.spell_target_pid = 0; | |
162 pSpellObject.uFacing = 0; | |
163 pSpellObject.Create(0, 0, 0, 0); | |
2534 | 164 pAudioPlayer->PlaySound(SOUND_fireBall, 0, 0, -1, 0, 0, 0, 0); |
2497 | 165 pSpellObject.ExplosionTraps(); |
166 chest->uFlags &= 0xFEu; | |
167 if ( uActiveCharacter && !_A750D8_player_speech_timer && !OpenedTelekinesis ) | |
168 { | |
169 _A750D8_player_speech_timer = 256i64; | |
170 PlayerSpeechID = SPEECH_5; | |
171 uSpeakingCharacter = uActiveCharacter; | |
172 } | |
173 pIcons_LOD->RemoveTexturesPackFromTextureList(); | |
174 OpenedTelekinesis = false; | |
175 return false; | |
176 } | |
177 chest->uFlags &= 0xFEu; | |
178 flag_shout = true; | |
179 } | |
180 pAudioPlayer->StopChannels(-1, -1); | |
2534 | 181 pAudioPlayer->PlaySound(SOUND_openchest0101, 0, 0, -1, 0, 0, 0, 0); |
2497 | 182 if ( flag_shout == true ) |
183 { | |
184 if ( !OpenedTelekinesis ) | |
185 pPlayers[uActiveCharacter]->PlaySound(SPEECH_4, 0); | |
186 } | |
187 OpenedTelekinesis = false; | |
2544
c674d547cc7c
GUIWindow switch logic refactored into behaviour classes
a.parshin
parents:
2541
diff
changeset
|
188 pChestWindow = pGUIWindow_CurrentMenu = new GUIWindow_Chest(0, 0, window->GetWidth(), window->GetHeight(), uChestID, 0); |
2497 | 189 pBtn_ExitCancel = pChestWindow->CreateButton(471, 445, 169, 35, 1, 0, UIMSG_Escape, 0, 0, pGlobalTXT_LocalizationStrings[79], pIcons_LOD->GetTexture(uExitCancelTextureId), 0);// Exit |
190 pChestWindow->CreateButton( 7, 8, 460, 343, 1, 0, UIMSG_CHEST_ClickItem, 0, 0, "", 0); | |
2541 | 191 current_screen_type = SCREEN_CHEST; |
2497 | 192 pEventTimer->Pause(); |
193 return true; | |
194 } | |
195 | |
196 //----- (0042038D) -------------------------------------------------------- | |
197 void Chest::ChestUI_WritePointedObjectStatusString() | |
198 { | |
199 int v1; // ecx@2 | |
200 POINT cursor; // [sp+8h] [bp-8h]@1 | |
201 | |
202 pMouse->GetCursorPos(&cursor); | |
203 if ( cursor.y < 350 ) | |
204 { | |
205 v1 = pRenderer->pActiveZBuffer[cursor.x + pSRZBufferLineOffsets[cursor.y]]; | |
206 if ( v1 != 0 && v1 != -65536 ) | |
207 { | |
208 if ( v1 ) | |
209 { | |
210 ItemGen* item = &pChests[pChestWindow->par1C].igChestItems[pChests[pChestWindow->par1C].pInventoryIndices[(v1 & 0xFFFF) - 1] - 1]; | |
211 GameUI_SetFooterString(item->GetDisplayName()); | |
212 } | |
213 } | |
214 } | |
215 } | |
216 | |
217 //----- (0042092D) -------------------------------------------------------- | |
218 void Chest::DrawChestUI(signed int uChestID) | |
219 { | |
220 | |
221 int chestBitmapId; // eax@1 | |
222 unsigned int v5; // eax@1 | |
223 int chest_item_index; // ecx@3 | |
224 unsigned int item_texture_id; // eax@4 | |
225 Texture *item_texture; // esi@4 | |
226 signed int itemPixelWidth; // ecx@4 | |
227 signed int itemPixelHeght; // edx@4 | |
228 // signed int v11; // eax@4 | |
229 int v12; // eax@6 | |
230 int v13; // eax@6 | |
231 unsigned int itemPixelPosX; // ST34_4@8 | |
232 int itemPixelPosY; // edi@8 | |
233 int *v16; // [sp+Ch] [bp-28h]@1 | |
234 // int v17; // [sp+10h] [bp-24h]@4 | |
235 int chest_offs_y; // [sp+14h] [bp-20h]@1 | |
236 signed int chestHeghtCells; // [sp+18h] [bp-1Ch]@1 | |
237 int chest_offs_x; // [sp+1Ch] [bp-18h]@1 | |
238 signed int chestWidthCells; // [sp+20h] [bp-14h]@1 | |
239 signed int item_counter; // [sp+30h] [bp-4h]@1 | |
240 | |
241 v16 = pRenderer->pActiveZBuffer; | |
242 pRenderer->ClearZBuffer(0, 479); | |
243 chestBitmapId = pChests[uChestID].uChestBitmapID; | |
244 chest_offs_x = pChestPixelOffsetX[chestBitmapId]; | |
245 chest_offs_y = pChestPixelOffsetY[chestBitmapId]; | |
246 chestWidthCells = pChestWidthsByType[chestBitmapId]; | |
247 chestHeghtCells = pChestHeightsByType[chestBitmapId]; | |
248 sprintfex(pTmpBuf.data(), "chest%02d", pChestList->pChests[chestBitmapId].uTextureID); | |
249 v5 = pIcons_LOD->LoadTexture(pTmpBuf.data(), TEXTURE_16BIT_PALETTE); | |
250 pRenderer->DrawTextureIndexed(8u, 8u, pIcons_LOD->GetTexture(v5)); | |
251 | |
252 for (item_counter = 0; item_counter < chestWidthCells * chestHeghtCells; ++item_counter) | |
253 { | |
254 chest_item_index = pChests[uChestID].pInventoryIndices[item_counter]; | |
255 if ( chest_item_index > 0 ) | |
256 { | |
257 item_texture_id = pIcons_LOD->LoadTexture( | |
258 //pItemsTable->pItems[*(int *)((char *)&pOtherOverlayList->pOverlays[49].field_4 + 36 * v6 + v3 * 5324)].pIconName, | |
259 pChests[uChestID].igChestItems[chest_item_index - 1].GetIconName(), TEXTURE_16BIT_PALETTE); | |
260 item_texture = pIcons_LOD->GetTexture(item_texture_id); | |
261 itemPixelWidth = item_texture->uTextureWidth; | |
262 itemPixelHeght = item_texture->uTextureHeight; | |
263 if ( itemPixelWidth < 14 ) | |
264 itemPixelWidth = 14; | |
265 v12 = itemPixelWidth - 14; | |
266 v12 = v12 & 0xFFFFFFE0; | |
267 v13 = v12 + 32; | |
268 if ( itemPixelHeght < 14 ) | |
269 itemPixelHeght = 14; | |
270 itemPixelPosX = chest_offs_x + 32 * (item_counter % chestWidthCells) + ((signed int)(v13 - itemPixelWidth)/2); | |
271 itemPixelPosY = chest_offs_y + 32 * (item_counter / chestHeghtCells) + | |
272 ((signed int)(((itemPixelHeght - 14) & 0xFFFFFFE0) + 32- item_texture->uTextureHeight ) /2); | |
2524 | 273 pRenderer->DrawTextureIndexedAlpha( itemPixelPosX, itemPixelPosY, item_texture); |
2497 | 274 ZBuffer_DoFill2(&v16[itemPixelPosX + pSRZBufferLineOffsets[itemPixelPosY]], item_texture, item_counter + 1); |
275 } | |
276 } | |
277 pRenderer->DrawTextureIndexed(pBtn_ExitCancel->uX, pBtn_ExitCancel->uY, pIcons_LOD->GetTexture(uExitCancelTextureId)); | |
278 } | |
279 | |
280 | |
281 //----- (0041FE71) -------------------------------------------------------- | |
282 bool Chest::CanPlaceItemAt( signed int test_cell_position, int item_id, signed int uChestID ) | |
283 { | |
284 // int v3; // eax@1 | |
285 unsigned int item_texture_id; // eax@1 | |
286 Texture *item_texture; // ecx@1 | |
287 signed int v6; // eax@1 | |
288 // signed int v7; // edi@3 | |
289 signed int v8; // eax@3 | |
290 int texture_cell_width; // edi@3 | |
291 int texture_cell_height; // ebx@5 | |
292 int _row; // esi@9 | |
293 int _cell_rows; // edx@10 | |
294 int _column; // ecx@11 | |
295 // char *v14; // eax@12 | |
296 int chest_cell_heght; // [sp+Ch] [bp-Ch]@1 | |
297 // signed int v17; // [sp+10h] [bp-8h]@1 | |
298 signed int chest_cell_width; // [sp+14h] [bp-4h]@1 | |
299 | |
300 chest_cell_heght = pChestHeightsByType[pChests[uChestID].uChestBitmapID]; | |
301 chest_cell_width = pChestWidthsByType[pChests[uChestID].uChestBitmapID]; | |
302 item_texture_id = pIcons_LOD->LoadTexture(pItemsTable->pItems[item_id].pIconName, TEXTURE_16BIT_PALETTE); | |
303 item_texture = pIcons_LOD->GetTexture(item_texture_id); | |
304 v6 = item_texture->uTextureWidth; | |
305 if ( v6 < 14 ) | |
306 v6 = 14; | |
307 texture_cell_width = ((v6 - 14) >> 5) + 1; | |
308 v8 = item_texture->uTextureHeight; | |
309 if ( v8 < 14 ) | |
310 v8 = 14; | |
311 texture_cell_height = ((v8 - 14) >> 5) + 1; | |
312 if ( !areWeLoadingTexture ) | |
313 { | |
314 item_texture->Release(); | |
315 pIcons_LOD->SyncLoadedFilesCount(); | |
316 } | |
317 if ( (texture_cell_width + test_cell_position % chest_cell_width <= chest_cell_width) && | |
318 (texture_cell_height + test_cell_position / chest_cell_width <= chest_cell_heght) ) | |
319 { //we not put over borders | |
320 _row = 0; | |
321 if ( texture_cell_height <= 0 ) | |
322 return true; | |
323 _cell_rows = 0; | |
324 while ( 1 ) | |
325 { | |
326 _column = 0; | |
327 if ( texture_cell_width > 0 ) | |
328 { | |
329 while ( pChests[uChestID].pInventoryIndices[test_cell_position + _cell_rows+_column]==0) | |
330 { | |
331 ++_column; | |
332 if ( _column >= texture_cell_width ) | |
333 break; | |
334 } | |
335 if (pChests[uChestID].pInventoryIndices[test_cell_position + _cell_rows+_column]!=0) | |
336 return false; | |
337 } | |
338 _cell_rows += chest_cell_width; | |
339 ++_row; | |
340 if ( _row >= texture_cell_height ) | |
341 return true; | |
342 } | |
343 | |
344 } | |
345 return false; | |
346 } | |
347 // 506128: using guessed type int areWeLoadingTexture; | |
348 | |
349 //----- (0041FF64) -------------------------------------------------------- | |
350 int Chest::CountChestItems(signed int uChestID) | |
351 { | |
352 signed int item_count; // eax@1 | |
353 int max_items; // edx@1 | |
354 item_count = 0; | |
355 max_items = pChestWidthsByType[pChests[uChestID].uChestBitmapID] * pChestHeightsByType[pChests[uChestID].uChestBitmapID]; | |
356 if ( max_items <= 0 ) | |
357 item_count = -1; | |
358 else | |
359 { | |
360 while ( pChests[uChestID].igChestItems[item_count].uItemID ) | |
361 { | |
362 ++item_count; | |
363 if ( item_count >= max_items ) | |
364 { | |
365 item_count = -1; | |
366 break; | |
367 } | |
368 } | |
369 } | |
370 return item_count; | |
371 } | |
372 | |
373 //----- (0041FFA2) -------------------------------------------------------- | |
374 int Chest::PutItemInChest(int position, ItemGen *put_item, signed int uChestID) | |
375 {//(rus: положить предмет в ящик) | |
376 ItemGen *v4; // edi@1 | |
377 int v5; // esi@1 | |
378 int result; // eax@11 | |
379 unsigned int v7; // eax@12 | |
380 int v8; // edx@12 | |
381 Texture *texture; // ecx@12 | |
382 signed int v10; // eax@12 | |
383 signed int v11; // edi@14 | |
384 unsigned int v12; // esi@14 | |
385 int v13; // edi@16 | |
386 void *v14; // edi@21 | |
387 int v15; // edi@21 | |
388 int i; // ecx@21 | |
389 ItemGen *Src; // [sp+Ch] [bp-18h]@1 | |
390 signed int item_in_chest_count; // [sp+10h] [bp-14h]@2 | |
391 int v19; // [sp+14h] [bp-10h]@1 | |
392 int v20; // [sp+18h] [bp-Ch]@19 | |
393 signed int v21; // [sp+1Ch] [bp-8h]@1 | |
394 // signed int v22; // [sp+20h] [bp-4h]@3 | |
395 int v23; // [sp+20h] [bp-4h]@19 | |
396 | |
397 v21 = 0; | |
398 v4 = put_item; | |
399 v5 = pChestWidthsByType[pChests[uChestID].uChestBitmapID] * pChestHeightsByType[pChests[uChestID].uChestBitmapID]; | |
400 Src = put_item; | |
401 v19 = pChestWidthsByType[pChests[uChestID].uChestBitmapID]; | |
402 if ( position == -1 ) | |
403 { | |
404 item_in_chest_count = CountChestItems(uChestID); | |
405 if ( item_in_chest_count == -1 ) | |
406 return 0; | |
407 for( int _i = 0; _i < v5; _i++) | |
408 { | |
409 if ( Chest::CanPlaceItemAt(_i, v4->uItemID, pChestWindow->par1C) ) | |
410 v21 = _i; | |
411 } | |
412 if ( v21 == v5 ) | |
413 { | |
414 if ( uActiveCharacter ) | |
415 pPlayers[uActiveCharacter]->PlaySound(SPEECH_NoRoom, 0); | |
416 return 0; | |
417 } | |
418 v7 = pIcons_LOD->LoadTexture(v4->GetIconName(), TEXTURE_16BIT_PALETTE); | |
419 HIWORD(v8) = 0; | |
420 texture = pIcons_LOD->GetTexture(v7); | |
421 v10 = texture->uTextureWidth; | |
422 if ( texture->uTextureWidth < 14 ) | |
423 v10 = 14; | |
424 v12 = ((v10 - 14) >> 5) + 1; | |
425 v11 = texture->uTextureHeight; | |
426 if ( texture->uTextureHeight < 14 ) | |
427 v11 = 14; | |
428 v13 = ((v11 - 14) >> 5) + 1; | |
429 if ( !areWeLoadingTexture ) | |
430 { | |
431 texture->Release(); | |
432 pIcons_LOD->SyncLoadedFilesCount(); | |
433 } | |
434 if ( v13 > 0 ) | |
435 { | |
436 v23 = 0; | |
437 v20 = v13; | |
438 do | |
439 { | |
440 if ( (signed int)v12 > 0 ) | |
441 { | |
442 v14 = &pChests[uChestID].pInventoryIndices[v21 + v23]; | |
443 LOWORD(v8) = -1 - v21; | |
444 v8 <<= 16; | |
445 LOWORD(v8) = -1 - v21; | |
446 memset32(v14, v8, v12 >> 1); | |
447 v15 = (int)((char *)v14 + 4 * (v12 >> 1)); | |
448 for ( i = v12 & 1; i; --i ) | |
449 { | |
450 *(short *)v15 = v8; | |
451 v15 += 2; | |
452 } | |
453 } | |
454 v23 += v19; | |
455 --v20; | |
456 } | |
457 while ( v20 ); | |
458 } | |
459 pChests[uChestID].pInventoryIndices[v21] = item_in_chest_count + 1; | |
460 memcpy(&pChests[uChestID].igChestItems[item_in_chest_count], put_item, sizeof(ItemGen)); | |
461 result = v21 + 1; | |
462 } | |
463 else | |
464 result = 1; | |
465 return result; | |
466 } | |
467 // 506128: using guessed type int areWeLoadingTexture; | |
468 | |
469 //----- (0042013E) -------------------------------------------------------- | |
470 void Chest::PlaceItemAt( unsigned int put_cell_pos, unsigned int item_at_cell, signed int uChestID ) | |
471 { | |
472 int uItemID; // edi@1 | |
473 int v6; // edx@4 | |
474 unsigned int v7; // eax@5 | |
475 Texture *texture; // ecx@5 | |
476 signed int v9; // eax@5 | |
477 signed int v10; // edi@7 | |
478 unsigned int texture_cell_width; // ebx@7 | |
479 int textute_cell_height; // edi@9 | |
480 int chest_cell_row_pos; // edx@12 | |
481 int chest_cell_width; // [sp+10h] [bp-Ch]@11 | |
482 | |
483 uItemID = pChests[ uChestID].igChestItems[item_at_cell].uItemID; | |
484 pItemsTable->SetSpecialBonus(&pChests[ uChestID].igChestItems[item_at_cell]); | |
485 if ( uItemID >= 135 && uItemID <= 159 && !pChests[ uChestID].igChestItems[item_at_cell].uNumCharges) | |
486 { | |
487 v6 = rand() % 21 + 10; | |
488 pChests[ uChestID].igChestItems[item_at_cell].uNumCharges = v6; | |
489 pChests[ uChestID].igChestItems[item_at_cell].uMaxCharges = v6; | |
490 } | |
491 v7 = pIcons_LOD->LoadTexture(pItemsTable->pItems[uItemID].pIconName, TEXTURE_16BIT_PALETTE); | |
492 texture = pIcons_LOD->GetTexture(v7); | |
493 v9 = texture->uTextureWidth; | |
494 if ( texture->uTextureWidth < 14 ) | |
495 v9 = 14; | |
496 texture_cell_width = ((v9 - 14) >> 5) + 1; | |
497 v10 = texture->uTextureHeight; | |
498 if ( texture->uTextureHeight < 14 ) | |
499 v10 = 14; | |
500 textute_cell_height = ((v10 - 14) >> 5) + 1; | |
501 if ( !areWeLoadingTexture ) | |
502 { | |
503 texture->Release(); | |
504 pIcons_LOD->SyncLoadedFilesCount(); | |
505 } | |
506 chest_cell_width = pChestWidthsByType[pChests[ uChestID].uChestBitmapID]; | |
507 chest_cell_row_pos = 0; | |
508 for(int i = 0; i < textute_cell_height; ++i) | |
509 { | |
510 for (int j = 0; j < texture_cell_width; ++j) | |
511 pChests[uChestID].pInventoryIndices[put_cell_pos + chest_cell_row_pos+j]=(signed __int16)-(put_cell_pos+1); | |
512 chest_cell_row_pos += chest_cell_width; | |
513 } | |
514 pChests[uChestID].pInventoryIndices[put_cell_pos] = item_at_cell + 1; | |
515 } | |
516 // 506128: using guessed type int areWeLoadingTexture; | |
517 | |
518 //----- (00420284) -------------------------------------------------------- | |
519 void Chest::PlaceItems(signed int uChestID ) | |
520 { | |
521 int uChestArea; // edi@1 | |
522 int random_chest_pos; // eax@2 | |
523 int test_position; // ebx@11 | |
524 char chest_cells_map[144]; // [sp+Ch] [bp-A0h]@1 | |
525 int chest_item_id; // [sp+9Ch] [bp-10h]@10 | |
526 unsigned int items_counter; // [sp+A4h] [bp-8h]@8 | |
527 | |
528 pRenderer->ClearZBuffer(0, 479); | |
529 uChestArea = pChestWidthsByType[pChests[uChestID].uChestBitmapID] * pChestHeightsByType[pChests[uChestID].uChestBitmapID]; | |
530 memset(chest_cells_map, 0, 144); | |
531 //fill cell map at random positions | |
532 for ( items_counter = 0; items_counter < uChestArea; ++items_counter ) | |
533 { | |
534 //get random position in chest | |
535 do | |
536 random_chest_pos = (unsigned __int8)rand(); | |
537 while ( random_chest_pos >= uChestArea ); | |
538 //if this pos occupied move to next | |
539 while ( chest_cells_map[random_chest_pos] ) | |
540 { | |
541 ++random_chest_pos; | |
542 if ( random_chest_pos == uChestArea ) | |
543 random_chest_pos = 0; | |
544 } | |
545 chest_cells_map[random_chest_pos] = items_counter; | |
546 } | |
547 items_counter = 0; | |
548 | |
549 for (items_counter = 0; items_counter<uChestArea; ++items_counter) | |
550 { | |
551 chest_item_id = pChests[uChestID].igChestItems[items_counter].uItemID; | |
552 if ( chest_item_id ) | |
553 { | |
554 test_position = 0; | |
555 while ( !Chest::CanPlaceItemAt((unsigned __int8)chest_cells_map[test_position], chest_item_id, uChestID) ) | |
556 { | |
557 ++test_position; | |
558 if ( test_position >= uChestArea ) | |
559 break; | |
560 } | |
561 if(test_position<uChestArea) | |
562 { | |
563 Chest::PlaceItemAt((unsigned __int8)chest_cells_map[test_position], items_counter, uChestID); | |
564 if ( pChests[uChestID].uFlags & CHEST_OPENED) | |
565 pChests[uChestID].igChestItems[items_counter].SetIdentified(); | |
566 } | |
567 } | |
568 } | |
569 pChests[uChestID].SetInitialized(true); | |
570 } | |
571 // 420284: using guessed type char Dst[144]; | |
572 | |
573 //----- (00448A17) -------------------------------------------------------- | |
574 void Chest::ToggleFlag(signed int uChestID, unsigned __int16 uFlag, unsigned int bToggle) | |
575 { | |
576 if ( uChestID >= 0 && uChestID <= 19 ) | |
577 { | |
578 if ( bToggle ) | |
579 pChests[uChestID].uFlags |= uFlag; | |
580 else | |
581 pChests[uChestID].uFlags &= ~uFlag; | |
582 } | |
583 } | |
584 | |
585 //----- (00458B03) -------------------------------------------------------- | |
586 void ChestList::ToFile() | |
587 { | |
588 FILE *v2; // eax@1 | |
589 FILE *v3; // edi@1 | |
590 | |
591 v2 = fopen("data\\dchest.bin", "wb"); | |
592 v3 = v2; | |
593 if ( !v2 ) | |
594 Error("Unable to save dchest.bin!"); | |
595 | |
596 fwrite(this, 4, 1, v2); | |
597 fwrite(this->pChests, 36, this->uNumChests, v3); | |
598 fclose(v3); | |
599 } | |
600 | |
601 | |
602 //----- (00458B4F) -------------------------------------------------------- | |
603 void ChestList::FromFile(void *data_mm6, void *data_mm7, void *data_mm8) | |
604 { | |
605 uint num_mm6_chests = data_mm6 ? *(int *)data_mm6 : 0, | |
606 num_mm7_chests = data_mm7 ? *(int *)data_mm7 : 0, | |
607 num_mm8_chests = data_mm8 ? *(int *)data_mm8 : 0; | |
608 | |
609 uNumChests = num_mm6_chests + num_mm7_chests + num_mm8_chests; | |
610 assert(uNumChests); | |
611 assert(!num_mm8_chests); | |
612 | |
613 pChests = (ChestDesc *)malloc(uNumChests * sizeof(ChestDesc)); | |
614 memcpy(pChests, (char *)data_mm7 + 4, num_mm7_chests * sizeof(ChestDesc)); | |
615 memcpy(pChests + num_mm7_chests, (char *)data_mm6 + 4, num_mm6_chests * sizeof(ChestDesc)); | |
616 memcpy(pChests + num_mm6_chests + num_mm7_chests, (char *)data_mm8 + 4, num_mm8_chests * sizeof(ChestDesc)); | |
617 } | |
618 | |
619 | |
620 //----- (00458B9C) -------------------------------------------------------- | |
621 int ChestList::FromFileTxt(const char *Args) | |
622 { | |
623 //ChestList *v2; // ebx@1 | |
624 __int32 v3; // edi@1 | |
625 FILE *v4; // eax@1 | |
626 unsigned int v5; // esi@3 | |
627 const void *v6; // ST18_4@9 | |
628 void *v7; // eax@9 | |
629 FILE *v8; // ST0C_4@11 | |
630 char *i; // eax@11 | |
631 char v10; // al@14 | |
632 const char *v11; // ST14_4@14 | |
633 char v12; // al@14 | |
634 const char *v13; // ST10_4@14 | |
635 char Buf; // [sp+8h] [bp-2F0h]@3 | |
636 FrameTableTxtLine v16; // [sp+1FCh] [bp-FCh]@4 | |
637 FrameTableTxtLine v17; // [sp+278h] [bp-80h]@4 | |
638 FILE *File; // [sp+2F4h] [bp-4h]@1 | |
639 unsigned int Argsa; // [sp+300h] [bp+8h]@3 | |
640 | |
641 //v2 = this; | |
642 free(this->pChests); | |
643 v3 = 0; | |
644 this->pChests = 0; | |
645 this->uNumChests = 0; | |
646 v4 = fopen(Args, "r"); | |
647 File = v4; | |
648 if ( !v4 ) | |
649 Error("ChestDescriptionList::load - Unable to open file: %s."); | |
650 | |
651 v5 = 0; | |
652 Argsa = 0; | |
653 if ( fgets(&Buf, 490, v4) ) | |
654 { | |
655 do | |
656 { | |
657 *strchr(&Buf, 10) = 0; | |
658 memcpy(&v17, txt_file_frametable_parser(&Buf, &v16), sizeof(v17)); | |
659 if ( v17.uPropCount && *v17.pProperties[0] != 47 ) | |
660 ++Argsa; | |
661 } | |
662 while ( fgets(&Buf, 490, File) ); | |
663 v5 = Argsa; | |
664 v3 = 0; | |
665 } | |
666 v6 = this->pChests; | |
667 this->uNumChests = v5; | |
668 v7 = malloc(36 * v5); | |
669 this->pChests = (ChestDesc *)v7; | |
670 if ( v7 == (void *)v3 ) | |
671 Error("ChestDescriptionList::load - Out of Memory!"); | |
672 | |
673 memset(v7, v3, 36 * this->uNumChests); | |
674 v8 = File; | |
675 this->uNumChests = v3; | |
676 fseek(v8, v3, v3); | |
677 for ( i = fgets(&Buf, 490, File); i; i = fgets(&Buf, 490, File) ) | |
678 { | |
679 *strchr(&Buf, 10) = 0; | |
680 memcpy(&v17, txt_file_frametable_parser(&Buf, &v16), sizeof(v17)); | |
681 if ( v17.uPropCount && *v17.pProperties[0] != 47 ) | |
682 { | |
683 strcpy(this->pChests[this->uNumChests].pName, v17.pProperties[0]); | |
684 v10 = atoi(v17.pProperties[1]); | |
685 v11 = v17.pProperties[2]; | |
686 this->pChests[this->uNumChests].uWidth = v10; | |
687 v12 = atoi(v11); | |
688 v13 = v17.pProperties[3]; | |
689 this->pChests[this->uNumChests].uHeight = v12; | |
690 this->pChests[this->uNumChests++].uTextureID = atoi(v13); | |
691 } | |
692 } | |
693 fclose(File); | |
694 return 1; | |
695 } | |
696 | |
697 //----- (00420B13) -------------------------------------------------------- | |
698 void __fastcall sub_420B13(int a1, int a2) | |
699 { //Give item from chest(rus: Взять предмет из ящика) | |
700 void *v2; // eax@1 | |
701 unsigned int v4; // eax@1 | |
702 Texture *texture; // ecx@1 | |
703 signed int v6; // eax@1 | |
704 signed int v7; // edi@3 | |
705 signed int v8; // eax@3 | |
706 int v9; // edi@3 | |
707 int v10; // eax@5 | |
708 int v11; // esi@8 | |
709 unsigned int v12; // ecx@10 | |
710 void *v13; // edi@10 | |
711 unsigned __int8 v14; // cf@10 | |
712 int v15; // edi@10 | |
713 int i; // ecx@10 | |
714 int v17; // [sp+Ch] [bp-14h]@1 | |
715 int v18; // [sp+10h] [bp-10h]@3 | |
716 int v21; // [sp+1Ch] [bp-4h]@5 | |
717 int v22; // [sp+1Ch] [bp-4h]@8 | |
718 | |
719 v2 = (void *)(5324 * (int)pChestWindow->ptr_1C); | |
720 v17 = pChestWidthsByType[pChests[(int)pChestWindow->ptr_1C].uChestBitmapID]; | |
721 v4 = pIcons_LOD->LoadTexture(pChests[(int)pChestWindow->ptr_1C].igChestItems[a1].GetIconName(), TEXTURE_16BIT_PALETTE); | |
722 texture = pIcons_LOD->GetTexture(v4); | |
723 | |
724 v6 = texture->uTextureWidth; | |
725 if ( texture->uTextureWidth < 14 ) | |
726 v6 = 14; | |
727 v7 = v6 - 14; | |
728 v9 = (v7 >> 5) + 1; | |
729 v18 = v9; | |
730 | |
731 v8 = texture->uTextureHeight; | |
732 if ( texture->uTextureHeight < 14 ) | |
733 v8 = 14; | |
734 v10 = ((v8 - 14) >> 5) + 1; | |
735 v21 = v10; | |
736 | |
737 if ( !areWeLoadingTexture ) | |
738 { | |
739 texture->Release(); | |
740 pIcons_LOD->SyncLoadedFilesCount(); | |
741 v10 = v21; | |
742 } | |
743 if ( v10 > 0 ) | |
744 { | |
745 v11 = 0; | |
746 for ( v22 = v10; v22; --v22 ) | |
747 { | |
748 if ( v9 > 0 ) | |
749 { | |
750 v12 = v9; | |
751 v13 = &pChests[(int)pChestWindow->ptr_1C].pInventoryIndices[a2 + v11]; | |
752 v14 = v12 & 1; | |
753 v12 >>= 1; | |
754 memset(&pChests[(int)pChestWindow->ptr_1C].pInventoryIndices[a2 + v11], 0, 4 * v12); | |
755 v15 = (int)((char *)v13 + 4 * v12); | |
756 for ( i = v14; i; --i ) | |
757 { | |
758 *(short *)v15 = 0; | |
759 v15 += 2; | |
760 } | |
761 v9 = v18; | |
762 } | |
763 v11 += v17; | |
764 } | |
765 } | |
766 pChests[(int)pChestWindow->ptr_1C].igChestItems[a1].Reset(); | |
767 } | |
768 // 506128: using guessed type int areWeLoadingTexture; | |
769 //----- (00420E01) -------------------------------------------------------- | |
770 void Chest::OnChestLeftClick() | |
771 { | |
772 int v2; // eax@2 | |
773 int v3; // ebx@4 | |
774 int v4; // esi@6 | |
775 POINT cursor; // [sp+84h] [bp-8h]@2 | |
776 | |
777 SpriteObject v6; // [sp+Ch] [bp-80h]@1 | |
778 if ( pParty->pPickedItem.uItemID ) | |
779 { | |
780 if ( Chest::PutItemInChest(-1, &pParty->pPickedItem, pGUIWindow_CurrentMenu->par1C) ) | |
781 pMouse->RemoveHoldingItem(); | |
782 } | |
783 else | |
784 { | |
785 pMouse->GetCursorPos(&cursor); | |
786 v2 = pRenderer->pActiveZBuffer[cursor.x + pSRZBufferLineOffsets[cursor.y]] & 0xFFFF; | |
787 if ( v2 ) | |
788 { | |
789 if ( v2 ) | |
790 v3 = v2 - 1; | |
791 else | |
792 v3 = -1; | |
793 v4 = pChests[(int)pGUIWindow_CurrentMenu->par1C].pInventoryIndices[v3] - 1; | |
794 if ( pChests[(int)pGUIWindow_CurrentMenu->par1C].igChestItems[v4].GetItemEquipType() == EQUIP_GOLD ) | |
795 { | |
796 pParty->PartyFindsGold(pChests[(int)pGUIWindow_CurrentMenu->par1C].igChestItems[v4].uSpecEnchantmentType, 0); | |
797 viewparams->bRedrawGameUI = 1; | |
798 } | |
799 else | |
800 pParty->SetHoldingItem(&pChests[(int)pGUIWindow_CurrentMenu->par1C].igChestItems[v4]); | |
801 sub_420B13(v4, v3); | |
802 } | |
803 } | |
804 } |