Added custom monsters and custom items support

This commit is contained in:
Hedgehog Fog 2020-12-03 14:14:22 +02:00
commit d5107daad4
7 changed files with 82 additions and 6 deletions

View file

@ -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_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
ConVar mp_c4timer ("mp_c4timer", nullptr, Var::GameRef);
ConVar mp_flashlight ("mp_flashlight", nullptr, Var::GameRef);
@ -573,6 +576,10 @@ void Bot::updatePickups () {
allowPickup = true;
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...
@ -1690,7 +1697,7 @@ void Bot::overrideConditions () {
m_moveToGoal = false; // don't move to goal
m_navTimeset = game.time ();
if (util.isPlayer (m_enemy)) {
if (util.isPlayer (m_enemy) || (cv_attack_monsters.bool_ () && util.isMonster (m_enemy))) {
attackMovement ();
}
}
@ -1704,7 +1711,7 @@ void Bot::overrideConditions () {
}
// 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 ();
// 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;
updatePracticeValue (damage);
if (util.isPlayer (inflictor)) {
if (cv_tkpunish.bool_ () && game.getTeam (inflictor) == m_team && !util.isFakeClient (inflictor)) {
if (util.isPlayer (inflictor) || (cv_attack_monsters.bool_ () && util.isMonster (inflictor))) {
if (!util.isMonster (inflictor) && cv_tkpunish.bool_ () && game.getTeam (inflictor) == m_team && !util.isFakeClient (inflictor)) {
// alright, die you teamkiller!!!
m_actualReactionTime = 0.0f;
m_seeEnemyTime = game.time ();

View file

@ -234,6 +234,30 @@ bool Bot::lookupEnemies () {
// ignore shielded enemies, while we have real one
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...
for (const auto &client : util.getClients ()) {
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);
m_aimFlags |= AimFlags::Enemy;

View file

@ -1652,7 +1652,7 @@ void BotManager::updateIntrestingEntities () {
auto classname = e->v.classname.chars ();
// 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);
}
@ -1671,6 +1671,10 @@ void BotManager::updateIntrestingEntities () {
m_intrestingEntities.push (e);
}
if (cv_attack_monsters.bool_ () && util.isMonster (e)) {
m_intrestingEntities.push (e);
}
// continue iteration
return EntitySearchResult::Continue;
});

View file

@ -205,6 +205,26 @@ bool BotSupport::isPlayer (edict_t *ent) {
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) {
if (!game.mapIs (MapFlags::Assassination)) {
return false;