GambleBot!

mredge73

Member
Rahmus
Here is my sticky note function. You should be able to modify it to meet your needs.
Code:
//ChatBot Routines = Notetaking
//used to pass notes to other players through chat
//command order: 1 Add, 2 view, 3 erase, 4 count
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
string StickyNotes(int command, string sender, string message)
{
	string Outgoing;
	
	//Load Chatbot note taking Log
	note[int] notelog;
	File_to_Map("StickyNotes.txt",notelog);
		
	//Add
	if (command==1)
	{
		//parse out command
		int spacing = index_of( message, "add notes:" ) + 10;
		string cropped = substring( message , spacing );
		//find new index
		int newnote= count(notelog);
		//write note to map
		notelog[newnote].sender= sender+": ";
		notelog[newnote].message= cropped;
		//save new map
		Map_to_File(notelog,"StickyNotes.txt");	
		Outgoing = "Added Note: "+cropped;	
	}
	//view
	if (command==2)
	{
		if (count(notelog)>0)
		{	
			//PM the notelog to the sender
			foreach note in notelog
				if(my_name() != sender)
					chat_private(sender, notelog[note].sender + notelog[note].message);
		}
		else
			OutGoing= "The notelog is empty!";
	}
	//erase
	if (command==3)
	{
		//pass an empty log to the file to erase it
		note[int] emptylog;
		Map_to_File(emptylog,"StickyNotes.txt");	
		OutGoing= "The notelog is empty!";	
	}
	//count
	if (command==4)
	{
		OutGoing= "There are "+count(notelog)+" notes on the notepad";
	}
	return OutGoing;
}

I call it by a chatbot function in the middle of a switch:
(see the unofficial gamblebot script)
Code:
//"add note" = adds note to the sticky note file
		case contains_text( message, "add notes:" ):
			Outgoing= StickyNotes(1,sender,message);
			break ;
		
		//"view notes" = sends PM to caller of all notes on file
		case contains_text( message, "view notes" ):
			Outgoing= StickyNotes(2,sender,message);
			break ;
		
		//"clear notes" = erases note file by passing empty map to file
		case contains_text( message, "clear notes" ):
			Outgoing= StickyNotes(3,sender,message);
			break ;
		//"count notes"= returns how many notes exist
		case contains_text( message, "notes" ):
			Outgoing= StickyNotes(4,sender,message);
			break ;

**These are copy/pasted from another script (excerpts). Don't expect them to work right out of the box.
My clan requested this feature but only used it for a short time.
 
Last edited:

Rahmuss

Member
Well, my first response got deleted somehow, so here it is again. I originally tried to explain all the horror I went through; but now I'll just recap. Had to move variable for noteP and record stuff outside of IF statement to make it global so that my later IF statement would recognize it. I know it's getting into the second IF statement because it prints the message to the clan chat window as instructed in the IF statement. No errors now finally (Hurray!); but the foreach loop is not doing anything. Here is the meat and potatoes of what I have:

Code:
void main( string sender , string message )  {
	print(sender+ ": "+message,"olive");	

	string text = message;
	int hoboint = 0;
	int slimeint = 0;
	int talkint = 0;

	record noteP  {
		string sender;
		string message;
	}
	[int] PMlog;

	if ( text.contains_text( "savenotes" ))  {
		File_to_Map("PMlog.txt",PMlog);
		int newPM= count(PMlog);
		PMlog[newPM].sender= sender + ": ";
		PMlog[newPM].message= message;
		Map_to_File(PMlog,"PMlog.txt");	
		talkint = newPM;
	}
	if (text.contains_text( "shownotes" ))  {
		chat_clan(text);
		foreach noteP in PMlog
			chat_clan(sender, PMlog[noteP].sender + PMlog[noteP].message);
	}
	else  { 
		switch(random(40))  {
			case 1: //A bunch of random PMs
		}
	}
}

I stayed up way too late trying to get this done and now it seems I'm back where I started. Any help would be VERY greatly appreciated. Thanks.
 

slyz

Developer
You need to load PMlog.txt before the foreach loop. If the message doesn't contain "savenotes", file_to_map() is never called in the code above.
 

Rahmuss

Member
So put it the File_to_Map directly after the record is called and before the PMlog is defined? I'll have to try that later when I have time. I see what you're saying, and I think I've tried that (though maybe not with the record and / or variable outside the IF statement as well).
 

mredge73

Member
In the example above, you are declaring the record and defining PMlog at the same time.
A record is a user defined datatype, like string and int are pre-defined datatypes.

So the line should be placed:
Code:
record noteP  {string sender; string message;}[int] PMlog;
File_to_Map("PMlog.txt",PMlog); 
//other stuff

Or to prevent confusion you can split the definition and declaration.
Code:
//record definition
record noteP
{ 
string sender;
string message;
};

//map declaration
noteP [int] PMlog;

//Fill the empty map with data from a file
File_to_Map("PMlog.txt",PMlog);
 
Last edited:

Rahmuss

Member
So, this is directly from my test script. You can copy / paste it to a text file, save it as .ash and run it yourself. My PMlogged file has five entries in it currently. When I message him to shownotes, then he PMs me "shownotes" five times because I have private chat in the foreach loop. So I know it's getting inside the foreach loop, and I know that it knows how many records are in the file because it sends the same message five times (and no, the messages are not all the same thing in the PMlogged file). Nothing goes to the clan chat window though. Here is the code:

