BurnySc2 / python-sc2

A StarCraft II bot api client library for Python 3
MIT License
491 stars 157 forks source link

self.client.query_paths always return 0 #195

Open ramsayxiaoshao opened 5 months ago

BurnySc2 commented 5 months ago

Can you post a code example please? How are you attempting to use it? It returns 0 when there is no valid path, I believe

ramsayxiaoshao commented 5 months ago

When I'm using the function self.client.query_paths, I was thinking to get the path from my units to my set point, for example "self.enemy_start_location[0]". I don't remember my code very clear because I already deleted them cause they're not working. It's just something like below: pathing_responses = await self.client.query_pathings( [(unit.position, self.enemy_start_location[0]) for unit in attacking_units] ) I always found that the pathing_responses is always the list full of 0.0, then I just look into the function "self.client.query_pathings" to take a deep look and found that the calculated distance of all units are all the same, like 3250.0 So I don't know what's going on.

ramsayxiaoshao commented 5 months ago

I found my code and I will show you below: avenager_units_types = [ UnitTypeId.ZERGLING, UnitTypeId.OVERSEER, UnitTypeId.ROACH, UnitTypeId.RAVAGER, UnitTypeId.BANELING, UnitTypeId.HYDRALISK, UnitTypeId.INFESTOR, UnitTypeId.SWARMHOSTMP, UnitTypeId.MUTALISK, UnitTypeId.CORRUPTOR, UnitTypeId.VIPER, UnitTypeId.ULTRALISK, UnitTypeId.BROODLORD ]

    attacking_units = self.units.filter(lambda unit: unit.type_id in avenager_units_types)

    pathing_responses = await self.client.query_pathings(
        [[unit.position, target_position] for unit in attacking_units]
    )
    print("pathing_responses:", pathing_responses)

The result is: pathing_responses: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

Thank you so much!

BurnySc2 commented 5 months ago

I haven't used it in a long time but there may be cases where the target_position is something that ground units can't reach, in which case it returns 0.

Can you try using the following, where you use the unit instead of the unit.position of the first parameter? Like so:

    attacking_units = self.units.filter(lambda unit: unit.type_id in avenager_units_types)

    pathing_responses = await self.client.query_pathings(
        [[unit, target_position] for unit in attacking_units]
    )
    print("pathing_responses:", pathing_responses)

I believe the second parameter always has to be a position, so keep it that way. I got this info from the asserts: https://github.com/BurnySc2/python-sc2/blob/f175e8160762dcba9a1524b3491cf5f522e01fde/sc2/client.py#L235-L236

ramsayxiaoshao commented 5 months ago

Thank you for your reply! Actually, I was trying these two ways before and always got the 0.0. Lol The reason why I want to use the self.client.query_pathings, is that I want to fix the problem that when I sending my armies to attack the enemy, due to the diverse speed of different Zerg units (Zergling is the fastest and the Roach is related slow), which cause my Zerg armies to move one by one instead of moving together, causing my armies to be defeated one by one by the enemy. Do you have any ideas to let the armies move to the location together? Instead of moving there one by one, haha. If there's another way to fix this, I maybe don't need to use the self.client.query_pathings.