Server Help

Bot Questions - Where can I throw this function in mervbot?

hellzlaker - Thu Aug 14, 2008 10:52 am
Post subject: Where can I throw this function in mervbot?
I made a function for a bot I'm trying to make but no matter where I put it, VC++ tells get_tag() set_tag() and p are undeclared (I tried to put it in spawn.h spawn.cpp command.cpp neither worked)

here is the function

Code: Show/Hide
   void startMission(int mission,int name,String difficulty)
{
   _listnode <Player> *parse = playerlist->head;

   while(parse)
   {
   if(get_tag(p,ACTIVE)==ON)
   {
      sendPrivate(p,"You have started a mission already.");
   }

   if(get_tag(p,BREAKTIME)!=0)
   {
      sendPrivate(p,"You need to take a break between missions, "+(String)get_tag(p,BREAKTIME)+" seconds left.");
   }

   else
   {
      int reward;
      
      if(difficulty=="easy")reward=5000;
      else if(difficulty=="med")reward=10000;
      else if(difficulty=="hard")reward=25000;
      else reward=50000;
      
      set_tag(p,_REWARD,reward);
      
      set_tag(p,mission,ON);

      set_tag(p,ACTIVE);

      sendPrivate("You have started "+difficulty+" mission "+(String)name+". Type !abort to abort this mission.");
   }
   }
}

k0zy - Thu Aug 14, 2008 2:00 pm
Post subject:
I think your function has to be a member of the botInfo class.
Samapico - Thu Aug 14, 2008 5:29 pm
Post subject:
Bob Dole.. Bob Dole... Bob Dole...... bob dole.... bob... dole.... wrote:
I think your function has to be a member of the botInfo class.


Yes it does.

The declaration of your function
Code: Show/Hide
void startMission(int mission,int name,String difficulty);

has to be in the class botInfo { ... } part, in spawn.h. Look for where other functions are declared.

The definition of your function would be in spawn.cpp, anywhere you want.

But for it to be a member of botInfo, you have to do it like:
Code: Show/Hide
void botInfo::startMission(int mission,int name,String difficulty)
{
//...
}

hellzlaker - Thu Aug 14, 2008 9:51 pm
Post subject:
ok declared it in botInfo and defined it with botInfo:: but now I get these errors
Code: Show/Hide
error C2065: 'p' : undeclared identifier
and my function is almost the same
Code: Show/Hide
void botInfo::startMission(int mission,int name,String difficulty)
{
   _listnode <Player> *parse = playerlist->head;

   while(parse)
   {
   if(get_tag(p,ACTIVE)==ON)
   {
      sendPrivate(p,"You have started a mission already.");
   }

   if(get_tag(p,BREAKTIME)!=0)
   {
      sendPrivate(p,"You need to take a break between missions, "+(String)get_tag(p,BREAKTIME)+" seconds left.");
   }

   else
   {
      int reward;
      
      if(difficulty=="easy")reward=5000;
      else if(difficulty=="med")reward=10000;
      else if(difficulty=="hard")reward=25000;
      else reward=50000;
      
      set_tag(p,_REWARD,reward);
      
      set_tag(p,mission,ON);

      set_tag(p,ACTIVE);

      set_tag(p,CURRENT_MISSION,mission);

      sendPrivate(p,"You have started "+difficulty+" mission "+(String)name+". Type !abort to abort this mission.");
   }
   }
}

Samapico - Thu Aug 14, 2008 10:04 pm
Post subject:
well

that's maybe because 'p' is undeclared in that function?

I'm guessing you'll need to add 'Player * p' as a parameter if you want to start a mission for a specific player

