items first.
Removed arena tag "move_spawners", replaced it with "move_summons", which moves summons to a random location as soon as they're placed.
Added tag "summon_throttle:", which if set prevents summons from being placed if the summoner has N or more allies.
Make arena monsters ignore test spawners, since spawners are only pseudo-monsters placed in order to summons real monsters (plus attacking them is a waste of time since they're unkillable).
Tell the arena when a corpse is placed.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@8349 c06c8d41-db1a-0410-9941-cceddc491573
3HBQJBTXTMATEKEZ7ANDLAXVKS4F45YS647KYWNKQE32GQW22S3AC USIGLWEX5AA7IJ2U6ZMKFMMVZMRAKC3TKXAPBOF457DP4ND6ZT5AC IA4AZVXJEZP6QRPKUUPBLZQWY36PSN4UMGXVLINXJNTKJR2NXHEAC 2RJUPYKEDZZCW4GDG6WLEDVYF32ADC4W5I42KSKHN3MWEBCWSAHQC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC TZMLB4SJENS4JWIPIG7HFOFRIOZYYH5YB4TG7ZGBYT63C5B3MXDQC KOVRG7IPNFPXQNBFVMYEY7T6WM55CHJ37I4E763S6EJ6IZH32FYAC YJC3XCYRRQGOL2OCWAJJKBS6BGUHBVHWEL72HHEHRC6HG7WAHIOAC HM6NOS7BN5665KWIFGBXOHZIDMRSVCESN72GMGI6NVBFZGCF3L6QC ED62QWGKBPORWVKDFOQRKJXEIWZVNGR3O4KWQBDSRNPT36AYOQYAC 2J3TK3NYTO5XO6IHLTV5O6B3HYN2NHXD5ST3WLL5KPTUOVS5F3RQC PKXXBHS3LWLPZI2QVRX22MSQ4R2626IXRSNHFFYHXYTLJJQU54LQC R32CQ6FQJTQLB35P3HENIDCBDT3UWXBBCDAAUWHUQO6G6NKEDPKQC CKKQS65COJ4KKOWYCKSEAPTH2X6HZSCFOT62JQOK5QDSILBKSFDAC AAHHHRIYK53GIYQOZIGCBFI6ZM3SKN7OBRNLHQ5WVKV73MPK2H5QC PTZ3HVXCKCJ3R2Q6R2MYNSNFJMZ5ZGJEGLBNFC5WG5VQROS6HR3QC MB3ZKRP3CSLCJJSXQ44QTAME4M4OOAQLNQ2K3D3AFQV5FO6H3EPQC WGM77XP66ZEIRWAOKAJDICJ4ZBEUKGAEY6MZQQJ2LUWG5PCG722QC 3EREXXQMWTOWPI5ZV4UABEIR4RTGPNM7V2O6CG2EOFPHA5GEB2WAC Y26UG3JWXZG3USM5R36UIZAZWVSC67ZKPE6CSIP3SUBVPB7MZSGQC K4CJM2GNQKZAPQT3FD2FSG4IXBUUZS42VSXH3QCVSWTZ3JOZT6YQC // Don't fight test spawners, since they're only pseduo-monsters// placed to spawn real monsters, plus they're impossible to kill.// But test spawners can fight each other, to give them a target o// spawn against.if (other->type == MONS_TEST_SPAWNER&& mons->type != MONS_TEST_SPAWNER){continue;}
allow_summons = !strip_tag(spec, "no_summons");allow_immobile = !strip_tag(spec, "no_immobile");allow_bands = !strip_tag(spec, "no_bands");allow_zero_xp = strip_tag(spec, "allow_zero_xp");real_summons = strip_tag(spec, "real_summons");do_move_spawners = strip_tag(spec, "move_spawners");
allow_summons = !strip_tag(spec, "no_summons");allow_animate = !strip_tag(spec, "no_animate");allow_immobile = !strip_tag(spec, "no_immobile");allow_bands = !strip_tag(spec, "no_bands");allow_zero_xp = strip_tag(spec, "allow_zero_xp");real_summons = strip_tag(spec, "real_summons");move_summons = strip_tag(spec, "move_summons");summon_throttle = strip_number_tag(spec, "summon_throttle:");
// Move test spawners to a new position every turn to scatter each// faction all over the arena.void move_spawners()
// Try to prevent random luck from letting one spawner fill up the// arena with so many monsters that the other spawner can never get// back on even footing.void balance_spawners()
if (!mon->alive() || mon->type != MONS_TEST_SPAWNER)continue;monster_teleport(mon, true, true);
for (unsigned int i = 0; i < b_spawners.size(); i++){int idx = b_spawners[i];menv[idx].speed_increment *= faction_a.active_members;menv[idx].speed_increment /= faction_b.active_members;
if (!arena::allow_chain_summons)arena::zap_summons(monster);
if (arena::move_summons)monster_teleport(monster, true, true);if (!arena::allow_chain_summons || !arena::allow_animate)arena::adjust_spells(monster, !arena::allow_chain_summons,!arena::allow_animate);
if (corpse != -1 && corpse != NON_ITEM)arena::item_drop_times[corpse] = arena::turns;// Won't be dropping any items.if (monster->flags & MF_HARD_RESET)return;for (int i = 0; i < NUM_MONSTER_SLOTS; i++){int idx = monster->inv[i];if (idx == NON_ITEM)continue;if (mitm[idx].flags & ISFLAG_SUMMONED)continue;arena::item_drop_times[idx] = arena::turns;}
// Culls the items which have been on the floor the longest, culling the newest// items last. Items which a monster dropped voluntarily or because of// being polymorphed, rather than because of dying, are culled earlier than// they should be, but it's not like we have to be fair to the arena monsters.
case OBJ_MISSILES:if (item.sub_type == MI_JAVELIN|| item.sub_type == MI_THROWING_NET){ammo.push_back(i);}else// Arrows/needles/etc on the floor are just clutter.cull = true;break;
// Cull half of items on the floor.const int cull_target = items.size() / 2;int cull_count = 0;
case OBJ_CORPSES:if (item.sub_type == CORPSE_SKELETON)// If it's rotted away into a skeleton then there's no one// around who can uses corpses.cull = true;elsecorpses.push_back(i);
// Arrows/needles/etc on the floor is just clutter.if (item.base_type != OBJ_MISSILES|| item.sub_type == MI_JAVELIN|| item.sub_type == MI_THROWING_NET){ammo.push_back(idx);continue;}}DESTROY_ITEM(idx);if (cull_count >= cull_target)
// Get rid of oldest corpses first.std::sort(corpses.begin(), corpses.end(), _sort_corpses);std::vector<int>* lists[] = {&corpses, &ammo, &egos, &potions,&scrolls, &wands, &artefacts, NULL};#ifdef DEBUG_DIAGNOSTICSconst char* list_names[] = {"corpses", "ammo", "egos", "potions","scrolls", "wands", "artefacts"};#endif
const int count1 = cull_count;for (unsigned int i = 0; i < ammo.size(); i++){DESTROY_ITEM(ammo[i]);if (cull_count >= cull_target)break;}
std::vector<int>* vec = lists[i];for (unsigned int j = 0; j < vec->size(); j++){DESTROY_ITEM((*vec)[j]);if (cull_count >= cull_target){#ifdef DEBUG_DIAGNOSTICSmprf(MSGCH_DIAGNOSTICS, "Arena culled %d %s, done.", j + 1,list_names[i]);#endifreturn (first_avail);}} // for (unsigned int j = 0; j < vec->size(); j++)