| 965 | } |
| 966 | |
| 967 | void World::reload_units(const UnitResource *old_unit, const UnitResource *new_unit) |
| 968 | { |
| 969 | #if CROWN_CAN_RELOAD |
| 970 | for (u32 i = 0; i < array::size(_unit_resources); ++i) { |
| 971 | if (_unit_resources[i] == old_unit) { |
| 972 | Vector3 pos = VECTOR3_ZERO; |
| 973 | Quaternion rot = QUATERNION_IDENTITY; |
| 974 | Vector3 scl = VECTOR3_ONE; |
| 975 | TransformId ti = _scene_graph->instance(_units[i]); |
| 976 | |
| 977 | if (is_valid(ti)) { |
| 978 | pos = _scene_graph->local_position(ti); |
| 979 | rot = _scene_graph->local_rotation(ti); |
| 980 | scl = _scene_graph->local_scale(ti); |
| 981 | } |
| 982 | |
| 983 | // Collect units created when old_unit was spawned |
| 984 | // and destroy all their components. Unit IDs will be reused. |
| 985 | Array<UnitId> unit_lookup(default_scratch_allocator()); |
| 986 | collect_units(&unit_lookup, _scene_graph, _units[i]); |
| 987 | |
| 988 | for (u32 j = 0; j < array::size(unit_lookup); ++j) |
| 989 | _unit_manager->trigger_destroy_callbacks(unit_lookup[j]); |
| 990 | |
| 991 | // Create or destroy IDs if new_unit has different number of units. |
| 992 | u32 n = array::size(unit_lookup); |
| 993 | for (u32 i = new_unit->num_units; i > n; --i) { |
| 994 | UnitId u = _unit_manager->create(); |
| 995 | array::push_back(unit_lookup, u); |
| 996 | array::push_back(_units, u); |
| 997 | array::push_back(_unit_resources, (const UnitResource *)NULL); |
| 998 | } |
| 999 | for (u32 i = new_unit->num_units; i < n; ++i) { |
| 1000 | _unit_manager->destroy(array::back(unit_lookup)); |
| 1001 | array::pop_back(unit_lookup); |
| 1002 | } |
| 1003 | CE_ENSURE(array::size(unit_lookup) == new_unit->num_units); |
| 1004 | |
| 1005 | create_components(*this |
| 1006 | , new_unit |
| 1007 | , array::begin(unit_lookup) |
| 1008 | , SpawnFlags::OVERRIDE_POSITION |
| 1009 | | SpawnFlags::OVERRIDE_ROTATION |
| 1010 | | SpawnFlags::OVERRIDE_SCALE |
| 1011 | , pos |
| 1012 | , rot |
| 1013 | , scl |
| 1014 | ); |
| 1015 | _unit_resources[i] = new_unit; |
| 1016 | } |
| 1017 | } |
| 1018 | |
| 1019 | remove_dead_units(); |
| 1020 | #else |
| 1021 | CE_UNUSED_2(old_unit, new_unit); |
| 1022 | CE_NOOP(); |
| 1023 | #endif // if CROWN_CAN_RELOAD |
| 1024 | } |
no test coverage detected