Custom Combat Script: Difference between revisions

From Kolmafia
Jump to navigation Jump to search
imported>Bale
 
(26 intermediate revisions by 8 users not shown)
Line 1: Line 1:
= Basic CCS =
{{TOCright}}
== Basic CCS ==
A Custom Combat Script (CCS) is a way of instructing mafia how to handle combat, round by round. For example, a simple CCS would be to tell mafia to pickpocket on round 1, then cast entangling noodles on round 2 and finally on rounds 3+ to use shieldbutt. If it is unable to carry out one of those steps, then that step will be skipped. For instance, if the character failed to get initiative, then pickpocket will be skipped and the character will go straight to entangling noodles. That CCS would look like this:
A Custom Combat Script (CCS) is a way of instructing mafia how to handle combat, round by round. For example, a simple CCS would be to tell mafia to pickpocket on round 1, then cast entangling noodles on round 2 and finally on rounds 3+ to use shieldbutt. If it is unable to carry out one of those steps, then that step will be skipped. For instance, if the character failed to get initiative, then pickpocket will be skipped and the character will go straight to entangling noodles. That CCS would look like this:


<div style="border: solid 1px black; padding: 1em; margin:0px 20px;">
<div style="border: solid 1px black; padding: 1em; margin:0px 20px;">
[ default ]<br />
[ default ]<br />
1: try to steal an item<br />
try to steal an item<br />
2: skill entangling noodles<br />
skill entangling noodles<br />
3: skill shieldbutt<br />
skill shieldbutt<br />
</div>  
</div>  




If you wanted to treat different monsters differently, that can be accomodated also. For instance, the following CCS will attempt to cast Transcendent Olfaction upon Black Knights while treating all other monsters differently. If the character currently has "On the Trail" then that line will be skipped.
If you wanted to treat different monsters differently, that can be accommodated also. For instance, the following CCS will attempt to cast Transcendent Olfaction upon Black Knights while treating all other monsters differently. If the character currently has "On the Trail" then that line will be skipped.




