Added custom monsters and custom items support
This commit is contained in:
parent
ac86926dc8
commit
d5107daad4
7 changed files with 82 additions and 6 deletions
|
|
@ -401,3 +401,16 @@ yb_display_welcome_text "1"
|
||||||
//
|
//
|
||||||
yb_enable_query_hook "0"
|
yb_enable_query_hook "0"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Allows or disallows bots to take attack monsters.
|
||||||
|
// ---
|
||||||
|
// Default: "0", Min: "0", Max: "1"
|
||||||
|
//
|
||||||
|
yb_attack_monsters "0"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Allows or disallows bots to pickup custom items.
|
||||||
|
// ---
|
||||||
|
// Default: "0", Min: "0", Max: "1"
|
||||||
|
//
|
||||||
|
yb_pickup_custom_items "0"
|
||||||
|
|
@ -55,6 +55,12 @@ public:
|
||||||
// check if entitiy is a player
|
// check if entitiy is a player
|
||||||
bool isPlayer (edict_t *ent);
|
bool isPlayer (edict_t *ent);
|
||||||
|
|
||||||
|
// check if entitiy is a monster
|
||||||
|
bool isMonster (edict_t *ent);
|
||||||
|
|
||||||
|
// check if entitiy is a item
|
||||||
|
bool isItem (edict_t *ent);
|
||||||
|
|
||||||
// check if entity is a vip
|
// check if entity is a vip
|
||||||
bool isPlayerVIP (edict_t *ent);
|
bool isPlayerVIP (edict_t *ent);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1164,6 +1164,8 @@ extern ConVar cv_whose_your_daddy;
|
||||||
extern ConVar cv_chatter_path;
|
extern ConVar cv_chatter_path;
|
||||||
extern ConVar cv_quota;
|
extern ConVar cv_quota;
|
||||||
extern ConVar cv_difficulty;
|
extern ConVar cv_difficulty;
|
||||||
|
extern ConVar cv_attack_monsters;
|
||||||
|
extern ConVar cv_pickup_custom_items;
|
||||||
|
|
||||||
// execute client command helper
|
// execute client command helper
|
||||||
template <typename ...Args> void Bot::issueCommand (const char *fmt, Args &&...args) {
|
template <typename ...Args> void Bot::issueCommand (const char *fmt, Args &&...args) {
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,9 @@ ConVar cv_destroy_breakables_around ("yb_destroy_breakables_around", "1", "Allow
|
||||||
ConVar cv_chatter_path ("yb_chatter_path", "sound/radio/bot", "Specifies the paths for the bot chatter sound files.", false);
|
ConVar cv_chatter_path ("yb_chatter_path", "sound/radio/bot", "Specifies the paths for the bot chatter sound files.", false);
|
||||||
ConVar cv_restricted_weapons ("yb_restricted_weapons", "", "Specifies semicolon separated list of weapons that are not allowed to buy / pickup.", false);
|
ConVar cv_restricted_weapons ("yb_restricted_weapons", "", "Specifies semicolon separated list of weapons that are not allowed to buy / pickup.", false);
|
||||||
|
|
||||||
|
ConVar cv_attack_monsters ("yb_attack_monsters", "0", "Allows or disallows bots to take attack monsters.");
|
||||||
|
ConVar cv_pickup_custom_items ("yb_pickup_custom_items", "0", "Allows or disallows bots to pickup custom items.");
|
||||||
|
|
||||||
// game console variables
|
// game console variables
|
||||||
ConVar mp_c4timer ("mp_c4timer", nullptr, Var::GameRef);
|
ConVar mp_c4timer ("mp_c4timer", nullptr, Var::GameRef);
|
||||||
ConVar mp_flashlight ("mp_flashlight", nullptr, Var::GameRef);
|
ConVar mp_flashlight ("mp_flashlight", nullptr, Var::GameRef);
|
||||||
|
|
@ -573,6 +576,10 @@ void Bot::updatePickups () {
|
||||||
allowPickup = true;
|
allowPickup = true;
|
||||||
pickupType = Pickup::PlantedC4;
|
pickupType = Pickup::PlantedC4;
|
||||||
}
|
}
|
||||||
|
else if (cv_pickup_custom_items.bool_ () && util.isItem(ent) && strncmp ("item_thighpack", classname, 14) != 0) {
|
||||||
|
allowPickup = true;
|
||||||
|
pickupType = Pickup::None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the bot found something it can pickup...
|
// if the bot found something it can pickup...
|
||||||
|
|
@ -1690,7 +1697,7 @@ void Bot::overrideConditions () {
|
||||||
m_moveToGoal = false; // don't move to goal
|
m_moveToGoal = false; // don't move to goal
|
||||||
m_navTimeset = game.time ();
|
m_navTimeset = game.time ();
|
||||||
|
|
||||||
if (util.isPlayer (m_enemy)) {
|
if (util.isPlayer (m_enemy) || (cv_attack_monsters.bool_ () && util.isMonster (m_enemy))) {
|
||||||
attackMovement ();
|
attackMovement ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1704,7 +1711,7 @@ void Bot::overrideConditions () {
|
||||||
}
|
}
|
||||||
|
|
||||||
// special handling, if we have a knife in our hands
|
// special handling, if we have a knife in our hands
|
||||||
if ((bots.getRoundStartTime () + 6.0f > game.time () || !hasAnyWeapons ()) && usesKnife () && util.isPlayer (m_enemy)) {
|
if ((bots.getRoundStartTime () + 6.0f > game.time () || !hasAnyWeapons ()) && usesKnife () && (util.isPlayer (m_enemy) || (cv_attack_monsters.bool_ () && util.isMonster (m_enemy)))) {
|
||||||
float length = (pev->origin - m_enemy->v.origin).length2d ();
|
float length = (pev->origin - m_enemy->v.origin).length2d ();
|
||||||
|
|
||||||
// do waypoint movement if enemy is not reachable with a knife
|
// do waypoint movement if enemy is not reachable with a knife
|
||||||
|
|
@ -5096,8 +5103,8 @@ void Bot::takeDamage (edict_t *inflictor, int damage, int armor, int bits) {
|
||||||
m_lastDamageType = bits;
|
m_lastDamageType = bits;
|
||||||
updatePracticeValue (damage);
|
updatePracticeValue (damage);
|
||||||
|
|
||||||
if (util.isPlayer (inflictor)) {
|
if (util.isPlayer (inflictor) || (cv_attack_monsters.bool_ () && util.isMonster (inflictor))) {
|
||||||
if (cv_tkpunish.bool_ () && game.getTeam (inflictor) == m_team && !util.isFakeClient (inflictor)) {
|
if (!util.isMonster (inflictor) && cv_tkpunish.bool_ () && game.getTeam (inflictor) == m_team && !util.isFakeClient (inflictor)) {
|
||||||
// alright, die you teamkiller!!!
|
// alright, die you teamkiller!!!
|
||||||
m_actualReactionTime = 0.0f;
|
m_actualReactionTime = 0.0f;
|
||||||
m_seeEnemyTime = game.time ();
|
m_seeEnemyTime = game.time ();
|
||||||
|
|
|
||||||
|
|
@ -234,6 +234,30 @@ bool Bot::lookupEnemies () {
|
||||||
// ignore shielded enemies, while we have real one
|
// ignore shielded enemies, while we have real one
|
||||||
edict_t *shieldEnemy = nullptr;
|
edict_t *shieldEnemy = nullptr;
|
||||||
|
|
||||||
|
if (cv_attack_monsters. bool_()) {
|
||||||
|
// search the world for monsters...
|
||||||
|
for (const auto &intresting : bots.getIntrestingEntities ()) {
|
||||||
|
if (!util.isMonster(intresting)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check the engine PVS
|
||||||
|
if (!isEnemyInFrustum (intresting) || !game.checkVisibility (intresting, set)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// see if bot can see the monster...
|
||||||
|
if (seesEnemy (intresting)) {
|
||||||
|
float distance = (intresting->v.origin - pev->origin).lengthSq ();
|
||||||
|
|
||||||
|
if (distance * 0.7f < nearestDistance) {
|
||||||
|
nearestDistance = distance;
|
||||||
|
newEnemy = intresting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// search the world for players...
|
// search the world for players...
|
||||||
for (const auto &client : util.getClients ()) {
|
for (const auto &client : util.getClients ()) {
|
||||||
if (!(client.flags & ClientFlags::Used) || !(client.flags & ClientFlags::Alive) || client.team == m_team || client.ent == ent () || !client.ent) {
|
if (!(client.flags & ClientFlags::Used) || !(client.flags & ClientFlags::Alive) || client.team == m_team || client.ent == ent () || !client.ent) {
|
||||||
|
|
@ -277,7 +301,7 @@ bool Bot::lookupEnemies () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (util.isPlayer (newEnemy)) {
|
if (util.isPlayer (newEnemy) || (cv_attack_monsters.bool_ () && util.isMonster (newEnemy))) {
|
||||||
bots.setCanPause (true);
|
bots.setCanPause (true);
|
||||||
|
|
||||||
m_aimFlags |= AimFlags::Enemy;
|
m_aimFlags |= AimFlags::Enemy;
|
||||||
|
|
|
||||||
|
|
@ -1652,7 +1652,7 @@ void BotManager::updateIntrestingEntities () {
|
||||||
auto classname = e->v.classname.chars ();
|
auto classname = e->v.classname.chars ();
|
||||||
|
|
||||||
// search for grenades, weaponboxes, weapons, items and armoury entities
|
// search for grenades, weaponboxes, weapons, items and armoury entities
|
||||||
if (strncmp ("weaponbox", classname, 9) == 0 || strncmp ("grenade", classname, 7) == 0 || strncmp ("item", classname, 4) == 0 || strncmp ("armoury", classname, 7) == 0) {
|
if (strncmp ("weaponbox", classname, 9) == 0 || strncmp ("grenade", classname, 7) == 0 || util.isItem (e) || strncmp ("armoury", classname, 7) == 0) {
|
||||||
m_intrestingEntities.push (e);
|
m_intrestingEntities.push (e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1671,6 +1671,10 @@ void BotManager::updateIntrestingEntities () {
|
||||||
m_intrestingEntities.push (e);
|
m_intrestingEntities.push (e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cv_attack_monsters.bool_ () && util.isMonster (e)) {
|
||||||
|
m_intrestingEntities.push (e);
|
||||||
|
}
|
||||||
|
|
||||||
// continue iteration
|
// continue iteration
|
||||||
return EntitySearchResult::Continue;
|
return EntitySearchResult::Continue;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -205,6 +205,26 @@ bool BotSupport::isPlayer (edict_t *ent) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BotSupport::isMonster (edict_t *ent) {
|
||||||
|
if (game.isNullEntity (ent)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (~ent->v.flags & FL_MONSTER) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp ("hostage", ent->v.classname.chars(), 7) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BotSupport::isItem (edict_t *ent) {
|
||||||
|
return !!(strstr (ent->v.classname.chars(), "item"));
|
||||||
|
}
|
||||||
|
|
||||||
bool BotSupport::isPlayerVIP (edict_t *ent) {
|
bool BotSupport::isPlayerVIP (edict_t *ent) {
|
||||||
if (!game.mapIs (MapFlags::Assassination)) {
|
if (!game.mapIs (MapFlags::Assassination)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue