@@ -180,6 +180,97 @@ public void SortBattalions()
180180 Buffer . BlockCopy ( entries [ i ] , 0 , bytes , baseLoc . Offset + 8 * i , 8 ) ;
181181 }
182182
183+ public void SetInventoryDurability ( string mode )
184+ {
185+ if ( mode != "normal" && mode != "unlimited" && mode != "weapons-unlimited" )
186+ throw new ArgumentException ( "Durability mode must be normal, unlimited, or weapons-unlimited." ) ;
187+ for ( int i = 0 ; i < SaveData_V23 . ITEM_COUNT ; i ++ )
188+ {
189+ short id = checked ( ( short ) ( long ) Get ( $ "Items[{ i } ].Id") ) ;
190+ if ( id == - 1 ) continue ;
191+ int durability = mode == "unlimited" || ( mode == "weapons-unlimited" && id >= 10 && id < 510 )
192+ ? 100 : Database . GetItemDurability ( id ) ;
193+ Set ( $ "Items[{ i } ].Durability", durability ) ;
194+ }
195+ }
196+
197+ public void SetCharacterItemDurability ( int slot )
198+ {
199+ int count = checked ( ( int ) ( long ) Get ( $ "Characters[{ slot } ].data.ItemCount") ) ;
200+ if ( count > Database . MAX_CHARA_ITEMS )
201+ throw new InvalidDataException ( "Character item count is invalid." ) ;
202+ for ( int i = 0 ; i < count ; i ++ )
203+ if ( ( long ) Get ( $ "Characters[{ slot } ].data.Items[{ i } ].Id") != - 1 )
204+ Set ( $ "Characters[{ slot } ].data.Items[{ i } ].Durability", 100 ) ;
205+ }
206+
207+ public void MaxSkillExperience ( int slot )
208+ {
209+ for ( int i = 0 ; i < Database . MAX_SKILLS ; i ++ )
210+ {
211+ int rank = checked ( ( int ) ( long ) Get ( $ "Characters[{ slot } ].data.SkillLevel[{ i } ]") ) ;
212+ if ( rank < 0 || rank >= Database . SkillLevelupRank . Length )
213+ throw new InvalidDataException ( "Character skill rank is outside the game's table." ) ;
214+ Set ( $ "Characters[{ slot } ].data.SkillExp[{ i } ]", Database . SkillLevelupRank [ rank ] - 1 ) ;
215+ }
216+ }
217+
218+ public void MaxClassExperience ( int slot )
219+ {
220+ for ( int i = 0 ; i < Database . MAX_CLASS ; i ++ )
221+ Set ( $ "Characters[{ slot } ].data.ClassExp[{ i } ]", Database . GetMaxClassExp ( i ) ) ;
222+ }
223+
224+ public void UnlockAll ( int slot , string kind )
225+ {
226+ string path ;
227+ int count ;
228+ if ( kind == "abilities" )
229+ {
230+ path = $ "Characters[{ slot } ].data.Abilities";
231+ count = Database . MAX_ABILITIES * 8 ;
232+ }
233+ else if ( kind == "combat-arts" )
234+ {
235+ path = $ "Characters[{ slot } ].data.CombatArts";
236+ count = Database . COMBAT_ARTS_COUNT ;
237+ }
238+ else
239+ throw new ArgumentException ( "Unlock kind must be abilities or combat-arts." ) ;
240+ for ( int i = 0 ; i < count ; i ++ ) SetBit ( path , i , true ) ;
241+ }
242+
243+ public void FillItems ( string kind , byte amount )
244+ {
245+ if ( kind == "misc" )
246+ for ( int i = 0 ; i < Player_V23 . COUNT_MISC_ITEMS ; i ++ ) Set ( $ "Player.MiscItems[{ i } ]", amount ) ;
247+ else if ( kind == "gifts" )
248+ for ( int i = 0 ; i < Player_V23 . COUNT_GIFT_ITEMS ; i ++ ) Set ( $ "gifts[{ i } ]", amount ) ;
249+ else
250+ throw new ArgumentException ( "Fill kind must be misc or gifts." ) ;
251+ }
252+
253+ public void AddEssentialItems ( )
254+ {
255+ foreach ( short id in Database . EssentialItems . Distinct ( ) )
256+ {
257+ int slot = - 1 ;
258+ int free = - 1 ;
259+ for ( int i = 0 ; i < SaveData_V23 . ITEM_COUNT ; i ++ )
260+ {
261+ int itemId = checked ( ( int ) ( long ) Get ( $ "Items[{ i } ].Id") ) ;
262+ if ( itemId == id ) { slot = i ; break ; }
263+ if ( itemId == - 1 && free == - 1 ) free = i ;
264+ }
265+ if ( slot == - 1 ) slot = free ;
266+ if ( slot == - 1 ) throw new InvalidOperationException ( "Inventory has no free slot for essential items." ) ;
267+ Set ( $ "Items[{ slot } ].Id", id ) ;
268+ Set ( $ "Items[{ slot } ].Durability", Database . GetItemDurability ( id ) ) ;
269+ Set ( $ "Items[{ slot } ].Amount", 99 ) ;
270+ }
271+ SortItems ( ) ;
272+ }
273+
183274 public IReadOnlyList < object > Differences ( )
184275 {
185276 var result = new List < object > ( ) ;
@@ -295,8 +386,8 @@ private static void Validate(string path, long value)
295386 throw new ArgumentOutOfRangeException ( nameof ( value ) , "Professor experience exceeds the GUI limit." ) ;
296387 if ( Regex . IsMatch ( path , @"\.classlevel\[\d+\]$|\.currentclasslevel$" , RegexOptions . IgnoreCase ) && ( value < 0 || value > Database . MAX_CLASS_LEVEL ) )
297388 throw new ArgumentOutOfRangeException ( nameof ( value ) , "Class mastery must be 0 or 1." ) ;
298- if ( Regex . IsMatch ( path , @"^activities\.queststatelist\[\d+\]$" , RegexOptions . IgnoreCase ) && ( value < 0 || value > 3 ) )
299- throw new ArgumentOutOfRangeException ( nameof ( value ) , "Quest state must be 0 through 3 ." ) ;
389+ if ( Regex . IsMatch ( path , @"^activities\.queststatelist\[\d+\]$" , RegexOptions . IgnoreCase ) && ( value < 0 || value > 6 ) )
390+ throw new ArgumentOutOfRangeException ( nameof ( value ) , "Quest state must be 0 through 6 ." ) ;
300391 }
301392
302393 private sealed class Location
0 commit comments