Ver 1.10. Supports both JPN and USA/EUR version.
This commit is contained in:
parent
50f336721c
commit
3588806971
@ -6,29 +6,38 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using MHSEC_G.Annotations;
|
using MHSEC_G.Annotations;
|
||||||
|
using Microsoft.Win32;
|
||||||
|
|
||||||
namespace MHSEC_G
|
namespace MHSEC_G
|
||||||
{
|
{
|
||||||
public class Armor : INotifyPropertyChanged
|
public class Armor : InMemoryObject
|
||||||
{
|
{
|
||||||
private const uint OFFSETA_ARM = 0x55F0;
|
public uint index => (_obj_offset - Offsets.OFFSETA_ARM) / Offsets.SIZE_ARM + 1;
|
||||||
private const uint OFFSETA_ARM_END = 0x720E;
|
|
||||||
// 200 armors
|
|
||||||
private const uint SIZE_ARM = 0x24;
|
|
||||||
private const uint OFFSETR_ARM_ID = 0x2;
|
|
||||||
private const uint OFFSETR_ARM_LEVEL = 0x4;
|
|
||||||
private const uint OFFSETR_ARM_14h = 0x14;
|
|
||||||
private const uint OFFSETR_ARM_18h = 0x18;
|
|
||||||
private const uint OFFSETR_ARM_1C = 0x1c;
|
|
||||||
|
|
||||||
private readonly uint _offset;
|
public Armor(byte[] save, uint objOffset) : base(save, objOffset, Offsets.SIZE_ARM)
|
||||||
private readonly Model _model;
|
|
||||||
public uint index => (_offset - OFFSETA_ARM) / SIZE_ARM + 1;
|
|
||||||
|
|
||||||
public Armor(Model model, uint offset)
|
|
||||||
{
|
{
|
||||||
_offset = offset;
|
|
||||||
_model = model;
|
}
|
||||||
|
|
||||||
|
public string type
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
uint parsed;
|
||||||
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
||||||
|
{
|
||||||
|
Helper.write_uint16_le(_data, _obj_offset + Offsets.OFFSETR_ARM_TYPE, parsed);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Malformed int - must be at most 0xFFFF", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
}
|
||||||
|
OnPropertyChanged(nameof(type));
|
||||||
|
}
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Helper.byte_to_uint16_le(_data, _obj_offset + Offsets.OFFSETR_ARM_TYPE).ToString("X4");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string id
|
public string id
|
||||||
@ -36,9 +45,9 @@ namespace MHSEC_G
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
||||||
{
|
{
|
||||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_ARM_ID, parsed);
|
Helper.write_uint16_le(_data, _obj_offset + Offsets.OFFSETR_ARM_ID, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -48,7 +57,7 @@ namespace MHSEC_G
|
|||||||
}
|
}
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_ARM_ID).ToString("X4");
|
return Helper.byte_to_uint16_le(_data, _obj_offset + Offsets.OFFSETR_ARM_ID).ToString("X4");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,9 +66,9 @@ namespace MHSEC_G
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
||||||
{
|
{
|
||||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_ARM_LEVEL, parsed);
|
Helper.write_uint16_le(_data, _obj_offset + Offsets.OFFSETR_ARM_LEVEL, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -69,7 +78,7 @@ namespace MHSEC_G
|
|||||||
}
|
}
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_ARM_LEVEL).ToString("X4");
|
return Helper.byte_to_uint16_le(_data, _obj_offset + Offsets.OFFSETR_ARM_LEVEL).ToString("X4");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,9 +88,9 @@ namespace MHSEC_G
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed))
|
if (Helper.parse_hex_string(value, out parsed))
|
||||||
{
|
{
|
||||||
Model.write_uint32_le(_model.save_file, _offset + OFFSETR_ARM_14h, parsed);
|
Helper.write_uint32_le(_data, _obj_offset + Offsets.OFFSETR_ARM_14h, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -91,7 +100,7 @@ namespace MHSEC_G
|
|||||||
}
|
}
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Model.byte_to_uint32_le(_model.save_file, _offset + OFFSETR_ARM_14h).ToString("X8");
|
return Helper.byte_to_uint32_le(_data, _obj_offset + Offsets.OFFSETR_ARM_14h).ToString("X8");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,9 +109,9 @@ namespace MHSEC_G
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed))
|
if (Helper.parse_hex_string(value, out parsed))
|
||||||
{
|
{
|
||||||
Model.write_uint32_le(_model.save_file, _offset + OFFSETR_ARM_18h, parsed);
|
Helper.write_uint32_le(_data, _obj_offset + Offsets.OFFSETR_ARM_18h, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -112,7 +121,7 @@ namespace MHSEC_G
|
|||||||
}
|
}
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Model.byte_to_uint32_le(_model.save_file, _offset + OFFSETR_ARM_18h).ToString("X8");
|
return Helper.byte_to_uint32_le(_data, _obj_offset + Offsets.OFFSETR_ARM_18h).ToString("X8");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,9 +130,9 @@ namespace MHSEC_G
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed))
|
if (Helper.parse_hex_string(value, out parsed))
|
||||||
{
|
{
|
||||||
Model.write_uint32_le(_model.save_file, _offset + OFFSETR_ARM_1C, parsed);
|
Helper.write_uint32_le(_data, _obj_offset + Offsets.OFFSETR_ARM_1C, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -133,28 +142,18 @@ namespace MHSEC_G
|
|||||||
}
|
}
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Model.byte_to_uint32_le(_model.save_file, _offset + OFFSETR_ARM_1C).ToString("X8");
|
return Helper.byte_to_uint32_le(_data, _obj_offset + Offsets.OFFSETR_ARM_1C).ToString("X8");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ObservableCollection<Armor> read_all_armors(Model model)
|
public static ObservableCollection<Armor> read_all_armors(byte[] save)
|
||||||
{
|
{
|
||||||
ObservableCollection<Armor> ret = new ObservableCollection<Armor>();
|
ObservableCollection<Armor> ret = new ObservableCollection<Armor>();
|
||||||
for (uint i = OFFSETA_ARM; i < OFFSETA_ARM_END; i += SIZE_ARM)
|
for (uint i = Offsets.OFFSETA_ARM; i < Offsets.OFFSETA_ARM_END; i += Offsets.SIZE_ARM)
|
||||||
{
|
{
|
||||||
ret.Add(new Armor(model, i));
|
ret.Add(new Armor(save, i));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
|
||||||
|
|
||||||
[NotifyPropertyChangedInvocator]
|
|
||||||
protected virtual void OnPropertyChanged(string propertyName)
|
|
||||||
{
|
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,34 +1,24 @@
|
|||||||
using System.ComponentModel;
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using MHSEC_G.Annotations;
|
using MHSEC_G.Annotations;
|
||||||
|
|
||||||
namespace MHSEC_G
|
namespace MHSEC_G
|
||||||
{
|
{
|
||||||
public class Character : INotifyPropertyChanged
|
public class Character : InMemoryObject
|
||||||
{
|
{
|
||||||
private const uint OFFSETA_CHAR_NAME = 0x9DA0;
|
|
||||||
private const uint LENGTH_CHAR_NAME = 6;
|
|
||||||
private const uint OFFSETA_CHAR_MONEY = 0x5B404;
|
|
||||||
private const uint OFFSETA_CHAR_EXP = 0x9E68;
|
|
||||||
private const uint OFFSETA_CHAR_LEVEL = 0x9E64;
|
|
||||||
public const uint LIMIT_LEVEL = 99;
|
|
||||||
public const uint LIMIT_MONEY = 9999999;
|
|
||||||
public const uint LIMIT_EXP = 25165822;
|
|
||||||
|
|
||||||
private readonly Model _model;
|
|
||||||
|
|
||||||
public uint level
|
public uint level
|
||||||
{
|
{
|
||||||
get { return Model.byte_to_uint(_model.save_file[OFFSETA_CHAR_LEVEL]); }
|
get { return Helper.byte_to_uint(_data[Offsets.OFFSETA_CHAR_LEVEL]); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value <= LIMIT_LEVEL)
|
if (value <= Offsets.LIMIT_LEVEL)
|
||||||
{
|
{
|
||||||
Model.write_byte(_model.save_file, OFFSETA_CHAR_LEVEL, value);
|
Helper.write_byte(_data, Offsets.OFFSETA_CHAR_LEVEL, value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MessageBox.Show("Level must be less than " + LIMIT_LEVEL, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBox.Show("Level must be less than " + Offsets.LIMIT_LEVEL, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
}
|
}
|
||||||
OnPropertyChanged(nameof(level));
|
OnPropertyChanged(nameof(level));
|
||||||
}
|
}
|
||||||
@ -36,16 +26,16 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public uint exp
|
public uint exp
|
||||||
{
|
{
|
||||||
get { return Model.byte_to_uint32_le(_model.save_file, OFFSETA_CHAR_EXP); }
|
get { return Helper.byte_to_uint32_le(_data, Offsets.OFFSETA_CHAR_EXP); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value <= LIMIT_EXP)
|
if (value <= Offsets.LIMIT_EXP)
|
||||||
{
|
{
|
||||||
Model.write_uint32_le(_model.save_file, OFFSETA_CHAR_EXP, value);
|
Helper.write_uint32_le(_data, Offsets.OFFSETA_CHAR_EXP, value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MessageBox.Show("Exp must be less than " + LIMIT_EXP, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBox.Show("Exp must be less than " + Offsets.LIMIT_EXP, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
}
|
}
|
||||||
OnPropertyChanged(nameof(exp));
|
OnPropertyChanged(nameof(exp));
|
||||||
}
|
}
|
||||||
@ -53,16 +43,16 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public uint money
|
public uint money
|
||||||
{
|
{
|
||||||
get { return Model.byte_to_uint32_le(_model.save_file, OFFSETA_CHAR_MONEY); }
|
get { return Helper.byte_to_uint32_le(_data, Offsets.OFFSETA_CHAR_MONEY); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value <= LIMIT_MONEY)
|
if (value <= Offsets.LIMIT_MONEY)
|
||||||
{
|
{
|
||||||
Model.write_uint32_le(_model.save_file, OFFSETA_CHAR_MONEY, value);
|
Helper.write_uint32_le(_data, Offsets.OFFSETA_CHAR_MONEY, value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MessageBox.Show("Money must be less than " + LIMIT_MONEY, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBox.Show("Money must be less than " + Offsets.LIMIT_MONEY, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
}
|
}
|
||||||
OnPropertyChanged(nameof(money));
|
OnPropertyChanged(nameof(money));
|
||||||
}
|
}
|
||||||
@ -70,33 +60,33 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public string name
|
public string name
|
||||||
{
|
{
|
||||||
get { return Model.read_unicode_string(_model.save_file, OFFSETA_CHAR_NAME, LENGTH_CHAR_NAME); }
|
get { return Helper.read_unicode_string(_data, Offsets.OFFSETA_CHAR_NAME, Offsets.LENGTH_CHAR_NAME); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value.Length <= LENGTH_CHAR_NAME && value.Length > 0)
|
if (value.Length <= Offsets.LENGTH_CHAR_NAME && value.Length > 0)
|
||||||
{
|
{
|
||||||
Model.write_unicode_string(_model.save_file, OFFSETA_CHAR_NAME, value, LENGTH_CHAR_NAME);
|
Helper.write_unicode_string(_data, Offsets.OFFSETA_CHAR_NAME, value, Offsets.LENGTH_CHAR_NAME);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MessageBox.Show("Name must be 1-" + LENGTH_CHAR_NAME + " characters.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
MessageBox.Show("Name must be 1-" + Offsets.LENGTH_CHAR_NAME + " characters.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
}
|
}
|
||||||
OnPropertyChanged(nameof(name));
|
OnPropertyChanged(nameof(name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Character(Model model)
|
public Character(byte[] model) : base(model, Offsets.OFFSETA_CHAR_NAME, 0)
|
||||||
{
|
{
|
||||||
_model = model;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public override byte[] toByteArray()
|
||||||
|
|
||||||
[NotifyPropertyChangedInvocator]
|
|
||||||
protected virtual void OnPropertyChanged(string propertyName)
|
|
||||||
{
|
{
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
public override void setByteArray(byte[] data)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,28 +6,17 @@ using MHSEC_G.Annotations;
|
|||||||
|
|
||||||
namespace MHSEC_G
|
namespace MHSEC_G
|
||||||
{
|
{
|
||||||
public class Egg : INotifyPropertyChanged
|
public class Egg : InMemoryObject
|
||||||
{
|
{
|
||||||
private const int OFFSETA_EGG_START = 0x53EC0;
|
|
||||||
private const int OFFSETA_EGG_END = 0x54597;
|
|
||||||
private const int OFFSETR_EGG_GENE = 0x30;
|
|
||||||
private const int SIZE_EGG_GENE = 0x2;
|
|
||||||
private const int SIZE_EGG = 0x92;
|
|
||||||
private const int OFFSETR_SPE = 0x0;
|
|
||||||
private const int OFFSETR_WGT = 0x2E;
|
|
||||||
|
|
||||||
private readonly Genes _genes;
|
private readonly Genes _genes;
|
||||||
public Genes genes => _genes;
|
public Genes genes => _genes;
|
||||||
|
|
||||||
private readonly uint _offset;
|
public uint index => (_obj_offset - Offsets.OFFSETA_EGG_START) / Offsets.SIZE_EGG + 1;
|
||||||
private readonly Model _model;
|
|
||||||
public uint index => (_offset - OFFSETA_EGG_START) / SIZE_EGG + 1;
|
|
||||||
|
|
||||||
public Egg(Model model, uint offset)
|
public Egg(byte[] model, uint objOffset) : base(model, objOffset, Offsets.SIZE_EGG)
|
||||||
{
|
{
|
||||||
_offset = offset;
|
_genes = new Genes(model, objOffset + Offsets.OFFSETR_EGG_GENE, Offsets.SIZE_EGG_GENE);
|
||||||
_model = model;
|
|
||||||
_genes = new Genes(model, offset + OFFSETR_EGG_GENE, SIZE_EGG_GENE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string spe
|
public string spe
|
||||||
@ -35,9 +24,9 @@ namespace MHSEC_G
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFF)
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0xFF)
|
||||||
{
|
{
|
||||||
Model.write_byte(_model.save_file, _offset + OFFSETR_SPE, parsed);
|
Helper.write_byte(_data, _obj_offset + Offsets.OFFSETR_SPE, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -47,7 +36,7 @@ namespace MHSEC_G
|
|||||||
}
|
}
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Model.byte_to_uint(_model.save_file[_offset + OFFSETR_SPE]).ToString("X2");
|
return Helper.byte_to_uint(_data[_obj_offset + Offsets.OFFSETR_SPE]).ToString("X2");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,9 +45,9 @@ namespace MHSEC_G
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFF)
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0xFF)
|
||||||
{
|
{
|
||||||
Model.write_byte(_model.save_file, _offset + OFFSETR_WGT, parsed);
|
Helper.write_byte(_data, _obj_offset + Offsets.OFFSETR_WGT, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -68,34 +57,18 @@ namespace MHSEC_G
|
|||||||
}
|
}
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Model.byte_to_uint(_model.save_file[_offset + OFFSETR_WGT]).ToString("X2");
|
return Helper.byte_to_uint(_data[_obj_offset + Offsets.OFFSETR_WGT]).ToString("X2");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ObservableCollection<Egg> read_all_eggs(Model model)
|
public static ObservableCollection<Egg> read_all_eggs(byte[] model)
|
||||||
{
|
{
|
||||||
ObservableCollection<Egg> ret = new ObservableCollection<Egg>();
|
ObservableCollection<Egg> ret = new ObservableCollection<Egg>();
|
||||||
for (uint i = OFFSETA_EGG_START; i < OFFSETA_EGG_END; i += SIZE_EGG)
|
for (uint i = Offsets.OFFSETA_EGG_START; i < Offsets.OFFSETA_EGG_END; i += Offsets.SIZE_EGG)
|
||||||
{
|
{
|
||||||
ret.Add(new Egg(model, i));
|
ret.Add(new Egg(model, i));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setByteArray(byte[] ret)
|
|
||||||
{
|
|
||||||
Array.Copy(ret, 0, _model.save_file, _offset, SIZE_EGG);
|
|
||||||
OnPropertyChanged(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
|
||||||
|
|
||||||
[NotifyPropertyChangedInvocator]
|
|
||||||
protected virtual void OnPropertyChanged(string propertyName)
|
|
||||||
{
|
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,43 +6,23 @@ using MHSEC_G.Annotations;
|
|||||||
|
|
||||||
namespace MHSEC_G
|
namespace MHSEC_G
|
||||||
{
|
{
|
||||||
public class EggFragment : INotifyPropertyChanged
|
public class EggFragment : InMemoryObject
|
||||||
{
|
{
|
||||||
private const uint OFFSETA_EGG_FRAGMENTS = 0x9790;
|
public uint idx => (_obj_offset - Offsets.OFFSETA_EGG_FRAGMENTS) / Offsets.SIZE_EGG_FRAGMENT + 1;
|
||||||
private const uint OFFSETA_EGG_FRAGMENTS_END = 0x9C3F;
|
|
||||||
private const uint SIZE_EGG_FRAGMENT = 0xC;
|
|
||||||
private const uint OFFSETR_EF_SPE = 0x0;
|
|
||||||
private const uint OFFSETR_EF_POS = 0x1;
|
|
||||||
private const uint OFFSETR_EF_NEW = 0x2;
|
|
||||||
private const uint OFFSETR_EF_RAR = 0x3;
|
|
||||||
private const uint OFFSETR_EF_COL = 0x4;
|
|
||||||
private const uint OFFSETR_EF_DLC = 0x5;
|
|
||||||
private const uint OFFSETR_EF_6H = 0x6;
|
|
||||||
private const uint OFFSETR_EF_7H = 0x7;
|
|
||||||
|
|
||||||
private readonly uint _offset;
|
public EggFragment(byte[] model, uint objOffset) : base(model, objOffset, Offsets.SIZE_EGG_FRAGMENT)
|
||||||
public uint idx => (_offset - OFFSETA_EGG_FRAGMENTS) / SIZE_EGG_FRAGMENT + 1;
|
|
||||||
|
|
||||||
public uint offset
|
|
||||||
{
|
{
|
||||||
get { return _offset;}
|
|
||||||
}
|
|
||||||
private readonly Model _model;
|
|
||||||
public EggFragment(uint offset, Model model)
|
|
||||||
{
|
|
||||||
_model = model;
|
|
||||||
_offset = offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string spe
|
public string spe
|
||||||
{
|
{
|
||||||
get { return Model.byte_to_uint(_model.save_file[_offset + OFFSETR_EF_SPE]).ToString("X2"); }
|
get { return Helper.byte_to_uint(_data[_obj_offset + Offsets.OFFSETR_EF_SPE]).ToString("X2"); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0x0E)
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0x0E)
|
||||||
{
|
{
|
||||||
Model.write_byte(_model.save_file, _offset + OFFSETR_EF_SPE, parsed);
|
Helper.write_byte(_data, _obj_offset + Offsets.OFFSETR_EF_SPE, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -54,13 +34,13 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public string pos
|
public string pos
|
||||||
{
|
{
|
||||||
get { return Model.byte_to_uint(_model.save_file[_offset + OFFSETR_EF_POS]).ToString("X2"); }
|
get { return Helper.byte_to_uint(_data[_obj_offset + Offsets.OFFSETR_EF_POS]).ToString("X2"); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0x08)
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0x08)
|
||||||
{
|
{
|
||||||
Model.write_byte(_model.save_file, _offset + OFFSETR_EF_POS, parsed);
|
Helper.write_byte(_data, _obj_offset + Offsets.OFFSETR_EF_POS, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -72,13 +52,13 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public string new_flag
|
public string new_flag
|
||||||
{
|
{
|
||||||
get { return Model.byte_to_uint(_model.save_file[_offset + OFFSETR_EF_NEW]).ToString("X2"); }
|
get { return Helper.byte_to_uint(_data[_obj_offset + Offsets.OFFSETR_EF_NEW]).ToString("X2"); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0x01)
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0x01)
|
||||||
{
|
{
|
||||||
Model.write_byte(_model.save_file, _offset + OFFSETR_EF_NEW, parsed);
|
Helper.write_byte(_data, _obj_offset + Offsets.OFFSETR_EF_NEW, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -89,13 +69,13 @@ namespace MHSEC_G
|
|||||||
}
|
}
|
||||||
public string rarity
|
public string rarity
|
||||||
{
|
{
|
||||||
get { return Model.byte_to_uint(_model.save_file[_offset + OFFSETR_EF_RAR]).ToString("X2"); }
|
get { return Helper.byte_to_uint(_data[_obj_offset + Offsets.OFFSETR_EF_RAR]).ToString("X2"); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0x01)
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0x01)
|
||||||
{
|
{
|
||||||
Model.write_byte(_model.save_file, _offset + OFFSETR_EF_RAR, parsed);
|
Helper.write_byte(_data, _obj_offset + Offsets.OFFSETR_EF_RAR, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -107,13 +87,13 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public string color
|
public string color
|
||||||
{
|
{
|
||||||
get { return Model.byte_to_uint(_model.save_file[_offset + OFFSETR_EF_COL]).ToString("X2"); }
|
get { return Helper.byte_to_uint(_data[_obj_offset + Offsets.OFFSETR_EF_COL]).ToString("X2"); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFF)
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0xFF)
|
||||||
{
|
{
|
||||||
Model.write_byte(_model.save_file, _offset + OFFSETR_EF_COL, parsed);
|
Helper.write_byte(_data, _obj_offset + Offsets.OFFSETR_EF_COL, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -125,13 +105,13 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public string dlc
|
public string dlc
|
||||||
{
|
{
|
||||||
get { return Model.byte_to_uint(_model.save_file[_offset + OFFSETR_EF_DLC]).ToString("X2"); }
|
get { return Helper.byte_to_uint(_data[_obj_offset + Offsets.OFFSETR_EF_DLC]).ToString("X2"); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFF)
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0xFF)
|
||||||
{
|
{
|
||||||
Model.write_byte(_model.save_file, _offset + OFFSETR_EF_DLC, parsed);
|
Helper.write_byte(_data, _obj_offset + Offsets.OFFSETR_EF_DLC, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -143,13 +123,13 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public string unknown_6h
|
public string unknown_6h
|
||||||
{
|
{
|
||||||
get { return Model.byte_to_uint(_model.save_file[_offset + OFFSETR_EF_6H]).ToString("X2"); }
|
get { return Helper.byte_to_uint(_data[_obj_offset + Offsets.OFFSETR_EF_6H]).ToString("X2"); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFF)
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0xFF)
|
||||||
{
|
{
|
||||||
Model.write_byte(_model.save_file, _offset + OFFSETR_EF_6H, parsed);
|
Helper.write_byte(_data, _obj_offset + Offsets.OFFSETR_EF_6H, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -161,13 +141,13 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public string unknown_7h
|
public string unknown_7h
|
||||||
{
|
{
|
||||||
get { return Model.byte_to_uint(_model.save_file[_offset + OFFSETR_EF_7H]).ToString("X2"); }
|
get { return Helper.byte_to_uint(_data[_obj_offset + Offsets.OFFSETR_EF_7H]).ToString("X2"); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFF)
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0xFF)
|
||||||
{
|
{
|
||||||
Model.write_byte(_model.save_file, _offset + OFFSETR_EF_7H, parsed);
|
Helper.write_byte(_data, _obj_offset + Offsets.OFFSETR_EF_7H, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -177,55 +157,14 @@ namespace MHSEC_G
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ObservableCollection<EggFragment> read_all_egg_fragments(Model model)
|
public static ObservableCollection<EggFragment> read_all_egg_fragments(byte[] model)
|
||||||
{
|
{
|
||||||
ObservableCollection<EggFragment> ret = new ObservableCollection<EggFragment>();
|
ObservableCollection<EggFragment> ret = new ObservableCollection<EggFragment>();
|
||||||
byte[] buffer = model.save_file;
|
for (uint offset = Offsets.OFFSETA_EGG_FRAGMENTS; offset < Offsets.OFFSETA_EGG_FRAGMENTS_END; offset += Offsets.SIZE_EGG_FRAGMENT)
|
||||||
for (uint offset = OFFSETA_EGG_FRAGMENTS; offset < OFFSETA_EGG_FRAGMENTS_END; offset += SIZE_EGG_FRAGMENT)
|
|
||||||
{
|
{
|
||||||
ret.Add(new EggFragment(offset, model));
|
ret.Add(new EggFragment(model, offset));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static EggFragment egg_frag_offset_exist(ObservableCollection<EggFragment> fragments, uint offset)
|
|
||||||
{
|
|
||||||
for (uint i = 0; i < fragments.Count; i++)
|
|
||||||
{
|
|
||||||
if(fragments.ElementAt((int)i).offset == offset)
|
|
||||||
return fragments.ElementAt((int)i);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void write_dlc_egg_fragment(ObservableCollection<EggFragment> fragments, Model model, uint dlc)
|
|
||||||
{
|
|
||||||
for (uint offset = OFFSETA_EGG_FRAGMENTS; offset < OFFSETA_EGG_FRAGMENTS + 9*SIZE_EGG_FRAGMENT ; offset += SIZE_EGG_FRAGMENT)
|
|
||||||
{
|
|
||||||
EggFragment each_frag = egg_frag_offset_exist(fragments, offset);
|
|
||||||
if (each_frag == null)
|
|
||||||
{
|
|
||||||
each_frag = new EggFragment(offset, model);
|
|
||||||
fragments.Insert((int)((offset - OFFSETA_EGG_FRAGMENTS) / SIZE_EGG_FRAGMENT), each_frag);
|
|
||||||
}
|
|
||||||
each_frag.new_flag = "0";
|
|
||||||
each_frag.spe = "08";
|
|
||||||
each_frag.pos = ((offset-OFFSETA_EGG_FRAGMENTS) / SIZE_EGG_FRAGMENT).ToString();
|
|
||||||
each_frag.rarity = "0";
|
|
||||||
each_frag.color = "0";
|
|
||||||
each_frag.dlc = dlc.ToString("X2");
|
|
||||||
each_frag.unknown_6h = "0";
|
|
||||||
each_frag.unknown_7h = "0";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
|
||||||
|
|
||||||
[NotifyPropertyChangedInvocator]
|
|
||||||
protected virtual void OnPropertyChanged(string propertyName)
|
|
||||||
{
|
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,40 +9,28 @@ using MHSEC_G.Annotations;
|
|||||||
|
|
||||||
namespace MHSEC_G
|
namespace MHSEC_G
|
||||||
{
|
{
|
||||||
public class Genes : INotifyPropertyChanged
|
public class Genes : InMemoryObject
|
||||||
{
|
{
|
||||||
public static readonly List<uint> GENE_ID = new List<uint>();
|
public List<string> gene_name => Offsets.GENE_NAME;
|
||||||
public static readonly List<string> GENE_NAME = new List<string>();
|
private readonly uint _gene_size;
|
||||||
public List<string> gene_name => GENE_NAME;
|
public Genes(byte[] model, uint objOffset, uint gene_size) : base(model, objOffset, 9 * gene_size)
|
||||||
|
|
||||||
private readonly uint _size;
|
|
||||||
private readonly Model _model;
|
|
||||||
private readonly uint _offset;
|
|
||||||
public Genes(Model model, uint offset, uint size)
|
|
||||||
{
|
{
|
||||||
this._size = size;
|
_gene_size = gene_size;
|
||||||
this._offset = offset;
|
|
||||||
this._model = model;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Genes
|
|
||||||
//
|
|
||||||
|
|
||||||
private uint extract_gene(uint gene_idx)
|
private uint extract_gene(uint gene_idx)
|
||||||
{
|
{
|
||||||
if (gene_idx >= 9)
|
if (gene_idx >= 9)
|
||||||
{
|
{
|
||||||
BugCheck.bug_check(BugCheck.ErrorCode.MON_GENE_IDX_OVERFLOW, "Invalid gene index: " + gene_idx);
|
BugCheck.bug_check(BugCheck.ErrorCode.MON_GENE_IDX_OVERFLOW, "Invalid gene index: " + gene_idx);
|
||||||
}
|
}
|
||||||
return Model.byte_to_uint16_le(_model.save_file,
|
return Helper.byte_to_uint16_le(_data, _obj_offset + gene_idx * _gene_size);
|
||||||
_offset + gene_idx * _size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void set_gene_str(uint gene_idx, string val)
|
private void set_gene_str(uint gene_idx, string val)
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(val, out parsed))
|
if (Helper.parse_hex_string(val, out parsed))
|
||||||
{
|
{
|
||||||
set_gene(gene_idx, parsed);
|
set_gene(gene_idx, parsed);
|
||||||
}
|
}
|
||||||
@ -61,7 +49,7 @@ namespace MHSEC_G
|
|||||||
}
|
}
|
||||||
if (val <= 0xFFFF)
|
if (val <= 0xFFFF)
|
||||||
{
|
{
|
||||||
Model.write_uint16_le(_model.save_file, _offset + gene_idx * _size,
|
Helper.write_uint16_le(_data, _obj_offset + gene_idx * _gene_size,
|
||||||
val);
|
val);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -74,20 +62,20 @@ namespace MHSEC_G
|
|||||||
private int extract_gene_idx(uint gene_idx)
|
private int extract_gene_idx(uint gene_idx)
|
||||||
{
|
{
|
||||||
uint gene_id = extract_gene(gene_idx);
|
uint gene_id = extract_gene(gene_idx);
|
||||||
int idx = GENE_ID.IndexOf(gene_id);
|
int idx = Offsets.GENE_ID.IndexOf(gene_id);
|
||||||
if (idx == -1)
|
if (idx == -1)
|
||||||
{
|
{
|
||||||
// unknown
|
// unknown
|
||||||
return GENE_NAME.Count - 1;
|
return Offsets.GENE_NAME.Count - 1;
|
||||||
}
|
}
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void set_gene_idx(uint gene_idx, int val)
|
private void set_gene_idx(uint gene_idx, int val)
|
||||||
{
|
{
|
||||||
if (val != -1 && val != GENE_NAME.Count - 1)
|
if (val != -1 && val != Offsets.GENE_NAME.Count - 1)
|
||||||
{
|
{
|
||||||
set_gene(gene_idx, GENE_ID.ElementAt(val));
|
set_gene(gene_idx, Offsets.GENE_ID.ElementAt(val));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,38 +285,5 @@ namespace MHSEC_G
|
|||||||
OnPropertyChanged(nameof(gene9_selected));
|
OnPropertyChanged(nameof(gene9_selected));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void read_gene_mapping()
|
|
||||||
{
|
|
||||||
string line;
|
|
||||||
StringReader file = new StringReader(Properties.Resources.gene);
|
|
||||||
|
|
||||||
while ((line = file.ReadLine()) != null)
|
|
||||||
{
|
|
||||||
if (line.Length == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
string[] eachline = line.Split('\t');
|
|
||||||
if (eachline.Length != 2)
|
|
||||||
{
|
|
||||||
BugCheck.bug_check(BugCheck.ErrorCode.MON_GENE_MAPPING_CORRUPTED,
|
|
||||||
"Invalid gene mapping file line:\n" + line);
|
|
||||||
}
|
|
||||||
|
|
||||||
GENE_ID.Add(uint.Parse(eachline[0], System.Globalization.NumberStyles.HexNumber));
|
|
||||||
GENE_NAME.Add(eachline[1]);
|
|
||||||
}
|
|
||||||
GENE_NAME.Add("Custom");
|
|
||||||
|
|
||||||
file.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
|
||||||
|
|
||||||
[NotifyPropertyChangedInvocator]
|
|
||||||
protected virtual void OnPropertyChanged(string propertyName)
|
|
||||||
{
|
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,26 +4,8 @@ using System.Text;
|
|||||||
|
|
||||||
namespace MHSEC_G
|
namespace MHSEC_G
|
||||||
{
|
{
|
||||||
public class Model
|
public static class Helper
|
||||||
{
|
{
|
||||||
public const uint SAVE_FILE_SIZE = 483976;
|
|
||||||
|
|
||||||
private readonly byte[] _save_file;
|
|
||||||
|
|
||||||
public byte[] save_file
|
|
||||||
{
|
|
||||||
get { return _save_file; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Model(byte[] save_file)
|
|
||||||
{
|
|
||||||
if (save_file.Length != SAVE_FILE_SIZE)
|
|
||||||
{
|
|
||||||
BugCheck.bug_check(BugCheck.ErrorCode.MODEL_INVALID_FILE_SIZE, "Invalid file size.\nExpected: " + SAVE_FILE_SIZE + " Got: " + save_file.Length);
|
|
||||||
}
|
|
||||||
_save_file = save_file;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static uint byte_to_uint(byte b)
|
public static uint byte_to_uint(byte b)
|
||||||
{
|
{
|
||||||
return (uint) (b) & 0xFF;
|
return (uint) (b) & 0xFF;
|
48
MHSEC-G/MHSEC-G/InMemoryObject.cs
Normal file
48
MHSEC-G/MHSEC-G/InMemoryObject.cs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using MHSEC_G.Annotations;
|
||||||
|
|
||||||
|
namespace MHSEC_G
|
||||||
|
{
|
||||||
|
public class InMemoryObject : INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
protected readonly uint _obj_offset;
|
||||||
|
protected readonly byte[] _data;
|
||||||
|
protected readonly uint _obj_size;
|
||||||
|
|
||||||
|
public InMemoryObject(byte[] data, uint objOffset, uint objSize)
|
||||||
|
{
|
||||||
|
_obj_offset = objOffset;
|
||||||
|
_data = data;
|
||||||
|
_obj_size = objSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual byte[] toByteArray()
|
||||||
|
{
|
||||||
|
byte[] ret = new byte[_obj_size];
|
||||||
|
Array.Copy(_data, _obj_offset, ret, 0, _obj_size);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void setByteArray(byte[] data)
|
||||||
|
{
|
||||||
|
if (data.Length != _obj_size)
|
||||||
|
{
|
||||||
|
BugCheck.bug_check(BugCheck.ErrorCode.MODEL_INVALID_FILE_SIZE, "Invalid data size in setByteArray.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Array.Copy(data, 0, _data, _obj_offset, _obj_size);
|
||||||
|
OnPropertyChanged(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
|
[NotifyPropertyChangedInvocator]
|
||||||
|
protected virtual void OnPropertyChanged(string propertyName)
|
||||||
|
{
|
||||||
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,34 +8,16 @@ using MHSEC_G.Annotations;
|
|||||||
|
|
||||||
namespace MHSEC_G
|
namespace MHSEC_G
|
||||||
{
|
{
|
||||||
public class Item : INotifyPropertyChanged
|
public class Item : InMemoryObject
|
||||||
{
|
{
|
||||||
private static readonly uint OFFSETA_ITEM_BOX = 0x10;
|
public uint offset => _obj_offset;
|
||||||
private static readonly uint SIZE_ITEM = 0x8;
|
|
||||||
private static readonly uint OFFSETR_ITEM_ID = 0x0;
|
|
||||||
private static readonly uint OFFSETR_ITEM_COUNT = 0x2;
|
|
||||||
private static readonly uint OFFSETA_ITEM_BOX_END = 0x2EE7;
|
|
||||||
public static readonly uint OFFSETA_FIRST_KEY_ITEM = 0x17B0;
|
|
||||||
|
|
||||||
private static readonly Dictionary<uint, uint> OFFSET_ID_MAPPING = new Dictionary<uint, uint>();
|
|
||||||
private static readonly Dictionary<uint, string> OFFSET_NAME_MAPPING = new Dictionary<uint, string>();
|
|
||||||
|
|
||||||
private readonly uint _offset;
|
|
||||||
|
|
||||||
public uint offset
|
|
||||||
{
|
|
||||||
get { return _offset; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly Model _model;
|
|
||||||
|
|
||||||
public string name
|
public string name
|
||||||
{
|
{
|
||||||
get {
|
get {
|
||||||
string name = _offset >= OFFSETA_FIRST_KEY_ITEM ? "Key Item [" + id.ToString("X4") + "]" : "Unknown";
|
string name = _obj_offset >= Offsets.OFFSETA_FIRST_KEY_ITEM ? "Key Item [" + id.ToString("X4") + "]" : "Unknown";
|
||||||
if (OFFSET_NAME_MAPPING.ContainsKey(_offset))
|
if (Offsets.OFFSET_NAME_MAPPING.ContainsKey(_obj_offset))
|
||||||
{
|
{
|
||||||
name = OFFSET_NAME_MAPPING[_offset];
|
name = Offsets.OFFSET_NAME_MAPPING[_obj_offset];
|
||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
@ -44,12 +26,12 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public uint count
|
public uint count
|
||||||
{
|
{
|
||||||
get { return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_ITEM_COUNT); }
|
get { return Helper.byte_to_uint16_le(_data, _obj_offset + Offsets.OFFSETR_ITEM_COUNT); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value <= 999)
|
if (value <= 999)
|
||||||
{
|
{
|
||||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_ITEM_COUNT, value);
|
Helper.write_uint16_le(_data, _obj_offset + Offsets.OFFSETR_ITEM_COUNT, value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -61,85 +43,52 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public uint id
|
public uint id
|
||||||
{
|
{
|
||||||
get { return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_ITEM_ID); }
|
get { return Helper.byte_to_uint16_le(_data, _obj_offset + Offsets.OFFSETR_ITEM_ID); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Item(uint offset, Model model)
|
public Item(byte[] model, uint objOffset) : base(model, objOffset, Offsets.SIZE_ITEM)
|
||||||
{
|
{
|
||||||
_offset = offset;
|
|
||||||
_model = model;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Item> read_all_items(Model model)
|
public static List<Item> read_all_items(byte[] model)
|
||||||
{
|
{
|
||||||
byte[] buffer = model.save_file;
|
|
||||||
List<Item> ret = new List<Item>();
|
List<Item> ret = new List<Item>();
|
||||||
for (uint offset = OFFSETA_ITEM_BOX; offset < OFFSETA_ITEM_BOX_END; offset += SIZE_ITEM)
|
for (uint offset = Offsets.OFFSETA_ITEM_BOX;
|
||||||
|
offset < Offsets.OFFSETA_ITEM_BOX_END;
|
||||||
|
offset += Offsets.SIZE_ITEM)
|
||||||
{
|
{
|
||||||
uint item_id = Model.byte_to_uint16_le(buffer, offset + OFFSETR_ITEM_ID);
|
uint item_id = Helper.byte_to_uint16_le(model, offset + Offsets.OFFSETR_ITEM_ID);
|
||||||
if (item_id == 0)
|
if (item_id == 0)
|
||||||
{
|
{
|
||||||
// if not obtained yet
|
// if not obtained yet
|
||||||
if (!OFFSET_ID_MAPPING.ContainsKey(offset))
|
if (!Offsets.OFFSET_ID_MAPPING.ContainsKey(offset))
|
||||||
{
|
{
|
||||||
// well we dont know the id to this offset either. just ignore!
|
// well we dont know the id to this offset either. just ignore!
|
||||||
// continue
|
// continue
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// if we know the id to the offset, just set it
|
// if we know the id to the offset, just set it
|
||||||
Model.write_uint16_le(model.save_file, offset + OFFSETR_ITEM_ID, OFFSET_ID_MAPPING[offset]);
|
Helper.write_uint16_le(model, offset + Offsets.OFFSETR_ITEM_ID, Offsets.OFFSET_ID_MAPPING[offset]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// already obtained
|
// already obtained
|
||||||
// validate
|
// validate
|
||||||
if (OFFSET_ID_MAPPING.ContainsKey(offset))
|
if (Offsets.OFFSET_ID_MAPPING.ContainsKey(offset))
|
||||||
{
|
{
|
||||||
if (item_id != OFFSET_ID_MAPPING[offset])
|
if (item_id != Offsets.OFFSET_ID_MAPPING[offset])
|
||||||
{
|
{
|
||||||
// correct to the correct id
|
// correct to the correct id
|
||||||
// don't bug_check since too many people's files are broken
|
// don't bug_check since too many people's files are broken
|
||||||
// TODO: BugCheck.bug_check(BugCheck.ErrorCode.ITEM_NO_CORRESPONDENCE, "Item offset " + offset.ToString("X") + " and item ID " + item_id.ToString("X") + " do not correspond.");
|
// TODO: BugCheck.bug_check(BugCheck.ErrorCode.ITEM_NO_CORRESPONDENCE, "Item offset " + offset.ToString("X") + " and item ID " + item_id.ToString("X") + " do not correspond.");
|
||||||
Model.write_uint16_le(model.save_file, offset + OFFSETR_ITEM_ID, OFFSET_ID_MAPPING[offset]);
|
Helper.write_uint16_le(model, offset + Offsets.OFFSETR_ITEM_ID, Offsets.OFFSET_ID_MAPPING[offset]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// valid offset
|
// valid offset
|
||||||
ret.Add(new Item(offset, model));
|
ret.Add(new Item(model, offset));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void read_item_mappings()
|
|
||||||
{
|
|
||||||
string line;
|
|
||||||
StringReader file = new StringReader(Properties.Resources.idmap);
|
|
||||||
|
|
||||||
while ((line = file.ReadLine()) != null)
|
|
||||||
{
|
|
||||||
if (line.Length == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
string[] eachline = line.Split('\t');
|
|
||||||
if (eachline.Length != 3)
|
|
||||||
{
|
|
||||||
|
|
||||||
BugCheck.bug_check(BugCheck.ErrorCode.ITEM_MAPPING_CORRUPTED, "Invalid mapping file line:\n" + line);
|
|
||||||
}
|
|
||||||
|
|
||||||
OFFSET_ID_MAPPING.Add(uint.Parse(eachline[0], System.Globalization.NumberStyles.HexNumber), uint.Parse(eachline[1], System.Globalization.NumberStyles.HexNumber));
|
|
||||||
OFFSET_NAME_MAPPING.Add(uint.Parse(eachline[0], System.Globalization.NumberStyles.HexNumber), eachline[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
file.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
|
||||||
|
|
||||||
[NotifyPropertyChangedInvocator]
|
|
||||||
protected virtual void OnPropertyChanged(string propertyName)
|
|
||||||
{
|
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,12 +90,14 @@
|
|||||||
<Compile Include="GeneWindow.xaml.cs">
|
<Compile Include="GeneWindow.xaml.cs">
|
||||||
<DependentUpon>GeneWindow.xaml</DependentUpon>
|
<DependentUpon>GeneWindow.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="InMemoryObject.cs" />
|
||||||
<Compile Include="Item.cs" />
|
<Compile Include="Item.cs" />
|
||||||
<Compile Include="Model.cs" />
|
<Compile Include="Helper.cs" />
|
||||||
<Compile Include="Monster.cs" />
|
<Compile Include="Monster.cs" />
|
||||||
<Compile Include="MonsterWindow.xaml.cs">
|
<Compile Include="MonsterWindow.xaml.cs">
|
||||||
<DependentUpon>MonsterWindow.xaml</DependentUpon>
|
<DependentUpon>MonsterWindow.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Offsets.cs" />
|
||||||
<Compile Include="Properties\Annotations.cs" />
|
<Compile Include="Properties\Annotations.cs" />
|
||||||
<Compile Include="Properties\Resources.Designer.cs">
|
<Compile Include="Properties\Resources.Designer.cs">
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
|
@ -81,7 +81,7 @@
|
|||||||
Header="Index" IsReadOnly="True"/>
|
Header="Index" IsReadOnly="True"/>
|
||||||
<DataGridTextColumn CanUserReorder="False" CanUserResize="False" CanUserSort="False"
|
<DataGridTextColumn CanUserReorder="False" CanUserResize="False" CanUserSort="False"
|
||||||
Width="50" Binding="{Binding spe}"
|
Width="50" Binding="{Binding spe}"
|
||||||
Header="Species" />
|
Header="Genus" />
|
||||||
<DataGridTextColumn CanUserReorder="False" CanUserResize="False" CanUserSort="False"
|
<DataGridTextColumn CanUserReorder="False" CanUserResize="False" CanUserSort="False"
|
||||||
Width="60" Binding="{Binding pos}"
|
Width="60" Binding="{Binding pos}"
|
||||||
Header="Position" />
|
Header="Position" />
|
||||||
@ -109,8 +109,8 @@
|
|||||||
</TabItem>
|
</TabItem>
|
||||||
<TabItem Header="Eggs">
|
<TabItem Header="Eggs">
|
||||||
<Grid Background="#FFE5E5E5">
|
<Grid Background="#FFE5E5E5">
|
||||||
<DataGrid x:Name="egg_grid" HorizontalAlignment="Left" Margin="10,30,0,0"
|
<DataGrid x:Name="egg_grid" HorizontalAlignment="Left" Margin="10,54,0,0"
|
||||||
VerticalAlignment="Top" Height="287" Width="417" CanUserAddRows="False"
|
VerticalAlignment="Top" Height="263" Width="417" CanUserAddRows="False"
|
||||||
AutoGenerateColumns="False" ItemsSource="{Binding eggs}" SelectionMode="Single">
|
AutoGenerateColumns="False" ItemsSource="{Binding eggs}" SelectionMode="Single">
|
||||||
<DataGrid.RowStyle>
|
<DataGrid.RowStyle>
|
||||||
<Style TargetType="{x:Type DataGridRow}">
|
<Style TargetType="{x:Type DataGridRow}">
|
||||||
@ -123,15 +123,15 @@
|
|||||||
Header="Index" IsReadOnly="True"/>
|
Header="Index" IsReadOnly="True"/>
|
||||||
<DataGridTextColumn CanUserReorder="False" CanUserResize="False" CanUserSort="False"
|
<DataGridTextColumn CanUserReorder="False" CanUserResize="False" CanUserSort="False"
|
||||||
Width="*" Binding="{Binding spe}"
|
Width="*" Binding="{Binding spe}"
|
||||||
Header="Hatched Monster Type" />
|
Header="Hatched Monster Species" />
|
||||||
<DataGridTextColumn CanUserReorder="False" CanUserResize="False" CanUserSort="False"
|
<DataGridTextColumn CanUserReorder="False" CanUserResize="False" CanUserSort="False"
|
||||||
Width="*" Binding="{Binding wgt}"
|
Width="*" Binding="{Binding wgt}"
|
||||||
Header="Weight" />
|
Header="Weight" />
|
||||||
</DataGrid.Columns>
|
</DataGrid.Columns>
|
||||||
</DataGrid>
|
</DataGrid>
|
||||||
<Label x:Name="label_monster_Copy" Content="Double-click an entry to edit genes." HorizontalAlignment="Left" Margin="10,4,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.184,0.019"/>
|
<Label x:Name="label_monster_Copy" Content="Double-click an entry to edit genes. Click twice to edit the table entry." HorizontalAlignment="Left" Margin="10,0,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.184,0.019"/>
|
||||||
<Button x:Name="button_eggs_delete" Content="Delete" HorizontalAlignment="Left" Margin="353,5,0,0" VerticalAlignment="Top" Width="74" RenderTransformOrigin="1.601,-0.2" Click="button_eggs_delete_Click"/>
|
<Button x:Name="button_eggs_delete" Content="Delete" HorizontalAlignment="Left" Margin="319,29,0,0" VerticalAlignment="Top" Width="108" RenderTransformOrigin="1.601,-0.2" Click="button_eggs_delete_Click"/>
|
||||||
<Button x:Name="button_eggs_dummy" Content="Set Dummy Egg" HorizontalAlignment="Left" Margin="240,5,0,0" VerticalAlignment="Top" Width="108" RenderTransformOrigin="1.601,-0.2" Click="button_eggs_dummy_Click"/>
|
<Button x:Name="button_eggs_dummy" Content="Set Dummy Egg" HorizontalAlignment="Left" Margin="206,29,0,0" VerticalAlignment="Top" Width="108" RenderTransformOrigin="1.601,-0.2" Click="button_eggs_dummy_Click"/>
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
@ -226,10 +226,13 @@
|
|||||||
Width="40" Binding="{Binding index}"
|
Width="40" Binding="{Binding index}"
|
||||||
Header="Index" IsReadOnly="True"/>
|
Header="Index" IsReadOnly="True"/>
|
||||||
<DataGridTextColumn CanUserReorder="False" CanUserResize="False" CanUserSort="False"
|
<DataGridTextColumn CanUserReorder="False" CanUserResize="False" CanUserSort="False"
|
||||||
Width="50" Binding="{Binding id}"
|
Width="40" Binding="{Binding type}"
|
||||||
|
Header="Type" />
|
||||||
|
<DataGridTextColumn CanUserReorder="False" CanUserResize="False" CanUserSort="False"
|
||||||
|
Width="40" Binding="{Binding id}"
|
||||||
Header="ID" />
|
Header="ID" />
|
||||||
<DataGridTextColumn CanUserReorder="False" CanUserResize="False" CanUserSort="False"
|
<DataGridTextColumn CanUserReorder="False" CanUserResize="False" CanUserSort="False"
|
||||||
Width="50" Binding="{Binding level}"
|
Width="40" Binding="{Binding level}"
|
||||||
Header="Level" />
|
Header="Level" />
|
||||||
<DataGridTextColumn CanUserReorder="False" CanUserResize="False" CanUserSort="False"
|
<DataGridTextColumn CanUserReorder="False" CanUserResize="False" CanUserSort="False"
|
||||||
Width="*" Binding="{Binding unknown_14h}"
|
Width="*" Binding="{Binding unknown_14h}"
|
||||||
@ -239,7 +242,7 @@
|
|||||||
Header="Color2 (RGB)" />
|
Header="Color2 (RGB)" />
|
||||||
<DataGridTextColumn CanUserReorder="False" CanUserResize="False" CanUserSort="False"
|
<DataGridTextColumn CanUserReorder="False" CanUserResize="False" CanUserSort="False"
|
||||||
Width="*" Binding="{Binding unknown_1ch}"
|
Width="*" Binding="{Binding unknown_1ch}"
|
||||||
Header="Unknown 1Ch" />
|
Header="0x1Ch" />
|
||||||
</DataGrid.Columns>
|
</DataGrid.Columns>
|
||||||
</DataGrid>
|
</DataGrid>
|
||||||
</Grid>
|
</Grid>
|
||||||
@ -250,6 +253,8 @@
|
|||||||
<Button x:Name="button_load" Content="Load" HorizontalAlignment="Left" Margin="90,10,0,0"
|
<Button x:Name="button_load" Content="Load" HorizontalAlignment="Left" Margin="90,10,0,0"
|
||||||
VerticalAlignment="Top" Width="74" Click="button_load_click" />
|
VerticalAlignment="Top" Width="74" Click="button_load_click" />
|
||||||
<Button x:Name="button_about" Content="About" HorizontalAlignment="Left" Margin="379,10,0,0" VerticalAlignment="Top" Width="74" Click="button_about_Click"/>
|
<Button x:Name="button_about" Content="About" HorizontalAlignment="Left" Margin="379,10,0,0" VerticalAlignment="Top" Width="74" Click="button_about_Click"/>
|
||||||
|
<Label x:Name="label_save_ver_cap" Content="Save Version:" HorizontalAlignment="Left" Margin="164,7,0,0" VerticalAlignment="Top"/>
|
||||||
|
<Label x:Name="label_save_ver" Content="JPN" HorizontalAlignment="Left" Margin="235,7,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.237,0.519" FontWeight="Bold"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Window>
|
</Window>
|
||||||
|
|
||||||
|
@ -16,8 +16,6 @@ namespace MHSEC_G
|
|||||||
{
|
{
|
||||||
public partial class MainWindow : Window, INotifyPropertyChanged
|
public partial class MainWindow : Window, INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
private readonly byte[] _dummy_data = new byte[Model.SAVE_FILE_SIZE];
|
|
||||||
|
|
||||||
private static string get_app_version()
|
private static string get_app_version()
|
||||||
{
|
{
|
||||||
Version v = Assembly.GetExecutingAssembly().GetName().Version;
|
Version v = Assembly.GetExecutingAssembly().GetName().Version;
|
||||||
@ -29,11 +27,13 @@ namespace MHSEC_G
|
|||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
button_save.IsEnabled = false;
|
button_save.IsEnabled = false;
|
||||||
Item.read_item_mappings();
|
byte[] dummy = new byte[Offsets.SAVE_FILE_SIZE_JPN];
|
||||||
Genes.read_gene_mapping();
|
Array.Clear(dummy, 0, dummy.Length);
|
||||||
Array.Clear(_dummy_data, 0, _dummy_data.Length);
|
|
||||||
this.Title = "MHSEC-G Ver " + get_app_version();
|
this.Title = "MHSEC-G Ver " + get_app_version();
|
||||||
init(_dummy_data);
|
|
||||||
|
Offsets.init(dummy);
|
||||||
|
init(dummy);
|
||||||
|
|
||||||
DataContext = this;
|
DataContext = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,16 +45,25 @@ namespace MHSEC_G
|
|||||||
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
||||||
{
|
{
|
||||||
byte[] buffer = File.ReadAllBytes(dialog.FileName);
|
byte[] buffer = File.ReadAllBytes(dialog.FileName);
|
||||||
if (buffer.Length != Model.SAVE_FILE_SIZE)
|
if (buffer.Length != Offsets.SAVE_FILE_SIZE_JPN && buffer.Length != Offsets.SAVE_FILE_SIZE_NA)
|
||||||
{
|
{
|
||||||
System.Windows.Forms.MessageBox.Show(
|
System.Windows.Forms.MessageBox.Show(
|
||||||
"Wrong save file size! Expected: " + Model.SAVE_FILE_SIZE + " Got: " + buffer.Length,
|
"Unsupported save file!",
|
||||||
"Error",
|
"MHSEC-G",
|
||||||
MessageBoxButtons.OK,
|
MessageBoxButtons.OK,
|
||||||
MessageBoxIcon.Error);
|
MessageBoxIcon.Error);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (buffer.Length == Offsets.SAVE_FILE_SIZE_JPN)
|
||||||
|
{
|
||||||
|
label_save_ver.Content = "JPN";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
label_save_ver.Content = "EUR/USA";
|
||||||
|
}
|
||||||
|
Offsets.init(buffer);
|
||||||
init(buffer);
|
init(buffer);
|
||||||
OnPropertyChanged(null);
|
OnPropertyChanged(null);
|
||||||
button_save.IsEnabled = true;
|
button_save.IsEnabled = true;
|
||||||
@ -64,12 +73,12 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
private void button_char_money_Click(object sender, RoutedEventArgs e)
|
private void button_char_money_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
_character.money = Character.LIMIT_MONEY;
|
_character.money = Offsets.LIMIT_MONEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void button_char_exp_Click(object sender, RoutedEventArgs e)
|
private void button_char_exp_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
_character.exp = Character.LIMIT_EXP;
|
_character.exp = Offsets.LIMIT_EXP;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void button_item_all_Click(object sender, RoutedEventArgs e)
|
private void button_item_all_Click(object sender, RoutedEventArgs e)
|
||||||
@ -77,7 +86,7 @@ namespace MHSEC_G
|
|||||||
List<Item> items = _items;
|
List<Item> items = _items;
|
||||||
for (uint i = 0; i < items.Count; i++)
|
for (uint i = 0; i < items.Count; i++)
|
||||||
{
|
{
|
||||||
if (items.ElementAt((int) i).offset >= Item.OFFSETA_FIRST_KEY_ITEM)
|
if (items.ElementAt((int) i).offset >= Offsets.OFFSETA_FIRST_KEY_ITEM)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
items.ElementAt((int) i).count = 986;
|
items.ElementAt((int) i).count = 986;
|
||||||
@ -89,7 +98,7 @@ namespace MHSEC_G
|
|||||||
List<Item> items = _items;
|
List<Item> items = _items;
|
||||||
for (uint i = 0; i < items.Count; i++)
|
for (uint i = 0; i < items.Count; i++)
|
||||||
{
|
{
|
||||||
if (items.ElementAt((int) i).offset >= Item.OFFSETA_FIRST_KEY_ITEM)
|
if (items.ElementAt((int) i).offset >= Offsets.OFFSETA_FIRST_KEY_ITEM)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (items.ElementAt((int) i).count != 0)
|
if (items.ElementAt((int) i).count != 0)
|
||||||
@ -107,55 +116,20 @@ namespace MHSEC_G
|
|||||||
dialog.FileName = "mhr_game0.sav";
|
dialog.FileName = "mhr_game0.sav";
|
||||||
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
||||||
{
|
{
|
||||||
File.WriteAllBytes(dialog.FileName, _model.save_file);
|
File.WriteAllBytes(dialog.FileName, _model);
|
||||||
MessageBox.Show("Saved to \"" + dialog.FileName + "\"", "MHSEC-G", MessageBoxButton.OK,
|
MessageBox.Show("Saved to \"" + dialog.FileName + "\"", "MHSEC-G", MessageBoxButton.OK,
|
||||||
MessageBoxImage.Information);
|
MessageBoxImage.Information);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void button_give_epony_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
EggFragment.write_dlc_egg_fragment(_egg_fragments, _model, 0x4);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void button_give_bear_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
EggFragment.write_dlc_egg_fragment(_egg_fragments, _model, 0x5);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void button_give_mtiggy_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
EggFragment.write_dlc_egg_fragment(_egg_fragments, _model, 0x20);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void button_give_okirin_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
EggFragment.write_dlc_egg_fragment(_egg_fragments, _model, 0x21);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void button_give_dino_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
EggFragment.write_dlc_egg_fragment(_egg_fragments, _model, 0x6);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void button_give_wm_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
EggFragment.write_dlc_egg_fragment(_egg_fragments, _model, 0x1F);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void button_give_pd_Click(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
EggFragment.write_dlc_egg_fragment(_egg_fragments, _model, 0x3);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void button_about_Click(object sender, RoutedEventArgs e)
|
private void button_about_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
MessageBox.Show("MHSEC-G Version " + get_app_version() + "\nDeveloped by secXsQuared", "About",
|
MessageBox.Show("MHSEC-G Version " + get_app_version() + "\nDeveloped by secXsQuared", "About",
|
||||||
MessageBoxButton.OK, MessageBoxImage.Information);
|
MessageBoxButton.OK, MessageBoxImage.Information);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Model _model;
|
private byte[] _model;
|
||||||
public Model model => _model;
|
public byte[] model => _model;
|
||||||
|
|
||||||
private Character _character;
|
private Character _character;
|
||||||
public Character character => _character;
|
public Character character => _character;
|
||||||
@ -187,7 +161,7 @@ namespace MHSEC_G
|
|||||||
{
|
{
|
||||||
BugCheck.bug_check(BugCheck.ErrorCode.VIEWMODEL_NULL_SAVE, "The save file reference is NULL.");
|
BugCheck.bug_check(BugCheck.ErrorCode.VIEWMODEL_NULL_SAVE, "The save file reference is NULL.");
|
||||||
}
|
}
|
||||||
_model = new Model(save);
|
_model = save;
|
||||||
_character = new Character(_model);
|
_character = new Character(_model);
|
||||||
_items = Item.read_all_items(_model);
|
_items = Item.read_all_items(_model);
|
||||||
_monsters = new ObservableCollection<Monster>(Monster.read_all_monsters(_model));
|
_monsters = new ObservableCollection<Monster>(Monster.read_all_monsters(_model));
|
||||||
|
@ -9,50 +9,23 @@ using MHSEC_G.Annotations;
|
|||||||
|
|
||||||
namespace MHSEC_G
|
namespace MHSEC_G
|
||||||
{
|
{
|
||||||
public class Monster : INotifyPropertyChanged
|
public class Monster : InMemoryObject
|
||||||
{
|
{
|
||||||
public const uint LIMIT_MONSTER_EXP = 0xFFFFFF;
|
public uint box => (_obj_offset - Offsets.OFFSETA_MONSTER) / Offsets.SIZE_MONSTER / 18 + 1;
|
||||||
public const uint SIZE_MONSTER = 0x478;
|
public uint slot => (_obj_offset - Offsets.OFFSETA_MONSTER) / Offsets.SIZE_MONSTER % 18 + 1;
|
||||||
private const uint OFFSETA_MONSTER = 0xA150;
|
|
||||||
private const uint OFFSETR_MONSTER_GENE = 0x424;
|
|
||||||
private const uint SIZE_MONSTER_GENE = 0x4;
|
|
||||||
private const uint OFFSETR_MONSTER_EXP = 0xE0;
|
|
||||||
private const uint OFFSETR_MONSTER_HIV = 0xD8;
|
|
||||||
private const uint OFFSETR_MONSTER_AIV = 0xD9;
|
|
||||||
private const uint OFFSETR_MONSTER_DIV = 0xDA;
|
|
||||||
private const uint OFFSETR_MONSTER_HPU = 0xD4;
|
|
||||||
private const uint OFFSETR_MONSTER_APU = 0xD5;
|
|
||||||
private const uint OFFSETR_MONSTER_DPU = 0xD6;
|
|
||||||
private const uint OFFSETR_MONSTER_SKILL = 0x38;
|
|
||||||
private const uint OFFSETR_MONSTER_LEVEL = 0x5C;
|
|
||||||
private const uint LIMIT_MONSTER_LEVEL = 99;
|
|
||||||
private const uint OFFSETR_MONSTER_NAME = 0;
|
|
||||||
private const uint LIMIT_MONSTER_NAME = 10;
|
|
||||||
private const uint OFFSETR_MONSTER_SPE = 0x30;
|
|
||||||
private const uint OFFSETA_MONSTE_END = 0x4786F;
|
|
||||||
private const uint OFFSETR_MONSTER_ATK = 0x48;
|
|
||||||
private const uint OFFSETR_MONSTER_HP = 0x46;
|
|
||||||
private const uint OFFSETR_MONSTER_DEF = 0x4A;
|
|
||||||
|
|
||||||
private readonly Model _model;
|
|
||||||
|
|
||||||
private readonly uint _offset;
|
|
||||||
public uint offset => _offset;
|
|
||||||
public uint box => (_offset - OFFSETA_MONSTER) / SIZE_MONSTER / 18 + 1;
|
|
||||||
public uint slot => (_offset - OFFSETA_MONSTER) / SIZE_MONSTER % 18 + 1;
|
|
||||||
|
|
||||||
private readonly Genes _genes;
|
private readonly Genes _genes;
|
||||||
public Genes genes => _genes;
|
public Genes genes => _genes;
|
||||||
|
|
||||||
public string spe
|
public string spe
|
||||||
{
|
{
|
||||||
get => Model.byte_to_uint(_model.save_file[_offset + OFFSETR_MONSTER_SPE]).ToString("X2");
|
get => Helper.byte_to_uint(_data[_obj_offset + Offsets.OFFSETR_MONSTER_SPE]).ToString("X2");
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFF)
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0xFF)
|
||||||
{
|
{
|
||||||
_model.save_file[_offset + OFFSETR_MONSTER_SPE] = (byte) (parsed & 0xFF);
|
_data[_obj_offset + Offsets.OFFSETR_MONSTER_SPE] = (byte) (parsed & 0xFF);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -65,12 +38,12 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public uint atk
|
public uint atk
|
||||||
{
|
{
|
||||||
get => Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_ATK);
|
get => Helper.byte_to_uint16_le(_data, _obj_offset + Offsets.OFFSETR_MONSTER_ATK);
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value <= 0xFFFF)
|
if (value <= 0xFFFF)
|
||||||
{
|
{
|
||||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_ATK, value);
|
Helper.write_uint16_le(_data, _obj_offset + Offsets.OFFSETR_MONSTER_ATK, value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -83,12 +56,12 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public uint def
|
public uint def
|
||||||
{
|
{
|
||||||
get => Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_DEF);
|
get => Helper.byte_to_uint16_le(_data, _obj_offset + Offsets.OFFSETR_MONSTER_DEF);
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value <= 0xFFFF)
|
if (value <= 0xFFFF)
|
||||||
{
|
{
|
||||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_DEF, value);
|
Helper.write_uint16_le(_data, _obj_offset + Offsets.OFFSETR_MONSTER_DEF, value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -101,12 +74,12 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public uint hp
|
public uint hp
|
||||||
{
|
{
|
||||||
get => Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_HP);
|
get => Helper.byte_to_uint16_le(_data, _obj_offset + Offsets.OFFSETR_MONSTER_HP);
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value <= 0xFFFF)
|
if (value <= 0xFFFF)
|
||||||
{
|
{
|
||||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_HP, value);
|
Helper.write_uint16_le(_data, _obj_offset + Offsets.OFFSETR_MONSTER_HP, value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -119,12 +92,12 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public uint hiv
|
public uint hiv
|
||||||
{
|
{
|
||||||
get => Model.byte_to_uint(_model.save_file[_offset + OFFSETR_MONSTER_HIV]);
|
get => Helper.byte_to_uint(_data[_obj_offset + Offsets.OFFSETR_MONSTER_HIV]);
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value <= 0xFF)
|
if (value <= 0xFF)
|
||||||
{
|
{
|
||||||
_model.save_file[_offset + OFFSETR_MONSTER_HIV] = (byte) (value & 0xFF);
|
_data[_obj_offset + Offsets.OFFSETR_MONSTER_HIV] = (byte) (value & 0xFF);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -136,12 +109,12 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public uint aiv
|
public uint aiv
|
||||||
{
|
{
|
||||||
get => Model.byte_to_uint(_model.save_file[_offset + OFFSETR_MONSTER_AIV]);
|
get => Helper.byte_to_uint(_data[_obj_offset + Offsets.OFFSETR_MONSTER_AIV]);
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value <= 0xFF)
|
if (value <= 0xFF)
|
||||||
{
|
{
|
||||||
_model.save_file[_offset + OFFSETR_MONSTER_AIV] = (byte) (value & 0xFF);
|
_data[_obj_offset + Offsets.OFFSETR_MONSTER_AIV] = (byte) (value & 0xFF);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -153,12 +126,12 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public uint div
|
public uint div
|
||||||
{
|
{
|
||||||
get => Model.byte_to_uint(_model.save_file[_offset + OFFSETR_MONSTER_DIV]);
|
get => Helper.byte_to_uint(_data[_obj_offset + Offsets.OFFSETR_MONSTER_DIV]);
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value <= 0xFF)
|
if (value <= 0xFF)
|
||||||
{
|
{
|
||||||
_model.save_file[_offset + OFFSETR_MONSTER_DIV] = (byte) (value & 0xFF);
|
_data[_obj_offset + Offsets.OFFSETR_MONSTER_DIV] = (byte) (value & 0xFF);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -170,12 +143,12 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public uint hpu
|
public uint hpu
|
||||||
{
|
{
|
||||||
get => Model.byte_to_uint(_model.save_file[_offset + OFFSETR_MONSTER_HPU]);
|
get => Helper.byte_to_uint(_data[_obj_offset + Offsets.OFFSETR_MONSTER_HPU]);
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value <= 0xFF)
|
if (value <= 0xFF)
|
||||||
{
|
{
|
||||||
_model.save_file[_offset + OFFSETR_MONSTER_HPU] = (byte) (value & 0xFF);
|
_data[_obj_offset + Offsets.OFFSETR_MONSTER_HPU] = (byte) (value & 0xFF);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -188,12 +161,12 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public uint apu
|
public uint apu
|
||||||
{
|
{
|
||||||
get => Model.byte_to_uint(_model.save_file[_offset + OFFSETR_MONSTER_APU]);
|
get => Helper.byte_to_uint(_data[_obj_offset + Offsets.OFFSETR_MONSTER_APU]);
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value <= 0xFF)
|
if (value <= 0xFF)
|
||||||
{
|
{
|
||||||
_model.save_file[_offset + OFFSETR_MONSTER_APU] = (byte) (value & 0xFF);
|
_data[_obj_offset + Offsets.OFFSETR_MONSTER_APU] = (byte) (value & 0xFF);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -206,12 +179,12 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public uint dpu
|
public uint dpu
|
||||||
{
|
{
|
||||||
get => Model.byte_to_uint(_model.save_file[_offset + OFFSETR_MONSTER_DPU]);
|
get => Helper.byte_to_uint(_data[_obj_offset + Offsets.OFFSETR_MONSTER_DPU]);
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value <= 0xFF)
|
if (value <= 0xFF)
|
||||||
{
|
{
|
||||||
_model.save_file[_offset + OFFSETR_MONSTER_DPU] = (byte) (value & 0xFF);
|
_data[_obj_offset + Offsets.OFFSETR_MONSTER_DPU] = (byte) (value & 0xFF);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -224,13 +197,13 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public string name
|
public string name
|
||||||
{
|
{
|
||||||
get => Model.read_unicode_string(_model.save_file, _offset + OFFSETR_MONSTER_NAME, LIMIT_MONSTER_NAME);
|
get => Helper.read_unicode_string(_data, _obj_offset + Offsets.OFFSETR_MONSTER_NAME, Offsets.LIMIT_MONSTER_NAME);
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value.Length <= 10 && value.Length > 0)
|
if (value.Length <= 10 && value.Length > 0)
|
||||||
{
|
{
|
||||||
Model.write_unicode_string(_model.save_file, _offset + OFFSETR_MONSTER_NAME, value,
|
Helper.write_unicode_string(_data, _obj_offset + Offsets.OFFSETR_MONSTER_NAME, value,
|
||||||
LIMIT_MONSTER_NAME);
|
Offsets.LIMIT_MONSTER_NAME);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -243,16 +216,16 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public uint exp
|
public uint exp
|
||||||
{
|
{
|
||||||
get => Model.byte_to_uint32_le(_model.save_file, _offset + OFFSETR_MONSTER_EXP);
|
get => Helper.byte_to_uint32_le(_data, _obj_offset + Offsets.OFFSETR_MONSTER_EXP);
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value <= LIMIT_MONSTER_EXP)
|
if (value <= Offsets.LIMIT_MONSTER_EXP)
|
||||||
{
|
{
|
||||||
Model.write_uint32_le(_model.save_file, _offset + OFFSETR_MONSTER_EXP, value);
|
Helper.write_uint32_le(_data, _obj_offset + Offsets.OFFSETR_MONSTER_EXP, value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MessageBox.Show("Exp must be at most " + LIMIT_MONSTER_EXP, "Error", MessageBoxButton.OK,
|
MessageBox.Show("Exp must be at most " + Offsets.LIMIT_MONSTER_EXP, "Error", MessageBoxButton.OK,
|
||||||
MessageBoxImage.Error);
|
MessageBoxImage.Error);
|
||||||
}
|
}
|
||||||
OnPropertyChanged(nameof(exp));
|
OnPropertyChanged(nameof(exp));
|
||||||
@ -261,16 +234,16 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public uint level
|
public uint level
|
||||||
{
|
{
|
||||||
get => Model.byte_to_uint(_model.save_file[_offset + OFFSETR_MONSTER_LEVEL]);
|
get => Helper.byte_to_uint(_data[_obj_offset + Offsets.OFFSETR_MONSTER_LEVEL]);
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value <= LIMIT_MONSTER_LEVEL)
|
if (value <= Offsets.LIMIT_MONSTER_LEVEL)
|
||||||
{
|
{
|
||||||
_model.save_file[_offset + OFFSETR_MONSTER_LEVEL] = (byte) (value & 0xFF);
|
_data[_obj_offset + Offsets.OFFSETR_MONSTER_LEVEL] = (byte) (value & 0xFF);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MessageBox.Show("Level must be at most " + LIMIT_MONSTER_LEVEL, "Error", MessageBoxButton.OK,
|
MessageBox.Show("Level must be at most " + Offsets.LIMIT_MONSTER_LEVEL, "Error", MessageBoxButton.OK,
|
||||||
MessageBoxImage.Error);
|
MessageBoxImage.Error);
|
||||||
}
|
}
|
||||||
OnPropertyChanged(nameof(level));
|
OnPropertyChanged(nameof(level));
|
||||||
@ -279,13 +252,13 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public string skill
|
public string skill
|
||||||
{
|
{
|
||||||
get => Model.byte_to_uint16_le(_model.save_file, offset + OFFSETR_MONSTER_SKILL).ToString("X4");
|
get => Helper.byte_to_uint16_le(_data, _obj_offset + Offsets.OFFSETR_MONSTER_SKILL).ToString("X4");
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed))
|
if (Helper.parse_hex_string(value, out parsed))
|
||||||
{
|
{
|
||||||
Model.write_uint16_le(_model.save_file, offset + OFFSETR_MONSTER_SKILL, parsed);
|
Helper.write_uint16_le(_data, _obj_offset + Offsets.OFFSETR_MONSTER_SKILL, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -298,44 +271,20 @@ namespace MHSEC_G
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Monster(uint offset, Model model)
|
public Monster(byte[] model, uint objOffset) : base(model, objOffset, Offsets.SIZE_MONSTER)
|
||||||
{
|
{
|
||||||
_offset = offset;
|
_genes = new Genes(model, objOffset + Offsets.OFFSETR_MONSTER_GENE, Offsets.SIZE_MONSTER_GENE);
|
||||||
_model = model;
|
|
||||||
_genes = new Genes(model, offset + OFFSETR_MONSTER_GENE, SIZE_MONSTER_GENE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Monster> read_all_monsters(Model model)
|
public static List<Monster> read_all_monsters(byte[] model)
|
||||||
{
|
{
|
||||||
byte[] save = model.save_file;
|
byte[] save = model;
|
||||||
List<Monster> ret = new List<Monster>();
|
List<Monster> ret = new List<Monster>();
|
||||||
for (uint i = OFFSETA_MONSTER; i < OFFSETA_MONSTE_END; i += SIZE_MONSTER)
|
for (uint i = Offsets.OFFSETA_MONSTER; i < Offsets.OFFSETA_MONSTE_END; i += Offsets.SIZE_MONSTER)
|
||||||
{
|
{
|
||||||
ret.Add(new Monster(i, model));
|
ret.Add(new Monster(model, i));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getByteArray()
|
|
||||||
{
|
|
||||||
byte[] ret = new byte[SIZE_MONSTER];
|
|
||||||
Array.Copy(_model.save_file, _offset, ret, 0, SIZE_MONSTER);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setByteArray(byte[] ret)
|
|
||||||
{
|
|
||||||
Array.Copy(ret, 0, _model.save_file, _offset, SIZE_MONSTER);
|
|
||||||
OnPropertyChanged(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
|
||||||
|
|
||||||
[NotifyPropertyChangedInvocator]
|
|
||||||
protected virtual void OnPropertyChanged(string propertyName)
|
|
||||||
{
|
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@
|
|||||||
VerticalAlignment="Top" RenderTransformOrigin="-0.263,0.135" />
|
VerticalAlignment="Top" RenderTransformOrigin="-0.263,0.135" />
|
||||||
<Label x:Name="label_mex" Content="Exp" HorizontalAlignment="Left" Margin="172,69,0,0"
|
<Label x:Name="label_mex" Content="Exp" HorizontalAlignment="Left" Margin="172,69,0,0"
|
||||||
VerticalAlignment="Top" RenderTransformOrigin="-0.263,0.135" />
|
VerticalAlignment="Top" RenderTransformOrigin="-0.263,0.135" />
|
||||||
<Label x:Name="label_spe" Content="Type (Hex)" Margin="168,97,97,0"
|
<Label x:Name="label_spe" Content="Species (Hex)" Margin="156,97,94,0"
|
||||||
VerticalAlignment="Top" RenderTransformOrigin="-0.263,0.135" />
|
VerticalAlignment="Top" RenderTransformOrigin="-0.263,0.135" />
|
||||||
<TextBox x:Name="textbox_mlv" HorizontalAlignment="Left" Height="24" Margin="240,39,0,0"
|
<TextBox x:Name="textbox_mlv" HorizontalAlignment="Left" Height="24" Margin="240,39,0,0"
|
||||||
TextWrapping="Wrap" Text="{Binding monster.level}" VerticalAlignment="Top"
|
TextWrapping="Wrap" Text="{Binding monster.level}" VerticalAlignment="Top"
|
||||||
|
@ -32,7 +32,7 @@ namespace MHSEC_G
|
|||||||
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
||||||
{
|
{
|
||||||
byte[] buffer = File.ReadAllBytes(dialog.FileName);
|
byte[] buffer = File.ReadAllBytes(dialog.FileName);
|
||||||
if (buffer.Length != Monster.SIZE_MONSTER)
|
if (buffer.Length != Offsets.SIZE_MONSTER)
|
||||||
{
|
{
|
||||||
System.Windows.Forms.MessageBox.Show(
|
System.Windows.Forms.MessageBox.Show(
|
||||||
"Wrong monster file size!",
|
"Wrong monster file size!",
|
||||||
@ -64,7 +64,7 @@ namespace MHSEC_G
|
|||||||
dialog.FileName = _monster.name + ".bin";
|
dialog.FileName = _monster.name + ".bin";
|
||||||
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
|
||||||
{
|
{
|
||||||
byte[] binary = _monster.getByteArray();
|
byte[] binary = _monster.toByteArray();
|
||||||
File.WriteAllBytes(dialog.FileName, binary);
|
File.WriteAllBytes(dialog.FileName, binary);
|
||||||
MessageBox.Show("Exported to \"" + dialog.FileName + "\"", "MHSEC-G", MessageBoxButton.OK,
|
MessageBox.Show("Exported to \"" + dialog.FileName + "\"", "MHSEC-G", MessageBoxButton.OK,
|
||||||
MessageBoxImage.Information);
|
MessageBoxImage.Information);
|
||||||
@ -73,7 +73,7 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
private void button_mexp_Click(object sender, RoutedEventArgs e)
|
private void button_mexp_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
_monster.exp = Monster.LIMIT_MONSTER_EXP;
|
_monster.exp = Offsets.LIMIT_MONSTER_EXP;
|
||||||
}
|
}
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
593
MHSEC-G/MHSEC-G/Offsets.cs
Normal file
593
MHSEC-G/MHSEC-G/Offsets.cs
Normal file
@ -0,0 +1,593 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Resources;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace MHSEC_G
|
||||||
|
{
|
||||||
|
public static class Offsets
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Save
|
||||||
|
//
|
||||||
|
public const uint SAVE_FILE_SIZE_JPN = 483976;
|
||||||
|
public const uint SAVE_FILE_SIZE_NA = 535736;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Genes
|
||||||
|
//
|
||||||
|
private static List<uint> _GENE_ID;
|
||||||
|
private static List<string> _GENE_NAME;
|
||||||
|
public static List<uint> GENE_ID => _GENE_ID;
|
||||||
|
public static List<string> GENE_NAME => _GENE_NAME;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Armors
|
||||||
|
//
|
||||||
|
private static uint _OFFSETA_ARM;
|
||||||
|
public static uint OFFSETA_ARM => _OFFSETA_ARM;
|
||||||
|
|
||||||
|
private static uint _SIZE_ARM;
|
||||||
|
public static uint SIZE_ARM => _SIZE_ARM;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_ARM_ID;
|
||||||
|
public static uint OFFSETR_ARM_ID => _OFFSETR_ARM_ID;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_ARM_LEVEL;
|
||||||
|
public static uint OFFSETR_ARM_LEVEL => _OFFSETR_ARM_LEVEL;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_ARM_14h;
|
||||||
|
public static uint OFFSETR_ARM_14h => _OFFSETR_ARM_14h;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_ARM_18h;
|
||||||
|
public static uint OFFSETR_ARM_18h => _OFFSETR_ARM_18h;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_ARM_1C;
|
||||||
|
public static uint OFFSETR_ARM_1C => _OFFSETR_ARM_1C;
|
||||||
|
|
||||||
|
private static uint _OFFSETA_ARM_END;
|
||||||
|
public static uint OFFSETA_ARM_END => _OFFSETA_ARM_END;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_ARM_TYPE;
|
||||||
|
public static uint OFFSETR_ARM_TYPE => _OFFSETR_ARM_TYPE;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Character
|
||||||
|
//
|
||||||
|
private static uint _OFFSETA_CHAR_NAME;
|
||||||
|
public static uint OFFSETA_CHAR_NAME => _OFFSETA_CHAR_NAME;
|
||||||
|
|
||||||
|
|
||||||
|
private static uint _LENGTH_CHAR_NAME;
|
||||||
|
public static uint LENGTH_CHAR_NAME => _LENGTH_CHAR_NAME;
|
||||||
|
|
||||||
|
private static uint _OFFSETA_CHAR_MONEY;
|
||||||
|
public static uint OFFSETA_CHAR_MONEY => _OFFSETA_CHAR_MONEY;
|
||||||
|
|
||||||
|
private static uint _OFFSETA_CHAR_EXP;
|
||||||
|
public static uint OFFSETA_CHAR_EXP => _OFFSETA_CHAR_EXP;
|
||||||
|
|
||||||
|
private static uint _OFFSETA_CHAR_LEVEL;
|
||||||
|
public static uint OFFSETA_CHAR_LEVEL => _OFFSETA_CHAR_LEVEL;
|
||||||
|
|
||||||
|
private static uint _LIMIT_LEVEL;
|
||||||
|
public static uint LIMIT_LEVEL => _LIMIT_LEVEL;
|
||||||
|
|
||||||
|
private static uint _LIMIT_MONEY;
|
||||||
|
public static uint LIMIT_MONEY => _LIMIT_MONEY;
|
||||||
|
|
||||||
|
private static uint _LIMIT_EXP;
|
||||||
|
public static uint LIMIT_EXP => _LIMIT_EXP;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Egg
|
||||||
|
//
|
||||||
|
private static uint _OFFSETA_EGG_START;
|
||||||
|
public static uint OFFSETA_EGG_START => _OFFSETA_EGG_START;
|
||||||
|
|
||||||
|
|
||||||
|
private static uint _OFFSETA_EGG_END;
|
||||||
|
public static uint OFFSETA_EGG_END => _OFFSETA_EGG_END;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_EGG_GENE;
|
||||||
|
public static uint OFFSETR_EGG_GENE => _OFFSETR_EGG_GENE;
|
||||||
|
|
||||||
|
private static uint _SIZE_EGG_GENE;
|
||||||
|
public static uint SIZE_EGG_GENE => _SIZE_EGG_GENE;
|
||||||
|
|
||||||
|
private static uint _SIZE_EGG;
|
||||||
|
public static uint SIZE_EGG => _SIZE_EGG;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_SPE;
|
||||||
|
public static uint OFFSETR_SPE => _OFFSETR_SPE;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_WGT;
|
||||||
|
public static uint OFFSETR_WGT => _OFFSETR_WGT;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Egg fragments
|
||||||
|
//
|
||||||
|
private static uint _OFFSETA_EGG_FRAGMENTS;
|
||||||
|
public static uint OFFSETA_EGG_FRAGMENTS => _OFFSETA_EGG_FRAGMENTS;
|
||||||
|
|
||||||
|
|
||||||
|
private static uint _OFFSETA_EGG_FRAGMENTS_END;
|
||||||
|
public static uint OFFSETA_EGG_FRAGMENTS_END => _OFFSETA_EGG_FRAGMENTS_END;
|
||||||
|
|
||||||
|
private static uint _SIZE_EGG_FRAGMENT;
|
||||||
|
public static uint SIZE_EGG_FRAGMENT => _SIZE_EGG_FRAGMENT;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_EF_SPE;
|
||||||
|
public static uint OFFSETR_EF_SPE => _OFFSETR_EF_SPE;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_EF_POS;
|
||||||
|
public static uint OFFSETR_EF_POS => _OFFSETR_EF_POS;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_EF_NEW;
|
||||||
|
public static uint OFFSETR_EF_NEW => _OFFSETR_EF_NEW;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_EF_RAR;
|
||||||
|
public static uint OFFSETR_EF_RAR => _OFFSETR_EF_RAR;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_EF_COL;
|
||||||
|
public static uint OFFSETR_EF_COL => _OFFSETR_EF_COL;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_EF_DLC;
|
||||||
|
public static uint OFFSETR_EF_DLC => _OFFSETR_EF_DLC;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_EF_6H;
|
||||||
|
public static uint OFFSETR_EF_6H => _OFFSETR_EF_6H;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_EF_7H;
|
||||||
|
public static uint OFFSETR_EF_7H => _OFFSETR_EF_7H;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Items
|
||||||
|
//
|
||||||
|
private static Dictionary<uint, uint> _OFFSET_ID_MAPPING;
|
||||||
|
public static Dictionary<uint, uint> OFFSET_ID_MAPPING => _OFFSET_ID_MAPPING;
|
||||||
|
private static Dictionary<uint, string> _OFFSET_NAME_MAPPING;
|
||||||
|
public static Dictionary<uint, string> OFFSET_NAME_MAPPING => _OFFSET_NAME_MAPPING;
|
||||||
|
|
||||||
|
private static uint _OFFSETA_ITEM_BOX;
|
||||||
|
public static uint OFFSETA_ITEM_BOX => _OFFSETA_ITEM_BOX;
|
||||||
|
|
||||||
|
|
||||||
|
private static uint _SIZE_ITEM;
|
||||||
|
public static uint SIZE_ITEM => _SIZE_ITEM;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_ITEM_ID;
|
||||||
|
public static uint OFFSETR_ITEM_ID => _OFFSETR_ITEM_ID;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_ITEM_COUNT;
|
||||||
|
public static uint OFFSETR_ITEM_COUNT => _OFFSETR_ITEM_COUNT;
|
||||||
|
|
||||||
|
private static uint _OFFSETA_ITEM_BOX_END;
|
||||||
|
public static uint OFFSETA_ITEM_BOX_END => _OFFSETA_ITEM_BOX_END;
|
||||||
|
|
||||||
|
private static uint _OFFSETA_FIRST_KEY_ITEM;
|
||||||
|
public static uint OFFSETA_FIRST_KEY_ITEM => _OFFSETA_FIRST_KEY_ITEM;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Monsters
|
||||||
|
//
|
||||||
|
private static uint _LIMIT_MONSTER_EXP;
|
||||||
|
public static uint LIMIT_MONSTER_EXP => _LIMIT_MONSTER_EXP;
|
||||||
|
|
||||||
|
|
||||||
|
private static uint _SIZE_MONSTER;
|
||||||
|
public static uint SIZE_MONSTER => _SIZE_MONSTER;
|
||||||
|
|
||||||
|
private static uint _OFFSETA_MONSTER;
|
||||||
|
public static uint OFFSETA_MONSTER => _OFFSETA_MONSTER;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_MONSTER_GENE;
|
||||||
|
public static uint OFFSETR_MONSTER_GENE => _OFFSETR_MONSTER_GENE;
|
||||||
|
|
||||||
|
private static uint _SIZE_MONSTER_GENE;
|
||||||
|
public static uint SIZE_MONSTER_GENE => _SIZE_MONSTER_GENE;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_MONSTER_EXP;
|
||||||
|
public static uint OFFSETR_MONSTER_EXP => _OFFSETR_MONSTER_EXP;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_MONSTER_HIV;
|
||||||
|
public static uint OFFSETR_MONSTER_HIV => _OFFSETR_MONSTER_HIV;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_MONSTER_AIV;
|
||||||
|
public static uint OFFSETR_MONSTER_AIV => _OFFSETR_MONSTER_AIV;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_MONSTER_DIV;
|
||||||
|
public static uint OFFSETR_MONSTER_DIV => _OFFSETR_MONSTER_DIV;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_MONSTER_HPU;
|
||||||
|
public static uint OFFSETR_MONSTER_HPU => _OFFSETR_MONSTER_HPU;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_MONSTER_APU;
|
||||||
|
public static uint OFFSETR_MONSTER_APU => _OFFSETR_MONSTER_APU;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_MONSTER_DPU;
|
||||||
|
public static uint OFFSETR_MONSTER_DPU => _OFFSETR_MONSTER_DPU;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_MONSTER_SKILL;
|
||||||
|
public static uint OFFSETR_MONSTER_SKILL => _OFFSETR_MONSTER_SKILL;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_MONSTER_LEVEL;
|
||||||
|
public static uint OFFSETR_MONSTER_LEVEL => _OFFSETR_MONSTER_LEVEL;
|
||||||
|
|
||||||
|
private static uint _LIMIT_MONSTER_LEVEL;
|
||||||
|
public static uint LIMIT_MONSTER_LEVEL => _LIMIT_MONSTER_LEVEL;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_MONSTER_NAME;
|
||||||
|
public static uint OFFSETR_MONSTER_NAME => _OFFSETR_MONSTER_NAME;
|
||||||
|
|
||||||
|
private static uint _LIMIT_MONSTER_NAME;
|
||||||
|
public static uint LIMIT_MONSTER_NAME => _LIMIT_MONSTER_NAME;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_MONSTER_SPE;
|
||||||
|
public static uint OFFSETR_MONSTER_SPE => _OFFSETR_MONSTER_SPE;
|
||||||
|
|
||||||
|
private static uint _OFFSETA_MONSTE_END;
|
||||||
|
public static uint OFFSETA_MONSTE_END => _OFFSETA_MONSTE_END;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_MONSTER_ATK;
|
||||||
|
public static uint OFFSETR_MONSTER_ATK => _OFFSETR_MONSTER_ATK;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_MONSTER_HP;
|
||||||
|
public static uint OFFSETR_MONSTER_HP => _OFFSETR_MONSTER_HP;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_MONSTER_DEF;
|
||||||
|
public static uint OFFSETR_MONSTER_DEF => _OFFSETR_MONSTER_DEF;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Talismans
|
||||||
|
//
|
||||||
|
private static uint _OFFSETA_TALI;
|
||||||
|
public static uint OFFSETA_TALI => _OFFSETA_TALI;
|
||||||
|
|
||||||
|
|
||||||
|
private static uint _OFFSETA_TALI_END;
|
||||||
|
public static uint OFFSETA_TALI_END => _OFFSETA_TALI_END;
|
||||||
|
|
||||||
|
private static uint _SIZE_TALI;
|
||||||
|
public static uint SIZE_TALI => _SIZE_TALI;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_TALI_RARITY;
|
||||||
|
public static uint OFFSETR_TALI_RARITY => _OFFSETR_TALI_RARITY;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_TALI_NEW;
|
||||||
|
public static uint OFFSETR_TALI_NEW => _OFFSETR_TALI_NEW;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_TALI_SKILL1;
|
||||||
|
public static uint OFFSETR_TALI_SKILL1 => _OFFSETR_TALI_SKILL1;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_TALI_SKILL2;
|
||||||
|
public static uint OFFSETR_TALI_SKILL2 => _OFFSETR_TALI_SKILL2;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_TALI_ID;
|
||||||
|
public static uint OFFSETR_TALI_ID => _OFFSETR_TALI_ID;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_EQUIPPED;
|
||||||
|
public static uint OFFSETR_EQUIPPED => _OFFSETR_EQUIPPED;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Weapons
|
||||||
|
//
|
||||||
|
private static uint _OFFSETA_WEAPON_START;
|
||||||
|
public static uint OFFSETA_WEAPON_START => _OFFSETA_WEAPON_START;
|
||||||
|
|
||||||
|
private static uint _OFFSETA_WEAPON_END;
|
||||||
|
public static uint OFFSETA_WEAPON_END => _OFFSETA_WEAPON_END;
|
||||||
|
|
||||||
|
private static uint _SIZE_WEAPON;
|
||||||
|
public static uint SIZE_WEAPON => _SIZE_WEAPON;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_CLASS;
|
||||||
|
public static uint OFFSETR_CLASS => _OFFSETR_CLASS;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_ID;
|
||||||
|
public static uint OFFSETR_ID => _OFFSETR_ID;
|
||||||
|
|
||||||
|
private static uint _OFFSETR_LEVEL;
|
||||||
|
public static uint OFFSETR_LEVEL => _OFFSETR_LEVEL;
|
||||||
|
|
||||||
|
|
||||||
|
public static void init(byte[] save)
|
||||||
|
{
|
||||||
|
if (save.Length == SAVE_FILE_SIZE_JPN)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
//Armors
|
||||||
|
//
|
||||||
|
_OFFSETA_ARM = 0x55F0;
|
||||||
|
_SIZE_ARM = 0x24;
|
||||||
|
_OFFSETR_ARM_ID = 0x2;
|
||||||
|
_OFFSETR_ARM_LEVEL = 0x4;
|
||||||
|
_OFFSETR_ARM_14h = 0x14;
|
||||||
|
_OFFSETR_ARM_18h = 0x18;
|
||||||
|
_OFFSETR_ARM_1C = 0x1c;
|
||||||
|
_OFFSETA_ARM_END = 0x720E;
|
||||||
|
_OFFSETR_ARM_TYPE = 0x0;
|
||||||
|
|
||||||
|
//
|
||||||
|
//Character
|
||||||
|
//
|
||||||
|
_OFFSETA_CHAR_NAME = 0x9DA0;
|
||||||
|
_LENGTH_CHAR_NAME = 6;
|
||||||
|
_OFFSETA_CHAR_MONEY = 0x5B404;
|
||||||
|
_OFFSETA_CHAR_EXP = 0x9E68;
|
||||||
|
_OFFSETA_CHAR_LEVEL = 0x9E64;
|
||||||
|
_LIMIT_LEVEL = 99;
|
||||||
|
_LIMIT_MONEY = 9999999;
|
||||||
|
_LIMIT_EXP = 25165822;
|
||||||
|
|
||||||
|
//
|
||||||
|
//Egg
|
||||||
|
//
|
||||||
|
_OFFSETA_EGG_START = 0x53EC0;
|
||||||
|
_OFFSETA_EGG_END = 0x54597;
|
||||||
|
_OFFSETR_EGG_GENE = 0x30;
|
||||||
|
_SIZE_EGG_GENE = 0x2;
|
||||||
|
_SIZE_EGG = 0x92;
|
||||||
|
_OFFSETR_SPE = 0x0;
|
||||||
|
_OFFSETR_WGT = 0x2E;
|
||||||
|
|
||||||
|
//
|
||||||
|
//Eggfragments
|
||||||
|
//
|
||||||
|
_OFFSETA_EGG_FRAGMENTS = 0x9790;
|
||||||
|
_OFFSETA_EGG_FRAGMENTS_END = 0x9C3F;
|
||||||
|
_SIZE_EGG_FRAGMENT = 0xC;
|
||||||
|
_OFFSETR_EF_SPE = 0x0;
|
||||||
|
_OFFSETR_EF_POS = 0x1;
|
||||||
|
_OFFSETR_EF_NEW = 0x2;
|
||||||
|
_OFFSETR_EF_RAR = 0x3;
|
||||||
|
_OFFSETR_EF_COL = 0x4;
|
||||||
|
_OFFSETR_EF_DLC = 0x5;
|
||||||
|
_OFFSETR_EF_6H = 0x6;
|
||||||
|
_OFFSETR_EF_7H = 0x7;
|
||||||
|
|
||||||
|
//
|
||||||
|
//Items
|
||||||
|
//
|
||||||
|
_OFFSETA_ITEM_BOX = 0x10;
|
||||||
|
_SIZE_ITEM = 0x8;
|
||||||
|
_OFFSETR_ITEM_ID = 0x0;
|
||||||
|
_OFFSETR_ITEM_COUNT = 0x2;
|
||||||
|
_OFFSETA_ITEM_BOX_END = 0x2EE7;
|
||||||
|
_OFFSETA_FIRST_KEY_ITEM = 0x17B0;
|
||||||
|
|
||||||
|
//
|
||||||
|
//Monsters
|
||||||
|
//
|
||||||
|
_LIMIT_MONSTER_EXP = 0xFFFFFF;
|
||||||
|
_SIZE_MONSTER = 0x478;
|
||||||
|
_OFFSETA_MONSTER = 0xA150;
|
||||||
|
_OFFSETR_MONSTER_GENE = 0x424;
|
||||||
|
_SIZE_MONSTER_GENE = 0x4;
|
||||||
|
_OFFSETR_MONSTER_EXP = 0xE0;
|
||||||
|
_OFFSETR_MONSTER_HIV = 0xD8;
|
||||||
|
_OFFSETR_MONSTER_AIV = 0xD9;
|
||||||
|
_OFFSETR_MONSTER_DIV = 0xDA;
|
||||||
|
_OFFSETR_MONSTER_HPU = 0xD4;
|
||||||
|
_OFFSETR_MONSTER_APU = 0xD5;
|
||||||
|
_OFFSETR_MONSTER_DPU = 0xD6;
|
||||||
|
_OFFSETR_MONSTER_SKILL = 0x38;
|
||||||
|
_OFFSETR_MONSTER_LEVEL = 0x5C;
|
||||||
|
_LIMIT_MONSTER_LEVEL = 99;
|
||||||
|
_OFFSETR_MONSTER_NAME = 0;
|
||||||
|
_LIMIT_MONSTER_NAME = 10;
|
||||||
|
_OFFSETR_MONSTER_SPE = 0x30;
|
||||||
|
_OFFSETA_MONSTE_END = 0x4786F;
|
||||||
|
_OFFSETR_MONSTER_ATK = 0x48;
|
||||||
|
_OFFSETR_MONSTER_HP = 0x46;
|
||||||
|
_OFFSETR_MONSTER_DEF = 0x4A;
|
||||||
|
|
||||||
|
//
|
||||||
|
//Talismans
|
||||||
|
//
|
||||||
|
_OFFSETA_TALI = 0x7210;
|
||||||
|
_OFFSETA_TALI_END = 0x978F;
|
||||||
|
_SIZE_TALI = 0x30;
|
||||||
|
_OFFSETR_TALI_RARITY = 0x24;
|
||||||
|
_OFFSETR_TALI_NEW = 0x12;
|
||||||
|
_OFFSETR_TALI_SKILL1 = 0x28;
|
||||||
|
_OFFSETR_TALI_SKILL2 = 0x2A;
|
||||||
|
_OFFSETR_TALI_ID = 0x2;
|
||||||
|
_OFFSETR_EQUIPPED = 0x11;
|
||||||
|
|
||||||
|
//
|
||||||
|
//Weapons
|
||||||
|
//
|
||||||
|
_OFFSETA_WEAPON_START = 0x39D0;
|
||||||
|
_OFFSETA_WEAPON_END = 0x55EF;
|
||||||
|
_SIZE_WEAPON = 0x24;
|
||||||
|
_OFFSETR_CLASS = 0x0;
|
||||||
|
_OFFSETR_ID = 0x2;
|
||||||
|
_OFFSETR_LEVEL = 0x4;
|
||||||
|
|
||||||
|
read_item_mappings(Properties.Resources.idmap);
|
||||||
|
read_gene_mapping(Properties.Resources.gene);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Armors ok
|
||||||
|
//
|
||||||
|
_OFFSETA_ARM = 0x5694;
|
||||||
|
_SIZE_ARM = 0x24;
|
||||||
|
_OFFSETR_ARM_ID = 0x2;
|
||||||
|
_OFFSETR_ARM_LEVEL = 0x4;
|
||||||
|
_OFFSETR_ARM_14h = 0x14;
|
||||||
|
_OFFSETR_ARM_18h = 0x18;
|
||||||
|
_OFFSETR_ARM_1C = 0x1c;
|
||||||
|
_OFFSETA_ARM_END = 0x72B3;
|
||||||
|
_OFFSETR_ARM_TYPE = 0x0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Character ok
|
||||||
|
//
|
||||||
|
_OFFSETA_CHAR_NAME = 0x9E44;
|
||||||
|
_LENGTH_CHAR_NAME = 12;
|
||||||
|
_OFFSETA_CHAR_MONEY = 0x5E394;
|
||||||
|
_OFFSETA_CHAR_EXP = 0x9F14;
|
||||||
|
_OFFSETA_CHAR_LEVEL = 0x9F10;
|
||||||
|
_LIMIT_LEVEL = 99;
|
||||||
|
_LIMIT_MONEY = 9999999;
|
||||||
|
_LIMIT_EXP = 25165822;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Egg ok
|
||||||
|
//
|
||||||
|
_OFFSETA_EGG_START = 0x56E50;
|
||||||
|
_OFFSETA_EGG_END = 0x57527;
|
||||||
|
_OFFSETR_EGG_GENE = 0x30;
|
||||||
|
_SIZE_EGG_GENE = 0x2;
|
||||||
|
_SIZE_EGG = 0x92;
|
||||||
|
_OFFSETR_SPE = 0x0;
|
||||||
|
_OFFSETR_WGT = 0x2E;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Eggfragments ok
|
||||||
|
//
|
||||||
|
_OFFSETA_EGG_FRAGMENTS = 0x9834;
|
||||||
|
_OFFSETA_EGG_FRAGMENTS_END = 0x9CE3;
|
||||||
|
_SIZE_EGG_FRAGMENT = 0xC;
|
||||||
|
_OFFSETR_EF_SPE = 0x0;
|
||||||
|
_OFFSETR_EF_POS = 0x1;
|
||||||
|
_OFFSETR_EF_NEW = 0x2;
|
||||||
|
_OFFSETR_EF_RAR = 0x3;
|
||||||
|
_OFFSETR_EF_COL = 0x4;
|
||||||
|
_OFFSETR_EF_DLC = 0x5;
|
||||||
|
_OFFSETR_EF_6H = 0x6;
|
||||||
|
_OFFSETR_EF_7H = 0x7;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Items ok
|
||||||
|
//
|
||||||
|
_OFFSETA_ITEM_BOX = 0x10;
|
||||||
|
_SIZE_ITEM = 0x8;
|
||||||
|
_OFFSETR_ITEM_ID = 0x0;
|
||||||
|
_OFFSETR_ITEM_COUNT = 0x2;
|
||||||
|
_OFFSETA_ITEM_BOX_END = 0x2EE7;
|
||||||
|
_OFFSETA_FIRST_KEY_ITEM = 0x17B0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Monsters ok
|
||||||
|
//
|
||||||
|
_LIMIT_MONSTER_EXP = 0xFFFFFF;
|
||||||
|
_SIZE_MONSTER = 0x4A0;
|
||||||
|
_OFFSETA_MONSTER = 0xA1FC;
|
||||||
|
_LIMIT_MONSTER_LEVEL = 99;
|
||||||
|
_OFFSETR_MONSTER_NAME = 0;
|
||||||
|
_LIMIT_MONSTER_NAME = 20;
|
||||||
|
_OFFSETA_MONSTE_END = 0x49B7B;
|
||||||
|
_SIZE_MONSTER_GENE = 0x4;
|
||||||
|
|
||||||
|
_OFFSETR_MONSTER_GENE = 0x424 + 0x28;
|
||||||
|
_OFFSETR_MONSTER_EXP = 0xE0 + 0x28;
|
||||||
|
_OFFSETR_MONSTER_HIV = 0xD8 + 0x28;
|
||||||
|
_OFFSETR_MONSTER_AIV = 0xD9 + 0x28;
|
||||||
|
_OFFSETR_MONSTER_DIV = 0xDA + 0x28;
|
||||||
|
_OFFSETR_MONSTER_HPU = 0xD4 + 0x28;
|
||||||
|
_OFFSETR_MONSTER_APU = 0xD5 + 0x28;
|
||||||
|
_OFFSETR_MONSTER_DPU = 0xD6 + 0x28;
|
||||||
|
_OFFSETR_MONSTER_SKILL = 0x38 + 0x28;
|
||||||
|
_OFFSETR_MONSTER_LEVEL = 0x5C + 0x28;
|
||||||
|
_OFFSETR_MONSTER_SPE = 0x30 + 0x28;
|
||||||
|
_OFFSETR_MONSTER_ATK = 0x48 + 0x28;
|
||||||
|
_OFFSETR_MONSTER_HP = 0x46 + 0x28;
|
||||||
|
_OFFSETR_MONSTER_DEF = 0x4A + 0x28;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Talismans ok
|
||||||
|
//
|
||||||
|
_OFFSETA_TALI = 0x72B4;
|
||||||
|
_OFFSETA_TALI_END = 0x9833;
|
||||||
|
_SIZE_TALI = 0x30;
|
||||||
|
_OFFSETR_TALI_RARITY = 0x24;
|
||||||
|
_OFFSETR_TALI_NEW = 0x12;
|
||||||
|
_OFFSETR_TALI_SKILL1 = 0x28;
|
||||||
|
_OFFSETR_TALI_SKILL2 = 0x2A;
|
||||||
|
_OFFSETR_TALI_ID = 0x2;
|
||||||
|
_OFFSETR_EQUIPPED = 0x11;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Weapons ok
|
||||||
|
//
|
||||||
|
_OFFSETA_WEAPON_START = 0x3A74;
|
||||||
|
_OFFSETA_WEAPON_END = 0x5693;
|
||||||
|
_SIZE_WEAPON = 0x24;
|
||||||
|
_OFFSETR_CLASS = 0x0;
|
||||||
|
_OFFSETR_ID = 0x2;
|
||||||
|
_OFFSETR_LEVEL = 0x4;
|
||||||
|
|
||||||
|
read_item_mappings(Properties.Resources.idmap);
|
||||||
|
read_gene_mapping(Properties.Resources.gene);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void read_item_mappings(string src)
|
||||||
|
{
|
||||||
|
_OFFSET_ID_MAPPING = new Dictionary<uint, uint>();
|
||||||
|
_OFFSET_NAME_MAPPING = new Dictionary<uint, string>();
|
||||||
|
|
||||||
|
string line;
|
||||||
|
StringReader file = new StringReader(src);
|
||||||
|
|
||||||
|
while ((line = file.ReadLine()) != null)
|
||||||
|
{
|
||||||
|
if (line.Length == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
string[] eachline = line.Split('\t');
|
||||||
|
if (eachline.Length != 3)
|
||||||
|
{
|
||||||
|
|
||||||
|
BugCheck.bug_check(BugCheck.ErrorCode.ITEM_MAPPING_CORRUPTED, "Invalid mapping file line:\n" + line);
|
||||||
|
}
|
||||||
|
|
||||||
|
_OFFSET_ID_MAPPING.Add(uint.Parse(eachline[0], System.Globalization.NumberStyles.HexNumber), uint.Parse(eachline[1], System.Globalization.NumberStyles.HexNumber));
|
||||||
|
_OFFSET_NAME_MAPPING.Add(uint.Parse(eachline[0], System.Globalization.NumberStyles.HexNumber), eachline[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
file.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void read_gene_mapping(string src)
|
||||||
|
{
|
||||||
|
_GENE_NAME = new List<string>();
|
||||||
|
_GENE_ID = new List<uint>();
|
||||||
|
|
||||||
|
string line;
|
||||||
|
StringReader file = new StringReader(src);
|
||||||
|
|
||||||
|
while ((line = file.ReadLine()) != null)
|
||||||
|
{
|
||||||
|
if (line.Length == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
string[] eachline = line.Split('\t');
|
||||||
|
if (eachline.Length != 2)
|
||||||
|
{
|
||||||
|
BugCheck.bug_check(BugCheck.ErrorCode.MON_GENE_MAPPING_CORRUPTED,
|
||||||
|
"Invalid gene mapping file line:\n" + line);
|
||||||
|
}
|
||||||
|
|
||||||
|
_GENE_ID.Add(uint.Parse(eachline[0], System.Globalization.NumberStyles.HexNumber));
|
||||||
|
_GENE_NAME.Add(eachline[1]);
|
||||||
|
}
|
||||||
|
_GENE_NAME.Add("Custom");
|
||||||
|
|
||||||
|
file.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -51,5 +51,5 @@ using System.Windows;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.0.0.0")]
|
[assembly: AssemblyVersion("1.1.0.0")]
|
||||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
[assembly: AssemblyFileVersion("1.1.0.0")]
|
||||||
|
Binary file not shown.
@ -6,43 +6,24 @@ using MHSEC_G.Annotations;
|
|||||||
|
|
||||||
namespace MHSEC_G
|
namespace MHSEC_G
|
||||||
{
|
{
|
||||||
public class Talisman
|
public class Talisman : InMemoryObject
|
||||||
{
|
{
|
||||||
private const uint OFFSETA_TALI = 0x7210;
|
public uint index => (_obj_offset - Offsets.OFFSETA_TALI) / Offsets.SIZE_TALI + 1;
|
||||||
private const uint OFFSETA_TALI_END = 0x978F;
|
|
||||||
private const uint SIZE_TALI = 0x30;
|
|
||||||
private const uint OFFSETR_TALI_RARITY = 0x24;
|
|
||||||
private const uint OFFSETR_TALI_NEW = 0x12;
|
|
||||||
private const uint OFFSETR_TALI_SKILL1 = 0x28;
|
|
||||||
private const uint OFFSETR_TALI_SKILL2 = 0x2A;
|
|
||||||
private const uint OFFSETR_TALI_ID = 0x2;
|
|
||||||
private const uint OFFSETR_EQUIPPED = 0x11;
|
|
||||||
|
|
||||||
private readonly uint _offset;
|
public Talisman(byte[] model, uint objOffset) : base(model, objOffset, Offsets.SIZE_TALI)
|
||||||
public uint index => (_offset - OFFSETA_TALI) / SIZE_TALI + 1;
|
|
||||||
|
|
||||||
public uint offset
|
|
||||||
{
|
{
|
||||||
get { return _offset; }
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly Model _model;
|
|
||||||
|
|
||||||
public Talisman(uint offset, Model model)
|
|
||||||
{
|
|
||||||
_model = model;
|
|
||||||
_offset = offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string rarity
|
public string rarity
|
||||||
{
|
{
|
||||||
get { return Model.byte_to_uint(_model.save_file[_offset + OFFSETR_TALI_RARITY]).ToString("X2"); }
|
get { return Helper.byte_to_uint(_data[_obj_offset + Offsets.OFFSETR_TALI_RARITY]).ToString("X2"); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFF)
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0xFF)
|
||||||
{
|
{
|
||||||
Model.write_byte(_model.save_file, _offset + OFFSETR_TALI_RARITY, parsed);
|
Helper.write_byte(_data, _obj_offset + Offsets.OFFSETR_TALI_RARITY, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -54,13 +35,13 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public string id
|
public string id
|
||||||
{
|
{
|
||||||
get { return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_TALI_ID).ToString("X4"); }
|
get { return Helper.byte_to_uint16_le(_data, _obj_offset + Offsets.OFFSETR_TALI_ID).ToString("X4"); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
||||||
{
|
{
|
||||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_TALI_ID, parsed);
|
Helper.write_uint16_le(_data, _obj_offset + Offsets.OFFSETR_TALI_ID, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -72,13 +53,13 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public string new_flag
|
public string new_flag
|
||||||
{
|
{
|
||||||
get { return Model.byte_to_uint(_model.save_file[_offset + OFFSETR_TALI_NEW]).ToString("X2"); }
|
get { return Helper.byte_to_uint(_data[_obj_offset + Offsets.OFFSETR_TALI_NEW]).ToString("X2"); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0x1)
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0x1)
|
||||||
{
|
{
|
||||||
Model.write_byte(_model.save_file, _offset + OFFSETR_TALI_NEW, parsed);
|
Helper.write_byte(_data, _obj_offset + Offsets.OFFSETR_TALI_NEW, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -89,13 +70,13 @@ namespace MHSEC_G
|
|||||||
}
|
}
|
||||||
public string skill1
|
public string skill1
|
||||||
{
|
{
|
||||||
get { return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_TALI_SKILL1).ToString("X4"); }
|
get { return Helper.byte_to_uint16_le(_data, _obj_offset + Offsets.OFFSETR_TALI_SKILL1).ToString("X4"); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
||||||
{
|
{
|
||||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_TALI_SKILL1, parsed);
|
Helper.write_uint16_le(_data, _obj_offset + Offsets.OFFSETR_TALI_SKILL1, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -107,13 +88,13 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public string skill2
|
public string skill2
|
||||||
{
|
{
|
||||||
get { return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_TALI_SKILL2).ToString("X4"); }
|
get { return Helper.byte_to_uint16_le(_data, _obj_offset + Offsets.OFFSETR_TALI_SKILL2).ToString("X4"); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
||||||
{
|
{
|
||||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_TALI_SKILL2, parsed);
|
Helper.write_uint16_le(_data, _obj_offset + Offsets.OFFSETR_TALI_SKILL2, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -125,13 +106,13 @@ namespace MHSEC_G
|
|||||||
|
|
||||||
public string equipped
|
public string equipped
|
||||||
{
|
{
|
||||||
get { return Model.byte_to_uint(_model.save_file[_offset + OFFSETR_EQUIPPED]).ToString("X2"); }
|
get { return Helper.byte_to_uint(_data[_obj_offset + Offsets.OFFSETR_EQUIPPED]).ToString("X2"); }
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFF)
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0xFF)
|
||||||
{
|
{
|
||||||
Model.write_byte(_model.save_file, _offset + OFFSETR_EQUIPPED, parsed);
|
Helper.write_byte(_data, _obj_offset + Offsets.OFFSETR_EQUIPPED, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -141,23 +122,15 @@ namespace MHSEC_G
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ObservableCollection<Talisman> read_all_talismans(Model model)
|
public static ObservableCollection<Talisman> read_all_talismans(byte[] model)
|
||||||
{
|
{
|
||||||
ObservableCollection<Talisman> ret = new ObservableCollection<Talisman>();
|
ObservableCollection<Talisman> ret = new ObservableCollection<Talisman>();
|
||||||
for (uint offset = OFFSETA_TALI; offset < OFFSETA_TALI_END; offset += SIZE_TALI)
|
for (uint offset = Offsets.OFFSETA_TALI; offset < Offsets.OFFSETA_TALI_END; offset += Offsets.SIZE_TALI)
|
||||||
{
|
{
|
||||||
ret.Add(new Talisman(offset, model));
|
ret.Add(new Talisman(model, offset));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
|
||||||
|
|
||||||
[NotifyPropertyChangedInvocator]
|
|
||||||
protected virtual void OnPropertyChanged(string propertyName)
|
|
||||||
{
|
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,25 +6,12 @@ using MHSEC_G.Annotations;
|
|||||||
|
|
||||||
namespace MHSEC_G
|
namespace MHSEC_G
|
||||||
{
|
{
|
||||||
public class Weapon : INotifyPropertyChanged
|
public class Weapon : InMemoryObject
|
||||||
{
|
{
|
||||||
private const int OFFSETA_WEAPON_START = 0x39D0;
|
public uint index => (_obj_offset - Offsets.OFFSETA_WEAPON_START) / Offsets.SIZE_WEAPON + 1;
|
||||||
private const int OFFSETA_WEAPON_END = 0x55EF;
|
|
||||||
// 200 weapons
|
|
||||||
private const int SIZE_WEAPON = 0x24;
|
|
||||||
|
|
||||||
private const int OFFSETR_CLASS = 0x0;
|
public Weapon(byte[] model, uint objOffset) : base(model, objOffset, Offsets.SIZE_WEAPON)
|
||||||
private const int OFFSETR_ID = 0x2;
|
|
||||||
private const int OFFSETR_LEVEL = 0x4;
|
|
||||||
|
|
||||||
private readonly uint _offset;
|
|
||||||
private readonly Model _model;
|
|
||||||
public uint index => (_offset - OFFSETA_WEAPON_START) / SIZE_WEAPON + 1;
|
|
||||||
|
|
||||||
public Weapon(Model model, uint offset)
|
|
||||||
{
|
{
|
||||||
_offset = offset;
|
|
||||||
_model = model;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string clazz
|
public string clazz
|
||||||
@ -32,9 +19,9 @@ namespace MHSEC_G
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
||||||
{
|
{
|
||||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_CLASS, parsed);
|
Helper.write_uint16_le(_data, _obj_offset + Offsets.OFFSETR_CLASS, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -44,7 +31,7 @@ namespace MHSEC_G
|
|||||||
}
|
}
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_CLASS).ToString("X4");
|
return Helper.byte_to_uint16_le(_data, _obj_offset + Offsets.OFFSETR_CLASS).ToString("X4");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,9 +40,9 @@ namespace MHSEC_G
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
||||||
{
|
{
|
||||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_ID, parsed);
|
Helper.write_uint16_le(_data, _obj_offset + Offsets.OFFSETR_ID, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -65,7 +52,7 @@ namespace MHSEC_G
|
|||||||
}
|
}
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_ID).ToString("X4");
|
return Helper.byte_to_uint16_le(_data, _obj_offset + Offsets.OFFSETR_ID).ToString("X4");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,9 +62,9 @@ namespace MHSEC_G
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
uint parsed;
|
uint parsed;
|
||||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
if (Helper.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
||||||
{
|
{
|
||||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_LEVEL, parsed);
|
Helper.write_uint16_le(_data, _obj_offset + Offsets.OFFSETR_LEVEL, parsed);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -87,26 +74,18 @@ namespace MHSEC_G
|
|||||||
}
|
}
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_LEVEL).ToString("X4");
|
return Helper.byte_to_uint16_le(_data, _obj_offset + Offsets.OFFSETR_LEVEL).ToString("X4");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ObservableCollection<Weapon> read_all_weapons(Model model)
|
public static ObservableCollection<Weapon> read_all_weapons(byte[] model)
|
||||||
{
|
{
|
||||||
ObservableCollection<Weapon> ret = new ObservableCollection<Weapon>();
|
ObservableCollection<Weapon> ret = new ObservableCollection<Weapon>();
|
||||||
for (uint i = OFFSETA_WEAPON_START; i < OFFSETA_WEAPON_END; i += SIZE_WEAPON)
|
for (uint i = Offsets.OFFSETA_WEAPON_START; i < Offsets.OFFSETA_WEAPON_END; i += Offsets.SIZE_WEAPON)
|
||||||
{
|
{
|
||||||
ret.Add(new Weapon(model, i));
|
ret.Add(new Weapon(model, i));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
|
||||||
|
|
||||||
[NotifyPropertyChangedInvocator]
|
|
||||||
protected virtual void OnPropertyChanged(string propertyName)
|
|
||||||
{
|
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user