diff --git a/reapi/include/cssdk/dlls/regamedll_api.h b/reapi/include/cssdk/dlls/regamedll_api.h index efb87d47..64a308dc 100644 --- a/reapi/include/cssdk/dlls/regamedll_api.h +++ b/reapi/include/cssdk/dlls/regamedll_api.h @@ -818,12 +818,12 @@ struct ReGameFuncs_t { class CWeaponBox *(*CreateWeaponBox)(CBasePlayerItem *pItem, CBasePlayer *pPlayerOwner, const char *modelName, Vector &origin, Vector &angles, Vector &velocity, float lifeTime, bool packAmmo); class CGrenade *(*SpawnGrenade)(WeaponIdType weaponId, entvars_t *pevOwner, Vector &vecSrc, Vector &vecThrow, float time, int iTeam, unsigned short usEvent); - // navs // navs NavErrorType (*LoadNavigationMap)(); + bool (*CheckNavigationmap)(); void (*DestroyNavigationMap)(); - ConnectInfoData *(*AddConnectInfoList)(CBaseEntity *entity); + ConnectInfoData *(*AddConnectInfoList)(CBaseEntity *entity, float update_min, float update_max); bool (*RemoveConnectInfoList)(CBaseEntity *entity); void (*DestroyConnectInfoList)(); @@ -832,8 +832,6 @@ struct ReGameFuncs_t { ConnectInfoData *(*ComputePath)(CBaseEntity *entity, ConnectInfoData *data, CNavArea *startArea, const Vector *start, CNavArea *goalArea, const Vector *goal, RouteType route); bool (*UpdatePathMovement)(CBaseEntity *entity, ConnectInfoData *data, float tolerance, bool check2D); - - ConnectInfoList *(*GetConnectInfoList)(); }; class IReGameApi { diff --git a/reapi/include/cssdk/game_shared/bot/nav_api.h b/reapi/include/cssdk/game_shared/bot/nav_api.h index 6edfeba0..92d9a2c3 100644 --- a/reapi/include/cssdk/game_shared/bot/nav_api.h +++ b/reapi/include/cssdk/game_shared/bot/nav_api.h @@ -42,6 +42,7 @@ struct ConnectInfoData { CBaseEntity* entity; // path entity ConnectInfo_api *path; // path pointer + CNavArea *currentArea; // path's current area Vector currentGoal; // path current goal (fast access) int length; // path length int index; // path current index @@ -53,10 +54,15 @@ struct ConnectInfoData enum ConnectInfoData_e { e_path, + e_path_flags, + e_path_how, + e_area, + e_goal, e_length, e_index, e_update, - e_goal + e_update_min, + e_update_max, }; typedef std::list ConnectInfoList; \ No newline at end of file diff --git a/reapi/src/natives/natives_helper.h b/reapi/src/natives/natives_helper.h index e3ef79f8..f6c664e4 100644 --- a/reapi/src/natives/natives_helper.h +++ b/reapi/src/natives/natives_helper.h @@ -57,13 +57,6 @@ class CAmxArg return nullptr; return UTIL_PlayerByIndex(m_value); } - operator CNavArea*() const - { - if (m_value < 0) - return nullptr; - - return getPrivate(m_value); - } operator IGameClient *() const { if (m_value <= 0) diff --git a/reapi/src/natives/natives_nav.cpp b/reapi/src/natives/natives_nav.cpp index 49d63f09..9d82a214 100644 --- a/reapi/src/natives/natives_nav.cpp +++ b/reapi/src/natives/natives_nav.cpp @@ -39,6 +39,12 @@ cell AMX_NATIVE_CALL rg_get_nearest_nav_area(AMX *amx, cell *params) { enum args_e { arg_count, arg_origin, arg_anyz }; + if(!g_ReGameFuncs->CheckNavigationmap()) + { + AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: Navigation map is not loaded!", __FUNCTION__); + return 0; + } + Vector* origin = (Vector *)getAmxAddr(amx, params[arg_origin]); CNavArea* area = g_ReGameFuncs->GetNearestNavArea(origin, params[arg_anyz]); @@ -54,15 +60,19 @@ cell AMX_NATIVE_CALL rg_get_nearest_nav_area(AMX *amx, cell *params) * * @return true if area was valid, false otherwise * -* native rg_get_closes_point_in_area(const pArea, Float:vOrigin[3], Float:vPosition[3]) +* native rg_get_closest_point_in_area(const pArea, Float:vOrigin[3], Float:vPosition[3]) */ cell AMX_NATIVE_CALL rg_get_closest_point_in_area(AMX *amx, cell *params) { enum args_e { arg_count, arg_area, arg_origin, arg_position}; - cell *pArea = getAmxAddr(amx, params[arg_area]); + if(!g_ReGameFuncs->CheckNavigationmap()) + { + AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: Navigation map is not loaded!", __FUNCTION__); + return 0; + } - if(!pArea) + if(!params[arg_area]) return FALSE; CNavArea *area = reinterpret_cast(params[arg_area]); @@ -91,51 +101,38 @@ cell AMX_NATIVE_CALL rg_get_closest_point_in_area(AMX *amx, cell *params) * * @return connect info pointer * -* native ConnectInfo:rg_compute_path(const entity, ConnectInfo:cInfo, const startArea, const Float:vStart[3], goalarea, const Float:vGoal[3], RouteType:route) +* native ConnectInfo:rg_compute_path(const entity, ConnectInfo:cInfo, const startArea, Float:vStart[3], goalarea, Float:vGoal[3], RouteType:route) */ cell AMX_NATIVE_CALL rg_compute_path(AMX* amx, cell *params) { enum args_e { arg_count, arg_entity, arg_data, arg_startarea, arg_vecstart, arg_goalarea, arg_vecgoal, arg_routetype }; - CAmxArgs args(amx, params); - CBaseEntity *entity = nullptr; - ConnectInfoData *data = nullptr; - - // if an entity was provided, do this - if(args[arg_entity]) + if(!g_ReGameFuncs->CheckNavigationmap()) { - CHECK_ISENTITY(arg_entity); - entity = args[arg_entity]; + AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: Navigation map is not loaded!", __FUNCTION__); + return 0; } - // cast data pointer - cell *ptr = getAmxAddr(amx, params[arg_data]); + CHECK_ISENTITY(arg_entity); - if(ptr) - data = reinterpret_cast(params[arg_data]); + CAmxArgs args(amx, params); + CBaseEntity *entity = args[arg_entity]; - // get areas, goalarea can be invalid if computepath was not provided - cell *pArea = getAmxAddr(amx, params[arg_startarea]); + ConnectInfoData *data = nullptr; - if(!pArea) - { - UTIL_ServerPrint("Invalid start area provided\n"); - return reinterpret_cast(data); - } + // cast data pointer + if(params[arg_data]) + data = reinterpret_cast(params[arg_data]); - CNavArea *startarea = reinterpret_cast(params[arg_startarea]); + // get areas, areas can be invalid + CNavArea *startarea = nullptr; - // invalid - if (!startarea) - { - UTIL_ServerPrint("Invalid start area cast provided\n"); - return reinterpret_cast(data); - } + if(params[arg_startarea]) + startarea = reinterpret_cast(params[arg_startarea]); CNavArea *goalarea = nullptr; - pArea = getAmxAddr(amx, params[arg_goalarea]); - if(pArea) + if(params[arg_goalarea]) goalarea = reinterpret_cast(params[arg_goalarea]); Vector* startvec = (Vector *)getAmxAddr(amx, params[arg_vecstart]); @@ -145,29 +142,36 @@ cell AMX_NATIVE_CALL rg_compute_path(AMX* amx, cell *params) ConnectInfoData *retData; retData = g_ReGameFuncs->ComputePath(entity, data, startarea, startvec, goalarea, goalvec, route); - UTIL_ServerPrint("Path computed, data: %d\n", reinterpret_cast(retData)); return reinterpret_cast(retData); } /* * Creates a connect info pointer * -* @param entity (can be null) +* @param entity entity (worldspawn is valid too if you want a global one) +* @param update_min min update delay +* @param update_max max update delay * * @return connect info pointer * -* native rg_create_connect_info(const entity); +* native rg_create_connect_info(const entity, const Float:update_min = 0.4, const Float:update_max = 0.6); */ cell AMX_NATIVE_CALL rg_create_connect_info(AMX* amx, cell *params) { - enum args_e { arg_count, arg_entity }; + enum args_e { arg_count, arg_entity, arg_update_min, arg_update_max }; + if(!g_ReGameFuncs->CheckNavigationmap()) + { + AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: Navigation map is not loaded!", __FUNCTION__); + return 0; + } + CHECK_ISENTITY(arg_entity); CAmxArgs args(amx, params); CBaseEntity *entity = args[arg_entity]; - ConnectInfoData *data = g_ReGameFuncs->AddConnectInfoList(entity); + ConnectInfoData *data = g_ReGameFuncs->AddConnectInfoList(entity, args[arg_update_min], args[arg_update_max]); return reinterpret_cast(data); } @@ -184,6 +188,12 @@ cell AMX_NATIVE_CALL rg_remove_connect_info(AMX* amx, cell *params) { enum args_e { arg_count, arg_entity, arg_data }; + if(!g_ReGameFuncs->CheckNavigationmap()) + { + AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: Navigation map is not loaded!", __FUNCTION__); + return 0; + } + CHECK_ISENTITY(arg_entity); CAmxArgs args(amx, params); @@ -229,10 +239,13 @@ cell AMX_NATIVE_CALL rg_get_connect_info_data(AMX* amx, cell *params) { enum args_e { arg_count, arg_pointer, arg_data_enum, arg_return, arg_index }; - //CAmxArgs args(amx, params); - cell *ptr = getAmxAddr(amx, params[arg_pointer]); + if(!g_ReGameFuncs->CheckNavigationmap()) + { + AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: Navigation map is not loaded!", __FUNCTION__); + return 0; + } - if(!ptr) + if(!params[arg_pointer]) { AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: Invalid connect info provided", __FUNCTION__); return 0; @@ -241,35 +254,47 @@ cell AMX_NATIVE_CALL rg_get_connect_info_data(AMX* amx, cell *params) ConnectInfoData *data = reinterpret_cast(params[arg_pointer]); ConnectInfoData_e data_enum = static_cast(params[arg_data_enum]); + int index; + + // not provided + if(PARAMS_COUNT < arg_index) + { + // get current index then + index = data->index; + } + else + { + index = params[arg_index]; + + if(index < 0 || index > MAX_PATH_LENGTH_API) + { + AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: e_path->index out of bounds (%d)", __FUNCTION__, index); + return 0; + } + } + switch(data_enum) { case e_path: { - int index; + cell *vecRet = getAmxAddr(amx, params[arg_return]); + Vector pos; + int length = data->length; - if(PARAMS_COUNT < arg_index) - index = data->index; + if(length) + { + // get latest then + if(index >= length) + index = length - 1; + + pos = data->path[index].pos; + } else - index = params[arg_index]; - - //cell *cRet = getAmxAddr(amx, params[arg_index]); - - if(index < 0 || index >= MAX_PATH_LENGTH_API) { - AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: e_path->index out of bounds (%d)", __FUNCTION__, index); - return 0; + // copy current origin then + pos = data->entity->pev->origin; } - - int length = data->length; - // get latest then - if(index >= length) - index = length - 1; - - cell *vecRet = getAmxAddr(amx, params[arg_return]); - Vector pos = data->path[index].pos; - - // copy vector vecRet[0] = amx_ftoc(pos.x); vecRet[1] = amx_ftoc(pos.y); vecRet[2] = amx_ftoc(pos.z); @@ -280,7 +305,6 @@ cell AMX_NATIVE_CALL rg_get_connect_info_data(AMX* amx, cell *params) cell *vecRet = getAmxAddr(amx, params[arg_return]); Vector pos = data->currentGoal; - // copy vector vecRet[0] = amx_ftoc(pos.x); vecRet[1] = amx_ftoc(pos.y); vecRet[2] = amx_ftoc(pos.z); @@ -297,9 +321,31 @@ cell AMX_NATIVE_CALL rg_get_connect_info_data(AMX* amx, cell *params) case e_update: { cell *fRet = getAmxAddr(amx, params[arg_return]); - *fRet = *((cell*)&data->update); + *fRet = amx_ftoc(data->update); + return 1; + } + case e_update_min: + { + cell *fRet = getAmxAddr(amx, params[arg_return]); + *fRet = amx_ftoc(data->update_min); + return 1; + } + case e_update_max: + { + cell *fRet = getAmxAddr(amx, params[arg_return]); + *fRet = amx_ftoc(data->update_max); return 1; } + case e_path_flags: + { + unsigned char flags = data->path[index].area->GetAttributes(); + return (cell)flags; + } + case e_path_how: + { + int how = data->path[index].how; + return (cell)how; + } } return 0; @@ -310,11 +356,11 @@ cell AMX_NATIVE_CALL rg_get_connect_info_data(AMX* amx, cell *params) * * @param connectInfo connect info pointer * @param ConnectInfoData see nav_api.h -* @param any +* @param any ... * * @return true if changed * -* @note Only index & update are allowed, the rest are forbidden +* @note Only index, update and goal are allowed, the rest are forbidden * * native rg_set_connect_info_data(const connectInfo, ConnectInfoData_e, any:...) */ @@ -322,10 +368,13 @@ cell AMX_NATIVE_CALL rg_set_connect_info_data(AMX* amx, cell *params) { enum args_e { arg_count, arg_pointer, arg_data_enum, arg_value, arg_index }; - CAmxArgs args(amx, params); - cell *ptr = getAmxAddr(amx, params[arg_pointer]); + if(!g_ReGameFuncs->CheckNavigationmap()) + { + AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: Navigation map is not loaded!", __FUNCTION__); + return 0; + } - if(!ptr) + if(!params[arg_pointer]) { AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: Invalid connect info provided", __FUNCTION__); return 0; @@ -333,17 +382,62 @@ cell AMX_NATIVE_CALL rg_set_connect_info_data(AMX* amx, cell *params) ConnectInfoData *data = reinterpret_cast(params[arg_pointer]); ConnectInfoData_e data_enum = static_cast(params[arg_data_enum]); + + CAmxArgs args(amx, params); switch(data_enum) { + case e_index: + { + int value = params[arg_value]; + + if(value >= MAX_PATH_LENGTH_API) + { + AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: Index out of bounds (new value %d) (max value %d)", __FUNCTION__, value, MAX_PATH_LENGTH_API - 1); + return 0; + } + + // keep it at max + if(value >= data->length) + value = data->length - 1; + + data->index = value; + return 1; + } case e_update: { - data->update = *((float*)¶ms[arg_value]); + data->update = args[arg_value]; return 1; } - case e_index: + case e_update_min: { - data->index = params[arg_value]; + float value = args[arg_value]; + + if(value < 0.1) + value = 0.1; + else if(value > data->update_max) + value = data->update_max; + + data->update_min = value; + return 1; + } + case e_update_max: + { + float value = args[arg_value]; + + if(value < 0.1) + value = 0.1; + else if(value < data->update_min) + value = data->update_min; + + data->update_max = value; + return 1; + } + case e_goal: + { + Vector* vec = (Vector *)getAmxAddr(amx, params[arg_value]); + + data->currentGoal = *vec; return 1; } default: @@ -372,15 +466,20 @@ cell AMX_NATIVE_CALL rg_update_path_movement(AMX *amx, cell *params) { enum args_e { arg_count, arg_entity, arg_data, arg_tolerance, arg_check2d }; + if(!g_ReGameFuncs->CheckNavigationmap()) + { + AMXX_LogError(amx, AMX_ERR_NATIVE, "%s: Navigation map is not loaded!", __FUNCTION__); + return 0; + } + CHECK_ISENTITY(arg_entity); CAmxArgs args(amx, params); CBaseEntity *entity = args[arg_entity]; - cell *ptr = getAmxAddr(amx, params[arg_data]); ConnectInfoData *data = nullptr; - if(ptr) + if(params[arg_data]) data = reinterpret_cast(params[arg_data]); return (cell)g_ReGameFuncs->UpdatePathMovement(entity, data, args[arg_tolerance], args[arg_check2d]);