Wow. Well, that is some peculiar code.
Code:
record dbcnprof { effect e; float p; };
dbcnprof[int] bestdb;
// filter out unavailable combos
boolean can_combo() {
if (my_class() != $class[disco bandit]) return false;
int combocost,i;
bestdb.clear();
foreach eff in dcomb {
if (have_effect(eff) > 0 || monster_stat("hp") < combo_damage(eff)+1 || 29 - round < count(dcomb[eff]) ||
(eff == $effect[none] && stolen != $item[none])) { remove dcomb[eff]; continue; }
combocost = 0;
foreach num,sk in dcomb[eff] combocost = combocost + mp_cost(sk);
if (my_maxmp() < combocost) { remove dcomb[eff]; continue; }
else if (my_mp() < combocost) continue;
if (combo_profit(eff,combocost) <= 0) remove dcomb[eff];
else {
i = count(bestdb);
bestdb[i].e = eff;
bestdb[i].p = combo_profit(eff,combocost);
}
}
if (count(bestdb) > 0) sort bestdb by -value.p;
return (count(dcomb) > 0);
}
// cast a disco combo
string disco_combo(effect grants, string page) {
if (!can_combo() || !(dcomb contains grants)) return page;
int combocost;
foreach num,sk in dcomb[grants] combocost = combocost + mp_cost(sk);
if (my_mp() < combocost) return page;
foreach num,sk in dcomb[grants] page = try_skill(page,sk);
return page;
}
// casts combos in
string best_combos(string page) {
if (can_combo() && count(bestdb) > 0) foreach num,rec in bestdb
page = disco_combo(rec.e,page);
return page;
}
It is crashing in best_combos, trying to assign "rec" in the foreach loop.
Look at how that works:
can_combo creates and fills in the map bestdb, which is a sorted map of possible disco combos.
possible disco combos are in dcomb - and can_combo removes combos from the map, if they are too expensive - or if the combo is "steal" and you just stole...
This is an expensive function.
Note that it clears and recreates "bestdb".
best_combos calls can_combo and then iterates over the resulting map, calling disco_combo for everything in it.
disco_combo itself calls can_combo - which clears and regenerates that map.
So, best_combos is iterating over a map which is changing out from under it. It looks at index 0, 1, ... and so on - based on how many entries were in the map when it called can_combo itself - but by the time it wants to look at index 2, the map has been changed to no longer have that many entries in it.
I'd have to call that a coding error in the ASH program, but ASH should not throw a debug log in this case, and I will consider what needs to be done to fix that...