Author Topic: Bot Problems || Strings  (Read 3616 times)

Hello! I'm making a script where bots spawn at $botSpawn (defined elsewhere), in the class and quantity you want them in. Yet, once they spawn they keep getting deleted since they don't have a spawn brick. The game checks every tick (??) to see if every bot is accommodated with a spawn brick. If they don't, the bot gets deleted. The thing is they actually do. I'm not sure how to fix this. Also, is there a way to make the spawning section of the bot less spammy? I just want it to act like a zombie.

This is the default code responsible:

   if( %spawnBrick.itemPosition != 1 && !hBrickClientCheck( %brickGroup ) )
   {
      //%pos = %obj.spawnBrick.getPosition();
      //%pos = vectoradd(%pos,"0 0 0.15");
      //%rot = getwords(%obj.spawnBrick.getTransform(),3,6);
      // other options delete the bot until user comes back? ##
      //%obj.setTransform(%pos SPC %rot);

      //%obj.stopHoleLoop();
      %obj.delete();
      echo("it's calling this!");
      echo(%brickgroup);
      //%obj.hSched = %obj.scheduleNoQuota(%tickrate+getrandom(0,750),hLoop);
      return;
   }


and here's my bot code:

//$botspawn exists
function spawnBots(%amount, %class)
{
   //Does it %amount amount of times.
   for(%i=0;%i<%amount;%i++)
   {
      //Creates the neccisary spawn brick. Otherwise bot kablooey-s.
      if(!isObject(%brick = nameToID(UselessRoboBrick)))
      {
         %brick = new fxDtsBrick(UselessRoboBrick)
         {
            datablock = brick1x1Data;
            isPlanted = false;
            itemPosition = 1;
            position = $botSpawn;
         };
      }
      schedule(33, 0, createRobot);
   }
}

function createRobot()
{
   talk("aklamo");
   //Creates the bot.
   %robot = new AiPlayer()
   {
      spawnTime = $Sim::Time;
      spawnBrick = %brick;
      dataBlock = "ZombieHoleBot";
      position = $botSpawn;

      //Springtime for Riddler
      Name = ZombieHoleBot.hName;
      hType = ZombieHoleBot.hType;
      hSearchRadius = ZombieHoleBot.hSearchRadius;
      hSearch = ZombieHoleBot.hSearch;
      hSight = ZombieHoleBot.hSight;
      hWander = ZombieHoleBot.hWander;
      hGridWander = ZombieHoleBot.hGridWander;
      hReturnToSpawn = ZombieHoleBot.hReturnToSpawn;
      hSpawnDist = ZombieHoleBot.hSpawnDist;
      hMelee = ZombieHoleBot.hMelee;
      hAttackDamage = ZombieHoleBot.hAttackDamage;
      hSpazJump = ZombieHoleBot.hSpazJump;
      hSearchFOV = ZombieHoleBot.hSearchFOV;
      hFOVRadius = ZombieHoleBot.hFOVRadius;
      hTooCloseRange = ZombieHoleBot.hTooCloseRange;
      hAvoidCloseRange = ZombieHoleBot.hAvoidCloseRang e;
      hShoot = ZombieHoleBot.hShoot;
      hMaxShootRange = ZombieHoleBot.hMaxShootRange;
      hStrafe = ZombieHoleBot.hStrafe;
      hAlertOtherBots = ZombieHoleBot.hAlertOtherBots;
      hIdleAnimation = ZombieHoleBot.hIdleAnimation;
      hSpasticLook = ZombieHoleBot.hSpasticLook;
      hAvoidObstacles = ZombieHoleBot.hAvoidObstacles;
      hIdleLookAtOthers = ZombieHoleBot.hIdleLookAtOthe rs;
      hIdleSpam = ZombieHoleBot.hIdleSpam;
      hAFKOmeter = ZombieHoleBot.hAFKOmeter + getRandom( 0, 2 );
      hHearing = ZombieHoleBot.hHearing;
      hIdle = ZombieHoleBot.hIdle;
      hSmoothWander = ZombieHoleBot.hSmoothWander;
      hEmote = ZombieHoleBot.hEmote;
      hSuperStacker = ZombieHoleBot.hSuperStacker;
      hNeutralAttackChance = ZombieHoleBot.hNeutralAttackC hance;
      hFOVRange = ZombieHoleBot.hFOVRange;
      hMoveSlowdown = ZombieHoleBot.hMoveSlowdown;
      hMaxMoveSpeed = 1.0;
      hActivateDirection = ZombieHoleBot.hActivateDirect ion;
      isHoleBot = 1;
   };
   missionCleanup.add(%robot);
}

