#if defined _portal_gun_portalBox_inc #endinput #endif #define _portal_gun_portalBox_inc #define PBOX_SHIFT 1.0 // стандартный отступ от стены #define PBOX_DEPTH 3.0 // отступ 'вглубь' для построения portalBox для проверки поверхности #define PBOX_STEP 1.0 // шаг для смещения портала, смещение портала используется для обнаружения ровной поверхности #define PBOX_ITERS 35 // максимальное количество шагов для смещения портала enum _:portalBox_t { Float:ppointUL[3], // up left Float:ppointUR[3], // up right Float:ppointDR[3], // down right Float:ppointDL[3], // down left Float:pcenter[3], Float:pfwd[3], Float:pup[3], Float:pright[3] } bool:portalBox_create(const Float:shotFrom[3], const Float:shotDirection[3], playerId, outPortalBox[portalBox_t]) { static Float:pointEnd[3], Float:normal[3] xs_vec_mul_scalar(shotDirection, 9999.0, pointEnd) xs_vec_add(shotFrom, pointEnd, pointEnd) engfunc(EngFunc_TraceLine, shotFrom, pointEnd, 0, playerId, g_pCommonTr) get_tr2(g_pCommonTr, TR_vecEndPos, pointEnd) get_tr2(g_pCommonTr, TR_vecPlaneNormal, normal) portalBox_create2(pointEnd, normal, outPortalBox) static firstPortalBox[portalBox_t] portalBox_copy(outPortalBox, firstPortalBox) portalBox_move(outPortalBox, outPortalBox[pfwd], PBOX_SHIFT) static i, res for(i=0; i-1; i--) { if( (resTable[0] == dirState[i][0]) && (resTable[1] == dirState[i][1]) && (resTable[2] == dirState[i][2]) && (resTable[3] == dirState[i][3])) break } static Float:tmpVec[3] switch(dirAction[i]) { case VALID: return 1 case INVALID: return -1 case UP: xs_vec_copy(portalBox[pup], outBestDirection) case UP_RIGHT: { xs_vec_copy(portalBox[pup], outBestDirection) xs_vec_add(portalBox[pright], outBestDirection, outBestDirection) } case UP_LEFT: { xs_vec_neg(portalBox[pright],tmpVec) xs_vec_copy(portalBox[pup], outBestDirection) xs_vec_add(tmpVec, outBestDirection, outBestDirection) } case DOWN: xs_vec_neg(portalBox[pup], outBestDirection) case DOWN_RIGHT:{ xs_vec_neg(portalBox[pup], outBestDirection) xs_vec_add(outBestDirection, portalBox[pright], outBestDirection) } case DOWN_LEFT: { xs_vec_neg(portalBox[pright], tmpVec) xs_vec_neg(portalBox[pup], outBestDirection) xs_vec_add(tmpVec, outBestDirection, outBestDirection) } case RIGHT: xs_vec_copy(portalBox[pright], outBestDirection) case LEFT: xs_vec_neg(portalBox[pright], outBestDirection) } return 0 } void:portalBox_copy(const portalBox[portalBox_t], outPortalBox[portalBox_t]) { xs_vec_copy(portalBox[ppointUL], outPortalBox[ppointUL]) xs_vec_copy(portalBox[ppointDL], outPortalBox[ppointDL]) xs_vec_copy(portalBox[ppointDR], outPortalBox[ppointDR]) xs_vec_copy(portalBox[ppointUR], outPortalBox[ppointUR]) xs_vec_copy(portalBox[pcenter], outPortalBox[pcenter]) xs_vec_copy(portalBox[pfwd], outPortalBox[pfwd]) xs_vec_copy(portalBox[pup], outPortalBox[pup]) xs_vec_copy(portalBox[pright], outPortalBox[pright]) }