<div style="border: solid 1px black; padding: 1em; margin:0px 20px;">
[ Black Knight ]<br />
try to steal an item<br />
skill transcendent olfaction<br />
skill entangling noodles<br />
skill shieldbutt<br />
[ default ]<br />
try to steal an item<br />
skill entangling noodles<br />
skill shieldbutt<br />
</div>
Note that when you use a CCS, your CLI will report "character executes a macro!" because the CCS is converted into a macro to save on page loads
=== Available Commands ===
* attack
* skill
* item, use
* try to steal an item, pickpocket
* summon pastamancer ghost
* jiggle chefstaff
* combo {followed by one of the following}
** Disco Concentration, Disco Nirvana, Disco Inferno, Disco Bleeding, Disco Blindness
** Rave Knockout, Rave Bleeding, Rave Concentration, Rave Steal, Rave Nirvana, Rave Stats
** [http://kolmafia.us/showthread.php?5709-Add-rave-combo-learning-to-quot-special-action-quot&p=42107&viewfull=1#post42107 random rave]
* abort
* abort after
* section [section name]
* special
* delevel
* skip
* note
* twiddle
=== Using ASH Constants in CCS ===
Certain ASH constants can be used in CCS as section headers.
* '''$phylum[ ]''' refers to the 22 {{kolwiki|Monster Types|Monster Phylumn}}.
* '''$element[ ]''' refers to either the attack or the defense element. As long as one matches, this check will be satisfied.
* '''$item[ ]''' refers to an item that the monster drops. If there are multiple monsters that drop the item (such as SGEEA) it will match any of those monsters.
You may specify more than one of these, but unless everything matches, it won't match. So if you specify an impossible combination, that CCS section will not run.
<div style="border: solid 1px black; padding: 1em; margin:0px 20px;">
[ $element[ spooky ] $item[ hobo nickel ] ]<br />
skill entangling noodles<br />
skill weapon of the pastalord<br />
[ bathroom $element[ spooky ] ]<br />
attack<br />
[ $phylum[ beast ] ]<br />
skill stomp<br />
attack<br />
</div>
== Macros in CCS ==
Macros may be used in a Custom Combat Script in addition to the basic commands. Any line in quotes  and any macro command used in a CCS will be made into part of the macro which KoLmafia is passing to KoL. You can find an primer on all KoL's macros at {{kolwiki|Combat Macros}}.
Also there is a section in the CCS called "global prefix" which will be part of every combat macro KoLmafia generates, regardless of the monster encountered.
=== Example of CCS Macro ===
Here's an example of a CCS that generates a macro which will cause KoL to wait for a hobo monkey to steal meat from your enemy before launching attacks.
<div style="border: solid 1px black; padding: 1em; margin:0px 20px;">
<div style="border: solid 1px black; padding: 1em; margin:0px 20px;">
[ default ]<br />
[ default ]<br />
1: try to steal an item<br />
sub monkey_stasis<br />
2: skill entangling noodles<br />
:while !match "climbs up and sits on your shoulder" && !pastround 20 && !hppercentbelow 20
3: skill shieldbutt<br />
::call stasis_item
:endwhile
endsub<br />
call monkey_stasis<br />
attack




[ Black Knight ]<br />
[ global prefix ]<br />
1: try to steal an item<br />
scrollwhendone<br />
2: skill transcendent olfaction<br />
"abort missed 5"<br />
3: skill entangling noodles<br />
"abort pastround 27"<br />
4: skill shieldbutt<br />
sub stasis_item<br />
:if hascombatitem facsimile dictionary
::item facsimile dictionary
::goto _endstasisitem
:endif
:if hascombatitem seal tooth
::item seal tooth
::goto _endstasisitem
:endif
:if hascombatitem spices
::item spices
::goto _endstasisitem
:endif
:if hascombatitem spectre scepter
::item spectre scepter
::goto _endstasisitem
:endif
:if hascombatitem dictionary
::item dictionary
::goto _endstasisitem
:endif
:"abort "No infinite use items detected!" "
:mark _endstasisitem
endsub<br />
sub stasis<br />
:while !pastround 20 && !hppercentbelow 20 && mppercentbelow 99
::call stasis_item
:endwhile
endsub
</div>
 
=== Concerns for macros in CCS ===
*A macro's abort command needs to be encased in quotes because abort is also a legal CCS command. That's why all aborts in the previous example were quoted.
 
*If a comment is the last line in a CCS, that will be used as your finishing attack even though it does nothing. Never conclude a CCS with a macro comment or it will abort to the mini-browser with a warning from KoL that you executed 37 commands in a row without taking an action.
 
== Consult Scripts ==
While a CCS may seem reasonably flexible, sometimes you will want to do something too complicated to express in that format. For instance if you want your character to take different actions based on your characters current stats or current monster level, a consult script can automatically figure it out. There are few limits to what a consult script can enable. The downside to using a consult script is that KoLmafia will not be able to generate a combat macro to pass to KoL. As a result multi-round combat will take somewhat longer.
 
A consult script is called by using the "consult" command in your CCS, as follows:
 
<div style="border: solid 1px black; padding: 1em; margin:0px 20px;">
[ default ]<br />
consult myscript.ash<br />
attack<br />
</div>
</div>




= Consult Scripts =
The main() function in the ASH script being consulted must accept three parameters:
While this may seem reasonably flexible, sometimes you will want to do something too complicated to express in this format. For instance if you want your character to cast a Rave Combo if the character is a Disco Bandit, you'd have to change your CCS every ascension, but a consult script can automatically figure it out.


== Example of a Consult Script ==
void main(int round, monster mob, string page_text)
This example will attempt to pickpocket if possible. If not successful, then if the character is a Disco Bandit and he has learned the relevant Rave Combo, he will attempt to steal an item with the correct Rave combo.
 
These values will be supplied by mafia when the consult script is called.
 
=== Example of a Consult Script ===
This example will attempt to maximize use of a Sauceror's spells as a Sauceror by making use of sauce splash effects when they can be used.
<div style="margin-bottom: 1em; border: dashed 1px green; padding: 1em; margin:0px 20px;"><syntaxhighlight>
<div style="margin-bottom: 1em; border: dashed 1px green; padding: 1em; margin:0px 20px;"><syntaxhighlight>
// Save this as RaveSteal.ash
// Save this as SauceSplash.ash
void main(int initround, monster foe, string url) {
boolean sauceSplash() {
   boolean stolen = false;
   if(!my_class() == $class[Sauceror])
   while(contains_text(url, "form name=steal")) {
        return false;
       url = steal();
   int normal = numeric_modifier("spell damage");
      if((contains_text(url, "grab something") || contains_text(url, "You manage to wrest")))
  if(normal >= 25)
        return;   // Something has been stolen. Job done!
       return true;
   }
  int cold = numeric_modifier("cold spell damage");
   if(my_class() != $class[Disco Bandit]) return;
  int hot = numeric_modifier("hot spell damage");
  matcher combo = create_matcher("(.+),(.+),(.+)", get_property("raveCombo5"));
 
   if(combo.find())
  #deal with monsters weak to cold
       for i from 1 to 3 {
  if(((((monster_element() == $element[stench]) || (monster_element() == $element[sleaze]))
        if(contains_text(url, "You win the fight")) return;
    && have_skill($skill[Immaculate Seasoning]))
        url = use_skill(combo.group(i).to_skill());
    || have_equipped($item[Gazpacho's Glacial Grimoire]))
       }
    && cold + normal >= 25)
        return true;
   #deal with monsters weak to hot
   else if((((((monster_element() == $element[cold]) || (monster_element() == $element[spooky]))
    && have_skill($skill[Immaculate Seasoning]))
    || have_equipped($item[Codex of Capsaicin Conjuration])
    || have_equipped($item[Ol' Scratch's manacles])
    || have_equipped($item[Ol' Scratch's ash can]))
    && hot + normal >= 25)
  #deal with monsters weak to neither (hot/non-aligned)
   else if(have_skill($skill[Immaculate Seasoning])
       && cold != hot && max(cold, hot) + normal >= 25)
        return true;
  else return false;
}
 
void main(int initround, monster foe, string page) {
  if(have_effect($effect[Burning Soul]) || have_effect($effect[Soul Freeze]) || !sauceSplash())
      use_skill($skill[Saucegeyser]);
  else
       use_skill($skill[Wave of Sauce]);
}
}
</syntaxhighlight></div>
</syntaxhighlight></div>
Line 56: Line 192:
<div style="border: solid 1px black; padding: 1em; margin:0px 20px;">
<div style="border: solid 1px black; padding: 1em; margin:0px 20px;">
[ default ]<br />
[ default ]<br />
1: consult RaveSteal.ash<br />
consult SauceSplash.ash<br />
2: attack<br />
attack<br />
</div>
</div>


== Parts of a Combat Consultation Script ==
=== Parts of a Combat Consultation Script ===
As you can see in the above example, a consultation script is called with three parameters.
As you can see in the above example, a consultation script is called with three parameters.
*The first parameter is the round of combat that the script is called. Sometimes it is important to keep track of the round. This is particularly important to keep from losing the fight by going over 30 rounds.
*The first parameter is the round of combat that the script is called. Sometimes it is important to keep track of the round. This is particularly important to keep from losing the fight by going over 30 rounds.
Line 66: Line 202:
*The third parameter is the text of the page. This is important because it enables you to examine every detail of the fight as it is taking place. It can be analyzed for potential actions, damage that you deal to a monster and all other events.
*The third parameter is the text of the page. This is important because it enables you to examine every detail of the fight as it is taking place. It can be analyzed for potential actions, damage that you deal to a monster and all other events.


All possible actions you can take in a round of combat are listed under [[In-combat_Consulting]]
All possible actions you can take in a round of combat are listed under [[In-combat Consulting]].
 
=== Resolution of a Combat Consultation Script ===
The consult script can automate as many, or as few rounds of combat as desired to achieve its goal. When it finishes executing, if the monster is not yet dead, then the CCS will continue combat from the current round. Note that the current round is not always the next line in a script. For instance, if the consult script is called at round 1 and executes three actions, then it will return to the CCS at round 4. This is why most CCSs containing consult script prefer to have only a line after the consult script, usually a simple method of killing a monster.
 
Note: unlike CCS themselves or macros, consult scripts will NOT automatically stop if the monster dies. The entire consult script is seen as a single "action" by the CCS, which will go through its entirety before deciding whether to keep fighting or to give the control back to whatever script/player action/automation was going on prior to the fight.<br>
This means that a consult script such as...
<syntaxhighlight>
void main(int initround, monster foe, string page){
  use_skill($skill[Saucegeyser]);
  use_skill($skill[Saucegeyser]);
}
</syntaxhighlight>
...will GENERATE AN ERROR if the first saucegeyser defeats the monster, as mafia will try to look for a skill called "saucegeyser" to cast once out of combat.<br>
However, this also means that if you are sure the combat will be over at a certain point, you could include actions like changing your equipment, eating, or straight up adventuring at another location!
 
=== Macros in Consult Scripts ===
It is possible for a consult script to submit a macro. As a simple example, if your consult script wants to submit a macro that simply attacks the monster until the combat ends...
 
<div style="margin-bottom: 1em; border: dashed 1px green; padding: 1em; margin:0px 20px;"><syntaxhighlight>
string macro = "attack; repeat"
visit_url("fight.php?action=macro&macrotext=" + url_encode(macro) ,true,true);
</syntaxhighlight></div>


== Resolution of a Combat Consultation Script ==
Between macro commands you need to insert either <code>\n</code> or a semi-colon as in the above example. Your submitted macro can be as complicated as you wish.
The consult script can automate as many, or as few rounds of combat as desired to achieve its goal.  


It is preferable that the script be able to recognize when a monster is dead in case the combat ends before achieving that goal. For instance, when executing a Rave Combo, the damage may kill the monster before the combo is complete. The script should recognize the monsters death by the text "You win the fight" and immediately end.


If a consult script does not wish to finish killing a monster, then it may end at any time. If it does this, then the CCS will continue combat from the current round. Note that the current round is not always the next line in a script. For instance, if the consult script is called at round 1 and executes three actions, then it will return to the CCS at round 4. This is why most CCSs containing consult script prefer to have only a line after the consult script, usually a simple method of killing a monster.
[[Category:Scripting]]

Latest revision as of 08:04, 15 March 2021

Basic CCS

A Custom Combat Script (CCS) is a way of instructing mafia how to handle combat, round by round. For example, a simple CCS would be to tell mafia to pickpocket on round 1, then cast entangling noodles on round 2 and finally on rounds 3+ to use shieldbutt. If it is unable to carry out one of those steps, then that step will be skipped. For instance, if the character failed to get initiative, then pickpocket will be skipped and the character will go straight to entangling noodles. That CCS would look like this:

[ default ]
try to steal an item
skill entangling noodles
skill shieldbutt


If you wanted to treat different monsters differently, that can be accommodated also. For instance, the following CCS will attempt to cast Transcendent Olfaction upon Black Knights while treating all other monsters differently. If the character currently has "On the Trail" then that line will be skipped.


[ Black Knight ]
try to steal an item
skill transcendent olfaction
skill entangling noodles
skill shieldbutt

[ default ]
try to steal an item
skill entangling noodles
skill shieldbutt

Note that when you use a CCS, your CLI will report "character executes a macro!" because the CCS is converted into a macro to save on page loads

Available Commands

  • attack
  • skill
  • item, use
  • try to steal an item, pickpocket
  • summon pastamancer ghost
  • jiggle chefstaff
  • combo {followed by one of the following}
    • Disco Concentration, Disco Nirvana, Disco Inferno, Disco Bleeding, Disco Blindness
    • Rave Knockout, Rave Bleeding, Rave Concentration, Rave Steal, Rave Nirvana, Rave Stats
    • random rave
  • abort
  • abort after
  • section [section name]
  • special
  • delevel
  • skip
  • note
  • twiddle

Using ASH Constants in CCS

Certain ASH constants can be used in CCS as section headers.

  • $phylum[ ] refers to the 22 Monster Phylumn.
  • $element[ ] refers to either the attack or the defense element. As long as one matches, this check will be satisfied.
  • $item[ ] refers to an item that the monster drops. If there are multiple monsters that drop the item (such as SGEEA) it will match any of those monsters.

You may specify more than one of these, but unless everything matches, it won't match. So if you specify an impossible combination, that CCS section will not run.


[ $element[ spooky ] $item[ hobo nickel ] ]
skill entangling noodles
skill weapon of the pastalord

[ bathroom $element[ spooky ] ]
attack

[ $phylum[ beast ] ]
skill stomp
attack

Macros in CCS

Macros may be used in a Custom Combat Script in addition to the basic commands. Any line in quotes and any macro command used in a CCS will be made into part of the macro which KoLmafia is passing to KoL. You can find an primer on all KoL's macros at Combat Macros.

Also there is a section in the CCS called "global prefix" which will be part of every combat macro KoLmafia generates, regardless of the monster encountered.

Example of CCS Macro

Here's an example of a CCS that generates a macro which will cause KoL to wait for a hobo monkey to steal meat from your enemy before launching attacks.

[ default ]
sub monkey_stasis

while !match "climbs up and sits on your shoulder" && !pastround 20 && !hppercentbelow 20
call stasis_item
endwhile

endsub
call monkey_stasis
attack


[ global prefix ]
scrollwhendone
"abort missed 5"
"abort pastround 27"
sub stasis_item

if hascombatitem facsimile dictionary
item facsimile dictionary
goto _endstasisitem
endif
if hascombatitem seal tooth
item seal tooth
goto _endstasisitem
endif
if hascombatitem spices
item spices
goto _endstasisitem
endif
if hascombatitem spectre scepter
item spectre scepter
goto _endstasisitem
endif
if hascombatitem dictionary
item dictionary
goto _endstasisitem
endif
"abort "No infinite use items detected!" "
mark _endstasisitem

endsub
sub stasis

while !pastround 20 && !hppercentbelow 20 && mppercentbelow 99
call stasis_item
endwhile

endsub

Concerns for macros in CCS

  • A macro's abort command needs to be encased in quotes because abort is also a legal CCS command. That's why all aborts in the previous example were quoted.
  • If a comment is the last line in a CCS, that will be used as your finishing attack even though it does nothing. Never conclude a CCS with a macro comment or it will abort to the mini-browser with a warning from KoL that you executed 37 commands in a row without taking an action.

Consult Scripts

While a CCS may seem reasonably flexible, sometimes you will want to do something too complicated to express in that format. For instance if you want your character to take different actions based on your characters current stats or current monster level, a consult script can automatically figure it out. There are few limits to what a consult script can enable. The downside to using a consult script is that KoLmafia will not be able to generate a combat macro to pass to KoL. As a result multi-round combat will take somewhat longer.

A consult script is called by using the "consult" command in your CCS, as follows:

[ default ]
consult myscript.ash
attack


The main() function in the ASH script being consulted must accept three parameters:

void main(int round, monster mob, string page_text)

These values will be supplied by mafia when the consult script is called.

Example of a Consult Script

This example will attempt to maximize use of a Sauceror's spells as a Sauceror by making use of sauce splash effects when they can be used.

// Save this as SauceSplash.ash
boolean sauceSplash() {
   if(!my_class() == $class[Sauceror])
         return false;
   int normal = numeric_modifier("spell damage");
   if(normal >= 25)
      return true;
   int cold = numeric_modifier("cold spell damage");
   int hot = numeric_modifier("hot spell damage");

   #deal with monsters weak to cold
   if(((((monster_element() == $element[stench]) || (monster_element() == $element[sleaze]))
     && have_skill($skill[Immaculate Seasoning]))
     || have_equipped($item[Gazpacho's Glacial Grimoire]))
     && cold + normal >= 25)
        return true;
   #deal with monsters weak to hot
   else if((((((monster_element() == $element[cold]) || (monster_element() == $element[spooky]))
     && have_skill($skill[Immaculate Seasoning]))
     || have_equipped($item[Codex of Capsaicin Conjuration])
     || have_equipped($item[Ol' Scratch's manacles])
     || have_equipped($item[Ol' Scratch's ash can]))
     && hot + normal >= 25)
   #deal with monsters weak to neither (hot/non-aligned)
   else if(have_skill($skill[Immaculate Seasoning])
      && cold != hot && max(cold, hot) + normal >= 25)
         return true;
   else return false;
}

void main(int initround, monster foe, string page) {
   if(have_effect($effect[Burning Soul]) || have_effect($effect[Soul Freeze]) || !sauceSplash())
      use_skill($skill[Saucegeyser]);
   else
      use_skill($skill[Wave of Sauce]);
}


This consult script can then be integrated into a CCS like this:

[ default ]
consult SauceSplash.ash
attack

Parts of a Combat Consultation Script

As you can see in the above example, a consultation script is called with three parameters.

  • The first parameter is the round of combat that the script is called. Sometimes it is important to keep track of the round. This is particularly important to keep from losing the fight by going over 30 rounds.
  • The second parameter is the monster that you are fighting. This is important because it enables you to take different actions for different monsters.
  • The third parameter is the text of the page. This is important because it enables you to examine every detail of the fight as it is taking place. It can be analyzed for potential actions, damage that you deal to a monster and all other events.

All possible actions you can take in a round of combat are listed under In-combat Consulting.

Resolution of a Combat Consultation Script

The consult script can automate as many, or as few rounds of combat as desired to achieve its goal. When it finishes executing, if the monster is not yet dead, then the CCS will continue combat from the current round. Note that the current round is not always the next line in a script. For instance, if the consult script is called at round 1 and executes three actions, then it will return to the CCS at round 4. This is why most CCSs containing consult script prefer to have only a line after the consult script, usually a simple method of killing a monster.

Note: unlike CCS themselves or macros, consult scripts will NOT automatically stop if the monster dies. The entire consult script is seen as a single "action" by the CCS, which will go through its entirety before deciding whether to keep fighting or to give the control back to whatever script/player action/automation was going on prior to the fight.
This means that a consult script such as...

void main(int initround, monster foe, string page){
  use_skill($skill[Saucegeyser]);
  use_skill($skill[Saucegeyser]);
}

...will GENERATE AN ERROR if the first saucegeyser defeats the monster, as mafia will try to look for a skill called "saucegeyser" to cast once out of combat.
However, this also means that if you are sure the combat will be over at a certain point, you could include actions like changing your equipment, eating, or straight up adventuring at another location!

Macros in Consult Scripts

It is possible for a consult script to submit a macro. As a simple example, if your consult script wants to submit a macro that simply attacks the monster until the combat ends...

string macro = "attack; repeat"
visit_url("fight.php?action=macro&macrotext=" + url_encode(macro) ,true,true);

Between macro commands you need to insert either \n or a semi-colon as in the above example. Your submitted macro can be as complicated as you wish.