Hi,
So i have now a version of OpenXcom which allow to create custom screen and game logic. You can find the code here:
https://gchevallereau.net/cgit/cgit.cgi/OpenXcom/log/?h=swigXBefore introducing those modification, I want to explaing how the OpenXcom SWIG/python bindings work.
Before starting with OpenXcom, a little explanation on how swig work. swig parse the source code and output two kind of files.
* First a language specific(python here) which contains exported definitions.
* Second a really big C++ file(more than 145000 lines for OpenXcom!). This file is a glue code between C++ and the target language. In our case this file is built as a python module.
To parse the source code, swig need an input file. Most of the work is to write this input file. Now, if you look at the swig branch, you won't find it. I use CMake to auto-generate it.
If you look at the swig branch you will see that a lot a of file has been modified, but most of the modification are to build a libOpenXcomBase(Windows dll stuff). This library is needed to build the python module.
The python stuff is not that big. Only two files:
* python_out.cpp: A python module used to redirect the python stdout and stderr to the python console
* python.cpp: The main python interface. This file contains the two function used to execute python code(runPython and runPythonString). Also contains initialization and clean up code.
So how the custom State work?
to allow redefining state, i had to change the way state are created. Instead of directly creating it, we ask a StateFactory to do it. State are created using an instance of a StateInfo class. So in C++ we have:
class MyState : public State
{
};
class MyStateInfo : public StateInfo
{
};
REGISTER_CREATOR("MyStateId", MyStateInfo); https:// automatically append it to the StateFactory
and when we need to instantiate it:
State * s = _game->getStateFactory ()->createState("OPENXCOM_RESEARCHSTATE",
args);
This downside, is that when creating a state we usually need to pass some arguments. As we have no base class for thing in Ruleset or Savegame, I have used a little hack. All arguments are void * pointers. If it's not really the cleanest way to do it, it actually work great.
Another problem was the handling of callback function for events. They are at the moment pointer to class members. SWIG is not able to bind this. The solution was to create children class in python and reimplements event handling in those class. You can see that in Button for example are all PythonTextButton instead of TextButton.
game logic:
The implementation is quite similar to the custom state. There is GameLogic base class and a GameLogic manager. In python we can redefine child class of GameLogic and then add it to the GameLogicManager. They will be automatically handled.
Implementation note: I haven't changed all the code. Only the Research/Production State can be redefined. The same goes for GameLogic, new GameLogic elements can be added, but only craft repairing can be replaced. I do not plan to change this at the moment.
I put a windows build here:
https://gchevallereau.net/guillaume/openxcom/OpenXcom_python-0.3-win32.zipYou can find some example script here:
https://gchevallereau.net/guillaume/openxcom/scripts.zip. This zip contains 3 scripts:
* research.py: replace the Research screen
* repair_engineer.py: replace the craft repairing game logic. Craft can be repaired faster if you have available engineers.
* autosell.py: replace the production state to allow automatic selling of production.
Just unzip this file and copy all script to the python/auto-start folder.
Have fun!