Mercurial > mm7
changeset 138:a8ec7e1e18b6
Sliding downhill & relative subs.
how it's done: each time you get a little bit pushed in the air along terrain normal,
and then falling to the gravity, gradually sliding downwards. nice trick
author | Nomad |
---|---|
date | Tue, 12 Feb 2013 00:22:30 +0200 |
parents | a2ddaf0e4d8a |
children | 7eeea515f5ff |
files | Outdoor.cpp mm7_3.cpp mm7_4.cpp mm7_data.cpp mm7_data.h |
diffstat | 5 files changed, 232 insertions(+), 246 deletions(-) [+] |
line wrap: on
line diff
--- a/Outdoor.cpp Mon Feb 11 20:27:00 2013 +0200 +++ b/Outdoor.cpp Tue Feb 12 00:22:30 2013 +0200 @@ -315,7 +315,7 @@ signed int v11; // eax@23 int v12; // ST14_4@25 signed int v14; // [sp-4h] [bp-84h]@6 - char Str; // [sp+8h] [bp-78h]@3 + char Str[140]; // [sp+8h] [bp-78h]@3 int a5a; // [sp+94h] [bp+14h]@3 auto Source = this; @@ -323,9 +323,9 @@ v5 = Source; if ( a5 < 10 || strlen(Source->pLevelFilename) != 9 - || (strcpy(&Str, v5->pLevelFilename), - _strlwr(&Str), - v6 = strtok(&Str, "out"), + || (strcpy(Str, v5->pLevelFilename), + _strlwr(Str), + v6 = strtok(Str, "out"), v6[2] = 0, v7 = atoi(v6), v8 = v7,
--- a/mm7_3.cpp Mon Feb 11 20:27:00 2013 +0200 +++ b/mm7_3.cpp Tue Feb 12 00:22:30 2013 +0200 @@ -995,7 +995,7 @@ v74 = v4; if ( !v0->CanAct() ) v74 = 0; - v70 = GetTerrainHeightsAroundParty(v0->vPosition.x, v0->vPosition.y); + v70 = IsTerrainSlopeTooHigh(v0->vPosition.x, v0->vPosition.y); v5 = sub_46D49E_prolly_get_world_y_under_party( v0->vPosition.x, v0->vPosition.y, @@ -1088,7 +1088,7 @@ v18 = v0->vPosition.y; v19 = v0->vPosition.x; v0->vPosition.z = v7; - _46DCC8_get_gravity_direction_outdoor(v19, v18, &v62); + ODM_GetTerrainNormalAt(v19, v18, &v62); v20 = GetGravityStrength(); v21 = v62.y; v22 = v62.z; @@ -1826,7 +1826,7 @@ v1 = &pLayingItems[uLayingItemID]; v58 = 0; v2 = &pObjectList->pObjects[v1->uObjectDescID]; - v57 = GetTerrainHeightsAroundParty(v1->vPosition.x, v1->vPosition.y); + v57 = IsTerrainSlopeTooHigh(v1->vPosition.x, v1->vPosition.y); v3 = v1->vPosition.y; v4 = v1->vPosition.x; v5 = v2->uHeight; @@ -1864,7 +1864,7 @@ v11 = v1->vPosition.y; v12 = v1->vPosition.x; v1->vPosition.z = v8; - _46DCC8_get_gravity_direction_outdoor(v12, v11, &v51); + ODM_GetTerrainNormalAt(v12, v11, &v51); v1->vVelocity.z -= LOWORD(pEventTimer->uTimeElapsed) * GetGravityStrength(); v56 = abs(v51.y * v1->vVelocity.y + v51.z * v1->vVelocity.z + v51.x * v1->vVelocity.x) >> 16; v60 = (Actor *)((unsigned __int64)(v56 * (signed __int64)v51.x) >> 16); @@ -2994,7 +2994,7 @@ //----- (00473893) -------------------------------------------------------- void __cdecl ODM_ProcessPartyActions() { - int _zero; // esi@1 + //int _zero; // esi@1 int v1; // edi@1 int v2; // ebx@1 int v3; // eax@14 @@ -3092,9 +3092,10 @@ int v95; // [sp-4h] [bp-98h]@104 int v96; // [sp-4h] [bp-98h]@246 int v97; // [sp+Ch] [bp-88h]@180 - int v98; // [sp+10h] [bp-84h]@147 - int v99; // [sp+14h] [bp-80h]@147 - int v100; // [sp+18h] [bp-7Ch]@147 + Vec3_int_ v98; + //int v98; // [sp+10h] [bp-84h]@147 + //int v99; // [sp+14h] [bp-80h]@147 + //int v100; // [sp+18h] [bp-7Ch]@147 bool v101; // [sp+1Ch] [bp-78h]@33 int v102; // [sp+20h] [bp-74h]@1 int v103; // [sp+24h] [bp-70h]@1 @@ -3128,7 +3129,6 @@ v121 = pParty->uFallSpeed; v123 = pParty->vPosition.z; - _zero = 0; v1 = 0; v103 = 0; v2 = 0; @@ -3137,7 +3137,7 @@ v117 = pParty->vPosition.y; v113 = pParty->field_6F0; bJumping = 0; - v118 = GetTerrainHeightsAroundParty(pParty->vPosition.x, pParty->vPosition.y); + auto partyAtHighSlope = IsTerrainSlopeTooHigh(pParty->vPosition.x, pParty->vPosition.y); v114 = 0; v124 = 0; v108 = 0; @@ -3205,35 +3205,34 @@ ++v4; } while ( (signed int)v4 <= (signed int)&pPlayers[4] ); - _zero = 0; } } v109 = -1; - if ( pParty->bFlying != _zero ) + if ( pParty->bFlying ) v109 = sub_46D8E3(v116, v117, v123 + pParty->uPartyHeight, (int)&v102); - v107 = v108 == _zero; + v107 = v108 == 0; v105 = v111 + 1; if ( v123 <= v111 + 1 ) { v109 = -1; - pParty->bFlying = _zero; + pParty->bFlying = false; } else { bJumping = 1; } v101 = v123 - v111 <= 32; - if ( bWalkSound != _zero && pParty->field_6F8 > _zero ) + if ( bWalkSound && pParty->field_6F8 > 0 ) pParty->field_6F8 -= pEventTimer->uTimeElapsed; if ( !bUnderwater - && SHIDWORD(pParty->pPartyBuffs[7].uExpireTime) <= _zero - && (SHIDWORD(pParty->pPartyBuffs[7].uExpireTime) < _zero || LODWORD(pParty->pPartyBuffs[7].uExpireTime) <= _zero) ) - pParty->bFlying = _zero; - if ( bJumping == _zero ) + && SHIDWORD(pParty->pPartyBuffs[7].uExpireTime) <= 0 + && (SHIDWORD(pParty->pPartyBuffs[7].uExpireTime) < 0 || LODWORD(pParty->pPartyBuffs[7].uExpireTime) <= 0) ) + pParty->bFlying = false; + if (!bJumping) { if ( pParty->field_6F4_packedid != (8 * v108 | OBJECT_BModel) ) { - if ( v108 != _zero ) + if (v108) { if ( v108 >> 6 < pOutdoor->uNumBModels ) { @@ -3269,12 +3268,14 @@ switch ( pPartyActionQueue->Next() ) { case PARTY_FlyUp: - if ( (signed __int64)pParty->pPartyBuffs[7].uExpireTime > 0 || bUnderwater == 1 ) - { - pParty->bFlying = 0; - if ( bUnderwater - || pParty->pPartyBuffs[7].uFlags & 1 - || pParty->pPlayers[pParty->pPartyBuffs[7].uCaster-1].sMana <= 0 )//*(int *)&pParty->pArtifactsFound[6972 * pParty->pPartyBuffs[7].uCaster + 10] > 0 ) + { + if (!pParty->FlyActive() && !bUnderwater) + break; + + pParty->bFlying = false; + if (bUnderwater || + pParty->pPartyBuffs[PARTY_BUFF_FLY].uFlags & 1 || + pParty->pPlayers[pParty->pPartyBuffs[PARTY_BUFF_FLY].uCaster - 1].sMana <= 0 ) { if ( pParty->vPosition.z < 4000 || bJumping ) { @@ -3306,8 +3307,9 @@ v127 = (BSPModel *)1; } } - } - goto LABEL_118; + } + break; + case PARTY_FlyDown: if ( (signed __int64)pParty->pPartyBuffs[7].uExpireTime > 0 || bUnderwater == 1 ) { @@ -3456,7 +3458,7 @@ v1 += v129; goto LABEL_93; } - if ( v118 && !v108 ) + if ( partyAtHighSlope && !v108 ) { v23 = stru_5C6E00->SinCos(_angle_y); v24 = (double)_walk_speed; @@ -3548,7 +3550,7 @@ _angle_x = 0; goto LABEL_118; case PARTY_Jump: - if ( (!v118 || v108) && !bJumping && pParty->field_24 && !(pParty->uFlags & 4) && !(BYTE1(pParty->uFlags) & 2) ) + if ( (!partyAtHighSlope || v108) && !bJumping && pParty->field_24 && !(pParty->uFlags & 4) && !(BYTE1(pParty->uFlags) & 2) ) { v126 = pParty->field_24 << 6; bJumping = 1; @@ -3609,7 +3611,7 @@ v121 += 2 * v33; goto LABEL_149; } - if ( !v118 ) + if ( !partyAtHighSlope ) { v34 = v121; LABEL_149: @@ -3621,16 +3623,20 @@ { if ( v108 ) goto LABEL_150; + + // rolling down the hill + // how it's done: you get a little bit pushed in the air along terrain normal, getting in the air + // and falling to the gravity, gradually sliding downwards. nice trick v123 = v111; - _46DCC8_get_gravity_direction_outdoor(v116, v117, (Vec3_int_ *)&v98); + ODM_GetTerrainNormalAt(v116, v117, &v98); v35 = v121 + -8 * pEventTimer->uTimeElapsed * GetGravityStrength(); - v129 = abs((signed __int64)v2 * (signed __int64)v98 + (signed __int64)v1 * (signed __int64)v99 + (signed __int64)v35 * (signed __int64)v100) >> 16; - v127 = (BSPModel *)((unsigned __int64)(v129 * (signed __int64)v98) >> 16); + v129 = abs((signed __int64)v2 * v98.x + (signed __int64)v1 * v98.y + (signed __int64)v35 * v98.z) >> 16; + v127 = (BSPModel *)((unsigned __int64)(v129 * (signed __int64)v98.x) >> 16); v2 += (int)v127; - v127 = (BSPModel *)((unsigned __int64)(v129 * (signed __int64)v99) >> 16); + v127 = (BSPModel *)((unsigned __int64)(v129 * (signed __int64)v98.y) >> 16); v1 += (int)v127; v128 = v1; - v127 = (BSPModel *)((unsigned __int64)(v129 * (signed __int64)v100) >> 16); + v127 = (BSPModel *)((unsigned __int64)(v129 * (signed __int64)v98.z) >> 16); v34 = (int)((char *)v127 + v35); v32 = 0; v121 = v34; @@ -3660,7 +3666,7 @@ LABEL_150: pParty->uFallStartY = v123; LABEL_151: - if ( v2 * v2 + v1 * v1 < 400 && !v118 ) + if ( v2 * v2 + v1 * v1 < 400 && !partyAtHighSlope ) { *(float *)&v128 = 0.0; v2 = 0; @@ -3720,8 +3726,8 @@ &v130, &v110, 0); - v127 = (BSPModel *)GetTerrainHeightsAroundParty(_angle_x, v117); - v42 = GetTerrainHeightsAroundParty(v116, _angle_y); + v127 = (BSPModel *)IsTerrainSlopeTooHigh(_angle_x, v117); + v42 = IsTerrainSlopeTooHigh(v116, _angle_y); v107 = 0; v118 = v42; if ( !v97 && !v110 && !v108 ) @@ -3746,7 +3752,7 @@ &v130, &v108, 0); - if ( GetTerrainHeightsAroundParty(_angle_x, _angle_y) && (signed int)v127 <= v123 ) + if ( IsTerrainSlopeTooHigh(_angle_x, _angle_y) && (signed int)v127 <= v123 ) { v43 = 1; LABEL_197: @@ -9434,77 +9440,95 @@ //----- (004823F4) -------------------------------------------------------- -bool __fastcall GetTerrainHeightsAroundParty(int a1, int a2) -{ - unsigned int v2; // ebx@1 - unsigned int v3; // edi@1 - int v4; // eax@1 - int v6; // esi@5 - int v7; // ecx@6 - int v8; // edx@6 - int v9; // eax@6 - int v10; // esi@10 - int v11; // [sp+14h] [bp-8h]@1 - int v12; // [sp+18h] [bp-4h]@1 - - v12 = a1; - v11 = a2; - v2 = WorldPosToGridCellX(a1); - v3 = WorldPosToGridCellZ(v11) - 1; - dword_76D568_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v2); - dword_76D56C_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v2 + 1); - dword_76D570_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v2 + 1); - dword_76D574_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(v2); - dword_76D558_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v3); - dword_76D55C_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v3); - dword_76D560_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v3 + 1); - dword_76D564_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(v3 + 1); - dword_76D548_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v2, v3); - dword_76D54C_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v2 + 1, v3); - dword_76D550_terrain_cell_world_pos_around_party_y = pOutdoor->DoGetHeightOnTerrain(v2 + 1, v3 + 1); - v4 = pOutdoor->DoGetHeightOnTerrain(v2, v3 + 1); - dword_76D554_terrain_cell_world_pos_around_party_y = v4; - if ( dword_76D548_terrain_cell_world_pos_around_party_y == dword_76D54C_terrain_cell_world_pos_around_party_y - && dword_76D54C_terrain_cell_world_pos_around_party_y == dword_76D550_terrain_cell_world_pos_around_party_y - && dword_76D550_terrain_cell_world_pos_around_party_y == v4 ) - return 0; - v6 = abs(v12 - dword_76D568_terrain_cell_world_pos_around_party_x); - if ( abs(dword_76D558_terrain_cell_world_pos_around_party_z - v11) >= v6 ) - { - v7 = dword_76D554_terrain_cell_world_pos_around_party_y; - v8 = dword_76D550_terrain_cell_world_pos_around_party_y; - v9 = dword_76D548_terrain_cell_world_pos_around_party_y; - } - else - { - v7 = dword_76D54C_terrain_cell_world_pos_around_party_y; - v8 = dword_76D548_terrain_cell_world_pos_around_party_y; - v9 = dword_76D550_terrain_cell_world_pos_around_party_y; - } - if ( v7 >= v8 ) - { - v10 = v8; - if ( v8 < v9 ) +bool IsTerrainSlopeTooHigh(int pos_x, int pos_z) +{ + //unsigned int v2; // ebx@1 + //unsigned int v3; // edi@1 + //int v4; // eax@1 + //int v6; // esi@5 + //int v7; // ecx@6 + //int v8; // edx@6 + //int v9; // eax@6 + //int v10; // esi@10 + //int v11; // [sp+14h] [bp-8h]@1 + //int v12; // [sp+18h] [bp-4h]@1 + + //v12 = a1; + //v11 = a2; + auto grid_x = WorldPosToGridCellX(pos_x); + auto grid_z = WorldPosToGridCellZ(pos_z) - 1; + + auto party_grid_x1 = GridCellToWorldPosX(grid_x); + //dword_76D56C_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x + 1); + //dword_76D570_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x + 1); + //dword_76D574_terrain_cell_world_pos_around_party_x = GridCellToWorldPosX(grid_x); + auto party_grid_z1 = GridCellToWorldPosZ(grid_z); + //dword_76D55C_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z); + //dword_76D560_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z + 1); + //dword_76D564_terrain_cell_world_pos_around_party_z = GridCellToWorldPosZ(grid_z + 1); + auto party_x1z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z); + auto party_x2z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z); + auto party_x2z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1); + auto party_x1z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1); + //dword_76D554_terrain_cell_world_pos_around_party_y = v4; + if (party_x1z1_y == party_x2z1_y && + party_x2z1_y == party_x2z2_y && + party_x2z2_y == party_x1z2_y ) + return false; + + auto dx = abs(pos_x - party_grid_x1), + dz = abs(party_grid_z1 - pos_z); + + int y1, y2, y3; + if (dz >= dx) + { + y1 = party_x1z2_y; // lower-left triangle + y2 = party_x2z2_y; // y3 | \ + y3 = party_x1z1_y; // | \ + /* | \ + |______ \ + y1 y2 */ + } + else + { + y1 = party_x2z1_y; // upper-right + y2 = party_x1z1_y; // y2_______ y1 + y3 = party_x2z2_y; // \ | + /* \ | + \ | + y3 */ + } + + int y_min = min(y1, min(y2, y3)), + y_max = max(y1, max(y2, y3)); + return y_max - y_min > 512; + + /*if ( y1 >= y2 ) + { + y_min = y2; + if ( y2 < y3 ) goto LABEL_13; LABEL_12: - v10 = v9; + y_min = y3; goto LABEL_13; } - if ( v7 >= v9 ) + else if ( y1 >= y3 ) goto LABEL_12; - v10 = v7; + else + y_min = y1; + LABEL_13: - if ( v7 <= v8 ) - { - if ( v8 > v9 ) - v9 = v8; - } - else - { - if ( v7 > v9 ) - v9 = v7; - } - return v9 - v10 > 512; + if ( y1 <= y2 ) + { + if ( y2 > y3 ) + y3 = y2; + } + else + { + if ( y1 > y3 ) + y3 = y1; + } + return y3 - v10 > 512;*/ }
--- a/mm7_4.cpp Mon Feb 11 20:27:00 2013 +0200 +++ b/mm7_4.cpp Tue Feb 12 00:22:30 2013 +0200 @@ -977,118 +977,80 @@ return dword_720F20[v22]; } + +//not sure if right- or left-handed coordinate space assumed, so this could be normal of inverse normal +// for a right-handed system, that would be an inverse normal //----- (0046DCC8) -------------------------------------------------------- -signed __int64 __fastcall _46DCC8_get_gravity_direction_outdoor(int a1, int a2, Vec3_int_ *a3) -{ - int v3; // ebx@1 - int v4; // ST4C_4@1 - unsigned int v5; // ST54_4@1 - unsigned int v6; // edi@1 - unsigned int v7; // ST50_4@1 - int v8; // edi@1 - int v9; // esi@1 - int v10; // ebx@1 - int v11; // ecx@2 - int v12; // eax@2 - int v13; // edx@2 - int v14; // ebx@2 - double v15; // st7@4 - double v16; // st6@4 - double v17; // st5@4 - float v18; // ST44_4@4 - float v19; // ST54_4@4 - double v20; // st4@4 - double v21; // st5@4 - float v22; // ST44_4@6 - double v23; // st7@4 - double v24; // st7@6 - signed __int64 result; // qax@6 - int v26; // [sp+14h] [bp-44h]@1 - int v27; // [sp+18h] [bp-40h]@1 - int v28; // [sp+20h] [bp-38h]@1 - int v29; // [sp+24h] [bp-34h]@1 - int v30; // [sp+28h] [bp-30h]@1 - int v31; // [sp+2Ch] [bp-2Ch]@1 - int v32; // [sp+30h] [bp-28h]@1 - int v33; // [sp+34h] [bp-24h]@1 - int v34; // [sp+38h] [bp-20h]@1 - int v35; // [sp+3Ch] [bp-1Ch]@1 - int v36; // [sp+40h] [bp-18h]@1 - int v37; // [sp+4Ch] [bp-Ch]@2 - float v38; // [sp+4Ch] [bp-Ch]@4 - int v39; // [sp+50h] [bp-8h]@2 - float v40; // [sp+50h] [bp-8h]@4 - int v41; // [sp+54h] [bp-4h]@2 - - v3 = a1; - v4 = a2; - v5 = WorldPosToGridCellX(a1); - v6 = WorldPosToGridCellZ(v4) - 1; - v33 = GridCellToWorldPosX(v5); - v34 = GridCellToWorldPosX(v5 + 1); - v35 = GridCellToWorldPosX(v5 + 1); - v36 = GridCellToWorldPosX(v5); - v29 = GridCellToWorldPosZ(v6); - v30 = GridCellToWorldPosZ(v6); - v7 = v6 + 1; - v31 = GridCellToWorldPosZ(v6 + 1); - v32 = GridCellToWorldPosZ(v6 + 1); - v26 = pOutdoor->DoGetHeightOnTerrain(v5, v6); - v27 = pOutdoor->DoGetHeightOnTerrain(v5 + 1, v6); - v8 = pOutdoor->DoGetHeightOnTerrain(v5 + 1, v6 + 1); - v28 = pOutdoor->DoGetHeightOnTerrain(v5, v7); - v9 = v29; - v10 = abs(v3 - v33); - if ( abs(v29 - v4) >= v10 ) - { - v11 = v33; - v37 = v28; - v39 = v36; - v12 = v35; - v41 = v32; - v13 = v31; - v14 = v8; - v8 = v26; - } - else - { - v11 = v35; - v41 = v30; - v39 = v34; - v12 = v33; - v13 = v29; - v9 = v31; - v37 = v27; - v14 = v26; - } - v15 = (double)(v12 - v39); - v16 = (double)(v13 - v41); - v17 = (double)(v14 - v37); - v18 = (double)(v11 - v39); - v19 = (double)(v9 - v41); - v20 = (double)(v8 - v37); - v38 = v20 * v16 - v19 * v17; - v40 = v18 * v17 - v20 * v15; - v21 = v19 * v15 - v18 * v16; - v23 = sqrt(v21 * v21 + v40 * v40 + v38 * v38); - if ( v23 == 0.0 ) - { - a3->y = 0; - a3->x = 0; - a3->z = 65536; - } - v24 = 1.0 / v23; - a3->x = (signed __int64)(v24 * v38 * 65536.0); - a3->y = (signed __int64)(v24 * v40 * 65536.0); - v22 = v21; - result = (signed __int64)(v24 * v22 * 65536.0); - a3->z = result; - return result; -} -// 47F44B: using guessed type int __stdcall WorldPosToGridCellX(int); -// 47F458: using guessed type int __stdcall WorldPosToGridCellZ(int); -// 47F469: using guessed type int __stdcall GridCellToWorldPosX(int); -// 47F476: using guessed type int __stdcall GridCellToWorldPosZ(int); +void ODM_GetTerrainNormalAt(int pos_x, int pos_z, Vec3_int_ *out) +{ + auto grid_x = WorldPosToGridCellX(pos_x); + auto grid_z = WorldPosToGridCellZ(pos_z) - 1; + + auto grid_pos_x1 = GridCellToWorldPosX(grid_x); + auto grid_pos_x2 = GridCellToWorldPosX(grid_x + 1); + auto grid_pos_z1 = GridCellToWorldPosZ(grid_z); + auto grid_pos_z2 = GridCellToWorldPosZ(grid_z + 1); + + auto x1z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z); + auto x2z1_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z); + auto x2z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x + 1, grid_z + 1); + auto x1z2_y = pOutdoor->DoGetHeightOnTerrain(grid_x, grid_z + 1); + + float side1_dx, side1_dy, side1_dz, + side2_dx, side2_dy, side2_dz; + + auto dx = abs(pos_x - grid_pos_x1), + dz = abs(grid_pos_z1 - pos_z); + if (dz >= dx) + { + side1_dy = (double)(x1z1_y - x1z2_y); + side2_dy = (double)(x2z2_y - x1z2_y); + side2_dx = (double)(grid_pos_x2 - grid_pos_x1); + side1_dx = (double)(grid_pos_x1 - grid_pos_x1); + side2_dz = (double)(grid_pos_z2 - grid_pos_z2); // bug? z2 - z2 + side1_dz = (double)(grid_pos_z2 - grid_pos_z2); // z1 - z2 + Log::Warning(L"%s %s %u\n", __FILE__, __FUNCTION__, __LINE__); + /* |\ + side1 | \ + |____\ + side 2 */ + } + else + { + side1_dy = (double)(x2z2_y - x2z1_y); + side2_dy = (double)(x1z1_y - x2z1_y); + side2_dx = (double)(grid_pos_x1 - grid_pos_x2); + side1_dx = (double)(grid_pos_x2 - grid_pos_x2); + side2_dz = (double)(grid_pos_z1 - grid_pos_z1); + side1_dz = (double)(grid_pos_z2 - grid_pos_z1); + + /* side 2 + _____ + \ | + \ | side 1 + \| */ + } + + float nx = side1_dy * side2_dz - side1_dz * side2_dy; + float ny = side1_dx * side2_dy - side1_dy * side2_dx; + float nz = side1_dz * side2_dx - side1_dx * side2_dz; + + float mag = sqrt(nx * nx + ny * ny + nz * nz); + if (fabsf(mag) < 1e-6f) + { + out->y = 0; + out->x = 0; + out->z = 65536; + } + else + { + float invmag = 1.0 / mag; + out->x = invmag * nx * 65536.0; + out->y = invmag * ny * 65536.0; + out->z = invmag * nz * 65536.0; + } +} + //----- (0046DEF2) -------------------------------------------------------- unsigned int __fastcall sub_46DEF2(signed int a2, unsigned int uLayingItemID)
--- a/mm7_data.cpp Mon Feb 11 20:27:00 2013 +0200 +++ b/mm7_data.cpp Tue Feb 12 00:22:30 2013 +0200 @@ -1763,18 +1763,18 @@ int dword_76D53C_terrain_cell_world_pos_around_party_x; // weak int dword_76D540_terrain_cell_world_pos_around_party_x; // weak int dword_76D544_terrain_cell_world_pos_around_party_x; // weak -int dword_76D548_terrain_cell_world_pos_around_party_y; // weak -int dword_76D54C_terrain_cell_world_pos_around_party_y; // weak -int dword_76D550_terrain_cell_world_pos_around_party_y; // weak -int dword_76D554_terrain_cell_world_pos_around_party_y; // weak -int dword_76D558_terrain_cell_world_pos_around_party_z; // weak -int dword_76D55C_terrain_cell_world_pos_around_party_z; // weak -int dword_76D560_terrain_cell_world_pos_around_party_z; // weak -int dword_76D564_terrain_cell_world_pos_around_party_z; // weak -int dword_76D568_terrain_cell_world_pos_around_party_x; // weak -int dword_76D56C_terrain_cell_world_pos_around_party_x; // weak -int dword_76D570_terrain_cell_world_pos_around_party_x; // weak -int dword_76D574_terrain_cell_world_pos_around_party_x; // weak +//int dword_76D548_terrain_cell_world_pos_around_party_y; // weak +//int dword_76D54C_terrain_cell_world_pos_around_party_y; // weak +//int dword_76D550_terrain_cell_world_pos_around_party_y; // weak +//int dword_76D554_terrain_cell_world_pos_around_party_y; // weak +//int dword_76D558_terrain_cell_world_pos_around_party_z; // weak +//int dword_76D55C_terrain_cell_world_pos_around_party_z; // weak +//int dword_76D560_terrain_cell_world_pos_around_party_z; // weak +//int dword_76D564_terrain_cell_world_pos_around_party_z; // weak +//int dword_76D568_terrain_cell_world_pos_around_party_x; // weak +//int dword_76D56C_terrain_cell_world_pos_around_party_x; // weak +//int dword_76D570_terrain_cell_world_pos_around_party_x; // weak +//int dword_76D574_terrain_cell_world_pos_around_party_x; // weak struct unk_F7B60C stru_76D578; // struct @ MM7.exe::0076D578 struct unk_F7B60C stru_76D590; // struct @ MM7.exe::0076D590 struct unk_F7B60C stru_76D5A8; // struct @ MM7.exe::0076D5A8
--- a/mm7_data.h Mon Feb 11 20:27:00 2013 +0200 +++ b/mm7_data.h Tue Feb 12 00:22:30 2013 +0200 @@ -1608,18 +1608,18 @@ extern int dword_76D53C_terrain_cell_world_pos_around_party_x; // weak extern int dword_76D540_terrain_cell_world_pos_around_party_x; // weak extern int dword_76D544_terrain_cell_world_pos_around_party_x; // weak -extern int dword_76D548_terrain_cell_world_pos_around_party_y; // weak -extern int dword_76D54C_terrain_cell_world_pos_around_party_y; // weak -extern int dword_76D550_terrain_cell_world_pos_around_party_y; // weak -extern int dword_76D554_terrain_cell_world_pos_around_party_y; // weak -extern int dword_76D558_terrain_cell_world_pos_around_party_z; // weak -extern int dword_76D55C_terrain_cell_world_pos_around_party_z; // weak -extern int dword_76D560_terrain_cell_world_pos_around_party_z; // weak -extern int dword_76D564_terrain_cell_world_pos_around_party_z; // weak -extern int dword_76D568_terrain_cell_world_pos_around_party_x; // weak -extern int dword_76D56C_terrain_cell_world_pos_around_party_x; // weak -extern int dword_76D570_terrain_cell_world_pos_around_party_x; // weak -extern int dword_76D574_terrain_cell_world_pos_around_party_x; // weak +//extern int dword_76D548_terrain_cell_world_pos_around_party_y; // weak +//extern int dword_76D54C_terrain_cell_world_pos_around_party_y; // weak +//extern int dword_76D550_terrain_cell_world_pos_around_party_y; // weak +//extern int dword_76D554_terrain_cell_world_pos_around_party_y; // weak +//extern int dword_76D558_terrain_cell_world_pos_around_party_z; // weak +//extern int dword_76D55C_terrain_cell_world_pos_around_party_z; // weak +//extern int dword_76D560_terrain_cell_world_pos_around_party_z; // weak +//extern int dword_76D564_terrain_cell_world_pos_around_party_z; // weak +//extern int dword_76D568_terrain_cell_world_pos_around_party_x; // weak +//extern int dword_76D56C_terrain_cell_world_pos_around_party_x; // weak +//extern int dword_76D570_terrain_cell_world_pos_around_party_x; // weak +//extern int dword_76D574_terrain_cell_world_pos_around_party_x; // weak extern char byte_76D5C0; extern struct unk_F7B60C stru_76D578; extern struct unk_F7B60C stru_76D590; @@ -2163,7 +2163,7 @@ int _46CEC3_get_floor_level(int x, int y, int z, unsigned int uSectorID, unsigned int *pFaceID); int __fastcall sub_46D49E_prolly_get_world_y_under_party(int a1, signed int a2, int a3, int a4, int *a5, int *a6, int a7); int __fastcall sub_46D8E3(int a1, signed int a2, int a3, int a4); -signed __int64 __fastcall _46DCC8_get_gravity_direction_outdoor(int a1, int a2, Vec3_int_ *a3); +void ODM_GetTerrainNormalAt(int pos_x, int pos_z, Vec3_int_ *out); unsigned int __fastcall sub_46DEF2(signed int a2, unsigned int uLayingItemID); int __fastcall _46DF1A_collide_against_actor(int, int); // weak void __cdecl _46E0B2_collide_against_decorations(); @@ -2225,7 +2225,7 @@ void __cdecl sub_481ED9_MessWithOutdoorCamera(); bool __fastcall sub_481EFA(RenderVertexSoft *a1, RenderVertexSoft *a2, RenderVertexSoft *a3, RenderVertexSoft *a4, int a5); signed int __fastcall sub_481FC9(RenderVertexSoft *_ECX, RenderVertexSoft *a2, RenderVertexSoft *a3, stru148 *a4); -bool __fastcall GetTerrainHeightsAroundParty(int a1, int a2); +bool IsTerrainSlopeTooHigh(int pos_x, int pos_y); int __fastcall GetTerrainHeightsAroundParty2(int a1, int a2, int *a3, int a4); struct stru148 *__fastcall sr_sub_4829B9(RenderVertexSoft *a1, RenderVertexSoft *a2, RenderVertexSoft *a3, stru148 *a4, int a5); signed int __cdecl const_1_0();