Mercurial > mm7
diff mm7_3.cpp @ 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 | 1c471f3629fb |
children | 7eeea515f5ff |
line wrap: on
line diff
--- 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;*/ }