My first attempt at a script

My problem is that I'm basically stumbling around in the dark. I looked at the mafia guide and was able to pick up a few things that helped me get this far, but as I'm sure you'll be able to tell by what I came up with that I could use some help.

PHP:
void main {
if( my_name() == "Red Maw" )
{
cli_execute("eatdrink.ash 15 19 15 f f")
cli_execute("restore hp") 
cli_execute("bounty.ash *")
cli_execute("farm.ash f")
cli_execute("csend 1 meat to Testudinata");
wait 45;
if(have_effect($effect[Ode to Booze]))
{
cli_execute("buy 1 a little sump'm sump'm")
cli_execute("drink a little sump'm sump'm")
}

else 
{
cli_execute("csend 15 meat to Noblesse Oblige")
wait 45
cli_execute("buy 1 a little sump'm sump'm")
cli_execute("drink a little sump'm sump'm")
}}}

I really did try, but I'm pretty much learning from scratch here. I suspect the biggest thing I need to work on is syntax, the brackets and everything are pretty confusing to me. Is the "void main" at the top necessary? Will the scripts I'm invoking have the parameters I named entered correctly? For instance, for eat,drink.ash I want it eating, drinking, and spleening to max, and not overdrinking or simming. Hopefully what I want the script to do is self explanatory based on how I wrote it, but just to be totally clear, here's what I want it to do written out:

