Skip to content

Commit

Permalink
More Engineer Stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
caxanga334 committed Jun 14, 2024
1 parent 0622366 commit 90eca6d
Show file tree
Hide file tree
Showing 37 changed files with 309 additions and 453 deletions.
4 changes: 1 addition & 3 deletions extension/AMBuilder
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ sourceFiles = [
'manager.cpp',
'extplayer.cpp',
'natives.cpp',
'core/eventmanager.cpp',
'sdkports/sdk_timers.cpp',
'sdkports/debugoverlay_shared.cpp',
'sdkports/studio.cpp',
Expand All @@ -23,7 +22,6 @@ sourceFiles = [
'entities/worldspawn.cpp',
'entities/tf2/tf_entities.cpp',
'mods/basemod.cpp',
'mods/basemod_gameevents.cpp',
# Nav Mesh
'navmesh/nav_area.cpp',
'navmesh/nav_colors.cpp',
Expand Down Expand Up @@ -82,12 +80,12 @@ sourceFiles = [
'bot/tf2/tasks/engineer/tf2bot_engineer_build_object.cpp',
'bot/tf2/tasks/engineer/tf2bot_engineer_repair_object.cpp',
'bot/tf2/tasks/engineer/tf2bot_engineer_upgrade_object.cpp',
'bot/tf2/tasks/engineer/tf2bot_engineer_speedup_object.cpp',
'bot/tf2/tasks/scenario/tf2bot_map_ctf.cpp',
'bot/tf2/tasks/scenario/mvm/tf2bot_mvm_idle.cpp',
'bot/tf2/tasks/scenario/mvm/tf2bot_mvm_upgrade.cpp',
'mods/tf2/teamfortress2mod.cpp',
'mods/tf2/tf2lib.cpp',
'mods/tf2/tf2mod_gameevents.cpp',
'mods/tf2/tf2_class_selection.cpp',
'mods/tf2/mvm_upgrade_manager.cpp',
'mods/tf2/nav/tfnavarea.cpp',
Expand Down
5 changes: 5 additions & 0 deletions extension/bot/interfaces/behavior.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,8 @@ QueryAnswerType IBehavior::IsReady(CBaseBot* me)
{
return GetDecisionQueryResponder()->IsReady(me);
}

QueryAnswerType IBehavior::ShouldAssistTeammate(CBaseBot* me, CBaseExtPlayer& teammate)
{
return GetDecisionQueryResponder()->ShouldAssistTeammate(me, teammate);
}
1 change: 1 addition & 0 deletions extension/bot/interfaces/behavior.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class IBehavior : public IBotInterface, public IDecisionQuery
const CKnownEntity* SelectTargetThreat(CBaseBot* me, const CKnownEntity* threat1, const CKnownEntity* threat2) override;
Vector GetTargetAimPos(CBaseBot* me, edict_t* entity, CBaseExtPlayer* player = nullptr) override;
QueryAnswerType IsReady(CBaseBot* me) override;
QueryAnswerType ShouldAssistTeammate(CBaseBot* me, CBaseExtPlayer& teammate) override;

private:

Expand Down
7 changes: 7 additions & 0 deletions extension/bot/interfaces/decisionquery.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ class IDecisionQuery
virtual Vector GetTargetAimPos(CBaseBot* me, edict_t* entity, CBaseExtPlayer* player = nullptr);
// If a game mode has a toggle ready feature, this asks if the bot is ready
virtual QueryAnswerType IsReady(CBaseBot* me);
// Should the bot help a specific teammate?
virtual QueryAnswerType ShouldAssistTeammate(CBaseBot* me, CBaseExtPlayer& teammate);
private:

};
Expand Down Expand Up @@ -116,5 +118,10 @@ inline QueryAnswerType IDecisionQuery::IsReady(CBaseBot* me)
return ANSWER_UNDEFINED;
}

inline QueryAnswerType IDecisionQuery::ShouldAssistTeammate(CBaseBot* me, CBaseExtPlayer& teammate)
{
return ANSWER_UNDEFINED;
}

#endif // !SMNAV_BOT_DECISION_QUERY_H_

5 changes: 5 additions & 0 deletions extension/bot/interfaces/tasks.h
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,11 @@ class AITaskManager : public IEventListener, public IDecisionQuery
PROPAGATE_DECISION_WITH_1ARG(IsReady, me);
}

