SHOW:
|
|
- or go back to the newest paste.
1 | Scriptname _avarisc_metachest_script extends ObjectReference | |
2 | ||
3 | int array | |
4 | int barray | |
5 | bool mutex = false | |
6 | ||
7 | Event OnInit() | |
8 | BlockActivation() | |
9 | endEvent | |
10 | ||
11 | Event OnLoad() | |
12 | BlockActivation() | |
13 | endEvent | |
14 | ||
15 | Event OnClose(ObjectReference akActionRef) | |
16 | saveMetachest() | |
17 | EndEvent | |
18 | ||
19 | Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) | |
20 | if(akBaseItem.GetFormID() < 0) ; dynamic item id | |
21 | Debug.Notification("This item cannot exist in other realities.") | |
22 | refuseItem(akBaseItem, akItemReference, aiItemCount, akSourceContainer) | |
23 | endif | |
24 | endEvent | |
25 | ||
26 | function refuseItem(Form refusedItemBase, ObjectReference refusedItemReference, int refusedItemCount, ObjectReference refusedSource) | |
27 | Self.RemoveItem(refusedItemBase, refusedItemCount, false, refusedSource) | |
28 | endfunction | |
29 | ||
30 | Event OnActivate(ObjectReference akActionRef) | |
31 | if(!mutex) ; a simplistic concurrency lock to prevent crosswriting errors | |
32 | loadMetachest() | |
33 | Activate(akActionRef, true) | |
34 | endif | |
35 | EndEvent | |
36 | ||
37 | function loadMetachest() | |
38 | mutex = true | |
39 | ; clear save-local (unwanted) data | |
40 | Self.RemoveAllItems() | |
41 | if(array != 0) | |
42 | array = JValue.release(array) | |
43 | endif | |
44 | ; load data | |
45 | array = JValue.readFromFile(JContainers.userDirectory() + "avarisc_metachest.json") | |
46 | if(array == 0) | |
47 | array = JArray.object() | |
48 | endif | |
49 | ; restore the chest | |
50 | int itemCounter = JArray.count(array) | |
51 | while itemCounter > 0 | |
52 | itemCounter -= 1 | |
53 | DeserializeItemIntoInventory(JArray.getObj(array, itemCounter)) | |
54 | endwhile | |
55 | JValue.release(array) | |
56 | mutex = false | |
57 | endfunction | |
58 | ||
59 | function saveMetachest() | |
60 | mutex = true | |
61 | if(array != 0) | |
62 | array = JValue.release(array) | |
63 | endif | |
64 | array = JArray.object(); | |
65 | if(barray != 0) | |
66 | barray = JValue.release(barray) | |
67 | endif | |
68 | barray = JMap.object(); | |
69 | Int iFormIndex = Self.GetNumItems() | |
70 | While iFormIndex > 0 | |
71 | iFormIndex -= 1 | |
72 | Form kForm = Self.GetNthForm(iFormIndex) | |
73 | int itemcount = Self.GetItemCount(kForm) | |
74 | int itemcount2 = itemcount | |
75 | while(itemcount2 > 0) | |
76 | ObjectReference amor = Self.DropObject(kForm, 1) | |
77 | if(ItemHasMetadata(amor) != 0) | |
78 | JArray.addObj(array, SerializeItemWithMetadata(amor)) | |
79 | else | |
80 | JMap.SetInt(barray, amor.GetBaseObject().GetFormID() as string, JMap.GetInt(barray, amor.GetBaseObject().GetFormID(), 0) + 1) | |
81 | endif | |
82 | amor.Delete() | |
83 | itemcount2 -= 1 | |
84 | endwhile | |
85 | EndWhile | |
86 | ;add teh simple items | |
87 | string simpleid = JMap.nextKey(barray) | |
88 | while simpleid | |
89 | JArray.addObj(array, SerializeItem(simpleid as int, JMap.GetInt(barray, simpleid))) | |
90 | simpleid = JMap.nextKey(barray, simpleid) | |
91 | endwhile | |
92 | JValue.writeToFile(array, JContainers.userDirectory() + "avarisc_metachest.json") | |
93 | mutex = false | |
94 | endfunction | |
95 | ||
96 | ;should take a JMap int and return an objectreference | |
97 | function DeserializeItemIntoInventory(int avmsmap) | |
98 | if(JMap.GetInt(avmsmap, "hasMetadata") > 0) | |
99 | ObjectReference tobj = Self.PlaceAtMe(Game.GetForm(JMap.GetInt(avmsmap, "baseItemId", 0))) | |
100 | int numEnchantEffects = JMap.GetInt(avmsmap, "numEnchantEffects", 0) | |
101 | if(numEnchantEffects > 0) | |
102 | MagicEffect[] avmsMagicEffects | |
103 | float[] avmsMags | |
104 | int[] avmsAreas | |
105 | int[] avmsDurations | |
106 | ||
107 | ; SO ridiculous that this is necessary. but arrays require a literal. | |
108 | ; If you have more than 20 enchants on one item, God help you- I won't. | |
109 | if(numEnchantEffects == 1) | |
110 | avmsMagicEffects = new MagicEffect[1] | |
111 | avmsMags = new float[1] | |
112 | avmsAreas = new int[1] | |
113 | avmsDurations = new int[1] | |
114 | elseif(numEnchantEffects == 2) | |
115 | avmsMagicEffects = new MagicEffect[2] | |
116 | avmsMags = new float[2] | |
117 | avmsAreas = new int[2] | |
118 | avmsDurations = new int[2] | |
119 | elseif(numEnchantEffects == 3) | |
120 | avmsMagicEffects = new MagicEffect[3] | |
121 | avmsMags = new float[3] | |
122 | avmsAreas = new int[3] | |
123 | avmsDurations = new int[3] | |
124 | elseif(numEnchantEffects == 4) | |
125 | avmsMagicEffects = new MagicEffect[4] | |
126 | avmsMags = new float[4] | |
127 | avmsAreas = new int[4] | |
128 | avmsDurations = new int[4] | |
129 | elseif(numEnchantEffects == 5) | |
130 | avmsMagicEffects = new MagicEffect[5] | |
131 | avmsMags = new float[5] | |
132 | avmsAreas = new int[5] | |
133 | avmsDurations = new int[5] | |
134 | elseif(numEnchantEffects == 6) | |
135 | avmsMagicEffects = new MagicEffect[6] | |
136 | avmsMags = new float[6] | |
137 | avmsAreas = new int[6] | |
138 | avmsDurations = new int[6] | |
139 | elseif(numEnchantEffects == 7) | |
140 | avmsMagicEffects = new MagicEffect[7] | |
141 | avmsMags = new float[7] | |
142 | avmsAreas = new int[7] | |
143 | avmsDurations = new int[7] | |
144 | elseif(numEnchantEffects == 8) | |
145 | avmsMagicEffects = new MagicEffect[8] | |
146 | avmsMags = new float[8] | |
147 | avmsAreas = new int[8] | |
148 | avmsDurations = new int[8] | |
149 | elseif(numEnchantEffects == 9) | |
150 | avmsMagicEffects = new MagicEffect[9] | |
151 | avmsMags = new float[9] | |
152 | avmsAreas = new int[9] | |
153 | avmsDurations = new int[9] | |
154 | elseif(numEnchantEffects == 10) | |
155 | avmsMagicEffects = new MagicEffect[10] | |
156 | avmsMags = new float[10] | |
157 | avmsAreas = new int[10] | |
158 | avmsDurations = new int[10] | |
159 | elseif(numEnchantEffects == 11) | |
160 | avmsMagicEffects = new MagicEffect[11] | |
161 | avmsMags = new float[11] | |
162 | avmsAreas = new int[11] | |
163 | avmsDurations = new int[11] | |
164 | elseif(numEnchantEffects == 12) | |
165 | avmsMagicEffects = new MagicEffect[12] | |
166 | avmsMags = new float[12] | |
167 | avmsAreas = new int[12] | |
168 | avmsDurations = new int[12] | |
169 | elseif(numEnchantEffects == 13) | |
170 | avmsMagicEffects = new MagicEffect[13] | |
171 | avmsMags = new float[13] | |
172 | avmsAreas = new int[13] | |
173 | avmsDurations = new int[13] | |
174 | elseif(numEnchantEffects == 14) | |
175 | avmsMagicEffects = new MagicEffect[14] | |
176 | avmsMags = new float[14] | |
177 | avmsAreas = new int[14] | |
178 | avmsDurations = new int[14] | |
179 | elseif(numEnchantEffects == 15) | |
180 | avmsMagicEffects = new MagicEffect[15] | |
181 | avmsMags = new float[15] | |
182 | avmsAreas = new int[15] | |
183 | avmsDurations = new int[15] | |
184 | elseif(numEnchantEffects == 16) | |
185 | avmsMagicEffects = new MagicEffect[16] | |
186 | avmsMags = new float[16] | |
187 | avmsAreas = new int[16] | |
188 | avmsDurations = new int[16] | |
189 | elseif(numEnchantEffects == 17) | |
190 | avmsMagicEffects = new MagicEffect[17] | |
191 | avmsMags = new float[17] | |
192 | avmsAreas = new int[17] | |
193 | avmsDurations = new int[17] | |
194 | elseif(numEnchantEffects == 18) | |
195 | avmsMagicEffects = new MagicEffect[18] | |
196 | avmsMags = new float[18] | |
197 | avmsAreas = new int[18] | |
198 | avmsDurations = new int[18] | |
199 | elseif(numEnchantEffects == 19) | |
200 | avmsMagicEffects = new MagicEffect[19] | |
201 | avmsMags = new float[19] | |
202 | avmsAreas = new int[19] | |
203 | avmsDurations = new int[19] | |
204 | else | |
205 | avmsMagicEffects = new MagicEffect[20] | |
206 | avmsMags = new float[20] | |
207 | avmsAreas = new int[20] | |
208 | avmsDurations = new int[20] | |
209 | endif | |
210 | float avmsMaxCharge = JMap.GetInt(avmsmap, "enchantMaxCharge", 0) | |
211 | int avmsMagicEffectsJObj = JMap.GetObj(avmsmap, "enchantMagicEffectIds") | |
212 | int avmsMagsJObj = JMap.GetObj(avmsmap, "enchantMagnitudes") | |
213 | int avmsAreasJObj = JMap.GetObj(avmsmap, "enchantAreas") | |
214 | int avmsDurationsJObj = JMap.GetObj(avmsmap, "enchantDurations") | |
215 | int enEfC = 0 | |
216 | while(enEfC < numEnchantEffects) | |
217 | avmsMagicEffects[enEfC] = Game.GetForm(JArray.GetInt(avmsMagicEffectsJObj, enEfC)) as MagicEffect | |
218 | avmsMags[enEfC] = JArray.GetFlt(avmsMagsJObj, enEfC) | |
219 | avmsAreas[enEfC] = JArray.GetInt(avmsAreasJObj, enEfC) | |
220 | avmsDurations[enEfC] = JArray.GetInt(avmsDurationsJObj, enEfC) | |
221 | enEfC += 1 | |
222 | endwhile | |
223 | tobj.CreateEnchantment(avmsMaxCharge, avmsMagicEffects, avmsMags, avmsAreas, avmsDurations) | |
224 | endif | |
225 | tobj.SetItemHealthPercent(JMap.GetFlt(avmsmap, "smithStatus")); | |
226 | tobj.SetDisplayName(JMap.GetStr(avmsmap, "itemName")) | |
227 | Self.AddItem(tobj as Form) | |
228 | else | |
229 | Self.AddItem(Game.GetForm(JMap.GetInt(avmsmap, "baseItemId", 0)), JMap.GetInt(avmsmap, "quantity", 1)) | |
230 | endif | |
231 | endfunction | |
232 | ||
233 | ;returns 1 if it has metadata, 0 otherwise | |
234 | int function ItemHasMetadata(ObjectReference aor) | |
235 | if(aor.GetItemHealthPercent() > 1.0) ; metadata: smithed | |
236 | return 1 | |
237 | elseif(aor.GetEnchantment() != None) ; metadata: enchanted | |
238 | return 1 | |
239 | elseif(aor.GetPoison() != None) ; metadata: potion effects | |
240 | return 1 | |
241 | else | |
242 | return 0 | |
243 | endif | |
244 | endfunction | |
245 | ||
246 | ;takes simple item id/quantity pairs and serializes them | |
247 | int function SerializeItem(int id, int count) | |
248 | int retval = JMap.Object() | |
249 | JMap.SetInt(retval, "baseItemId", id) | |
250 | JMap.SetInt(retval, "hasMetadata", 0) | |
251 | JMap.SetInt(retval, "quantity", count) | |
252 | return retval | |
253 | endfunction | |
254 | ||
255 | ; parameter - a name containing a smithy string such as (Legendary) or (Fine) | |
256 | ; return - the parameter, trimmed to the last instance of "(" | |
257 | string function StripSmithingTagFromItemName(string displayName) | |
258 | return StringUtil.Substring(displayName, 0, FindLastOccurence(displayName, "(")) | |
259 | endfunction | |
260 | ||
261 | ; paramater - haystack - the string to search | |
262 | ; parameter - needle - the character to find | |
263 | ; return - int position of the last occurence of needle in haystack | |
264 | int function FindLastOccurence(string haystack, string needle) | |
265 | int search = StringUtil.GetLength(haystack) ; find in reverse from end | |
266 | while search > 0 | |
267 | search -= 1 | |
268 | if(StringUtil.GetNthChar(haystack, search) == needle) | |
269 | return search | |
270 | endif | |
271 | endwhile | |
272 | return -1; not found | |
273 | endfunction | |
274 | ||
275 | ;should take an objectreference and return a JMap int | |
276 | int function SerializeItemWithMetadata(ObjectReference avmsitem) | |
277 | int retval = JMap.object() | |
278 | JMap.SetInt(retval, "baseItemId", avmsitem.GetBaseObject().GetFormID()) | |
279 | JMap.SetFlt(retval, "smithStatus", avmsitem.GetItemHealthPercent()) | |
280 | if(avmsitem.GetItemHealthPercent() > 1.0); if the item is smithed, the display name contains a smithy string | |
281 | JMap.SetStr(retval, "itemName", StripSmithingTagFromItemName(avmsitem.GetDisplayName())) | |
282 | else | |
283 | JMap.SetStr(retval, "itemName", avmsitem.GetDisplayName()) ; this _should_ work for everything else? | |
284 | endif | |
285 | JMap.SetInt(retval, "hasMetadata", 1) | |
286 | JMap.SetInt(retval, "quantity", 1) | |
287 | ; serialize enchantment if present | |
288 | if(avmsitem.GetEnchantment() != None) | |
289 | Enchantment eForm = avmsitem.GetEnchantment() | |
290 | int numEffects = eForm.GetNumEffects() | |
291 | JMap.SetInt(retval, "numEnchantEffects", numEffects) | |
292 | int avmsEnIds = JArray.object() | |
293 | int avmsEnMags = JArray.object() | |
294 | int avmsEnAreas = JArray.object() | |
295 | int avmsEnDurations = JArray.object() | |
296 | int currentEffect = 0 | |
297 | while currentEffect < numEffects | |
298 | JArray.AddInt(avmsEnIds, eForm.GetNthEffectMagicEffect(currentEffect).GetFormID()) | |
299 | JArray.AddFlt(avmsEnMags, eForm.GetNthEffectMagnitude(currentEffect)) | |
300 | JArray.AddInt(avmsEnAreas, eForm.GetNthEffectArea(currentEffect)) | |
301 | JArray.AddInt(avmsEnDurations, eForm.GetNthEffectDuration(currentEffect)) | |
302 | currentEffect += 1 | |
303 | endwhile | |
304 | JMap.SetFlt(retval, "enchantMaxCharge", avmsitem.GetItemMaxCharge()) | |
305 | JMap.SetObj(retval, "enchantMagicEffectIds", avmsEnIds) | |
306 | JMap.SetObj(retval, "enchantMagnitudes", avmsEnMags) | |
307 | JMap.SetObj(retval, "enchantAreas", avmsEnAreas) | |
308 | JMap.SetObj(retval, "enchantDurations", avmsEnDurations) | |
309 | else | |
310 | JMap.SetInt(retval, "numEnchantEffects", 0) | |
311 | endif | |
312 | return retval | |
313 | endfunction |