falconne
meep
I wanted to create a combat simulation routine to help the AI determine whether it has enough units to defeat an enemy stack.
From a few threads I see in this subforum, it looks like the developers of this mod have already thought about this a bit. I was wondering if you have anything in progress?
From what I can tell from the code, solving this can get messy as the methods that calculate the result of a one on one duel between two units has side effects that change CvUnit fields, so it's not possible to simply call those methods and read the result and still keep the game state.
I see 3 messy solutions to the problem so far:
1) Create a new set of methods that are copies of the combat calculation methods but rewritten so they don't affect the game state. This solution obviously has so many problems I won't bother talking about them - it's not really a viable solution anyway.
2) At runtime, create copies of all the units involved in the combat and send those objects to the combat calculator (after which they can be destroyed). This would require subclassing CvUnit as it's an abstract class. The problem I see with this is that if I instantiate a new CvUnit, it's going to invoke CvDLLEntity::createUnitEntity. I don't know what side effects that has. In general I don't know if creating temporary units on the fly is a good idea - it might have unintended consequences in the game system.
3) Store the original state of the unit inside of CvUnit itself and restore the state of the affected units after the combat calculation is done. The advantage with this method is the Read and Write methods that already read and write the entire state of the object could be used. I presume these methods are used to write to a read from a saved game file. Unfirtunately there doesn't appear to be an implementation of FDataStreamBase within the SDK, so it would have to be completely implemented. This might still be worth it, as using those methods means, if new member variables are added to CvUnit in the future, the state saving functionality will keep working (unlike in method 2) above).
Have you guys come up with any alternative solutions that would be cleaner? I'm going to work on method 3), but I wanted to check if there were any other ideas out there.
From a few threads I see in this subforum, it looks like the developers of this mod have already thought about this a bit. I was wondering if you have anything in progress?
From what I can tell from the code, solving this can get messy as the methods that calculate the result of a one on one duel between two units has side effects that change CvUnit fields, so it's not possible to simply call those methods and read the result and still keep the game state.
I see 3 messy solutions to the problem so far:
1) Create a new set of methods that are copies of the combat calculation methods but rewritten so they don't affect the game state. This solution obviously has so many problems I won't bother talking about them - it's not really a viable solution anyway.
2) At runtime, create copies of all the units involved in the combat and send those objects to the combat calculator (after which they can be destroyed). This would require subclassing CvUnit as it's an abstract class. The problem I see with this is that if I instantiate a new CvUnit, it's going to invoke CvDLLEntity::createUnitEntity. I don't know what side effects that has. In general I don't know if creating temporary units on the fly is a good idea - it might have unintended consequences in the game system.
3) Store the original state of the unit inside of CvUnit itself and restore the state of the affected units after the combat calculation is done. The advantage with this method is the Read and Write methods that already read and write the entire state of the object could be used. I presume these methods are used to write to a read from a saved game file. Unfirtunately there doesn't appear to be an implementation of FDataStreamBase within the SDK, so it would have to be completely implemented. This might still be worth it, as using those methods means, if new member variables are added to CvUnit in the future, the state saving functionality will keep working (unlike in method 2) above).
Have you guys come up with any alternative solutions that would be cleaner? I'm going to work on method 3), but I wanted to check if there were any other ideas out there.