QueryAnswerType ShouldAssistTeammate(CBaseBot* me, CBaseExtPlayer& teammate) override
{
PROPAGATE_DECISION_WITH_2ARGS(ShouldAssistTeammate, me, teammate);
}

private:
friend class AITask<BotClass>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <mods/tf2/tf2lib.h>
#include <bot/tf2/tf2bot.h>
#include <bot/tf2/tasks/tf2bot_find_ammo_task.h>
#include "tf2bot_engineer_speedup_object.h"
#include "tf2bot_engineer_build_object.h"

CTF2BotEngineerBuildObjectTask::CTF2BotEngineerBuildObjectTask(eObjectType type, const Vector& location)
Expand Down
76 changes: 75 additions & 1 deletion extension/bot/tf2/tasks/engineer/tf2bot_engineer_nest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,33 @@ AITask<CTF2Bot>* CTF2BotEngineerNestTask::NestTask(CTF2Bot* me)
return new CTF2BotEngineerBuildObjectTask(CTF2BotEngineerBuildObjectTask::OBJECT_TELEPORTER_ENTRANCE, goal);
}
}
else if (me->GetMySentryGun() == nullptr)
{
Vector goal;

if (FindSpotToBuildSentryGun(me, goal))
{
return new CTF2BotEngineerBuildObjectTask(CTF2BotEngineerBuildObjectTask::OBJECT_SENTRYGUN, goal);
}
}

if (me->GetMySentryGun() != nullptr)
{
tfentities::HBaseObject sentrygun(me->GetMySentryGun());

if (!sentrygun.IsAtMaxLevel())
{
return new CTF2BotEngineerUpgradeObjectTask(gamehelpers->ReferenceToEntity(sentrygun.GetIndex()));
}
}

return nullptr;
}

bool CTF2BotEngineerNestTask::FindSpotToBuildSentryGun(CTF2Bot* me, Vector& out)
{
return false;
// TO-DO: Add game mode specific sentry spots
return GetRandomSentrySpot(me, out);
}

bool CTF2BotEngineerNestTask::FindSpotToBuildTeleEntrance(CTF2Bot* me, Vector& out)
Expand Down Expand Up @@ -150,3 +170,57 @@ bool CTF2BotEngineerNestTask::FindSpotToBuildTeleEntrance(CTF2Bot* me, Vector& o
return true;
}

bool CTF2BotEngineerNestTask::GetRandomSentrySpot(CTF2Bot* me, Vector& out)
{
me->UpdateLastKnownNavArea(true);
CNavArea* start = me->GetLastKnownNavArea();

if (start == nullptr)
{
return false;
}

EngineerBuildableLocationCollector collector(me, static_cast<CTFNavArea*>(start));

collector.SetTravelLimit(4096.0f);
collector.Execute();

if (collector.IsEmpty())
{
return false;
}

auto& areas = collector.GetCollectedAreas();

CTFNavArea* buildGoal = nullptr;
std::vector<CTFNavArea*> hintAreas;
hintAreas.reserve(32);

for (auto tfarea : areas)
{
if (tfarea->HasTFAttributes(CTFNavArea::TFNAV_SENTRYGUN_HINT) && !tfarea->IsTFAttributesRestrictedForTeam(me->GetMyTFTeam()))
{
hintAreas.push_back(tfarea);
}
}

if (hintAreas.empty())
{
// no hints were found, pick a random one
buildGoal = areas[randomgen->GetRandomInt<size_t>(0, areas.size() - 1)];
}
else
{
buildGoal = hintAreas[randomgen->GetRandomInt<size_t>(0, hintAreas.size() - 1)];
}

out = buildGoal->GetCenter();

if (me->IsDebugging(BOTDEBUG_TASKS))
{
buildGoal->DrawFilled(0, 128, 0, 255, 10.0f, true);
}

return true;
}

1 change: 1 addition & 0 deletions extension/bot/tf2/tasks/engineer/tf2bot_engineer_nest.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class CTF2BotEngineerNestTask : public AITask<CTF2Bot>
AITask<CTF2Bot>* NestTask(CTF2Bot* me);
bool FindSpotToBuildSentryGun(CTF2Bot* me, Vector& out);
bool FindSpotToBuildTeleEntrance(CTF2Bot* me, Vector& out);
bool GetRandomSentrySpot(CTF2Bot* me, Vector& out);
};