//Experimental stuff, trying to fix the problem.
package xXhacksXx
{
   function hBrickClientCheck(%brickgroup)
   {
      talk("cl check");
      return 1;
   }
};
activatePackage(xXhacksXx);
« Last Edit: June 08, 2015, 09:53:43 PM by Johnny Blockhead »

-snip-

apparently you already did what I was suggesting
« Last Edit: June 04, 2015, 03:24:03 PM by Greek2me »

AiPlayer.cs doesn't really talk about spawning non-hole bots, unless I'm missing something? The other ones are just pathing.
« Last Edit: June 03, 2015, 10:53:11 PM by Johnny Blockhead »

-snip-

apparently you already did what I was suggesting
« Last Edit: June 04, 2015, 03:23:42 PM by Greek2me »

Your problem is that %brick is undefined here:
      spawnBrick = %brick;
because you are defining it in another function. I assume you had it as a single function and then split it up into two.

Simply using %brick = nameToID(UselessRoboBrick) again within the createRobot function should fix that.
« Last Edit: June 04, 2015, 12:50:41 PM by boodals 2 »

Thanks! It works now, after rewriting it:
//Bot Spawning
function spawnBots(%amount, %class)
{
   //Does it %amount amount of times.
   for(%i=0;%i<%amount;%i++)
   {
      //Creates the neccisary spawn brick. Otherwise bot kablooey-s.
      if(!isObject(%brick = nameToID(DumbRoboBrick)))
      {
         %brick = new fxDtsBrick(DumbRoboBrick)
         {
            datablock = brick1x1Data;
            isPlanted = false;
            itemPosition = 1;
            position = "0 0 -2000";
         };
      }
      //Creating the bot itself.
      %robot = new AiPlayer()
      {
         spawnTime = $Sim::Time;
         spawnBrick = %brick;
         dataBlock = PlayerNoJet;
         position = $botSpawn;
            //Springtime for Riddler
            Name = ZombieHoleBot.hName;
            hType = ZombieHoleBot.hType;
            hSearchRadius = ZombieHoleBot.hSearchRadius;
            hSearch = ZombieHoleBot.hSearch;
            hSight = ZombieHoleBot.hSight;
            hWander = ZombieHoleBot.hWander;
            hGridWander = ZombieHoleBot.hGridWander;
            hReturnToSpawn = ZombieHoleBot.hReturnToSpawn;
            hSpawnDist = ZombieHoleBot.hSpawnDist;
            hMelee = ZombieHoleBot.hMelee;
            hAttackDamage = ZombieHoleBot.hAttackDamage;
            hSpazJump = ZombieHoleBot.hSpazJump;
            hSearchFOV = ZombieHoleBot.hSearchFOV;
            hFOVRadius = ZombieHoleBot.hFOVRadius;
            hTooCloseRange = ZombieHoleBot.hTooCloseRange;
            hAvoidCloseRange = ZombieHoleBot.hAvoidCloseRang e;
            hShoot = ZombieHoleBot.hShoot;
            hMaxShootRange = ZombieHoleBot.hMaxShootRange;
            hStrafe = ZombieHoleBot.hStrafe;
            hAlertOtherBots = ZombieHoleBot.hAlertOtherBots;
            hIdleAnimation = ZombieHoleBot.hIdleAnimation;
            hSpasticLook = ZombieHoleBot.hSpasticLook;
            hAvoidObstacles = ZombieHoleBot.hAvoidObstacles;
            hIdleLookAtOthers = ZombieHoleBot.hIdleLookAtOthe rs;
            hIdleSpam = ZombieHoleBot.hIdleSpam;
            hAFKOmeter = ZombieHoleBot.hAFKOmeter + getRandom( 0, 2 );
            hHearing = ZombieHoleBot.hHearing;
            hIdle = ZombieHoleBot.hIdle;
            hSmoothWander = ZombieHoleBot.hSmoothWander;
            hEmote = ZombieHoleBot.hEmote;
            hSuperStacker = ZombieHoleBot.hSuperStacker;
            hNeutralAttackChance = ZombieHoleBot.hNeutralAttackC hance;
            hFOVRange = ZombieHoleBot.hFOVRange;
            hMoveSlowdown = ZombieHoleBot.hMoveSlowdown;
            hMaxMoveSpeed = 1.0;
            hActivateDirection = ZombieHoleBot.hActivateDirect ion;
            isHoleBot = 1;
      };
      missionCleanup.add(%robot);
   }
}


