You've probably done your own research by now, but here's some additional info:
Re: Unid blink scroll prompts: The prompt portion of this can be handled by c_answer_prompt -- prompt:find("cancel this blink") would handle it -- but that only handles the prompt, not the positional targeter input sink that happens prior to the prompt. As you've found, you can deal with the input sink through sendkeys.
Re: Monster weapon desc: Extracting a pattern with a regex from m:desc is also how I've been handling it. This approach is not ideal. Advil added some code in
0dde086 to access monster inventory -- but, although the context of that commit message might suggest an intent to expose it through clua, it looks like it's only exposed through dlua. (I think it would be helpful if that inventory information were exposed through clua in l-moninf, instead of through the dlua in l-mons. Maybe there were info leaks to consider that prevented an easy moninf bind for this?)
Re: "No reachable target in view!": As ebering mentioned, this is in
/dat/clua/autofight.lua. You can use grep to find things like this in a git repo: git grep -n "reachable target in view" should find it.
I was looking at that autofight code a few days ago, and I'm not really a fan of how any of that autofight pathfinding is written. It has that AF_FAILS special case that doesn't exist in crawlcode, it dies when pathing is blocked by non-feature things, it refuses to consider paths outside of the you.los() radius, and (if I'm reading this correctly) it looks like it's using a greedy depth-first algorithm inside of that weird unrolled loop that often brings the player towards things regardless of whether that would be the best path? I tried looking at the commit history for autofight to get a sense of why it's written that way, but this is vintage 2009 crawlcode and it's hard to be sure how much of that is intentional, for either optimization or predictability to players.
More broadly, I think it would be nice if the conditions for autoexplore and autofight were binary: It feels bad from a UX perspective when autoexplore breaks on something, but autofight refuses to take action.
Re: LOS blocking: Personally, I was using
you.see_cell_no_trans() for this, but I never reached the point in my script of adding ranged autofire targeting.
view.cell_see_cell() can be used to test visibility from one tile to another, but as you've found, Crawl has a bunch of visibility checks that differ in subtle ways. (This was somewhat thorny for me when I wrote Rampaging, which has a similar visibility raytrace
using see_cell_no_trans from the C side of the code, with some separate checks for the ray intersecting monsters.)
Re: How, exactly, the visibility checks differ: Uff. This is a bit of a rabbit hole, but ok.
you.cell_see_cell_solid and you.see_cell_solid_see are both defined in
l-you.cc L547. Both of those functions wrap the C function cell_see_cell (
losglobal.cc L116), passing a different los_type opacity parameter. Scrolling up a bit in losglobal, you can see the calls to opc_solid and opc_solid_see, grep from there and you'll find their definitions in
losparam.cc L21, another grep and you'll find opacity_solid and opacity_solid_see at
losparam.cc L81. It looks like opacity_solid_see has two extra checks: One for is_opaque_cloud(), another for mons_opacity(). mons_opacity() can be found over in
los.cc L883, which seems to return OPC_HALF for monsters with the MONS_BUSH species flag, and OPC_CLEAR for everything else. The mons_species() function def can be found over in
mon-util.cc L1311.
Here we run into what might be a bug in Crawl's code: mons_opacity() is *only* comparing the monster species flag to MONS_BUSH. Not the genus to MONS_PLANT, not the species to MONS_PLANT or MONS_DEMONIC_PLANT or MONS_WITHERED_PLANT or MONS_TOADSTOOL or MONS_FUNGUS or any other such cases. (These can be found in mon-data.h.) Possibly see_cell_solid_see wasn't intended to be used to check LOF-blocking, and may have originally been written as a connectivity or pathing check?edit: ebering's post above puts this in context: see_cell_solid_see is literally just a LOS-blocking check for clumps of bushes and clouds like fog, I think?
So, your test was probably working fine, but the you.see_cell_solid_see() doc comment is misleading. (It will return OPC_CLEAR on monsters that aren't bushes.)
Anyway, hopefully this wall of text provides some context to wrangle one of the available binds into working with your code.
I think you're probably looking for a bind like
opacity_no_actor(), but I don't see this exposed through clua anywhere. Good luck~ :/