#endif // !NAVBOT_TF2BOT_TASKS_ENGINEER_NEST_H_
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ TaskResult<CTF2Bot> CTF2BotEngineerRepairObjectTask::OnTaskUpdate(CTF2Bot* bot)
{
bot->GetControlInterface()->AimAt(object.WorldSpaceCenter(), IPlayerController::LOOK_VERY_IMPORTANT, 0.5f, "Looking at object to repair it.");
bot->GetControlInterface()->PressAttackButton(0.5f);
bot->GetControlInterface()->PressCrouchButton(0.5f);
}

return Continue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class CTF2BotEngineerRepairObjectTask : public AITask<CTF2Bot>
CHandle<CBaseEntity> m_object;
CMeshNavigator m_nav;

static constexpr auto get_object_melee_range() { return 72.0f; }
static constexpr auto get_object_melee_range() { return 64.0f; }
};

#endif // !NAVBOT_TF2BOT_TASKS_ENGINEER_REPAIR_OBJECT_H_
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#include <extension.h>
#include <util/helpers.h>
#include <entities/tf2/tf_entities.h>
#include <mods/tf2/tf2lib.h>
#include <bot/tf2/tf2bot.h>
#include "tf2bot_engineer_speedup_object.h"

CTF2BotEngineerSpeedUpObjectTask::CTF2BotEngineerSpeedUpObjectTask(CBaseEntity* object) :
m_object(object)
{
}

TaskResult<CTF2Bot> CTF2BotEngineerSpeedUpObjectTask::OnTaskStart(CTF2Bot* bot, AITask<CTF2Bot>* pastTask)
{
if (m_object.Get() == nullptr)
{
return Done("Goal object is no longer valid");
}

return Continue();
}

TaskResult<CTF2Bot> CTF2BotEngineerSpeedUpObjectTask::OnTaskUpdate(CTF2Bot* bot)
{
if (m_object.Get() == nullptr)
{
return Done("Goal object is no longer valid");
}

tfentities::HBaseObject object(m_object.Get());

if (object.GetPercentageConstructed() > 0.99f)
{
return Done("Object is fully constructed!");
}

/* TODO position behind sentry if under attack by enemy */

auto myweapon = bot->GetActiveBotWeapon();

if (myweapon && myweapon->GetModWeaponID<TeamFortress2::TFWeaponID>() != TeamFortress2::TFWeaponID::TF_WEAPON_WRENCH)
{
CBaseEntity* wrench = bot->GetWeaponOfSlot(TeamFortress2::TFWeaponSlot::TFWeaponSlot_Melee);

if (wrench)
{
bot->SelectWeapon(wrench);
}
}

if (bot->GetRangeTo(object.WorldSpaceCenter()) > get_object_melee_range())
{
if (!m_nav.IsValid() || m_nav.GetAge() > 3.0f)
{
CTF2BotPathCost cost(bot);

if (!m_nav.ComputePathToPosition(bot, object.GetAbsOrigin(), cost))
{
return Done("No path to object.");
}
}

m_nav.Update(bot);
}
else
{
bot->GetControlInterface()->AimAt(object.WorldSpaceCenter(), IPlayerController::LOOK_VERY_IMPORTANT, 0.5f, "Looking at object to construct it.");
bot->GetControlInterface()->PressAttackButton(0.5f);
bot->GetControlInterface()->PressCrouchButton(0.5f);
}

return Continue();
}
26 changes: 26 additions & 0 deletions extension/bot/tf2/tasks/engineer/tf2bot_engineer_speedup_object.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef NAVBOT_TF2BOT_TASKS_ENGINEER_SPEEDUP_OBJECT_H_
#define NAVBOT_TF2BOT_TASKS_ENGINEER_SPEEDUP_OBJECT_H_

#include <sdkports/sdk_ehandle.h>
#include <bot/interfaces/path/meshnavigator.h>

class CTF2Bot;

class CTF2BotEngineerSpeedUpObjectTask : public AITask<CTF2Bot>
{
public:
CTF2BotEngineerSpeedUpObjectTask(CBaseEntity* object);

TaskResult<CTF2Bot> OnTaskStart(CTF2Bot* bot, AITask<CTF2Bot>* pastTask) override;
TaskResult<CTF2Bot> OnTaskUpdate(CTF2Bot* bot) override;

const char* GetName() const override { return "SpeedUpConstruction"; }

private:
CHandle<CBaseEntity> m_object;
CMeshNavigator m_nav;

static constexpr auto get_object_melee_range() { return 64.0f; }
};