'p' isn't magical, it's just like any 'int' or String's you'd use. It has to be declared in the current scope. Some variables are declared to be available to the whole class (playerlist, for example), but 'p' is declared in every function it's used, either as a parameter, or declared directly
hellzlaker - Thu Aug 14, 2008 10:36 pm
Post subject:
I thought that _listnode <Player> *parse = playerlist->head; declared the 'p' icon_confused.gif
Purge - Fri Aug 15, 2008 12:17 am
Post subject:
hellzlaker wrote:
Code: Show/Hide
void botInfo::startMission(int mission,int name,String difficulty)
{
   _listnode <Player> *parse = playerlist->head;

   while(parse)
   {
   if(get_tag(p,ACTIVE)==ON)
   {
      sendPrivate(p,"You have started a mission already.");
   }

   if(get_tag(p,BREAKTIME)!=0)
   {
      sendPrivate(p,"You need to take a break between missions, "+(String)get_tag(p,BREAKTIME)+" seconds left.");
   }

   else
   {
      int reward;
      
      if(difficulty=="easy")reward=5000;
      else if(difficulty=="med")reward=10000;
      else if(difficulty=="hard")reward=25000;
      else reward=50000;
      
      set_tag(p,_REWARD,reward);
      
      set_tag(p,mission,ON);

      set_tag(p,ACTIVE);

      set_tag(p,CURRENT_MISSION,mission);

      sendPrivate(p,"You have started "+difficulty+" mission "+(String)name+". Type !abort to abort this mission.");
   }
   }
}


Looks like you are cycling through players. Try adding Player *p = parse->item; below the while statement and parse = parse->next; at the end of the while loop.
hellzlaker - Fri Aug 15, 2008 1:45 am
Post subject:
thanks I did it right in my last bot just forgot thought all you had to do was _listnode <Player> *parse = playerlist->head;

anyway worked
hellzlaker - Fri Aug 15, 2008 2:29 am
Post subject:
yea now that i got the code compiled, got a new problem, bot freezes when i do a command !easymission:1 which accesses the startMission() function

here is some code chunks

spawn.cpp
Code: Show/Hide
void botInfo::startMission(int mission,int name,String difficulty)
{
   _listnode <Player> *parse = playerlist->head;

   while(parse)
   {
   Player *p = parse->item;

   if(get_tag(p,ACTIVE)==ON)
   {
      sendPrivate(p,"You have started a mission already.");
   }

   if(get_tag(p,BREAKTIME)!=0)
   {
      sendPrivate(p,"You need to take a break between missions, "+(String)get_tag(p,BREAKTIME)+" seconds left.");
   }

   else
   {
      int reward;
      
      if(difficulty=="easy")reward=5000;
      else if(difficulty=="med")
      {
         reward=10000;
         difficulty="medium";
      }
      else if(difficulty=="hard")reward=25000;
      else reward=50000;
      
      set_tag(p,_REWARD,reward);
      
      set_tag(p,mission,ON);

      set_tag(p,ACTIVE,ON);

      set_tag(p,CURRENT_MISSION,mission);

      set_tag(p,CURRENT_MISSION_NAME,name);

      sendPrivate(p,"You have started "+difficulty+" mission "+(String)name+". Type !abort to abort this mission.");
   }
   }
   parse = parse->next;
}

void botInfo::beatMission()
{
   _listnode <Player> *parse = playerlist->head;

   while(parse)
   {
      Player *p = parse->item;

      set_tag(p,BREAKTIME,300);

      set_tag(p,ACTIVE,OFF);

      set_tag(p,get_tag(p,CURRENT_MISSION),OFF);

      String difficulty;

      if(get_tag(p,_REWARD)==5000)difficulty="easy";
      else if(get_tag(p,_REWARD)==10000)difficulty="medium";
      else if(get_tag(p,_REWARD)==25000)difficulty="hard";
      else difficulty="expert";

      sendPrivate(p,"*points "+get_tag(p,_REWARD));
      sendPrivate(p,"You have defeated "+difficulty+" mission "+(String)get_tag(p,CURRENT_MISSION_NAME)+".");
   }

   parse = parse->next;
}



command.cpp
Code: Show/Hide
else if (c->check("easymission:1"))startMission(MISSION1,1,"easy");


spawn.h
Code: Show/Hide
#define ON 0
#define OFF 1

#define ACTIVE 1
#define BREAKTIME 2
#define _REWARD 3
#define CURRENT_MISSION 4
#define CURRENT_MISSION_NAME 5

#define MISSION1 6



for those who just want to look at full source files i attached them.
k0zy - Fri Aug 15, 2008 2:49 am
Post subject:
Not sure, but this might be a problem:

Code: Show/Hide
sendPrivate(p,"*points "+get_tag(p,_REWARD));


Adding an integer to a const char * is probably not such a good idea...
I guess the result will be a new pointer which points to nothing.
Purge - Fri Aug 15, 2008 10:50 am
Post subject:
Try:
Code: Show/Hide
sendPrivate(p,"*points " + (String)get_tag(p,_REWARD));


Essentially, you need to convert the int returned from get_tag() to a const char* or String. If that doesn't work, use _itoa().
hellzlaker - Fri Aug 15, 2008 11:16 am
Post subject:
yea I forgot to add the string type function but my bot still freezes no clue why.

my guess its something in the startMission()

or is there anything wrong in this code?

else if (c->check("easymission:1"))startMission(MISSION1,1,"easy");
Purge - Fri Aug 15, 2008 2:28 pm
Post subject:
You have to add parse = parse->next; within the while loop (at the end), not after it.
tcsoccerman - Fri Aug 15, 2008 4:18 pm
Post subject:
also maybe difficulty should be an integer not a string.

err and name maybe should be a string?

makes more sense to me.
Samapico - Fri Aug 15, 2008 5:11 pm
Post subject:
And emm...

Do you want a mission to be given to everyone at the same time?
Cause you're cycling through everyone and making them start the mission...

I think what you want to do is:


command.cpp
Code: Show/Hide
else if (c->check("easymission:1"))startMission(p, MISSION1,1,"easy");


spawn.cpp
Code: Show/Hide

void botInfo::startMission(Player * p, int mission,int name,String difficulty)
{
//Put code to start the mission for player p
}


Same for the beatMission() function, it would become
beatMission(Player * p );

and when you call that function (for example, in the Player_Death event):
Code: Show/Hide

if (<player is in mission> && <conditions for mission be beaten>)
   beatMission(k);  //k being the Player * representing the killer in player_death



tsoccerman is right about difficulty being an integer

Actually you should add an enumaration for it. Look at the top of spawn.h, where other enum's are, and put something like this:

Code: Show/Hide

enum DifficultyLevel
{
   DIFF_Easy,
   DIFF_Medium,
   DIFF_Hard,
};


'DifficultyLevel' becomes a new variable type you can use. DIFF_Easy, DIFF_Medium and DIFF_Hard are another way to say 0, 1 and 2. Kind of like constants. By default, values in an enum are 0, 1, 2... etc.
You could specify specific values if you needed to:

Code: Show/Hide

enum DifficultyLevel
{
   DIFF_Easy = 1,
   DIFF_Medium = 3,
   DIFF_Hard = 88,
};


Example usage:
Code: Show/Hide

DifficultyLevel diff1 = DIFF_Easy;
DifficultyLevel diff2 = DIFF_Medium;

int blah = diff1 + diff2; // that would be 1 (0 + 1)

if (diff1 == DIFF_Easy)
{ //this is true }

if (diff1 == 0)
{ //this is also true }

You can use it in your functions like any other type as well
hellzlaker - Sat Aug 16, 2008 12:26 am
Post subject:
woah I never knew about enumeration! really this a great tut you wrote thanks icon_smile.gif I'm going to add changes to the bot and see how it comes out biggrin.gif

to soccerman: only reason I used for mission name int because all missions are name mission 1,2,3 etc... Also I wanted to be able to set tags easily
Samapico - Sat Aug 16, 2008 10:48 am
Post subject:
You could also make an enum for mission names. This makes the code much more readable, too. If someone else sees your code, he won't know what mission 1 is, but if instead of 1 it's MISSION_Bounty or something like this, he can understand.

If you want to use the mission name in messages or things like that, you could use a constant char* array:
Code: Show/Hide

//30 would be the max length of the mission name
const char mission_label[MISSION_COUNT][30] = {
   "some mission",
   "a cool mission",
   "kill people",
   "do stuff",
   "be awesome"
};

Using mission_label[0] will bring up a char* pointing to "some mission"
All times are -5 GMT
View topic
Powered by phpBB 2.0 .0.11 © 2001 phpBB Group