PHP:
void main( string sender , string message )  {
	print(sender+ ": "+message,"olive");	

	string text = message;
	int hoboint = 0;
	int slimeint = 0;
	int talkint = 0;

	record noteP  {  string sender;  string message;  }
	[int] PMlogged;
	File_to_Map("PMlogged.txt",PMlogged);

	if ( text.contains_text( "savenotes" ))  {
		int newPM= count(PMlogged);
		PMlogged[newPM].sender= sender + ": ";
		PMlogged[newPM].message= message;
		Map_to_File(PMlogged,"PMlogged.txt");	
		talkint = newPM;
	}
	if (text.contains_text( "shownotes" ))  {
		foreach noteP in PMlogged  {
			chat_private(sender, text);
			chat_clan(sender, PMlogged[noteP].sender + PMlogged[noteP].message);
		}
	}
	else  { 
		switch(random(4))  {
			case 1: chat_private(sender , "You Rock!!!");
			case 2: chat_private(sender , "I don't think so.");  break;
			case 3: chat_private(sender , "Is that so?"); break;
			default: chat_private(sender , "Need some meat?"); break;
		}
	}
}

Any thoughts?

EDIT: Horray! I saw that I was doing a chat_clan with sender and message inputs instead of just a message. So I changed that and viola. Though, is there a way to get it so that it ignores the "savenotes" part of the message either when inputing or when outputing? (preferrably the former). I'll go look at it.
 
Last edited:

Rahmuss

Member
Wow, so I guess I can't figure out regexes. I thought it might be fairly simple to have it recognize "savenotes" and then have the rest of the text in a second group (or the first group, depending on how I did it) and then save the message as that group. Main area of concern:

PHP:
	if ( text.contains_text( "savenotes" ))  {
		matcher check_message = create_matcher("savenotes (.+)" , message);
		message = check_message.group(1);
		chat_private(sender, "You saved the message: " + message);
		int newPM= count(PMlogged);
		PMlogged[newPM].sender= sender + ": ";
		PMlogged[newPM].message= message;
		Map_to_File(PMlogged,"PMlogged.txt");	
		talkint = newPM;
	}

I've tried
matcher check_message = create_matcher("(savenotes) (*)" , message);
matcher check_message = create_matcher("(savenotes) ()" , message);
matcher check_message = create_matcher("savenotes (*)" , message);
matcher check_message = create_matcher("savenotes (????)" , message); //And messaged /msg clanchatbot savenotes Test
matcher check_message = create_matcher("savenotes (^*$)" , message);
matcher check_message = create_matcher("savenotes (.+)" , message);

And some others as well; but I can't remember them all. It sure sounds simple enough, and I'm sure if I knew regexes well enough then I might know how to do it. I'll have to keep looking.

EDIT: Also, a couple of times it gave the message: "No match attempted or previous match failed (test.ash, line 15)". That made it seem like it got past the matcher phrase; but didn't find a match. Just in case this helps.

EDIT, EDIT: Ok, looks like I figured it out. Nice

PHP:
		matcher check_message = create_matcher("((S|s)avenotes) (.+$)" , message);
		if (check_message.find())  {
			  message = check_message.group(3);
		}

Thanks for the help everyone.
 
Last edited:

slyz

Developer
If you want your regex to be case-insensitive, add "(?i)" in front. This worked for me:
PHP:
matcher check_message = create_matcher( "(?i)savenotes (.+)" , message);
 

mredge73

Member
This is a great tool for helping you learn regex:
http://www.fileformat.info/tool/regex.htm

You could avoid regex like Z and do something like my above example:
Code:
//parse out command
int spacing = index_of( message, "add notes:" ) + 10;
string cropped = substring( message , spacing );
This code crops out "add notes:" from the message.
 

Rahmuss

Member
StDoodle - Yep, I was using that Regex page on the wiki. Maybe it was the fact that it was so late in the evening (actually early in the morning) that made it so I could not think clearly.

slyz - Thanks slyz. For right now I don't care if they use upper or lower-case. Though that's good to know for later.

mredge73 - Wow, that's pretty cool. I didn't know you could crop things like that. Still a lot to learn.
 

Enameless

New member
So I've recently run into an issue. Gamblebot throws an error sending items to anyone with spaces in their name. It appears to be adding plus signs (+) as spaces. I've tried to see if I could find the issue but I have no clue what I'm looking for.

Edit:
Figured out the problem, it was using url_encode and opposed to url_decode for the sender and date thus adding +'s for spaces.
 
Last edited:

wilco ladd

New member
string ChatDice (string message)
{
matcher dice_matcher = create_matcher( "\\b(\\d+)[dD](\\d+)\\b", message);
if (dice_matcher.find())
{
int num = dice_matcher.group( 1 ).to_int();
int faces = dice_matcher.group( 2 ).to_int();
if ( faces == 0 ) return "Nice try small fry. There are no 0-sided die silly.";
if ( faces == 1 ) return "Oooo, wow, that would give some... uhm... interesting results. Try again.";
if ( num == 0 ) return "Ok, so you actually don't want me to roll any die?";
if ( num >50 ) return "Who do you think I am? I cannot find that many dice.";

string OutGoing=( "Rolling " + num + "D" + faces + " for " );
for i from 1 to num
OutGoing=Outgoing+"D"+i+"= "+(random(faces)+1)+" , ";
return OutGoing;

}
return "Usage: 'roll <xxx>d<yyy>' where xxx is the number of yyy-faced die to roll." ;
}


Is there anyway i can add +sender+ in the middle of the outgoing message so it shows the username? I have tried a few different ways but cant seem to get it to work, im pulling my hair out.
 

mredge73

Member
The string passed to that function is just the body of the message.
The output is just a string containing the result of the roll, it can manipulated outside of the function.

sender is not a global variable.
You would have to rewrite the function to accept the sender as a input in order to get that info.
May I ask, why would you need this?
 
Top