* Gets the best target unit for the given unit. * * @param u The Unit to get the best target for. * @param mode How to determine the best target. * @return The best target or NULL if none found. */
| 921 | * @return The best target or NULL if none found. |
| 922 | */ |
| 923 | Unit *Unit_FindBestTargetUnit(Unit *u, uint16 mode) |
| 924 | { |
| 925 | tile32 position; |
| 926 | uint16 distance; |
| 927 | PoolFindStruct find; |
| 928 | Unit *best = NULL; |
| 929 | uint16 bestPriority = 0; |
| 930 | |
| 931 | if (u == NULL) return NULL; |
| 932 | |
| 933 | position = u->o.position; |
| 934 | if (u->originEncoded == 0) { |
| 935 | u->originEncoded = Tools_Index_Encode(Tile_PackTile(position), IT_TILE); |
| 936 | } else { |
| 937 | position = Tools_Index_GetTile(u->originEncoded); |
| 938 | } |
| 939 | |
| 940 | distance = g_table_unitInfo[u->o.type].fireDistance << 8; |
| 941 | if (mode == 2) distance <<= 1; |
| 942 | |
| 943 | find.houseID = HOUSE_INVALID; |
| 944 | find.type = 0xFFFF; |
| 945 | find.index = 0xFFFF; |
| 946 | |
| 947 | while (true) { |
| 948 | Unit *target; |
| 949 | uint16 priority; |
| 950 | |
| 951 | target = Unit_Find(&find); |
| 952 | |
| 953 | if (target == NULL) break; |
| 954 | |
| 955 | if (mode != 0 && mode != 4) { |
| 956 | if (mode == 1) { |
| 957 | if (Tile_GetDistance(u->o.position, target->o.position) > distance) continue; |
| 958 | } |
| 959 | if (mode == 2) { |
| 960 | if (Tile_GetDistance(position, target->o.position) > distance) continue; |
| 961 | } |
| 962 | } |
| 963 | |
| 964 | priority = Unit_GetTargetUnitPriority(u, target); |
| 965 | |
| 966 | if ((int16)priority > (int16)bestPriority) { |
| 967 | best = target; |
| 968 | bestPriority = priority; |
| 969 | } |
| 970 | } |
| 971 | |
| 972 | if (bestPriority == 0) return NULL; |
| 973 | |
| 974 | return best; |
| 975 | } |
| 976 | |
| 977 | /** |
| 978 | * Get the priority for a target. Various of things have influence on this score, |
no test coverage detected