Thread: #bot filter
View Single Post
  #1  
Old 09-18-2009, 08:29 PM
Shin Noir's Avatar
Shin Noir
Legendary Member
 
Join Date: Apr 2002
Location: Seattle, WA
Posts: 502
Default #bot filter

So, I'm told that the bots will be rewritten from scratch again.

Assuming you utilize the same automated bot AI system, I really recommend writing something like I was working on. It's a #bot filter command.

It's a simple unsigned integer with a bunch of bitmask filters to specify turning on or off certain bot AI routines. Ideally store it in the database when the bot saves, and a simple system for allowing players to customize what they want their bot to do.

I wrote a bit of it, such as..
line 19 of bot.h
Code:
//Shin: AI Defines, used for ai filter list.
#define AI_HEAL 1
#define AI_ROOT 2 
#define AI_SNARE 4 
#define AI_SLOW 8 
#define AI_NUKE 16
#define AI_DOT 32
#define AI_PET 64 //Use a pet? (shamans etc)
#define AI_ILLUSION 128 //Use illusion spells? (annoying enchanter!)
#define AI_LIFETAP 256
#define AI_HOT 512 //Heal Over Time Spell Casting
#define AI_BUFF 1024 //Do Buff Routine/Keep Buffs Up?
#define AI_FEAR 2048 //Do Fear Type Spells
#define AI_DISPELL 4096 //Do Dispells?
Line 133 after SetTarget
Code:
	virtual void SetTarget(Mob* mob);
	virtual void SetFilter(uint16 value); //Shin: Set/Get AI bitmask
	uint16 GetFilter() { return _filter; }
Line 262 after the comment
Code:
	// Private "base stats" Members
	uint16 _filter; //Used for AI filter methods
[/code]

line 8345 after #bot camp help line
Code:
c->Message(0, "#bot filter[list|option] - Turn On/Off a bot routine filter."); //Shin: For filters

This code is incomplete, I was working on it but when I realize a total rewrite of the bot system was in place, I stopped. But here's a general example:

Code:
if (!strcasecmp(sep->arg[1], "filter")) 
	{ //Shin: AI Options! and yes, I put the { on next line. Sue me.
		if((c->GetTarget() == NULL) || (c->GetTarget() == c) || !c->GetTarget()->IsBot()) {
			c->Message(15, "You must target a bot!");
			return;
		}

		Bot* tBot = c->GetTarget()->CastToBot();

		if (!strcasecmp(sep->arg[2], "list"))
			c->Message(15, "This would list current AI options enabled.");
		if (!strcasecmp(sep->arg[2], "heal"))
		{			
			tBot->SetFilter(tBot->GetFilter() ^ AI_HEAL);
			(tBot->GetFilter() & AI_HEAL) ? tBot->Say("I will now heal members of my group.") : c->Message(15, "I will no longer heal members of my group.");
		}
		if (!strcasecmp(sep->arg[2], "root"))
		{			
			tBot->SetFilter(tBot->GetFilter() ^ AI_ROOT);
			(tBot->GetFilter() & AI_ROOT) ? tBot->Say("I will now try to root monsters.") : c->Message(15, "I will no longer try to root monsters.");
		}
		if (!strcasecmp(sep->arg[2], "snare"))
		{			
			tBot->SetFilter(tBot->GetFilter() ^ AI_SNARE);
			(tBot->GetFilter() & AI_SNARE) ? tBot->Say("I will now try to snare monsters.") : c->Message(15, "I will no longer try to snare monsters.");
		}
		if (!strcasecmp(sep->arg[2], "slow"))
		{			
			tBot->SetFilter(tBot->GetFilter() ^ AI_SLOW);
			(tBot->GetFilter() & AI_SLOW) ? tBot->Say("I will now try to slow monsters.") : c->Message(15, "I will no longer try to slow monsters.");
		}
		if (!strcasecmp(sep->arg[2], "nuke"))
		{			
			tBot->SetFilter(tBot->GetFilter() ^ AI_NUKE);
			(tBot->GetFilter() & AI_NUKE) ? tBot->Say("I will now try to cast direct damage spells on monsters.") : c->Message(15, "I will no longer try to cast direct damage spells on monsters.");
		}
		if (!strcasecmp(sep->arg[2], "dot"))
		{			
			tBot->SetFilter(tBot->GetFilter() ^ AI_DOT);
			(tBot->GetFilter() & AI_DOT) ? tBot->Say("I will now try to cast damage over time spells on monsters.") : c->Message(15, "I will no longer try to cast damage over time spells on monsters.");
		}
		if (!strcasecmp(sep->arg[2], "pet"))
		{			
			tBot->SetFilter(tBot->GetFilter() ^ AI_PET);
			(tBot->GetFilter() & AI_PET) ? tBot->Say("I will now try to keep a pet up.") : c->Message(15, "I will no longer try to keep a pet up.");
		}
		if (!strcasecmp(sep->arg[2], "illusion"))
		{			
			tBot->SetFilter(tBot->GetFilter() ^ AI_ILLUSION);
			(tBot->GetFilter() & AI_ILLUSION) ? tBot->Say("I will now cast illusion spells on the group when possible.") : c->Message(15, "I will no longer cast illusion spells on the group.");
		}
		if (!strcasecmp(sep->arg[2], "buff"))
		{			
			tBot->SetFilter(tBot->GetFilter() ^ AI_BUFF);
			(tBot->GetFilter() & AI_BUFF) ? tBot->Say("I will now try to keep buffs on group members.") : c->Message(15, "I will no longer try to keep buffs on group members.");
		}


	}
Then in each spelltype case, have an added condition such as:

Code:
case SpellType_Heal: {
						if (
							( (spells[AIspells[i].spellid].targettype==ST_GroupTeleport || spells[AIspells[i].spellid].targettype == ST_Target || tar == this)
							&& tar->DontHealMeBefore() < Timer::GetCurrentTime()
							&& tar->CanBuffStack(AIspells[i].spellid, botLevel, true) >= 0)
							&& (this->GetFilter() & AI_HEAL)) //Shin: Heal Filter Check
						{
Also around line 1740 I did a illusion check, Enchanters are annoying with scarecrow, but so do druids, having a universal filter would be nice.
Code:
//Shin: Check for illusion spells. Don't cast if filter prevents.
								if(	(IsEffectInSpell(AIspells[i].spellid, SE_Illusion) && !(this->GetFilter() & AI_ILLUSION))
										break;
I did a lot more modifications, but I'm not really sure it is even worth my time if you are totally revamping the system.... :/

Let me know!
__________________

~Shin Noir
DungeonEQ.com
Reply With Quote