Moving multiple couriers was a little tricky, but it was mainly because I didn’t realize what exactly I was supposed to be checking in my code.
I originally created a mapping of Courier pointers to bool values to represent whether a courier has been moved already.
std::map<Courier *, bool> m_couriersHaveMoved;
At the beginning of the Move phase, all of the values are set to false. When you select and move a Courier, its value is changed to true to indicate that it has already been moved. This way, during the Move phase, I can highlight only the active Couriers and prevent inactive Couriers from being clickable. As Couriers are moved, they become inactive and ineligible for later selection during this Move phase, and when it is time to move the Couriers again, they are reset to being active. Great!
The problem came when I tried to abuse those values to check if the move phase was completed.
It made sense at first. The Move phase is over when you have moved all of your Couriers. Checking if the Move phase is over was as simple as checking if any of the existing couriers had an associated false value in m_couriersHaveMoved.
Except there was a problem. If a courier COULD be moved but can’t due to the fact that all adjacent tiles are occupied, the Move phase would wait for you to click on a Courier, but none are selectable, so you wait forever, or at least until you pause the game and click “Return to Menu” to start over or quit in frustration.
So I tried to make sure that blocked couriers were considered finished with their move. Unfortunately, this had the side effect that if a courier is blocked at some point during the Move phase, it can’t be selected and moved later even if an adjacent tile opens up. Well, that’s unintuitive for the player!
Eventually I realized that I was trying to use the wrong solution to the problem. The actual problem I’m trying to solve is knowing when the Move phase is completed. The solution has nothing to do with whether or not all of the couriers have made their moves. The solution is to check whether or not there are any tiles adjacent to ACTIVE couriers that are empty.
So now I have the ability to move multiple Couriers in the same Move phase, and I solved the new application-hanging problems that cropped up involving the difference between an inactive Courier and an active Courier that just happens to be unable to move at this time.
– moving the agents towards the package holder
– win condition check
– lose condition check
– allow multiple couriers to move during move phase
– adding pedestrians
– moving pedestrians
– shoving package through pedestrians
Shoving is broken. It has been broken, but it wasn’t until I was able to use it more often that I can see what’s wrong.
Basically, shoving works fine if you shove a single Entity into the next empty square. There’s a potential bug when you shove entities into other entities. If an entity later down the chain can’t be shoved, it won’t be. But the entities earlier in the chain are still shoved, so it looks like one of the entities eats the other.
I need to do a complete chain check first before a shove is allowed. If the check says it is not possible, whether due to the existence of an unshoveable entity or the border of the game world, then no shove happens. If the check says it is possible, then the recursive shoving algorithm can go forward without a hitch.
Also, since shoving is how the package is passed off, I’d like the package to also shove through to the end of the chain if it is possible. Right now, it only passes to the first entity being shoved.
So with 7.5 hours left to go, I’m fixing shove mechanics before adding Pedestrians to make the game more interesting. After that, I suppose I would have time for sound effects and polish, but I hope to submit this game to the Jam long before the deadline so I can get back to actual work. Besides, it is Monday, and “Chuck” is on tonight.