This script will be set to run on login
If the character logging in is Red Maw
Invoke eatdrink.ash eat/drink/spleen to max, don't overdrink, don't sim
Recover HP (I have Bale's script set as mafia's default, so that's what it will use, right?)
Invoke bounty.ash, use as many turns as it takes
Invoke farm.ash, don't sim
Send 1 meat to Testudinata, wait 45 seconds
If ode is found, nightcap
If ode is not found, send 15 meat to Noblesse Oblige and wait 45 seconds, then nightcap regardless

Additionally, once another one of my accounts decides to take a break from making slimelings, I might want it to use this script too. To add a second character could I do something like this?

PHP:
void main {
if( my_name() == "Red Maw" ){
cli_execute("eatdrink.ash 15 19 15 f f")
-snip-
cli_execute("drink a little sump'm sump'm")}

if( my_name() == "Laser Bullet" ){
cli_execute("eatdrink.ash 15 19 15 f f")
-snip-
cli_execute("drink a little sump'm sump'm")}
}

I am interested in learning more about how this all works, but it's slow going since it's like learning another language. However, the guide was a helpful start, so hopefully I'll be able to improve to the point where I can both write basic scripts like this, as well as tweak the scripts already here on occasion if I need. Thanks in advance for your patience.
 

slyz

Developer
A few little things :

- the void main() isn't necessary for a simple/straightforward script. and it's void main(), the parenthesis is what makes it a 'function', you can't leave them out, even when there aren't any input parameters.

- you use cli_execute to call EatDrink.ash, but you can't call a script with more than one parameter from the CLI. You should import EatDrink.ash and call it directly from ash. put import "EatDrink.ash"; at the beginning of the script, and call the eatdrink() function like this: eatdrink(foodMax, drinkMax, spleenMax, overdrink); after declaring and defining foodMax, drinkMax, spleenMax and overdrink (you can use the ash functions fullness_limit( ), my_fulness(), inebriety_limit( ), my_inebriety( ), my_spleen_use( ) and spleen_limit( ) to pass in your current consumption and make the script foolproof).

- by the way, you only use cli_execute. Use the CLI command ashref name to search for an ash function (you can also use the shiny wiki). It will give the type of output, as well as the parameters and their type. Look for buy, drink etc...

- If you are used to calling some scripts from the CLI, like bounty.ash or farm.ash, and if those scripts only use one parameter, then no need to change I guess (especially since bounty.ash doesn't have a bounty() function you could import and call). Using a cli_execute for csend is nice too, it's simpler than searching for an ash equivalent since there isn't a built-in one if I recall correctly.

- to make your code clearer, use indentation. That way the structure will jump right out and you can fix any problems. Look at a few scripts posted here to see how people do that. Some scripters use
Code:
if ( condition ) {
     // do stuff
     // and more stuff
} else {
     // do different stuff
     // lots of different stuff
}
others do:
Code:
if ( condition )
{
     // do stuff
}
else
{
     // do different stuff
}
and if there's only one command after the if or the else, you can also skip the braces:
Code:
if ( condition )
     int foo = 1 ;
else
     int foo = 2 ;
There's no practical difference, maybe it comes down to what language you learned first.

- to add a multi's name to a list of names that will execute the eating/adventuring, you can use a map. These are usefull little creatures... here is an example:
Code:
boolean[string] multiNames ;
multiNames["Red Maw"] = true;
multiNames["Laser Bullet"] = false;

if ( multiNames[my_name()] ) {
      // stuff to do
}
We built a map associating a boolean value to strings. multiNames[my_name()] will return true if my_name() returns "Red Maw", false if it returns "Laser Bullet", and won't return true anyway if what my_name() returns isn't in the multiNames map.
When you want the instructions to run for Laser Bullet, just go to line 3 and change it to multiNames["Laser Bullet"] = true;

There are of course many other ways to do this, but jumping in and learning about maps will open up possibilities =)

EDIT: I almost forgot - once your script is done, run it with the CLI verify command, it will point out the syntax errors, like a missing ;, or using the wrong data type etc. Just type verify myScript.ash in the gCLI.
 
it comes down to what language you learned first

The extent of my programming training comes from a class called "Computing Concepts" I took to fulfill a gen. ed requirement in college. The first day we were told by our professor that if we actually wanted to learn how to program, we were in the wrong class. :D I don't remember much about the class, but I digress, here's what I've got so far:

PHP:
import <eatdrink.ash>

boolean[string] multiNames ;
multiNames["Red Maw"] = true;
multiNames["Laser Bullet"] = false;

if ( multiNames[my_name()] ) 
{
	eatdrink(15, 19, 15, false, false);
	cli_execute("restore hp");
	cli_execute("bounty.ash *");
	cli_execute("bounty.ash false");
	cli_execute("csend 1 meat to Testudinata");
	wait 45;
	status refresh;
	if(have_effect($effect[Ode to Booze]))
		{
		cli_execute("buy 1 a little sump'm sump'm");
		cli_execute("drink a little sump'm sump'm");
		}

	else 
		{
		cli_execute("csend 15 meat to Noblesse Oblige");
		wait 45;
		cli_execute("buy 1 a little sump'm sump'm");
		cli_execute("drink a little sump'm sump'm");
		}
}

Using the verify command in the CLI returns the following:
Function 'eatdrink( int, int, int, boolean, boolean )' undefined (grind.ash, line 9)

I stumbled around playing with the ash functions you posted and various related things but wasn't able to come up with something that didn't bring back some kind of error. Since it didn't return any other errors does that mean the rest of the script is fine, or does it stop at the first error?
 

heeheehee

Developer
Staff member
Re: your current error: The form of eatdrink you're calling only takes one boolean. So remove one of the two "false" parameters you have going.

It aborts at the first instance of an error, so you'll have to do some more testing.

Also: a fun little line to have instead of "wait 45":
Code:
while(have_effect$effect[ode])==0) {
   print("Don't have Ode yet...");
   wait 10;
}
 
I like your suggestion to print a message while waiting for ode, once I get the script to be functional I'll add that, and perhaps a few similar things. I removed the second false in the eatdrink line, and that did the trick. After a couple other tweaks, I got no errors when asking the CLI to verify the script. However, when I load the script nothing happens.

PHP:
import <eatdrink.ash>;

boolean[string] multiNames ;
multiNames["Red Maw"] = true;
multiNames["Laser Bullet"] = false;

