Since I try to make Survival Mod, the first thing I started is the bots, or rather their logic of movement and attack.
At the moment I only implemented LookLogic (not fully)
This is just a preview, I think in the future I can give the bots full logic, but my plans are only related to Survival Mod, I do not consider other modes yet (FFA is currently working)
Send me PM, if you have any ideas for realizing
Watching logic
Youtube Video
Move logic
Youtube Video
Animated move
Youtube Video
Implemeted:
- Look logic (default target player with num 0)
- Move logic (default target player with num 0) IF BOT SEE YOU
- Animated movement
[this list will be updated]
Download movement animation added
Source:
// This is preview version
// This is only the beginning of creating bots with the logic of movement and attack,
// but first of all I want to create Survival mode, so do not expect bots that can play in TDM, FFA, DZ and other.
// I guess I would do it after creating this script
// AIBots by S3VDITO
// Ver 0.0.0.3
// Realized:
// 1 - watching for player function (not works now)
// 2 - move logic [not fully] [without check collision] (in progress...)
// 3 - animated movement
gsc.setDvar("testClients_doAttack", 0);
gsc.setDvar("testClients_doCrouch", 0);
gsc.setDvar("testClients_doMove", 0);
gsc.setDvar("testClients_doReload", 0);
gsc.setDvar("testClients_doWatchKillcam", 0);
gsc.setDvarIfUninitialized("testClients_doSpeed", 4);
global bot_speed = to_float(gsc.getDvar("testClients_doSpeed"));
global bots_list = [];
global player_target_list = [];
level.onNotify("connected", fun(args) {
var player = args[0];
print(player.getGuid().find("bot"));
if(player.getGuid().find("bot") != 0)
{
print("Player connected");
player_target_list.push_back_ref(player);
}
});
level.onNotify("prematch_done", fun(args) {
if(gsc.getDvar("g_gametype") == "dm") {
for(var entRef = 0; entRef < 18; ++entRef)
{
var tempEntBot = gsc.getEntByNum(entRef);
if(tempEntBot.getGuid().find("bot") == 0)
{
var animBody = gsc.spawn("script_model", tempEntBot.getOrigin());
animBody.setmodel("mp_body_delta_elite_assault_ab");
animBody.notsolid();
animBody.LinkTo(tempEntBot, "tag_origin", [-4, 0, -1], [-4, 0, -1]);
bots_list.push_back_ref(tempEntBot);
setInterval(fun[tempEntBot, animBody]() {
botMove(tempEntBot, gsc.getEntByNum(0), animBody);
}, 50);
setInterval(fun[animBody]() {
animBody.scriptModelPlayAnim("pb_stumble_pistol_walk_forward");
}, 1000);
}
}
}
});
def botMove(bot, target, animModel)
{
var bot_weapon_origin = bot.getTagOrigin("tag_weapon_left");
HideTestClientParts(bot);
if(LockSightTest(bot, target) == false)
{
// animModel.scriptModelPlayAnim("pb_stand_alert_pistol");
return;
}
else
{
var angle = gsc.vectorToAngles([target.getTagOrigin("j_helmet")[0] - bot_weapon_origin[0], target.getTagOrigin("j_helmet")[1] - bot_weapon_origin[1], target.getTagOrigin("j_helmet")[2] - bot_weapon_origin[2]]);
bot.setPlayerAngles(angle);
// Spaming field bug =(
//animModel.set("angles", bot.getPlayerAngles());
}
var moveTarget = target.getOrigin();
var distance = gsc.distanceSquared(moveTarget, bot.getOrigin());
if(gsc.distance(moveTarget, bot.getOrigin()) <= 64)
{
// bot_speed = 0;
}
else
{
bot_speed = to_float(gsc.getDvar("testClients_doSpeed"));
var normalize = gsc.vectorNormalize([moveTarget[0] - bot.getOrigin()[0], moveTarget[1] - bot.getOrigin()[1], moveTarget[2] - bot.getOrigin()[2]]);
bot.setOrigin([bot.getOrigin()[0] + normalize[0] * bot_speed, bot.getOrigin()[1] + normalize[1] * bot_speed, bot.getOrigin()[2] + normalize[2] * bot_speed]);
}
}
def HideTestClientParts(bot)
{
bot.hidepart("j_ankle_le");
bot.hidepart("j_hiptwist_le");
bot.hidepart("j_head");
bot.hidepart("j_helmet");
bot.hidepart("j_eyeball_le");
bot.hidepart("j_clavicle_le");
}
// Stolen from _stinger.gsc :)
def LockSightTest(self, target)
{
var eyePos = self.GetEye();
var passed = gsc.SightTracePassed(eyePos, target.getOrigin(), false, target);
if ( passed == 1)
{
return true;
}
var front = target.GetPointInBounds(1, 0, 0);
passed = gsc.SightTracePassed( eyePos, front, false, target );
if (passed == 1)
{
return true;
}
var back = target.GetPointInBounds(-1, 0, 0);
passed = gsc.SightTracePassed( eyePos, back, false, target );
if (passed == 1)
{
return true;
}
return false;
}