comparison Outdoor.cpp @ 1295:86a83e12d795

moving files
author Ritor1
date Mon, 17 Jun 2013 17:34:01 +0600
parents 1803172dffd9
children 5450af4f57ef
comparison
equal deleted inserted replaced
1294:6bbd50bda571 1295:86a83e12d795
3168 if ( (end_evt->_e_type != EVENT_Exit) || (start_evt->_e_type!= EVENT_MouseOver) ) 3168 if ( (end_evt->_e_type != EVENT_Exit) || (start_evt->_e_type!= EVENT_MouseOver) )
3169 return false; 3169 return false;
3170 else 3170 else
3171 return true; 3171 return true;
3172 } 3172 }
3173 //----- (0046D49E) --------------------------------------------------------
3174 int __fastcall ODM_GetFloorLevel(int X, signed int Y, int Z, int __unused, int *pIsOnWater, int *a6, int bWaterWalk)
3175 {
3176 BSPModel *pBModel; // esi@4
3177 ODMFace *pFace; // ecx@11
3178 int v14; // edx@20
3179 signed int v18; // edx@26
3180 int v19; // eax@28
3181 int v20; // edx@30
3182 int v21; // ST1C_4@30
3183 signed int v22; // edx@30
3184 signed __int64 v23; // qtt@30
3185 int v24; // eax@36
3186 signed int v25; // ecx@38
3187 int result; // eax@42
3188 signed int v27; // ecx@43
3189 int v28; // edi@44
3190 signed int v29; // edx@44
3191 int v30; // esi@45
3192 int v31; // eax@45
3193 ODMFace *v32; // eax@57
3194 int v33; // ecx@59
3195 int v36; // [sp+14h] [bp-2Ch]@24
3196 int v38; // [sp+1Ch] [bp-24h]@2
3197 int v39; // [sp+20h] [bp-20h]@9
3198 signed int pBModelNum; // [sp+28h] [bp-18h]@1
3199 int pFaceNum; // [sp+2Ch] [bp-14h]@8
3200 bool v43; // [sp+30h] [bp-10h]@22
3201 bool v44; // [sp+34h] [bp-Ch]@24
3202 signed int v46; // [sp+3Ch] [bp-4h]@1
3203 signed int v48; // [sp+58h] [bp+18h]@22
3204 signed int v49; // [sp+58h] [bp+18h]@43
3205
3206 v46 = 1;
3207 dword_721160[0] = -1;
3208 dword_721110[0] = -1;
3209 odm_floor_level[0] = GetTerrainHeightsAroundParty2(X, Y, pIsOnWater, bWaterWalk);
3210
3211 for ( pBModelNum = 0; pBModelNum < pOutdoor->uNumBModels; ++pBModelNum )
3212 {
3213 pBModel = &pOutdoor->pBModels[pBModelNum];
3214 if ( X <= pBModel->sMaxX && X >= pBModel->sMinX &&
3215 Y <= pBModel->sMaxY && Y >= pBModel->sMinY )
3216 {
3217 if ( pBModel->uNumFaces > 0 )
3218 {
3219 v39 = 0;
3220 for ( pFaceNum = 0; pFaceNum < pBModel->uNumFaces; ++pFaceNum )
3221 {
3222 pFace = &pBModel->pFaces[pFaceNum];
3223 if ( (pFace->uPolygonType == POLYGON_Floor || pFace->uPolygonType == POLYGON_InBetweenFloorAndWall)
3224 && !(pFace->uAttributes & 0x20000000)
3225 && X <= pFace->pBoundingBox.x2 && X >= pFace->pBoundingBox.x1
3226 && Y <= pFace->pBoundingBox.y2 && Y >= pFace->pBoundingBox.y1 )
3227 {
3228
3229 for ( uint i = 0; i < pFace->uNumVertices; ++i)
3230 {
3231 word_721040[2 * i] = pFace->pXInterceptDisplacements[i] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i]].x;
3232 word_720F70[2 * i] = pFace->pXInterceptDisplacements[i + 1] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i]].y;
3233 word_721040[2 * i + 1] = pFace->pXInterceptDisplacements[i] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i + 1]].x;
3234 word_720F70[2 * i + 1] = pFace->pXInterceptDisplacements[i + 1] + pBModel->pVertices.pVertices[pFace->pVertexIDs[i + 1]].y;
3235 }
3236 word_721040[2 * pFace->uNumVertices] = word_721040[0];
3237 word_720F70[2 * pFace->uNumVertices] = word_720F70[0];
3238 v43 = word_720F70[0] >= Y;
3239 v48 = 0;
3240 if ( 2 * pFace->uNumVertices > 0 )
3241 {
3242 for ( int i = 0; i < 2 * pFace->uNumVertices; ++i )
3243 {
3244 if ( v48 >= 2 )
3245 break;
3246 v36 = word_720F70[i + 1];
3247 v44 = word_720F70[i + 1] >= Y;
3248 if ( v43 != v44 )
3249 {
3250 v18 = word_721040[i + 1] >= X ? 0 : 2;
3251 v19 = v18 | (word_721040[i] < X);
3252 if ( v19 != 3 )
3253 {
3254 if ( !v19 )
3255 ++v48;
3256 else
3257 {
3258 LODWORD(v23) = (Y - word_720F70[i]) << 16;
3259 HIDWORD(v23) = (Y - word_720F70[i]) >> 16;
3260 v22 = ((((word_721040[i + 1] - word_721040[i]) * v23 / (v36 - word_720F70[i])) >> 16) + word_721040[i]);
3261 if ( v22 >= X)
3262 ++v48;
3263 }
3264 }
3265 }
3266 v43 = v44;
3267 }
3268 if ( v48 == 1 )
3269 {
3270 if ( v46 >= 20 )
3271 break;
3272 if ( pFace->uPolygonType == POLYGON_Floor )
3273 v24 = pBModel->pVertices.pVertices[pFace->pVertexIDs[0]].z;
3274 else
3275 v24 = ((unsigned __int64)(pFace->zCalc1 * (signed __int64)X) >> 16) + ((unsigned __int64)(pFace->zCalc2 * (signed __int64)Y) >> 16)
3276 + HIWORD(pFace->zCalc3);
3277 v25 = v46++;
3278 odm_floor_level[v25] = v24;
3279 dword_721160[v25] = pBModelNum;
3280 dword_721110[v25] = pFaceNum;
3281 }
3282 }
3283 }
3284
3285 }
3286 }
3287 }
3288 }
3289 if ( v46 == 1 )
3290 {
3291 *a6 = 0;
3292 return odm_floor_level[0];
3293 }
3294 v27 = 0;
3295 if ( v46 <= 1 )
3296 *a6 = 0;
3297 else
3298 {
3299 //v29 = 1;
3300 for ( v49 = 1; v49 < v46; ++v49 )
3301 {
3302 if ( odm_floor_level[v49] == odm_floor_level[0] )
3303 {
3304 v27 = v49;
3305 //++v29;
3306 break;
3307 }
3308 if ( odm_floor_level[0] > Z + 5 )
3309 {
3310 if ( odm_floor_level[v49] >= odm_floor_level[0] )
3311 {
3312 //++v29;
3313 break;
3314 }
3315 v27 = v49;
3316 //++v29;
3317 break;
3318 }
3319 if ( odm_floor_level[v49] > odm_floor_level[0] && odm_floor_level[v49] <= Z + 5 )
3320 {
3321 v27 = v49;
3322 //++v29;
3323 }
3324 }
3325 if ( !v27 )
3326 *a6 = 0;
3327 else
3328 *a6 = dword_721110[v27] | (dword_721160[v27] << 6);
3329 }
3330 if ( v27 )
3331 {
3332 v32 = &pOutdoor->pBModels[dword_721160[v27]].pFaces[dword_721110[v27]];
3333 *pIsOnWater = false;
3334 if ( v32->Fluid())
3335 *pIsOnWater = true;
3336 }
3337 if ( odm_floor_level[v27] >= odm_floor_level[0] )
3338 odm_floor_level[0] = odm_floor_level[v27];
3339 return odm_floor_level[0];
3340 }
3341 //not sure if right- or left-handed coordinate space assumed, so this could be normal of inverse normal
3342 // for a right-handed system, that would be an inverse normal
3343 //----- (0046DCC8) --------------------------------------------------------
3344 void ODM_GetTerrainNormalAt(int pos_x, int pos_z, Vec3_int_ *out)
3345 {
3346 auto grid_x = WorldPosToGridCellX(pos_x);
3347 auto grid_z = WorldPosToGridCellZ(pos_z) - 1;
3348
3349 auto grid_pos_x1 = GridCellToWorldPosX(grid_x);
3350 auto grid_pos_x2 = GridCellToWorldPosX(grid_x + 1);
3351 auto grid_pos_z1 = GridCellToWorldPosZ(grid_z);
3352 auto grid_pos_z2 = GridCellToWorldPosZ(grid_z + 1);
3353
3354 auto x1z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z);
3355 auto x2z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z);
3356 auto x2z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1);
3357 auto x1z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1);
3358
3359 float side1_dx, side1_dy, side1_dz,
3360 side2_dx, side2_dy, side2_dz;
3361
3362 auto dx = abs(pos_x - grid_pos_x1),
3363 dz = abs(grid_pos_z1 - pos_z);
3364 if (dz >= dx)
3365 {
3366 side1_dy = (double)(x1z1_y - x1z2_y);
3367 side2_dy = (double)(x2z2_y - x1z2_y);
3368 side2_dx = (double)(grid_pos_x2 - grid_pos_x1);
3369 side1_dx = (double)(grid_pos_x1 - grid_pos_x2);
3370 side2_dz = 0.0;//(double)(grid_pos_z2 - grid_pos_z2); // bug? z2 - z2
3371 side1_dz = (double)(grid_pos_z1 - grid_pos_z2); // z1 - z2 yes
3372 //Log::Warning(L"%S %S %u\n", __FILE__, __FUNCTION__, __LINE__);
3373 /* |\
3374 side1 | \
3375 |____\
3376 side 2 */
3377 }
3378 else
3379 {
3380 side1_dy = (double)(x2z2_y - x2z1_y);
3381 side2_dy = (double)(x1z1_y - x2z1_y);
3382 side2_dx = (double)(grid_pos_x1 - grid_pos_x2);
3383 side1_dx = (double)(grid_pos_x2 - grid_pos_x1);
3384 side2_dz = 0.0;//(double)(grid_pos_z1 - grid_pos_z1);
3385 side1_dz = (double)(grid_pos_z2 - grid_pos_z1);
3386
3387 /* side 2
3388 _____
3389 \ |
3390 \ | side 1
3391 \| */
3392 }
3393
3394 float nx = side1_dy * side2_dz - side1_dz * side2_dy;
3395 float ny = side1_dx * side2_dy - side1_dy * side2_dx;
3396 float nz = side1_dz * side2_dx - side1_dx * side2_dz;
3397
3398 float mag = sqrt(nx * nx + ny * ny + nz * nz);
3399 if (fabsf(mag) < 1e-6f)
3400 {
3401 out->y = 0;
3402 out->x = 0;
3403 out->z = 65536;
3404 }
3405 else
3406 {
3407 float invmag = 1.0 / mag;
3408 out->x = invmag * nx * 65536.0;
3409 out->y = invmag * ny * 65536.0;
3410 out->z = invmag * nz * 65536.0;
3411 }
3412 }
3413 //----- (004014E6) --------------------------------------------------------
3414 void MakeActorAIList_ODM()
3415 {
3416 int v1; // eax@4
3417 int v2; // ebx@4
3418 unsigned int v3; // ecx@4
3419 int v4; // edx@5
3420 int v5; // edx@7
3421 unsigned int v6; // edx@9
3422 unsigned int v7; // ST20_4@10
3423 int v9; // edi@10
3424 int v10; // ebx@14
3425 int v21; // [sp+Ch] [bp-14h]@4
3426 int v22; // [sp+10h] [bp-10h]@4
3427
3428 pParty->uFlags &= 0xFFFFFFCFu;
3429
3430 ai_arrays_size = 0;
3431 for (uint i = 0; i < uNumActors; ++i)
3432 {
3433 auto actor = &pActors[i];
3434
3435 actor->uAttributes &= 0xFFFFFBFF;
3436 if (!actor->CanAct())
3437 {
3438 actor->uAttributes &= 0xFFFFBFFF;
3439 continue;
3440 }
3441
3442 v22 = abs(pParty->vPosition.z - actor->vPosition.z);
3443 v21 = abs(pParty->vPosition.y - actor->vPosition.y);
3444 v1 = abs(pParty->vPosition.x - actor->vPosition.x);
3445 v2 = v21;
3446 v3 = v22;
3447 if ( v1 < v21 )
3448 {
3449 v4 = v1;
3450 v1 = v21;
3451 v2 = v4;
3452 }
3453 if ( v1 < v22 )
3454 {
3455 v5 = v1;
3456 v1 = v22;
3457 v3 = v5;
3458 }
3459 if ( v2 < (signed int)v3 )
3460 {
3461 v6 = v3;
3462 v3 = v2;
3463 v2 = v6;
3464 }
3465 v7 = ((unsigned int)(11 * v2) >> 5) + (v3 >> 2) + v1;
3466 //v8 = actor->uActorRadius;
3467 v9 = v7 - actor->uActorRadius;
3468 //v23 = v7 - v8;
3469 if ( v9 < 0 )
3470 {
3471 v9 = 0;
3472 //v23 = 0;
3473 }
3474
3475 if (v9 < 5632)
3476 {
3477 v10 = actor->uAttributes & 0xFEFFFFFF;
3478 actor->uAttributes = v10;
3479 if ( v10 & 0x80000 || actor->GetActorsRelation(0) )
3480 {
3481 //v11 = (pParty->uFlags & 0x10) == 0;
3482 actor->uAttributes = v10 | 0x1000000;
3483 if (v9 < 5120 )
3484 pParty->SetYellowAlert();
3485 if (v9 < 307)
3486 pParty->SetRedAlert();
3487 }
3488 actor->uAttributes |= 0x00004000;
3489 ai_near_actors_distances[ai_arrays_size] = v9;
3490 ai_near_actors_ids[ai_arrays_size++] = i;
3491 }
3492 else
3493 actor->uAttributes &= 0xFFFFBFFF;
3494 }
3495
3496 /*
3497 result = v27;
3498 if ( v27 > 0 )
3499 {
3500 v14 = 0;
3501 v15 = 1;
3502 v26 = 1;
3503 do
3504 {
3505 while ( 1 )
3506 {
3507 v24 = v15;
3508 if ( v15 >= result )
3509 break;
3510 v16 = ai_near_actors_distances[v14];
3511 if ( v16 > ai_near_actors_distances[v15] )
3512 {
3513 v17 = &ai_near_actors_ids[v15];
3514 v18 = ai_near_actors_ids[v14];
3515 ai_near_actors_ids[v14] = *v17;
3516 *v17 = v18;
3517 v15 = v24;
3518 ai_near_actors_distances[v14] = ai_near_actors_distances[v24];
3519 ai_near_actors_distances[v24] = v16;
3520 }
3521 result = v27;
3522 ++v15;
3523 }
3524 ++v14;
3525 v15 = v26 + 1;
3526 v26 = v15;
3527 }
3528 while ( v15 - 1 < result );
3529 }*/
3530
3531 for (uint i = 0; i < ai_arrays_size; ++i)
3532 for (uint j = 0; j < i; ++j)
3533 if (ai_near_actors_distances[j] > ai_near_actors_distances[i])
3534 {
3535 int tmp = ai_near_actors_distances[j];
3536 ai_near_actors_distances[j] = ai_near_actors_distances[i];
3537 ai_near_actors_distances[i] = tmp;
3538
3539 tmp = ai_near_actors_ids[j];
3540 ai_near_actors_ids[j] = ai_near_actors_ids[i];
3541 ai_near_actors_ids[i] = tmp;
3542 }
3543
3544
3545 if (ai_arrays_size > 30)
3546 ai_arrays_size = 30;
3547
3548 for (uint i = 0; i < ai_arrays_size; ++i)
3549 pActors[ai_near_actors_ids[i]].uAttributes |= 0x0400;
3550 }