-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathitem-array-data.inc
More file actions
329 lines (242 loc) · 8.94 KB
/
Copy pathitem-array-data.inc
File metadata and controls
329 lines (242 loc) · 8.94 KB
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
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
// built-in include guard removal
// just in case the user has a local dependency with the same file name
#if defined _inc_item_array_data
#undef _inc_item_array_data
#endif
// custom include-guard to ensure we don't duplicate
#if defined _item_array_data_included
#endinput
#endif
#define _item_array_data_included
#include <a_samp>
#include <logger>
#include <errors>
#include <item>
#include <YSI_Coding\y_hooks>
#if !defined ITM_ARR_MAX_ARRAY_DATA
#define ITM_ARR_MAX_ARRAY_DATA (256)
#endif
// Functions
// SetItemTypeMaxArrayData sets the maximum size for array data for a specific
// item type. This should be only called once, preferably immediately after
// the item type has been defined. `protect` will mark items of this type as
// "protected" meaning they require explicit actions to modify.
forward SetItemTypeMaxArrayData(ItemType:itemtype, size, bool:protect = false);
// GetItemTypeArrayDataSize returns the array data size for a particular type.
forward GetItemTypeArrayDataSize(ItemType:itemtype, &size);
// SetItemArrayData is for setting the entire item array at once, the item's
// array size will be resized automatically unless it is protected.
forward Error:SetItemArrayData(Item:itemid, const data[], length, call = 1, bool:force = false);
// GetItemArrayData stores the entire array for an item in `data`.
forward Error:GetItemArrayData(Item:itemid, data[], length = sizeof data);
// SetItemArrayDataAtCell sets a single cell of an item's array data. `autosize`
// adjust the array data automatically if `cell` specifies a cell index beyond
// the current item's array size. `call` controls whether or not to call
// `OnItemArrayDataChanged` and `force` is required for protected item types.
forward Error:SetItemArrayDataAtCell(Item:itemid, data, cell, bool:autoSize = false, bool:call = true, bool:force = false);
// GetItemArrayDataAtCell stores into `data` the data in the item's array at
// `cell`.
forward Error:GetItemArrayDataAtCell(Item:itemid, &data, cell);
// SetItemArrayDataSize adjusts the array size for an item. This size must be
// within the item's max size for its type. `force` is required true for
// protected item types.
forward Error:SetItemArrayDataSize(Item:itemid, size, bool:force = false);
// GetItemArrayDataSize stores into `size` the size of the item's array.
forward GetItemArrayDataSize(Item:itemid, &size);
// AppendItemDataArray appends an entire array to an item's array.
forward Error:AppendItemDataArray(Item:itemid, const data[], length);
// AppendItemArrayCell appends a single cell to an item's array.
forward Error:AppendItemArrayCell(Item:itemid, data);
// SetItemArrayDataLength explicitly sets the array size for an item.
forward Error:SetItemArrayDataLength(Item:itemid, length, bool:force = false);
// RemoveItemArrayData clears all data for an item.
forward RemoveItemArrayData(Item:itemid);
// SetItemNoResetArrayData will ensure an item's data is not reset on
// `OnItemCreate`, this is useful if you want to set some array data when an
// item is created but you have no control over when the `OnItemCreate` hook in
// this library is called. If the hook in this library is called after your own
// hook then using this function will ensure that array data is not zeroed
// immediately after it has been set.
forward SetItemNoResetArrayData(Item:itemid, bool:toggle);
// OnItemArrayDataChanged is called whenever a function modifies an item's data.
forward OnItemArrayDataChanged(Item:itemid);
/*==============================================================================
Setup
==============================================================================*/
static
itm_arr_ItemTypeArrayMax[MAX_ITEM_TYPE],
bool:itm_arr_ItemTypeArrayProtect[MAX_ITEM_TYPE],
itm_arr_Data[MAX_ITEM][ITM_ARR_MAX_ARRAY_DATA],
itm_arr_Length[MAX_ITEM],
itm_arr_NoResetOnCreate[MAX_ITEM];
hook OnItemCreate(Item:itemid) {
if(!itm_arr_NoResetOnCreate[itemid]) {
for(new i; i < itm_arr_ItemTypeArrayMax[GetItemType(itemid)]; i++) {
itm_arr_Data[itemid][i] = 0;
}
itm_arr_Length[itemid] = 0;
} else {
itm_arr_NoResetOnCreate[itemid] = 0;
}
return 1;
}
stock SetItemTypeMaxArrayData(ItemType:itemtype, size, bool:protect = false) {
if(!IsValidItemType(itemtype)) {
Logger_Err("attempt to set max array data for invalid item type",
Logger_I("itemtype", _:itemtype));
return 1;
}
if(size > ITM_ARR_MAX_ARRAY_DATA) {
Logger_Err("attempt to set max array data beyond hard limit",
Logger_I("size", size),
Logger_I("max", ITM_ARR_MAX_ARRAY_DATA),
Logger_I("itemtype", _:itemtype));
return 2;
}
itm_arr_ItemTypeArrayMax[itemtype] = size;
itm_arr_ItemTypeArrayProtect[itemtype] = protect;
return 0;
}
stock GetItemTypeArrayDataSize(ItemType:itemtype, &size) {
if(!IsValidItemType(itemtype)) {
return 1;
}
size = itm_arr_ItemTypeArrayMax[itemtype];
return 0;
}
stock Error:SetItemArrayData(Item:itemid, const data[], length, call = 1, bool:force = false) {
if(!IsValidItem(itemid)) {
return Error(1, "invalid item id");
}
new ItemType:itemtype = GetItemType(itemid);
if(length > itm_arr_ItemTypeArrayMax[itemtype]) {
return Error(2, "length exceeds item type max data size");
}
if(itm_arr_ItemTypeArrayProtect[itemtype] && !force) {
return Error(3, "itemtype uses data protection, must force");
}
itm_arr_Length[itemid] = 0;
for(new i; i < length; i++) {
itm_arr_Data[itemid][itm_arr_Length[itemid]++] = data[i];
}
if(call) {
CallLocalFunction("OnItemArrayDataChanged", "d", _:itemid);
}
return Ok();
}
stock Error:GetItemArrayData(Item:itemid, data[], length = sizeof data) {
if(!IsValidItem(itemid)) {
return Error(1, "invalid item id");
}
new ItemType:itemtype = GetItemType(itemid);
if(length > itm_arr_ItemTypeArrayMax[itemtype]) {
length = itm_arr_ItemTypeArrayMax[itemtype];
}
for(new i; i < itm_arr_Length[itemid] && i < length; i++) {
data[i] = itm_arr_Data[itemid][i];
}
return Ok();
}
stock Error:SetItemArrayDataAtCell(Item:itemid, data, cell, bool:autoSize = false, bool:call = true, bool:force = false) {
if(!IsValidItem(itemid)) {
return Error(1, "invalid item id");
}
new ItemType:itemtype = GetItemType(itemid);
if(cell >= itm_arr_ItemTypeArrayMax[itemtype]) {
return Error(2, "attempt to write data beyond item type max");
}
if(itm_arr_ItemTypeArrayProtect[itemtype] && !force) {
return Error(3, "itemtype uses data protection, must force");
}
if(cell >= itm_arr_Length[itemid]) {
if(autoSize) {
itm_arr_Length[itemid] = cell + 1;
} else {
return Error(4, "attempt to write data beyond item array size");
}
}
itm_arr_Data[itemid][cell] = data;
if(call) {
CallLocalFunction("OnItemArrayDataChanged", "d", _:itemid);
}
return Ok();
}
stock Error:GetItemArrayDataAtCell(Item:itemid, &data, cell) {
if(!IsValidItem(itemid)) {
return Error(1, "invalid item id");
}
new ItemType:itemtype = GetItemType(itemid);
if(cell >= itm_arr_ItemTypeArrayMax[itemtype]) {
return Error(2, "attempt to read data beyond item type max");
}
if(cell >= itm_arr_Length[itemid]) {
return Error(3, "attempt to read data beyond data length");
}
data = itm_arr_Data[itemid][cell];
return Ok();
}
stock Error:SetItemArrayDataSize(Item:itemid, size, bool:force = false) {
if(!IsValidItem(itemid)) {
return Error(1, "invalid item id");
}
new ItemType:itemtype = GetItemType(itemid);
if(itm_arr_ItemTypeArrayProtect[itemtype] && !force) {
return Error(2, "itemtype uses data protection, must force");
}
itm_arr_Length[itemid] = size;
return Ok();
}
stock GetItemArrayDataSize(Item:itemid, &size) {
if(!IsValidItem(itemid)) {
return 1;
}
size = itm_arr_Length[itemid];
return 0;
}
stock Error:AppendItemDataArray(Item:itemid, const data[], length) {
if(!IsValidItem(itemid)) {
return Error(1, "invalid item id");
}
if(itm_arr_Length[itemid] + length > itm_arr_ItemTypeArrayMax[GetItemType(itemid)]) {
return Error(2, "append out of bounds of item type max size");
}
for(new i; i < length; i++) {
itm_arr_Data[itemid][itm_arr_Length[itemid]++] = data[i];
}
return Ok();
}
stock Error:AppendItemArrayCell(Item:itemid, data) {
if(!IsValidItem(itemid)) {
return Error(1, "invalid item id");
}
if(itm_arr_Length[itemid] + 1 > itm_arr_ItemTypeArrayMax[GetItemType(itemid)]) {
return Error(2, "append out of bounds of item type max size");
}
itm_arr_Data[itemid][itm_arr_Length[itemid]++] = data;
return Ok();
}
stock Error:SetItemArrayDataLength(Item:itemid, length, bool:force = false) {
if(!IsValidItem(itemid)) {
return Error(1, "invalid item id");
}
new ItemType:itemtype = GetItemType(itemid);
if(itm_arr_ItemTypeArrayProtect[itemtype] && !force) {
return Error(2, "itemtype uses data protection, must force");
}
itm_arr_Length[itemid] = length;
return Ok();
}
stock RemoveItemArrayData(Item:itemid) {
if(!IsValidItem(itemid)) {
return 1;
}
itm_arr_Length[itemid] = 0;
return 0;
}
stock SetItemNoResetArrayData(Item:itemid, bool:toggle) {
if(!IsValidItem(itemid)) {
return 1;
}
itm_arr_NoResetOnCreate[itemid] = toggle;
return 0;
}