CleverRaven / Cataclysm-DDA

Cataclysm - Dark Days Ahead. A turn-based survival game set in a post-apocalyptic world.
http://cataclysmdda.org
Other
10.63k stars 4.18k forks source link

`u_location_variable` only detects the first top left entity under the aoe #75997

Closed RedMisao closed 2 months ago

RedMisao commented 2 months ago

Describe the bug

The eoc effect u_location_variable can use to search for an entity's ("terrain" / "furniture" / "field" / "trap" / "monster" / "zone" / "npc") coordinates under the area where it's run. I tried to use it for a "detect X" kind of spell for non-monster entities, but it seems to return true after it finds the first target_id towards the top-left position.

Attach save file

N/A

Steps to reproduce

  1. Add the following json somewhere

    {
    "id": "utsuho_detectrad_furn_eoc_WIP",
    "type": "effect_on_condition",
    "effect": [
      { 
        "u_location_variable": { "global_val": "var_detectrad_furn_TEST_1" }, "furniture": "f_bench", "target_min_radius": 0, "target_max_radius": 32,
        "true_eocs": [
          {
            "id": "var_detectrad_furn_TEST_1_eoc",
            "effect": [ 
              { "u_set_field": "fd_clairvoyant", "radius": 0, "intensity": 1, "target_var": { "global_val": "var_detectrad_furn_TEST_1" } },
              { "message": "<global_val:var_detectrad_furn_TEST_1> AAA", "type": "mixed" }
            ]
          }
        ]
      },
      { 
        "u_location_variable": { "global_val": "var_detectrad_furn_TEST_2" }, "furniture": "f_bench", "target_min_radius": 0, "target_max_radius": 32,
        "true_eocs": [
          {
            "id": "var_detectrad_furn_TEST_2_eoc",
            "effect": [ 
              {
                "if": { "map_furniture_id": "f_bench", "loc": { "global_val": "var_detectrad_furn_TEST_2" } },
                "then": [
                  { "u_set_field": "fd_clairvoyant", "radius": 0, "intensity": 1, "target_var": { "global_val": "var_detectrad_furn_TEST_2" } },
                  { "message": "<global_val:var_detectrad_furn_TEST_2> BBB", "type": "mixed" }
                ]
              }
            ]
          }
        ]
      }
    ]
    },
  2. Create a new Evacuee at any of the refugee centers, so you have plenty of f_bench lying around

  3. Run the EOC, only a single pair of coordinates will be printed (bench located top left)

  4. Move that bench so another is located at the top-most left-most position

  5. Run the EOC again, same thing for the bench that's top-most left-most

Expected behavior

I expected to obtain the coordinates of all the benches under the aoe

Screenshots

1

2

Versions and configuration

Additional context

I believe this is unintended behavior because anything relying on u_location_variable (or npc_location_variable) that runs on an aoe will be pointed towards the top left direction and only for a single entity. For spells it will shoot only once and always towards that direction, it cannot be using for counting the number of entities because it will stop after it detects the first one, and so on.

I also tested this with type_id monster and then placing two mon_zombie_hazmat, again only the coordinates of the first one are printed. I did not tested it with the other type_ids.

PatrikLundell commented 2 months ago

There are really two different use cases:

  1. Find the first thingie matching the criteria and return that one (and the search behavior ought to be consistent and suitable for the usage: if you care about which one you get you usually wants the closest one [best hit chance, shortest distance to walk to, etc.]).
  2. Find all thingies matching the criteria and return all of them.

If you're attacking something, talking to it, or doing anything else that requires a single target you'd want the first behavior. On the other hand, if you wanted to count the number of thingies or do something to all of them you'd need the second one.

You shouldn't have a case where you'd look for something and then fire a gun at all matches at the same time, for instance, whereas some kind of field effect would apply it to all matches.

RedMisao commented 2 months ago

Yes, I'm aware of the different use cases and their different results. I'm just reporting that the current implementation is limited to work as either:

  1. detect X at Y point (radius = 0), which works as intended as radius = 0 means just coordinates
  2. detect any X at Y aoe (radius >0), starting from top left

The possibility of "detect every X at Y aoe", or "detect the closest X from Y", or any other variation won't work.

The screenshots I sent may not be clear enough. I ran the eoc closer to the central staircase, then moved to that position to drag the bench so the bench at the right (same y coordinates) would be found first. In other words, the current implementation is ignoring distance from the center of the alpha talker: it just scans the aoe starting from top left.

So, if you have a spell that is "cast fireball at X at Y aoe" and there are several X, then you will always cast 1 fireball at the same Y, scanning from the most* top left coordinate, even if you have an X that's hitting you from your right.

PatrikLundell commented 2 months ago

I consider the return of a single match to be the proper function of this. If you want something that somehow returns all and affects all of them it should be a separate operation (named appropriately, of course).

Which match you want to return depends on the use case, so some kind of search criterion should probably be a parameter. Some alternatives:

RedMisao commented 2 months ago

If this is the intended function, I will close the issue.