if ( multiNames[my_name()] ) 
{
	eatdrink(15, 19, 15, false);
	cli_execute("restore hp");
	cli_execute("bounty.ash *");
	cli_execute("bounty.ash false");
	cli_execute("csend 1 meat to Testudinata");
	cli_execute("wait 45");
	cli_execute("status refresh");
	if(have_effect($effect[Ode to Booze]) < 1)
		{
		cli_execute("buy a little sump'm sump'm");
		cli_execute("drink a little sump'm sump'm");
		}

	else 
		{
		cli_execute("csend 15 meat to Noblesse Oblige");
		cli_execute("wait 45");
		cli_execute("buy a little sump'm sump'm");
		cli_execute("drink a little sump'm sump'm");
		}
}
 

mredge73

Member
I would add a few print() lines in the script to find out why it is not doing anything. You can always remove them after you discover the problem.

My best guess is that it is not evaluating: my_name() == "Red Maw"

PHP:
import <eatdrink.ash>;

boolean[string] multiNames ;
multiNames["Red Maw"] = true;
multiNames["Laser Bullet"] = false;

foreach name in multiNames
if (multiNames[name] )
print("Script should run for " +name+ " without any problems");

if ( multiNames[my_name()] ) 
{
    eatdrink(15, 19, 15, false);
    cli_execute("restore hp");
    cli_execute("bounty.ash *");
    cli_execute("bounty.ash false");
    cli_execute("csend 1 meat to Testudinata");
    cli_execute("wait 45");
    cli_execute("status refresh");
    if(have_effect($effect[Ode to Booze]) < 1)
        {
        cli_execute("buy a little sump'm sump'm");
        cli_execute("drink a little sump'm sump'm");
        }

    else 
        {
        cli_execute("csend 15 meat to Noblesse Oblige");
        cli_execute("wait 45");
        cli_execute("buy a little sump'm sump'm");
        cli_execute("drink a little sump'm sump'm");
        }
} 
else
print(my_name()+ " cannot run this script, see Deathless Assassian to be put on the list");

print("Script Complete for "+ my_name());
 
Last edited:
Yep, the problem seems to be this line:
PHP:
if ( multiNames[my_name()] )

In order to test the execution of everything else I made another version that doesn't check what account is running the script, and the only problem I encountered was that eatdrink.ash was only simulated. This is why I originally had the variable false twice in the call to eatdrink.ash, the first to set overdrink to false, and the second to set simulate to false.
 

fronobulax

Developer
Staff member
The shiny new wiki entry for my_name() says that it
Returns the name of the logged-in character, all in lowercase.
The code examples are all case insensitive but they are also just a simple "if" test. Given everything, perhaps
Code:
multiNames["red maw"] = true;
would have more success?
 

StDoodle

Minion
I just removed the "all in lowercase" part, because apparently it isn't true. However, checking my_name() vs. a string DOES ignore capitalization. I suspect it may be the space (possibly it becomes an underscore). I will check & report (and update the wiki).

Edit; several checks ran, all show that the string returned by my_name() is exactly as your name is printed (capitalization & spaces as displayed).

In summary, I have no clue what's going on...

Edit 2: are you sure this script is running while your character is logged on? That's about all I can come up with...
 
Last edited:

fronobulax

Developer
Staff member
In summary, I have no clue what's going on...
It is probably a veer here but I might suggest that the string comparisons when a string is a map index and/or an == "statement" have some case games going on. I haven't looked at the code but I'm wondering if there is a feature to be documented or a bug to be reported?
 

StDoodle

Minion
In my limited testing, the == operator ignores case for straight strings, but capitalization counts for map keys... hmm...
 

Bale

Minion
I'm very fond of to_lower_case() for dealing with that sort of thing. No more fiddly nonsense required. It keeps me sane.

Also, I need to point out that the following command will not work:

PHP:
cli_execute("csend 15 meat to Noblesse Oblige");
There's nothing wrong with your syntax, but mafia refuses to send small amounts of meat to Noblesse Oblige. As I understand it, Noblesse Oblige has requested that its philanthropic buffs not be automatable so mafia obliges them.

Code:
[COLOR="#808000"]> csend 15 meat to Noblesse Oblige[/COLOR]

[COLOR="#ff0000"]Noblesse Oblige has requested to be excluded from scripted requests.[/COLOR]
 
Last edited:

slyz

