-
Notifications
You must be signed in to change notification settings - Fork 56
/
Copy pathfnc_serializeObjects.sqf
238 lines (181 loc) · 7.45 KB
/
fnc_serializeObjects.sqf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
#include "script_component.hpp"
/*
* Author: mharis001
* Returns serialized object data for the given objects.
* Position offset for the objects is calculated relative to the center position.
* If a center position is not given, the centroid of the objects is used.
*
* Arguments:
* 0: Objects <ARRAY>
* 1: Center Position <ARRAY> (default: nil)
* 2: Include Waypoints <BOOL> (default: false)
*
* Return Value:
* Serialized Data <ARRAY>
*
* Example:
* [_objects] call zen_common_fnc_serializeObjects
*
* Public: No
*/
params [["_objects", [], [[]]], ["_centerPos", nil, [[]], [2, 3]], ["_includeWaypoints", false, [false]]];
// Filter destroyed objects and any objects that are attached to or "part of" another
// The data for these objects will be included in the parent object's data
_objects = _objects select {alive _x && {isNull objectParent _x} && {isNull attachedTo _x} && {isNull ropeAttachedTo _x}};
_objects = _objects arrayIntersect _objects;
// Find the center position of all objects if one is not given
if (isNil "_centerPos") then {
_centerPos = [0, 0, 0];
{
_centerPos = _centerPos vectorAdd getPos _x;
} forEach _objects;
_centerPos = _centerPos vectorMultiply (1 / (count _objects max 1));
};
// Set center position to ground level over land and water level over the ocean
_centerPos set [2, 0];
// Group data is serialized separately, object data will reference a group by its index in this array
private _groupData = [];
private _processedGroups = [];
private _fnc_serializeGroup = {
params ["_unit"];
private _group = group _unit;
private _index = _processedGroups find _group;
if (_index == -1) then {
_index = _processedGroups pushBack _group;
private _waypoints = [];
if (_includeWaypoints) then {
_waypoints = waypoints _group apply {
[_x] call _fnc_serializeWaypoint
};
};
_groupData pushBack [side _group, formation _group, behaviour leader _group, combatMode _group, speedMode _group, _waypoints, currentWaypoint _group];
};
_index
};
private _fnc_serializeWaypoint = {
params ["_waypoint"];
[
waypointType _waypoint,
waypointName _waypoint,
waypointDescription _waypoint,
waypointPosition _waypoint vectorDiff _centerPos,
waypointFormation _waypoint,
waypointBehaviour _waypoint,
waypointCombatMode _waypoint,
waypointSpeed _waypoint,
waypointTimeout _waypoint,
waypointCompletionRadius _waypoint,
waypointStatements _waypoint,
waypointScript _waypoint
]
};
private _fnc_serializeUnit = {
params ["_unit"];
private _type = typeOf _unit;
private _position = ASLToAGL getPosASL _unit vectorDiff _centerPos;
private _direction = getDir _unit;
private _group = _unit call _fnc_serializeGroup;
private _isLeader = leader _unit == _unit;
private _rank = rank _unit;
private _skill = skill _unit;
private _stance = unitPos _unit;
private _loadout = [_unit] call CBA_fnc_getLoadout;
private _identity = [name _unit, face _unit, speaker _unit, pitch _unit, nameSound _unit, _unit call BIS_fnc_getUnitInsignia];
private _flagTexture = getForcedFlagTexture _unit;
private _attachedObjects = _unit call _fnc_serializeAttachedObjects;
[_type, _position, _direction, _group, _isLeader, _rank, _skill, _stance, _loadout, _identity, _flagTexture, _attachedObjects]
};
private _fnc_serializeVehicle = {
params ["_vehicle"];
private _type = typeOf _vehicle;
private _position = ASLToAGL getPosASL _vehicle vectorDiff _centerPos;
private _direction = [vectorDir _vehicle, vectorUp _vehicle];
private _fuel = fuel _vehicle;
private _inventory = _vehicle call FUNC(serializeInventory);
private _customization = _vehicle call BIS_fnc_getVehicleCustomization;
private _flagTexture = getForcedFlagTexture _vehicle;
private _pylonMagazines = getPylonMagazines _vehicle;
private _turretMagazines = magazinesAllTurrets _vehicle select {
!(_x select 0 in _pylonMagazines) // Do not include pylon magazines
} apply {
_x select [0, 3] // Discard ID and creator
};
{
private _turretPath = [_vehicle, _forEachIndex] call FUNC(getPylonTurret);
private _ammoCount = _vehicle ammoOnPylon (_forEachIndex + 1);
_pylonMagazines set [_forEachIndex, [_x, _turretPath, _ammoCount]];
} forEach _pylonMagazines;
private _crew = [];
{
_x params ["_unit", "_role", "_cargoIndex", "_turretPath"];
if (alive _unit) then {
_crew pushBack [_unit call _fnc_serializeUnit, toLower _role, _cargoIndex, _turretPath];
};
} forEach fullCrew _vehicle;
private _vehicleCargo = [];
{
if (alive _x) then {
private _data = _x call _fnc_serializeObject;
if (isNil "_data") exitWith {};
_vehicleCargo pushBack _data;
};
} forEach getVehicleCargo _vehicle;
private _slingLoadedObject = getSlingLoad _vehicle;
if (alive _slingLoadedObject) then {
_slingLoadedObject = _slingLoadedObject call _fnc_serializeObject;
if (isNil "_slingLoadedObject") then {
_slingLoadedObject = []; // Empty array to indicate that vehicle does not have a sling loaded object
};
};
private _attachedObjects = _vehicle call _fnc_serializeAttachedObjects;
[_type, _position, _direction, _fuel, _inventory, _customization, _flagTexture, _turretMagazines, _pylonMagazines, _crew, _vehicleCargo, _slingLoadedObject, _attachedObjects]
};
private _fnc_serializeStatic = {
params ["_object"];
private _type = typeOf _object;
private _position = ASLToAGL getPosASL _object vectorDiff _centerPos;
private _direction = [vectorDir _object, vectorUp _object];
private _simulationEnabled = simulationEnabled _object;
private _inventory = _object call FUNC(serializeInventory);
private _attachedObjects = _object call _fnc_serializeAttachedObjects;
[_type, _position, _direction, _simulationEnabled, _inventory, _attachedObjects]
};
private _fnc_serializeAttachedObjects = {
params ["_object"];
private _attachedObjects = [];
{
// Filter vehicle cargo objects, they are also attached
if (alive _x && {isNull isVehicleCargo _x}) then {
private _data = _x call _fnc_serializeObject;
if (isNil "_data") exitWith {};
private _offset = _object worldToModel ASLToAGL getPosWorld _x;
private _dirAndUp = [_object vectorWorldToModel vectorDir _x, _object vectorWorldToModel vectorUp _x];
_attachedObjects pushBack [_data, _offset, _dirAndUp];
};
} forEach attachedObjects _object;
_attachedObjects
};
private _fnc_serializeObject = {
params ["_object"];
if (_object isKindOf "AllVehicles") then {
if (_object isKindOf "CAManBase") then {
_object call _fnc_serializeUnit
} else {
if (_object isKindOf "Animal") exitWith {};
_object call _fnc_serializeVehicle
};
} else {
if (_object isKindOf "Static" || {_object isKindOf "Thing"}) then {
if (_object isKindOf "ThingEffect") exitWith {};
_object call _fnc_serializeStatic
};
};
};
private _objectData = [];
{
private _data = _x call _fnc_serializeObject;
if (!isNil "_data") then {
_objectData pushBack _data;
};
} forEach _objects;
[_objectData, _groupData]