nav: fixed lift usage as much as possible without full rewrite

mgr: end round with ``endround`` regamedll command if available (menus only)
aim: prevent look angles overflows in some situations
This commit is contained in:
jeefo 2024-04-14 17:13:22 +03:00
commit 0de53173f0
No known key found for this signature in database
GPG key ID: 927BCA0779BEA8ED
5 changed files with 67 additions and 45 deletions

View file

@ -519,7 +519,7 @@ private:
void pickupItem_ ();
void shootBreakable_ ();
edict_t *lookupButton (StringRef target);
edict_t *lookupButton (StringRef target, bool blindTest = false);
edict_t *lookupBreakable ();
edict_t *setCorrectGrenadeVelocity (StringRef model);

View file

@ -1025,7 +1025,12 @@ int BotControl::menuMain (int item) {
break;
case 4:
bots.killAllBots ();
if (game.is (GameFlags::ReGameDLL)) {
game.serverCommand ("endround");
}
else {
bots.killAllBots ();
}
break;
case 10:

View file

@ -1070,7 +1070,7 @@ bool Bot::updateNavigation () {
// delay task
if (m_buttonPushTime < game.time ()) {
auto button = lookupButton (tr.pHit->v.targetname.chars ());
auto button = lookupButton (tr.pHit->v.targetname.chars (), true);
// check if we got valid button
if (!game.isNullEntity (button)) {
@ -1241,6 +1241,7 @@ bool Bot::updateLiftHandling () {
auto wait = [&] () {
m_moveSpeed = 0.0f;
m_strafeSpeed = 0.0f;
m_checkTerrain = false;
m_navTimeset = game.time ();
m_aimFlags |= AimFlags::Nav;
@ -1250,6 +1251,13 @@ bool Bot::updateLiftHandling () {
ignoreCollision ();
};
// need to wait?
auto checkNeedToWait = [&] (float limitSq = 22.0f) {
if (pev->origin.distanceSq (m_destOrigin) < cr::sqrf (limitSq)) {
wait ();
}
};
// trace line to door
game.testLine (pev->origin, m_pathOrigin, TraceIgnore::Everything, ent (), &tr);
@ -1291,8 +1299,7 @@ bool Bot::updateLiftHandling () {
m_liftUsageTime = game.time () + 7.0f;
}
}
else if (!m_pathWalk.empty ()) // no lift found at node
{
else if (!m_pathWalk.empty ()) { // no lift found at node
if ((m_liftState == LiftState::None || m_liftState == LiftState::WaitingFor) && m_pathWalk.hasNext ()) {
int nextNode = m_pathWalk.next ();
@ -1313,7 +1320,7 @@ bool Bot::updateLiftHandling () {
m_destOrigin = m_liftTravelPos;
// check if we enough to destination
if (pev->origin.distanceSq (m_destOrigin) < cr::sqrf (20.0f)) {
if (pev->origin.distanceSq (m_destOrigin) < cr::sqrf (22.0f)) {
wait ();
// need to wait our following teammate ?
@ -1371,10 +1378,7 @@ bool Bot::updateLiftHandling () {
// need to wait for teammate
if (needWaitForTeammate) {
m_destOrigin = m_liftTravelPos;
if (pev->origin.distanceSq (m_destOrigin) < cr::sqrf (20.0f)) {
wait ();
}
checkNeedToWait ();
}
// else we need to look for button
@ -1386,7 +1390,9 @@ bool Bot::updateLiftHandling () {
// bot is trying to find button inside a lift
if (m_liftState == LiftState::LookingButtonInside) {
auto button = lookupButton (m_liftEntity->v.targetname.str ());
m_checkTerrain = false;
auto button = lookupButton (m_liftEntity->v.targetname.str (), true);
// got a valid button entity ?
if (!game.isNullEntity (button)
@ -1395,11 +1401,21 @@ bool Bot::updateLiftHandling () {
&& cr::fzero (m_liftEntity->v.velocity.z)
&& isOnFloor ()) {
m_pickupItem = button;
m_pickupType = Pickup::Button;
auto buttonWithLineOfSight = lookupButton (m_liftEntity->v.targetname.str (), false);
m_navTimeset = game.time ();
if (!game.isNullEntity (buttonWithLineOfSight)) {
m_pickupItem = buttonWithLineOfSight;
m_pickupType = Pickup::Button;
}
else {
MDLL_Use (button, ent ());
}
if (pev->origin.distanceSq2d (graph[m_previousNodes[0]].origin) < cr::sqrf (64.0f)) {
wait ();
}
}
ignoreCollision ();
}
// is lift activated and bot is standing on it and lift is moving ?
@ -1416,9 +1432,7 @@ bool Bot::updateLiftHandling () {
m_liftState = LiftState::TravelingBy;
m_liftUsageTime = game.time () + 14.0f;
if (pev->origin.distanceSq (m_destOrigin) < cr::sqrf (20.0f)) {
wait ();
}
checkNeedToWait ();
}
}
@ -1426,9 +1440,7 @@ bool Bot::updateLiftHandling () {
if (m_liftState == LiftState::TravelingBy) {
m_destOrigin = Vector (m_liftTravelPos.x, m_liftTravelPos.y, pev->origin.z);
if (pev->origin.distanceSq (m_destOrigin) < cr::sqrf (20.0f)) {
wait ();
}
checkNeedToWait ();
}
// need to find a button outside the lift
@ -1442,13 +1454,10 @@ bool Bot::updateLiftHandling () {
else {
m_destOrigin = pev->origin;
}
if (pev->origin.distanceSq (m_destOrigin) < cr::sqrf (20.0f)) {
wait ();
}
checkNeedToWait (64.0f);
}
else if (!game.isNullEntity (m_liftEntity)) {
auto button = lookupButton (m_liftEntity->v.targetname.str ());
auto button = lookupButton (m_liftEntity->v.targetname.str (), true);
// if we got a valid button entity
if (!game.isNullEntity (button)) {
@ -1457,7 +1466,11 @@ bool Bot::updateLiftHandling () {
// iterate though clients, and find if lift already used
for (const auto &client : util.getClients ()) {
if (!(client.flags & ClientFlags::Used) || !(client.flags & ClientFlags::Alive) || client.team != m_team || client.ent == ent () || game.isNullEntity (client.ent->v.groundentity)) {
if (!(client.flags & ClientFlags::Used)
|| !(client.flags & ClientFlags::Alive)
|| client.team != m_team
|| client.ent == ent ()
|| game.isNullEntity (client.ent->v.groundentity)) {
continue;
}
@ -1475,14 +1488,12 @@ bool Bot::updateLiftHandling () {
else {
m_destOrigin = button->v.origin;
}
if (pev->origin.distanceSq (m_destOrigin) < cr::sqrf (20.0f)) {
wait ();
}
checkNeedToWait (64.0f);
}
else {
m_pickupItem = button;
m_pickupType = Pickup::Button;
m_liftState = LiftState::WaitingFor;
m_navTimeset = game.time ();
@ -1506,10 +1517,7 @@ bool Bot::updateLiftHandling () {
m_destOrigin = graph[m_previousNodes[1]].origin;
}
}
if (pev->origin.distanceSq (m_destOrigin) < cr::sqrf (20.0f)) {
wait ();
}
checkNeedToWait (64.0f);
}
// if bot is waiting for lift, or going to it
@ -2409,7 +2417,7 @@ bool Bot::advanceMovement () {
// get ladder nodes used by other (first moving) bots
for (const auto &other : bots) {
// if another bot uses this ladder, wait 3 secs
if (other.get () != this && other->m_isAlive && other->m_currentNodeIndex == destIndex) {
if (other.get () != this && other->m_isAlive && other->m_currentNodeIndex == destIndex && other->isOnLadder ()) {
startTask (Task::Pause, TaskPri::Pause, kInvalidNodeIndex, game.time () + 3.0f, false);
return true;
}
@ -3074,7 +3082,7 @@ bool Bot::isOccupiedNode (int index, bool needZeroVelocity) {
return false;
}
edict_t *Bot::lookupButton (StringRef target) {
edict_t *Bot::lookupButton (StringRef target, bool blindTest) {
// this function tries to find nearest to current bot button, and returns pointer to
// it's entity, also here must be specified the target, that button must open.
@ -3090,10 +3098,12 @@ edict_t *Bot::lookupButton (StringRef target) {
game.searchEntities ("target", target, [&] (edict_t *ent) {
const Vector &pos = game.getEntityOrigin (ent);
game.testLine (pev->origin, pos, TraceIgnore::Monsters, pev->pContainingEntity, &tr);
if (!blindTest) {
game.testLine (pev->origin, pos, TraceIgnore::Monsters, pev->pContainingEntity, &tr);
}
// check if this place safe
if (tr.pHit == ent && tr.flFraction > 0.95f && !isDeadlyMove (pos)) {
if (blindTest || (tr.pHit == ent || tr.flFraction > 0.95f)) {
const float distanceSq = pev->origin.distanceSq (pos);
// check if we got more close button

View file

@ -1687,9 +1687,15 @@ void Bot::pickupItem_ () {
break;
}
float distanceToButtonSq = cr::sqrf (90.0f);
// reduce on lifts
if (!game.isNullEntity (m_liftEntity)) {
distanceToButtonSq = cr::sqrf (24.0f);
}
// near to the button?
if (itemDistanceSq < cr::sqrf (90.0f)) {
if (itemDistanceSq < distanceToButtonSq) {
m_moveSpeed = 0.0f;
m_strafeSpeed = 0.0f;
m_moveToGoal = false;

View file

@ -201,9 +201,9 @@ void Bot::setAimDirection () {
else {
m_lookAt = m_destOrigin;
}
const bool onLadder = (m_pathFlags & NodeFlag::Ladder);
const bool horizontalMovement = (m_pathFlags & NodeFlag::Ladder) || isOnLadder () || !cr::fzero (pev->velocity.z);
if (m_canChooseAimDirection && m_seeEnemyTime + 4.0f < game.time () && m_currentNodeIndex != kInvalidNodeIndex && !onLadder) {
if (m_canChooseAimDirection && m_seeEnemyTime + 4.0f < game.time () && m_currentNodeIndex != kInvalidNodeIndex && !horizontalMovement) {
const auto dangerIndex = practice.getIndex (m_team, m_currentNodeIndex, m_currentNodeIndex);
if (graph.exists (dangerIndex)
@ -223,7 +223,7 @@ void Bot::setAimDirection () {
}
// try look at next node if on ladder
if (onLadder && m_pathWalk.hasNext ()) {
if (horizontalMovement && m_pathWalk.hasNext ()) {
const auto &nextPath = graph[m_pathWalk.next ()];
if ((nextPath.flags & NodeFlag::Ladder) && m_destOrigin.distanceSq (pev->origin) < cr::sqrf (128.0f) && nextPath.origin.z > m_pathOrigin.z + 26.0f) {
@ -240,7 +240,7 @@ void Bot::setAimDirection () {
}
// don't look at bottom of node, if reached it
if (m_lookAt == m_destOrigin && !onLadder) {
if (m_lookAt == m_destOrigin && !horizontalMovement) {
m_lookAt.z = getEyesPos ().z;
}
}
@ -402,7 +402,7 @@ void Bot::updateLookAngles () {
updateBodyAngles ();
return;
}
float aimSkill = cr::clamp (static_cast <float> (m_difficulty), 1.0f, 4.0f) * 25.0f;
float aimSkill = cr::clamp (static_cast <float> (m_difficulty), 3.0f, 4.0f) * 25.0f;
// do not slowdown while on ladder
if (isOnLadderPath () || isOnLadder ()) {
@ -462,7 +462,8 @@ void Bot::updateLookAngles () {
m_lookPitchVel += delta * accel;
m_idealAngles.x += cr::clamp (delta * m_lookPitchVel, -89.0f, 89.0f);
pev->v_angle = m_idealAngles;
pev->v_angle = m_idealAngles.clampAngles ();
pev->v_angle.z = 0.0f;
updateBodyAngles ();
}