View difference between Paste ID: SRz3c8Ed and 77wZ6Ak1
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