#endif // !NAVBOT_TF2BOT_TASKS_ENGINEER_SPEEDUP_OBJECT_H_
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ TaskResult<CTF2Bot> CTF2BotEngineerUpgradeObjectTask::OnTaskUpdate(CTF2Bot* bot)
{
bot->GetControlInterface()->AimAt(object.WorldSpaceCenter(), IPlayerController::LOOK_VERY_IMPORTANT, 0.5f, "Looking at object to upgrade it.");
bot->GetControlInterface()->PressAttackButton(0.5f);
bot->GetControlInterface()->PressCrouchButton(0.5f);
}

return Continue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class CTF2BotEngineerUpgradeObjectTask : public AITask<CTF2Bot>
CHandle<CBaseEntity> m_object;
CMeshNavigator m_nav;

static constexpr auto get_object_melee_range() { return 72.0f; }
static constexpr auto get_object_melee_range() { return 64.0f; }
};


Expand Down
12 changes: 10 additions & 2 deletions extension/bot/tf2/tasks/tf2bot_find_ammo_task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ TaskResult<CTF2Bot> CTF2BotFindAmmoTask::OnTaskUpdate(CTF2Bot* bot)
return Done("Ammo collected!");
}

if (bot->GetMyClassType() == TeamFortress2::TFClass_Engineer && bot->GetAmmoOfIndex(TeamFortress2::TF_AMMO_METAL) >= 200)
{
return Done("Ammo collected!");
}

UpdateSourcePosition();

if (m_repathtimer.IsElapsed())
Expand Down Expand Up @@ -224,7 +229,7 @@ CTF2BotFindAmmoTask::AmmoSource CTF2BotFindAmmoTask::FindSource(CTF2Bot* me)

if (me->IsDebugging(BOTDEBUG_TASKS))
{
me->DebugPrintToConsole(BOTDEBUG_TASKS, 153, 156, 255, "%s Found Ammo Source <%i> at %3.2f, %3.2f, %3.2f", me->GetDebugIdentifier(), static_cast<int>(source),
me->DebugPrintToConsole(BOTDEBUG_TASKS, 153, 156, 255, "%s Found Ammo Source <%i> at %3.2f, %3.2f, %3.2f\n", me->GetDebugIdentifier(), static_cast<int>(source),
m_sourcepos.x, m_sourcepos.y, m_sourcepos.z);

NDebugOverlay::Text(m_sourcepos, "Ammo Source!", false, 10.0f);
Expand Down Expand Up @@ -260,7 +265,10 @@ bool CTF2BotFindAmmoTask::IsSourceStillValid(CTF2Bot* me)
{
tfentities::HTFBaseEntity entity(edict);

if (entity.IsEffectActive(EF_NODRAW) || entity.IsDisabled())
if (entity.IsEffectActive(EF_NODRAW))
return false;

if (entity.IsDisabled())
return false;

break;
Expand Down
2 changes: 2 additions & 0 deletions extension/bot/tf2/tf2bot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,8 @@ bool CTF2Bot::IsInsideSpawnRoom() const
return result > 0;
}



CTF2BotPathCost::CTF2BotPathCost(CTF2Bot* bot, RouteType routetype)
{
m_me = bot;
Expand Down
17 changes: 17 additions & 0 deletions extension/concommands_debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -495,4 +495,21 @@ CON_COMMAND(sm_navbot_debug_tests, "Debug stuff")
Msg("Flag return position: %3.2f %3.2f %3.2f\n", out.x, out.y, out.z);
}

CON_COMMAND_F(sm_navbot_debug_server_class, "Debug ServerClass class.", FCVAR_CHEAT)
{
CBaseEntity* entity = gamehelpers->ReferenceToEntity(1);
ServerClass* pClass = gamehelpers->FindEntityServerClass(entity);

auto name = pClass->GetName();
auto id = pClass->m_ClassID;
auto netname = pClass->m_pNetworkName;
auto table = pClass->m_pTable;
const char* tablename = table ? table->GetName() : "NULL";

Msg("Name: %s\n", name ? name : "NULL");
Msg("ID: %i\n", id);
Msg("Network Name: %s\n", netname ? netname : "NULL");
Msg("Table Name: %s\n", tablename ? tablename : "NULL");
}

#endif // EXT_DEBUG
Loading

0 comments on commit 90eca6d

Please sign in to comment.