diff --git a/source/src/bot/ac_bot.h b/source/src/bot/ac_bot.h index 1aac7cc0..84080300 100644 --- a/source/src/bot/ac_bot.h +++ b/source/src/bot/ac_bot.h @@ -15,7 +15,7 @@ #ifdef AC_CUBE -#define MAX_WEAPONS 7 +#define MAX_WEAPONS 10 class CACBot: public CBot { diff --git a/source/src/bot/ac_bot_ai.cpp b/source/src/bot/ac_bot_ai.cpp index 8b9926fc..7bf44ca3 100644 --- a/source/src/bot/ac_bot_ai.cpp +++ b/source/src/bot/ac_bot_ai.cpp @@ -13,26 +13,25 @@ #ifdef AC_CUBE -// UNDONE weaponinfo_s WeaponInfoTable[MAX_WEAPONS] = { - // KNIFE - { TYPE_MELEE, 0.0f, 2.0f, 0.0f, 3.5f, 1 }, - // PISTOL - { TYPE_NORMAL, 0.0f, 20.0f, 0.0f, 50.0f, 6 }, - // SHOTGUN - { TYPE_SHOTGUN, 0.0f, 15.0f, 0.0f, 40.0f, 3 }, - // SUBGUN - { TYPE_AUTO, 0.0f, 25.0f, 0.0f, 60.0f, 10 }, - // SNIPER - { TYPE_SNIPER, 30.0f, 50.0f, 20.0f, 200.0f, 3 }, - // ASSAULT - { TYPE_AUTO, 40.0f, 80.0f, 0.0f, 150.0f, 6 }, - // GRENADE - { TYPE_GRENADE, 30.0f, 25.0f, 0.0f, 50.0f, 1 } + // DD: desired distance + // FD: fire distance + // mA: min desired Ammo + // ---- Type : -- minDD -- maxDD -- minFD -- maxFD -- mA + { TYPE_MELEE, 0.0f, 2.0f, 0.0f, 3.5f, 1 }, // KNIFE + { TYPE_NORMAL, 0.0f, 20.0f, 0.0f, 50.0f, 6 }, // PISTOL + { TYPE_SNIPER, 20.0f, 80.0f, 0.0f, 0.0f, 2 }, // RIFLE + { TYPE_SHOTGUN, 0.0f, 15.0f, 0.0f, 40.0f, 3 }, // SHOTGUN + { TYPE_AUTO, 0.0f, 25.0f, 0.0f, 60.0f, 10 }, // SUBGUN + { TYPE_SNIPER, 23.0f, 75.0f, 20.0f, 200.0f, 3 }, // SNIPER + { TYPE_AUTO, 20.0f, 80.0f, 0.0f, 150.0f, 6 }, // ASSAULT + { TYPE_AUTO, 0.0f, 0.0f, 0.0f, 0.0f, 6 }, // CPISTOL + { TYPE_GRENADE, 30.0f, 25.0f, 0.0f, 50.0f, 1 }, // GRENADE + { TYPE_AUTO, 0.0f, 50.0f, 0.0f, 50.0f, 0 } // AKIMBO }; -// Code of CACBot - Start +// Code of CACBot - Start bool CACBot::ChoosePreferredWeapon() { @@ -47,13 +46,13 @@ bool CACBot::ChoosePreferredWeapon() if ((WeaponInfoTable[m_pMyEnt->gunselect].eWeaponType != TYPE_MELEE) || (flDist <= WeaponInfoTable[GUN_KNIFE].flMaxFireDistance)) return true; }; - + // Choose a weapon for(int i=0;imag[i] && !m_pMyEnt->ammo[i]) continue; - + sWeaponScore = 5; // Minimal score for a weapon // use the advantage of the melee weapon @@ -62,10 +61,10 @@ bool CACBot::ChoosePreferredWeapon() { if(WeaponInfoTable[i].eWeaponType == TYPE_MELEE) sWeaponScore += 5; } - + if ((flDist > WeaponInfoTable[i].flMinFireDistance) && // inside the range, continue to evaluate (flDist < WeaponInfoTable[i].flMaxFireDistance)) - { + { if(m_pMyEnt->mag[i]) sWeaponScore += 5; if(i > 1) sWeaponScore += 4; // prefer primary guns } @@ -75,13 +74,13 @@ bool CACBot::ChoosePreferredWeapon() bestWeaponScore = sWeaponScore; bestWeapon = i; } - } - + } + { m_iChangeWeaponDelay = lastmillis + 8000; //RandomLong(2000, 8000); m_bShootAtFeet = false; SelectGun(bestWeapon); - if(!m_pMyEnt->mag[bestWeapon]) + if(!m_pMyEnt->mag[bestWeapon]) { tryreload(m_pMyEnt); m_iShootDelay = lastmillis + reloadtime(bestWeapon) + 10; @@ -89,12 +88,12 @@ bool CACBot::ChoosePreferredWeapon() return true; } }; - + void CACBot::Reload(int Gun) { - + }; - + entity *CACBot::SearchForEnts(bool bUseWPs, float flRange, float flMaxHeight) { /* Entities are scored on the following things: @@ -102,32 +101,32 @@ entity *CACBot::SearchForEnts(bool bUseWPs, float flRange, float flMaxHeight) - For ammo: Need(ie has this bot much of this type or not) - distance */ - + float flNearestDist = 9999, flDist; entity *pNewTargetEnt = NULL; waypoint_s *pWptNearBot = NULL, *pBestWpt = NULL; short sScore, sHighestScore = 0; - + if ((WaypointClass.m_iWaypointCount >= 1) && bUseWPs) pWptNearBot = GetNearestWaypoint(15.0f); -#ifdef WP_FLOOD +#ifdef WP_FLOOD if (!pWptNearBot && bUseWPs) pWptNearBot = GetNearestFloodWP(5.0f); #endif - + loopv(ents) { sScore = 0; entity &e = ents[i]; vec o(e.x, e.y, S(e.x, e.y)->floor+player1->eyeheight); - + if (!ents[i].spawned) continue; if (OUTBORD(e.x, e.y)) continue; - + bool bInteresting = false; short sAmmo = 0, sMaxAmmo = 0; - + switch(e.type) { case I_CLIPS: @@ -147,7 +146,7 @@ entity *CACBot::SearchForEnts(bool bUseWPs, float flRange, float flMaxHeight) break; case I_HEALTH: sMaxAmmo = powerupstats[I_HEALTH-I_HEALTH].max; //FIXME - bInteresting = (m_pMyEnt->health < sMaxAmmo); + bInteresting = (m_pMyEnt->health < sMaxAmmo); sAmmo = m_pMyEnt->health; break; case I_ARMOUR: @@ -156,10 +155,10 @@ entity *CACBot::SearchForEnts(bool bUseWPs, float flRange, float flMaxHeight) sAmmo = m_pMyEnt->armour; break; }; - + if (!bInteresting) continue; // Not an interesting item, skip - + // Score on ammo and need if (sAmmo == -1) { @@ -176,38 +175,38 @@ entity *CACBot::SearchForEnts(bool bUseWPs, float flRange, float flMaxHeight) if (percent > 100.0f) percent = 100.0f; sScore += ((100 - short(percent))/2); } - + flDist = GetDistance(o); - + if (flDist > flRange) continue; - + // Score on distance float f = flDist; if (f > 100.0f) f = 100.0f; sScore += ((100 - short(f)) / 2); - + waypoint_s *pWptNearEnt = NULL; // If this entity isn't visible check if there is a nearby waypoint if (!IsReachable(o, flMaxHeight))//(!IsVisible(o)) { if (!pWptNearBot) continue; - -#ifdef WP_FLOOD + +#ifdef WP_FLOOD if (pWptNearBot->pNode->iFlags & W_FL_FLOOD) pWptNearEnt = GetNearestFloodWP(o, 8.0f); else -#endif +#endif pWptNearEnt = GetNearestWaypoint(o, 15.0f); - - if (!pWptNearEnt) continue; + + if (!pWptNearEnt) continue; } - + // Score on visibility if (pWptNearEnt == NULL) // Ent is visible sScore += 30; else sScore += 15; - + if (sScore > sHighestScore) { // Found a valid wp near the bot and the ent,so...lets store it :) @@ -215,15 +214,15 @@ entity *CACBot::SearchForEnts(bool bUseWPs, float flRange, float flMaxHeight) pBestWpt = pWptNearEnt; else pBestWpt = NULL; // Best ent so far doesn't need any waypoints - + sHighestScore = sScore; flNearestDist = flDist; pNewTargetEnt = &ents[i]; } } - + if (pNewTargetEnt) - { + { // Need waypoints to reach it? if (pBestWpt) { @@ -231,22 +230,22 @@ entity *CACBot::SearchForEnts(bool bUseWPs, float flRange, float flMaxHeight) SetCurrentWaypoint(pWptNearBot); SetCurrentGoalWaypoint(pBestWpt); } - + m_vGoal.x = pNewTargetEnt->x; m_vGoal.y = pNewTargetEnt->y; m_vGoal.z = S(pNewTargetEnt->x, pNewTargetEnt->y)->floor+player1->eyeheight; } - + return pNewTargetEnt; } bool CACBot::HeadToTargetEnt() -{ +{ if (m_pTargetEnt) { vec o(m_pTargetEnt->x, m_pTargetEnt->y, S(m_pTargetEnt->x, m_pTargetEnt->y)->floor+m_pMyEnt->eyeheight); - + if (m_pTargetEnt->spawned && (!UnderWater(m_pMyEnt->o) || !UnderWater(o))) { @@ -266,7 +265,7 @@ bool CACBot::HeadToTargetEnt() } else bIsVisible = IsVisible(o); - + if (bIsVisible) { if (m_pCurrentWaypoint || m_pCurrentGoalWaypoint) @@ -274,7 +273,7 @@ bool CACBot::HeadToTargetEnt() condebug("ent is now visible"); ResetWaypointVars(); } - + float flHeightDiff = o.z - m_pMyEnt->o.z; bool bToHigh = false; if (Get2DDistance(o) <= 2.0f) @@ -283,11 +282,11 @@ bool CACBot::HeadToTargetEnt() { if (flHeightDiff <= JUMP_HEIGHT) { -#ifndef RELEASE_BUILD +#ifndef RELEASE_BUILD char sz[64]; sprintf(sz, "Ent z diff: %f", o.z-m_pMyEnt->o.z); condebug(sz); -#endif +#endif // Jump if close to ent and the ent is high m_pMyEnt->jumpnext = true; } @@ -295,24 +294,24 @@ bool CACBot::HeadToTargetEnt() bToHigh = true; } } - + if (!bToHigh) { AimToVec(o); - return true; - } + return true; + } } } } - + return false; } - + bool CACBot::DoSPStuff() { return false; } - + // Code of CACBot - End #endif