I'm trying to figure out how to damage them, something about adding them to a minigame? Also iirc theres a preference for bot damage. Is it possible to have them take damage outside of the mini? I'm using slayer.
edit: %minigame.addBotToGame(%robot); doesn't work, the variable is defined. The robot isn't a control object. Would aiController be coming in handy right now? I think it's something more simple, though.
« Last Edit: June 04, 2015, 07:12:47 PM by Johnny Blockhead »

You can get them to take damage in the Slayer minigame by setting %bot.minigame = %minigame for all of them. Then make sure that bot damage is enabled.

What'd be the best thing to set it to? If there was a way to find out the default minigame, it'd come in handy. Searches don't turn up anything relevant.

When the bot spawns, do something like this to give it the same minigame as the brick.

%bot.minigame = getMinigameFromObject(%botSpawnBrick);

That method doesn't work, probably since the brick wasn't planted by a player. Therefore, it wouldn't inherit a minigame. Maybe is it possible to find a minigame by its name, or one hosted by a specific player? Or how about finding the nearest brick to $botSpawn and getting its minigame?
Edit: My script automatically adds items to the bot depending on its class. I can verify they are being added correctly, since when i dump() them it shows a value for tool0. When they come and attack me, they simply just use their fists. Is there any way I can force them to use their guns, like a hole zombie?
Edit2: With actual hole-spawned zombies, if you give them a flamethrower through script they don't acknowledge it either. But when you wrench their spawn point and add it in the GUI, they instantly start using it.
Edit3: I've changed things up, and added these to the part where I defined the AiPlayer I wanted:
//Winter, for poland, and france!
hMelee = 0;
hShoot = 1;
hShootTimes = 4;
hMaxShootRange = 32;
hAvoidCloseRange = 1;
hTooCloseRange = 2;
hReturnToSpawn = 0;
hSpawnDist = 500;
hWep = flamerImage;

Yet, now he just doesn't attack me :(. hWep might yeild some fruits though.
This is my ultra temporary fix for the minigame problem:
%robot.minigame = findclientbyname("Piexes").minigame;
Yet ofc I won't be online every time a bot spawns, so I need a better solution.
Edit4: Durr, turning hMelee to 1 fixes them not attacking. Still no flamethrower action, though.
« Last Edit: June 05, 2015, 04:47:50 PM by Johnny Blockhead »

Bump.
I'm still pretty much stumped. For now I've retreated to just using this:

hMelee = 1;
hShoot = 1;
   hWep = "flamerImage";
hReturnToSpawn = 0;


I'm specifically using flamerImage because I'm testing this solely with pyros. Also, I'm 100% positive that they're actually getting the flamethrower, because of this code:

talk("tool0:" SPC %robot.tool0);
%robot.addNewItem("TF2 Flamethrower");
talk("tool0:" SPC %robot.tool0);


In which %robot.tool0 returns nothing at first, but an ID later (that IS confirmed for the flamethrower ID). If I set melee to 0, the bots don't even come after me. Can someone please help? This has to have been done before. My full code.

Edit: I was able to figure out what minigame to assign the bot to by doing a containerRadiusSearch at $botSpawn, looking for bricks. Then, I'd get the minigame from the brick by doing getMinigameFromObject.
« Last Edit: June 07, 2015, 06:20:07 PM by Johnny Blockhead »

Try %robot.setWeapon(itemData), addNewItem just only goes to their slot like everyone else has to use commands to pull it out.

If you want to bots to always damage, do $DefaultMinigame = MinigameID;
« Last Edit: June 07, 2015, 09:58:48 PM by Advanced Bot »

Thanks! I haven't been able to test it out yet, but I will soon.
I have this code where I'm making Mann Vs Machine canteens, and I'm using strings to record the capacity of their canteen. It's in the variable %client.canteen, and it'd look like this: NONE NONE NONE, atleast when it's empty. What I want to do is when someone buys a canteen, one of those NONEs becomes something like CRITS. The only functions I have found would replace all instances of NONE, not just one. Here's my code, in the middle of a function.
else if(strPos(%client.canteen, "NONE") >= 0)
{
   //Artificial Critical Hits
   if(%upg $= "Artificial")
   {
      if(%client.cash < 100)
      {
         %client.chatMessage("\c3You don't have enough money to buy Artificial Crits!");
         %displayMoney = 1;
      }
      else
      {
         %client.chatMessage("\c3You bought a single Artificial Crit canteen.");
         %client.cash -= 100;
      }
   }
}

First of all, use strstr(sourceString, searchString); if you aren't using the offset argument. Secondly, you can use setWord(sourceString, index, replace); where replace is the replacement word.

First of all, use strstr(sourceString, searchString); if you aren't using the offset argument.

strPos is perfectly acceptable.