Developer
Dropping the case as suggested by fronobulax solved the problem. It looks like the only remaining problem I have is getting eat.drink to not be simulated.

The version of EatDrink.ash I have in my script folder uses a zlib variable called eatdrink_simConsume to decide if you want to simulate or not. Does that var show up when you type zlib vars in the gCLI ?

EDIT: open up your EatDrink.ash, look for void eatdrink(. In my copy, I have
Code:
void eatdrink(int foodMax, int drinkMax, int spleenMax, boolean overdrink)

I was suggesting you do something like this in your script, to make it foolproof:
Code:
int foodMax = fullness_limit() - my_fulness() ;
int drinkMax = inebriety_limit() - my_inebriety() ;
int spleenMax = spleen_limit() - my_spleen_use() ;
boolean overdrink = false ;
eatdrink(foodMax, drinkMax, spleenMax, overdrink) ;

This way, if you have to rerun the script twice for the same character, EatDrink won't do anything.
 
Last edited:
I'm very fond of to_lower_case() for dealing with that sort of thing. No more fiddly nonsense required. It keeps me sane.

Also, I need to point out that the following command will not work:

PHP:
cli_execute("csend 15 meat to Noblesse Oblige");
There's nothing wrong with your syntax, but mafia refuses to send small amounts of meat to Noblesse Oblige. As I understand it, Noblesse Oblige has requested that its philanthropic buffs not be automatable so mafia obliges them.

Thanks for the info. Switched to IocaineBot as the backup.

The version of EatDrink.ash I have in my script folder uses a zlib variable called eatdrink_simConsume to decide if you want to simulate or not. Does that var show up when you type zlib vars in the gCLI ?

EDIT: open up your EatDrink.ash, look for void eatdrink(. In my copy, I have
Code:
void eatdrink(int foodMax, int drinkMax, int spleenMax, boolean overdrink)

I was suggesting you do something like this in your script, to make it foolproof:
Code:
int foodMax = fullness_limit() - my_fulness() ;
int drinkMax = inebriety_limit() - my_inebriety() ;
int spleenMax = spleen_limit() - my_spleen_use() ;
boolean overdrink = false ;
eatdrink(foodMax, drinkMax, spleenMax, overdrink) ;

This way, if you have to rerun the script twice for the same character, EatDrink won't do anything.

Bingo, that got eatdrink.ash to stop simming, and I like your suggestion a lot! I also realized farm.ash eats food on its own, hence why I'm not eating when calling eatdrink.ash anymore. Everything went smoothly on my testing accounts, other than the script stopping once farm.ash finished. I tried running the script again with farm.ash commented out and it proceeded to nightcapping. So it looks like all I need to do is look in farm.ash and figure out how to stop it from aborting when it finishes. I haven't tested it, but I also added another feature that would skip bounty.ash if the account running the script isn't included in the getLucre map, once no more lucre is needed. Thank you all so much for your help.

Code:
import <eatdrink.ash>;

boolean[string] multiNames;
multiNames["red maw"] = true;
multiNames["laser bullet"] = false;

boolean[string] getLucre;
getLucre["red maw"] = true;

int drinkMax = inebriety_limit() - my_inebriety();
int spleenMax = spleen_limit() - my_spleen_use();
boolean overdrink = false;

if (multiNames[my_name()]) 
	{
	eatdrink(0, drinkMax, spleenMax, overdrink);
	cli_execute("restore hp");
	if (getLucre[my_name()])
		cli_execute("bounty.ash *");
	//cli_execute("farm.ash false");
	cli_execute("csend 1 meat to Testudinata");
	cli_execute("wait 45");
	cli_execute("status refresh");
	if(have_effect($effect[Ode to Booze]) > 1)
		{
		cli_execute("buy a little sump'm sump'm");
		cli_execute("drink a little sump'm sump'm");
		}

	else 
		{
		cli_execute("csend 23 meat to IocaineBot");
		cli_execute("wait 45");
		cli_execute("buy a little sump'm sump'm");
		cli_execute("drink a little sump'm sump'm");
		}

	}
 
Last edited:
Top