Saving and Loading
Menus! Right now there are no in-game menus or overlays and everything but new game and quit game do what they are supposed to do. The next task on the list is to fully implement saving/loading. Additionally, I wanted to fix up the menu transition in and out of game. There are two minor issues: you lose your selection of units and your mouse position is also reset.
Also I've been keeping a list of infrastructure debt but that list will be tackled on an as-needed basis to get a working game (also lets me have more time to figure out what I really need to do to solve those problems because I'm fairly unfamiliar with future issues that might arise in Cultura).
Saving/Loading
The saving and loading dialogs need you to be able to select save files or save to disk. I don't know if you really want a full file explorer or just a simplistic "save/load" console style. I'm leaning toward console style.
CEGUI provides something called the layout container which I plan to use to create the list of files to save/load. When the dialog is loaded it scans the save/load director for files following the *.sav format. This creates a cross-platform issue which will be ignored for now (we'll just use the windows directory system to load up the list of files). For each file we create a window and add it to the layout container. Then we will have the same functor used as the subscriber to the onClick event of each. We will set userData on each window so that when the user later clicks on it, in the listener function we can then determine what was clicked and set the correct file as the one to be saved/loaded (also do fancy UI stuff like highlight that box and unhighlight all other boxes).
Here are some CEGUI references that are relevant:
- CEGUI's Layout Container
- CEGUI Tutorial for User Data
- Window Property for multiclick events
- Double Click Event
The user then clicks on save/load to perform the actual save or load. For now, I will not allow user defined file names. Instead they will be automatically generated.
Currently, the serialisation works on creating a byte array that is then saved to disk. The serialisation is a bit manual. All objects that need to be serialised essentially derive from CGameEntity. The serialisation uses a custom class known as a CByteBuffer. Objects write to a byte buffer when serialisation or reads from the byte buffer when deserialising. Each class must know how to read/write its member variables inside its serialisation function. Each class calls the super class's serialisation function. That way you get a chain serialisation occurring. It's somewhat tricky to choose which variables inside a class to serialise but there are special considerations (which can be cleaned up with refactoring later): not serialising temporary member variables such as graphic entity pointers.
Also, to simplify serialisation, units/structures and many other entities are being compacted. Originally, I had subclasses for units and structures for different types of units/structures. However, when you get to serialisation that becomes a problem (I have a CUnit pointer but is it really a CAnimal?). Instead of something fancy, the different levels will be compacted into one with a few classes added to record large blobs of data (a new StorageStates class for structures).
I will have to serialise actions as well and in that case, I will have to serialise what action was just serialised (so I can perform proper desserialisation). This means adding a few constants to the UnitAction class and a variable for UnitActionType.
Compacting the Classes
In an effort to simplify serialization, I am compacting my unit and structure classes into a single class with several "container" classes hanging off of them.
Unit:
- CombatStats
- EquipmentStats
- CounterStats
- Carried items
- Location
Structure:
- CombatStats
- CounterStats
- StorageStats
- Location
CombatStats:
- Hitpoints
- Damage
EquipmentStats:
- Item* HeadSlot
- Torso
- LeftArm
- RightArm
- LeftHand (for weapons or equipment)
- RightHand (two handed weapons will have both slots point to the same item
- LeftLeg
- RightLeg
- LeftFoot
- RightFoot
CounterStats:
- int MoveCounter
- AttackCounter
- bool incrementMoveCounter //returns true when move counter gets reset and the unit should move, false otherwise
StorageStats:
- std::vector
Capacity //-1 means unlimited, uses constants for item categories, checks narrowest category first before moving upward, for alpha, just have all/food/non-food categories - std::vector
StoredAmount //list that mirrors capacity, must update all categories when giving or taking items - std::vector
- StoredItems
- int GiveItem(Item* item) //returns amount not stored
- void TakeItem(Item* item)
Carried items can just be a StorageStats object that is not using most of the functionality and only has a single storage limit for all items.
Location is a std::pair
No comments:
Post a Comment