State Management
Zara supports saving and restoring engine state. It will restore all its internal nodes, but some, more abstract entities, you must save and load yourself. Zara supports saving and loading of these nodes without any additional actions:
Game time
Player state
Weather state
Health vitals
Clothes
Body appliances
Weight of the inventory
Medical agents
Zara will not save inventory items.
Basically, to save the whole state, you need to:
- Get the core Zara state
- Save your inventory items separately
- Save active diseases and injuries separately (see below)
- Save your disease monitors, inventory monitors and side effects monitors separately (see below)
To get the core state, call
let state = person.get_state();
This will return ZaraControllerStateContract
.
To restore this state, call
person.restore_state(state);
These objects must be stored separately. To save the state of active diseases, you should do something like
for (key, disease) in person.health.diseases.borrow().iter() {
self.diseases.insert(key.clone(), disease.get_state());
}
Where self.diseases
is a collection that will hold these states (ActiveDiseaseStateContract
).
Same with injuries:
for (key, injury) in person.health.injuries.borrow().iter() {
self.injuries.insert(key.clone(), injury.get_state());
}
In order to restore diseases and injuries, you may want to first clear the current ones
// Clear diseases
person.health.clear_diseases();
// Clear injuries
person.health.clear_injuries();
And then restore them one by one. Here you need to provide state you captured before, and disease/injury
instance associated with this state. Your disease/injury instance can hold some internal fields, or your custom treatment state data, so here you need to save and load your disease/injury objects according to your needs.
// Restore diseases
for (_, state) in &self.diseases {
// ... get the associated disease instance, then restore the state:
person.health.restore_disease(state, disease);
}
// Restore injuries
for (_, state) in &self.injuries {
// ... get the associated injury instance, then restore the state:
person.health.restore_injury(state, injury);
}
If your disease/injury struct not holding any crucial data that needs to be saved, you can pass a new disease/injury instance here.
Every disease, injury, disease monitor, inventory monitor, inventory item and side effects monitor has as_any
function that allows you to downcast their instances from traits to their actual types, so you can access their custom methods to get and restore their state.
All built-in side effects for example have those methods, and can be easily saved and loaded:
let monitors = person.health.side_effects.borrow();
// Get monitor state
self.monitor_fatigue_state = match &self.monitor_fatigue {
Some(mid) => match monitors.get(mid) {
Some(m) => match m.as_any().downcast_ref::<FatigueSideEffects>() {
Some(o) => Some(o.get_state()),
None => None
}
None => None
},
None => None
};
// Restore monitor state
if let Some(st) = &self.monitor_fatigue_state {
if let Some(mid) = &self.monitor_fatigue {
if let Some(m) = monitors.get(mid) {
if let Some(o) = m.as_any().downcast_ref::<FatigueSideEffects>() {
o.restore_state(st)
}
}
}
}
Where mid
is an id
of the registered monitor instance.