Finished saving + editing - Monsters/Items/characters/
Will add Egg fragments and then release.
This commit is contained in:
parent
7ae1cde029
commit
f0cecf442d
@ -10,15 +10,5 @@ namespace MHSEC_G
|
||||
{
|
||||
public partial class App : Application
|
||||
{
|
||||
private Model model;
|
||||
public Model get_model()
|
||||
{
|
||||
return model;
|
||||
}
|
||||
|
||||
public void set_model(Model model)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using MHSEC_G.Annotations;
|
||||
|
||||
namespace MHSEC_G
|
||||
@ -6,46 +7,88 @@ namespace MHSEC_G
|
||||
public class Character : INotifyPropertyChanged
|
||||
{
|
||||
private const uint OFFSETA_CHAR_NAME = 0x9DA0;
|
||||
private const uint LENGTH_CHAR_NAME = 6;
|
||||
private const uint LENGTH_CHAR_NAME = 5;
|
||||
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 uint _char_level;
|
||||
public uint char_level
|
||||
private readonly Model _model;
|
||||
|
||||
public uint level
|
||||
{
|
||||
get { return _char_level; }
|
||||
set { _char_level = value; OnPropertyChanged(nameof(char_level)); }
|
||||
get { return Model.byte_to_uint(_model.save_file[OFFSETA_CHAR_LEVEL]); }
|
||||
set
|
||||
{
|
||||
if (value <= LIMIT_LEVEL)
|
||||
{
|
||||
Model.write_byte(_model.save_file, OFFSETA_CHAR_LEVEL, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Level must be less than " + LIMIT_LEVEL, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(level));
|
||||
}
|
||||
}
|
||||
|
||||
private uint _char_exp;
|
||||
public uint char_exp
|
||||
public uint exp
|
||||
{
|
||||
get { return _char_exp; }
|
||||
set { _char_exp = value; OnPropertyChanged(nameof(char_exp)); }
|
||||
get { return Model.byte_to_uint32_le(_model.save_file, OFFSETA_CHAR_EXP); }
|
||||
set
|
||||
{
|
||||
if (value <= LIMIT_EXP)
|
||||
{
|
||||
Model.write_uint32_le(_model.save_file, OFFSETA_CHAR_EXP, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Exp must be less than " + LIMIT_EXP, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(exp));
|
||||
}
|
||||
}
|
||||
|
||||
private uint _char_money;
|
||||
public uint char_money
|
||||
public uint money
|
||||
{
|
||||
get { return _char_money; }
|
||||
set { _char_money = value; OnPropertyChanged(nameof(char_money)); }
|
||||
get { return Model.byte_to_uint32_le(_model.save_file, OFFSETA_CHAR_MONEY); }
|
||||
set
|
||||
{
|
||||
if (value <= LIMIT_MONEY)
|
||||
{
|
||||
Model.write_uint32_le(_model.save_file, OFFSETA_CHAR_MONEY, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Money must be less than " + LIMIT_MONEY, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(money));
|
||||
}
|
||||
}
|
||||
|
||||
private string _char_name;
|
||||
public string char_name
|
||||
public string name
|
||||
{
|
||||
get { return _char_name; }
|
||||
set { _char_name = value; OnPropertyChanged(nameof(char_name)); }
|
||||
get { return Model.read_unicode_string(_model.save_file, OFFSETA_CHAR_NAME, LENGTH_CHAR_NAME); }
|
||||
set
|
||||
{
|
||||
if (value.Length <= LENGTH_CHAR_NAME && value.Length > 0)
|
||||
{
|
||||
Model.write_unicode_string(_model.save_file, OFFSETA_CHAR_NAME, value, LENGTH_CHAR_NAME);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Name must be 1-6 characters.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(name));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Character(byte[] save_data)
|
||||
public Character(Model model)
|
||||
{
|
||||
_char_level = Model.byte_to_uint(save_data[OFFSETA_CHAR_LEVEL]);
|
||||
_char_exp = Model.byte_to_uint32_le(save_data, OFFSETA_CHAR_EXP);
|
||||
_char_money = Model.byte_to_uint32_le(save_data, OFFSETA_CHAR_MONEY);
|
||||
_char_name = Model.read_unicode_string(save_data, OFFSETA_CHAR_NAME, LENGTH_CHAR_NAME);
|
||||
_model = model;
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
@ -1,11 +1,132 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using MHSEC_G.Annotations;
|
||||
|
||||
namespace MHSEC_G
|
||||
{
|
||||
class Item
|
||||
public class Item : INotifyPropertyChanged
|
||||
{
|
||||
private static readonly uint OFFSETA_ITEM_BOX = 0x10;
|
||||
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;
|
||||
|
||||
private static readonly string ID_MAPPING_FILE_NAME = "C:\\Users\\hyper\\Desktop\\idmap.txt";
|
||||
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;
|
||||
private readonly Model _model;
|
||||
|
||||
public string name
|
||||
{
|
||||
get {
|
||||
string name = "Unknown";
|
||||
if (OFFSET_NAME_MAPPING.ContainsKey(_offset))
|
||||
{
|
||||
name = OFFSET_NAME_MAPPING[_offset];
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public uint count
|
||||
{
|
||||
get { return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_ITEM_COUNT); }
|
||||
set
|
||||
{
|
||||
if (value <= 999)
|
||||
{
|
||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_ITEM_COUNT, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Quantity must be less than 999.","Error",MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(count));
|
||||
}
|
||||
}
|
||||
|
||||
public uint id
|
||||
{
|
||||
get { return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_ITEM_ID); }
|
||||
}
|
||||
|
||||
public Item(uint offset, Model model)
|
||||
{
|
||||
_offset = offset;
|
||||
_model = model;
|
||||
}
|
||||
|
||||
public static List<Item> read_all_items(Model model)
|
||||
{
|
||||
byte[] buffer = model.save_file;
|
||||
List<Item> ret = new List<Item>();
|
||||
for (uint offset = OFFSETA_ITEM_BOX; offset < OFFSETA_ITEM_BOX_END; offset += SIZE_ITEM)
|
||||
{
|
||||
string name = "Unknown";
|
||||
uint item_id = Model.byte_to_uint16_le(buffer, offset + OFFSETR_ITEM_ID);
|
||||
|
||||
if (item_id == 0)
|
||||
{
|
||||
// if not obtained yet
|
||||
if (!OFFSET_ID_MAPPING.ContainsKey(offset))
|
||||
{
|
||||
// well we dont know the id to this offset either. just ignore!
|
||||
// continue
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// already obtained
|
||||
// validate
|
||||
if (OFFSET_ID_MAPPING.ContainsKey(offset))
|
||||
{
|
||||
if (item_id != OFFSET_ID_MAPPING[offset])
|
||||
{
|
||||
throw new SystemException("Item offset and ID do not correspond.");
|
||||
}
|
||||
}
|
||||
}
|
||||
// valid offset
|
||||
ret.Add(new Item(offset, model));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void read_item_mappings()
|
||||
{
|
||||
string line;
|
||||
System.IO.StreamReader file = new System.IO.StreamReader(ID_MAPPING_FILE_NAME);
|
||||
while ((line = file.ReadLine()) != null)
|
||||
{
|
||||
if (line.Length == 0)
|
||||
continue;
|
||||
|
||||
string[] eachline = line.Split('\t');
|
||||
if (eachline.Length != 3)
|
||||
throw new SystemException("Item mapping file is corrupted.");
|
||||
|
||||
OFFSET_ID_MAPPING.Add(UInt32.Parse(eachline[0], System.Globalization.NumberStyles.HexNumber), UInt32.Parse(eachline[1], System.Globalization.NumberStyles.HexNumber));
|
||||
OFFSET_NAME_MAPPING.Add(UInt32.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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -98,6 +98,9 @@
|
||||
</None>
|
||||
<AppDesigner Include="Properties\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="idmap.txt" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
@ -15,25 +15,91 @@
|
||||
<Label x:Name="label_money" Content="Money" HorizontalAlignment="Left" Margin="10,40,0,0" VerticalAlignment="Top"/>
|
||||
<Label x:Name="label_leve" Content="Level" HorizontalAlignment="Left" Margin="10,70,0,0" VerticalAlignment="Top"/>
|
||||
<Label x:Name="label_exp" Content="Exp" HorizontalAlignment="Left" Margin="10,100,0,0" VerticalAlignment="Top"/>
|
||||
<TextBox x:Name="textbox_name" HorizontalAlignment="Left" Height="22" Margin="61,14,0,0" TextWrapping="NoWrap" VerticalAlignment="Top" Width="120" Text="{Binding model.character.char_name}"/>
|
||||
<TextBox x:Name="textbox_money" HorizontalAlignment="Left" Height="22" Margin="61,44,0,0" TextWrapping="NoWrap" VerticalAlignment="Top" Width="120" Text="{Binding model.character.char_money}"/>
|
||||
<TextBox x:Name="textbox_level" HorizontalAlignment="Left" Height="22" Margin="61,74,0,0" TextWrapping="NoWrap" VerticalAlignment="Top" Width="120" Text="{Binding model.character.char_level}"/>
|
||||
<TextBox x:Name="textbox_exp" HorizontalAlignment="Left" Height="22" Margin="61,104,0,0" TextWrapping="NoWrap" VerticalAlignment="Top" Width="120" Text="{Binding model.character.char_exp}"/>
|
||||
<TextBox x:Name="textbox_name" HorizontalAlignment="Left" Height="22" Margin="61,14,0,0" TextWrapping="NoWrap" VerticalAlignment="Top" Width="120" Text="{Binding character.name}"/>
|
||||
<TextBox x:Name="textbox_money" HorizontalAlignment="Left" Height="22" Margin="61,44,0,0" TextWrapping="NoWrap" VerticalAlignment="Top" Width="120" Text="{Binding character.money}"/>
|
||||
<TextBox x:Name="textbox_level" HorizontalAlignment="Left" Height="22" Margin="61,74,0,0" TextWrapping="NoWrap" VerticalAlignment="Top" Width="120" Text="{Binding character.level}"/>
|
||||
<TextBox x:Name="textbox_exp" HorizontalAlignment="Left" Height="22" Margin="61,104,0,0" TextWrapping="NoWrap" VerticalAlignment="Top" Width="120" Text="{Binding character.exp}"/>
|
||||
<Button x:Name="button_char_money" Content="Max Money" HorizontalAlignment="Left" Margin="200,44,0,0" VerticalAlignment="Top" Width="88" RenderTransformOrigin="0.065,-0.953" Height="22" Click="button_char_money_Click"/>
|
||||
<Button x:Name="button_char_exp" Content="Max Exp" HorizontalAlignment="Left" Margin="200,104,0,0" VerticalAlignment="Top" Width="88" RenderTransformOrigin="0.065,-0.953" Height="22" Click="button_char_exp_Click"/>
|
||||
|
||||
</Grid>
|
||||
</TabItem>
|
||||
<TabItem Header="Monsters">
|
||||
<Grid Background="#FFE5E5E5"/>
|
||||
</TabItem>
|
||||
<TabItem Header="Egg Fragments">
|
||||
<Grid Background="#FFE5E5E5"/>
|
||||
</TabItem>
|
||||
<TabItem Header="Items">
|
||||
<Grid Background="#FFE5E5E5" Margin="0,0,0,0">
|
||||
<Button x:Name="button1" Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="100,10,0,0"/>
|
||||
<DataGrid x:Name="item_table" ItemsSource="{Binding items}" HorizontalAlignment="Left" Margin="10,30,0,0" VerticalAlignment="Top" Height="276" Width="550" CanUserAddRows="False" AutoGenerateColumns="False" >
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn CanUserReorder ="False" CanUserResize="False" CanUserSort="False" Width ="100" Foreground="Gray" IsReadOnly="True" Binding="{Binding id}"
|
||||
Header="ID" />
|
||||
<DataGridTextColumn CanUserReorder ="False" CanUserResize="False" CanUserSort="False" Width ="100" Foreground="Gray" IsReadOnly="True" Binding="{Binding name}"
|
||||
Header="Name" />
|
||||
<DataGridTextColumn CanUserReorder ="False" CanUserResize="False" CanUserSort="False" Width ="*" Binding="{Binding count, Mode=TwoWay}"
|
||||
Header="Count" />
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<Button x:Name="button_item_all" Content="All 986x" HorizontalAlignment="Left" Margin="586,30,0,0" VerticalAlignment="Top" Width="108" RenderTransformOrigin="0.065,-0.953" Height="45" Click="button_item_all_Click"/>
|
||||
<Button x:Name="button_item_existing" Content="Existing 999x" HorizontalAlignment="Left" Margin="586,94,0,0" VerticalAlignment="Top" Width="108" RenderTransformOrigin="0.065,-0.953" Height="45" Click="button_item_existing_Click"/>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
<TabItem Header="Monsters" Margin="0,0,0,0">
|
||||
<Grid Background="#FFE5E5E5">
|
||||
<Label x:Name="label_mhp" Content="HP" HorizontalAlignment="Left" Margin="10,85,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.564,2.072"/>
|
||||
<Label x:Name="label_mat" Content="Atk" HorizontalAlignment="Left" Margin="10,115,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.564,2.072"/>
|
||||
<Label x:Name="label_mdf" Content="Def" HorizontalAlignment="Left" Margin="10,145,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.564,2.072"/>
|
||||
<Label x:Name="label_mhiv" Content="IV-HP" HorizontalAlignment="Left" Margin="10,175,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.564,2.072"/>
|
||||
<Label x:Name="label_mdiv" Content="IV-Atk" HorizontalAlignment="Left" Margin="10,205,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.564,2.072"/>
|
||||
<Label x:Name="label_maiv" Content="IV-Def" HorizontalAlignment="Left" Margin="10,235,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.564,2.072"/>
|
||||
<Label x:Name="label_mhpu" Content="PowerUp-HP" HorizontalAlignment="Left" Margin="150,175,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.564,2.072"/>
|
||||
<Label x:Name="label_mapu" Content="PowerUp-Atk" HorizontalAlignment="Left" Margin="150,205,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.564,2.072"/>
|
||||
<Label x:Name="label_mdpu" Content="PowerUp-Def" HorizontalAlignment="Left" Margin="150,235,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.564,2.072"/>
|
||||
<Label x:Name="label_mgen1" Content="Gene1 (Hex)" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="385,85,0,0"/>
|
||||
<Label x:Name="label_mgen2" Content="Gene2 (Hex)" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="505,85,0,0"/>
|
||||
<Label x:Name="label_mgen3" Content="Gene3 (Hex)" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="625,85,0,0" RenderTransformOrigin="0.537,0.19"/>
|
||||
<Label x:Name="label_mgen4" Content="Gene4 (Hex)" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="385,155,0,0"/>
|
||||
<Label x:Name="label_mgen5" Content="Gene5 (Hex)" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="505,155,0,0" RenderTransformOrigin="0.524,0.439"/>
|
||||
<Label x:Name="label_mgen6" Content="Gene6 (Hex)" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="625,155,0,0"/>
|
||||
<Label x:Name="label_mgen7" Content="Gene7 (Hex)" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="385,225,0,0"/>
|
||||
<Label x:Name="label_mgen8" Content="Gene8 (Hex)" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="505,225,0,0"/>
|
||||
<Label x:Name="label_mgen9" Content="Gene9 (Hex)" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="625,225,0,0"/>
|
||||
<TextBox x:Name="textbox_mhp" HorizontalAlignment="Left" Height="23" Margin="60,87,0,0" TextWrapping="Wrap" Text="{Binding Path=cur_monster.hp}" VerticalAlignment="Top" Width="75"/>
|
||||
<TextBox x:Name="textbox_mat" HorizontalAlignment="Left" Height="23" Margin="60,117,0,0" TextWrapping="Wrap" Text="{Binding Path=cur_monster.atk}" VerticalAlignment="Top" Width="75"/>
|
||||
<TextBox x:Name="textbox_mdf" HorizontalAlignment="Left" Height="23" Margin="60,147,0,0" TextWrapping="Wrap" Text="{Binding Path=cur_monster.def}" VerticalAlignment="Top" Width="75"/>
|
||||
<TextBox x:Name="textbox_mhiv" HorizontalAlignment="Left" Height="23" Margin="60,177,0,0" TextWrapping="Wrap" Text="{Binding Path=cur_monster.hiv}" VerticalAlignment="Top" Width="75"/>
|
||||
<TextBox x:Name="textbox_maiv" HorizontalAlignment="Left" Height="23" Margin="60,207,0,0" TextWrapping="Wrap" Text="{Binding Path=cur_monster.aiv}" VerticalAlignment="Top" Width="75"/>
|
||||
<TextBox x:Name="textbox_mdiv" HorizontalAlignment="Left" Height="23" Margin="60,237,0,0" TextWrapping="Wrap" Text="{Binding Path=cur_monster.div}" VerticalAlignment="Top" Width="75"/>
|
||||
<TextBox x:Name="textbox_mhpu" HorizontalAlignment="Left" Height="23" Margin="240,177,0,0" TextWrapping="Wrap" Text="{Binding Path=cur_monster.hpu}" VerticalAlignment="Top" Width="75"/>
|
||||
<TextBox x:Name="textbox_mapu" HorizontalAlignment="Left" Height="23" Margin="240,207,0,0" TextWrapping="Wrap" Text="{Binding Path=cur_monster.apu}" VerticalAlignment="Top" Width="75"/>
|
||||
<TextBox x:Name="textbox_mdpu" HorizontalAlignment="Left" Height="23" Margin="240,237,0,0" TextWrapping="Wrap" Text="{Binding Path=cur_monster.dpu}" VerticalAlignment="Top" Width="75"/>
|
||||
<TextBox x:Name="textbox_gene1" HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="{Binding Path=cur_monster.gene1}" VerticalAlignment="Top" Width="80" Margin="385,120,0,0"/>
|
||||
<TextBox x:Name="textbox_gene2" HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="{Binding Path=cur_monster.gene2}" VerticalAlignment="Top" Width="80" Margin="505,120,0,0"/>
|
||||
<TextBox x:Name="textbox_gene3" HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="{Binding Path=cur_monster.gene3}" VerticalAlignment="Top" Width="80" Margin="625,120,0,0"/>
|
||||
<TextBox x:Name="textbox_gene4" HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="{Binding Path=cur_monster.gene4}" VerticalAlignment="Top" Width="80" Margin="385,190,0,0"/>
|
||||
<TextBox x:Name="textbox_gene5" HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="{Binding Path=cur_monster.gene5}" VerticalAlignment="Top" Width="80" Margin="505,190,0,0"/>
|
||||
<TextBox x:Name="textbox_gene6" HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="{Binding Path=cur_monster.gene6}" VerticalAlignment="Top" Width="80" Margin="625,190,0,0"/>
|
||||
<TextBox x:Name="textbox_gene7" HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="{Binding Path=cur_monster.gene7}" VerticalAlignment="Top" Width="80" Margin="385,260,0,0"/>
|
||||
<TextBox x:Name="textbox_gene8" HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="{Binding Path=cur_monster.gene8}" VerticalAlignment="Top" Width="80" Margin="505,260,0,0"/>
|
||||
<TextBox x:Name="textbox_gene9" HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="{Binding Path=cur_monster.gene9}" VerticalAlignment="Top" Width="80" Margin="625,260,0,0"/>
|
||||
<Label x:Name="label_mlv" Content="Level" HorizontalAlignment="Left" Margin="150,85,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.263,0.135"/>
|
||||
<Label x:Name="label_mex" Content="Exp" HorizontalAlignment="Left" Margin="150,115,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.263,0.135"/>
|
||||
<Label x:Name="label_spe" Content="Species (Hex)" HorizontalAlignment="Left" Margin="150,145,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.263,0.135"/>
|
||||
<TextBox x:Name="textbox_mlv" HorizontalAlignment="Left" Height="24" Margin="240,87,0,0" TextWrapping="Wrap" Text="{Binding Path=cur_monster.level}" VerticalAlignment="Top" Width="75"/>
|
||||
<TextBox x:Name="textbox_mex" HorizontalAlignment="Left" Height="24" Margin="240,117,0,0" TextWrapping="Wrap" Text="{Binding Path=cur_monster.exp}" VerticalAlignment="Top" Width="75"/>
|
||||
<TextBox x:Name="textbox_spe" HorizontalAlignment="Left" Height="24" Margin="240,147,0,0" TextWrapping="Wrap" Text="{Binding Path=cur_monster.spe}" VerticalAlignment="Top" Width="75"/>
|
||||
<Label x:Name="label_mname" Content="Name" HorizontalAlignment="Left" Margin="10,54,0,0" VerticalAlignment="Top"/>
|
||||
<TextBox x:Name="textbox_mname" HorizontalAlignment="Left" Height="22" Margin="60,58,0,0" TextWrapping="Wrap" Text="{Binding Path=cur_monster.name}" VerticalAlignment="Top" Width="255"/>
|
||||
<Label x:Name="label_slct" Content="Monster" HorizontalAlignment="Left" Margin="2,10,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.466,0.596"/>
|
||||
<ComboBox x:Name="combobox_slct" HorizontalAlignment="Left" Margin="60,10,0,0" VerticalAlignment="Top" Width="255" ItemsSource="{Binding Path=monsters}" DisplayMemberPath="full_name" IsReadOnly="True" SelectedValue="{Binding Path=cur_monster}"/>
|
||||
<Label x:Name="label_m_warn" Content="Warning: The sum of PowerUps should be at most 10." HorizontalAlignment="Left" Margin="12,265,0,0" VerticalAlignment="Top"/>
|
||||
<Label x:Name="label_m_warn2" Content="The exact IV algorithm is unknown. Edit wisely." HorizontalAlignment="Left" Margin="62,285,0,0" VerticalAlignment="Top"/>
|
||||
<TextBlock x:Name="textblock_gene101" HorizontalAlignment="Left" Margin="385,16,0,0" TextWrapping="Wrap" Text="MHST Gene 101:
0x0001 = Empty Slot
0x0002 = No Slot
For other genes codes, refer to the gene code mapping." VerticalAlignment="Top"/>
|
||||
<Button x:Name="button_mexp" Content="Max" HorizontalAlignment="Left" Margin="193,119,0,0" VerticalAlignment="Top" Width="35" Click="button_mexp_Click"/>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
<Button x:Name="button_save" Content="Save" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="74"/>
|
||||
<Button x:Name="button_save" Content="Save" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="74" Click="button_save_Click"/>
|
||||
<Button x:Name="button_load" Content="Load" HorizontalAlignment="Left" Margin="90,10,0,0" VerticalAlignment="Top" Width="74" Click="button_load_click"/>
|
||||
<DataGrid x:Name="dataGrid" HorizontalAlignment="Left" Height="100" Margin="1046,415,-390,-95.5" VerticalAlignment="Top" Width="100"/>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
@ -1,20 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Forms;
|
||||
using MessageBox = System.Windows.MessageBox;
|
||||
|
||||
namespace MHSEC_G
|
||||
{
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
private ViewModel view_model;
|
||||
private readonly byte[] dummy_data = new byte[Model.SAVE_FILE_SIZE];
|
||||
private const string Version = "0.1";
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
Item.read_item_mappings();
|
||||
Array.Clear(dummy_data, 0, dummy_data.Length);
|
||||
this.Title = "MHSEC-G Ver" + Version;
|
||||
DataContext = new ViewModel(dummy_data);
|
||||
view_model = new ViewModel(dummy_data);
|
||||
DataContext = view_model;
|
||||
}
|
||||
|
||||
private void button_load_click(object sender, RoutedEventArgs e)
|
||||
@ -35,9 +41,58 @@ namespace MHSEC_G
|
||||
}
|
||||
else
|
||||
{
|
||||
DataContext = new ViewModel(buffer);
|
||||
view_model = new ViewModel(buffer);
|
||||
DataContext = view_model;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void button_char_money_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
view_model.character.money = Character.LIMIT_MONEY;
|
||||
}
|
||||
|
||||
private void button_char_exp_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
view_model.character.exp = Character.LIMIT_EXP;
|
||||
}
|
||||
|
||||
private void button_item_all_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
List<Item> items = view_model.items;
|
||||
for (uint i = 0; i < items.Count; i++)
|
||||
{
|
||||
if (items.ElementAt((int)i).id == 1227)
|
||||
break;
|
||||
|
||||
items.ElementAt((int)i).count = 986;
|
||||
}
|
||||
}
|
||||
|
||||
private void button_item_existing_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
List<Item> items = view_model.items;
|
||||
for (uint i = 0; i < items.Count; i++)
|
||||
{
|
||||
if (items.ElementAt((int) i).id == 1227)
|
||||
break;
|
||||
|
||||
if (items.ElementAt((int)i).count != 0)
|
||||
{
|
||||
items.ElementAt((int) i).count = 999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void button_mexp_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
view_model.cur_monster.exp = Monster.LIMIT_MONSTER_EXP;
|
||||
}
|
||||
|
||||
private void button_save_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
File.WriteAllBytes("C:\\Users\\hyper\\Desktop\\mhr_save0.hacked", view_model.model.save_file);
|
||||
MessageBox.Show("Saved to \"mhr_save0.hacked\"","MHSEC-G",MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Dynamic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using MHSEC_G.Annotations;
|
||||
|
||||
namespace MHSEC_G
|
||||
{
|
||||
@ -13,44 +8,35 @@ namespace MHSEC_G
|
||||
{
|
||||
public const uint SAVE_FILE_SIZE = 483976;
|
||||
|
||||
private readonly byte[] save_file;
|
||||
private readonly byte[] _save_file;
|
||||
|
||||
private readonly Character _character;
|
||||
public Character character
|
||||
public byte[] save_file
|
||||
{
|
||||
get { return _character; }
|
||||
get { return _save_file; }
|
||||
}
|
||||
|
||||
private uint cur_monster_selection;
|
||||
private readonly List<Monster> monsters;
|
||||
|
||||
private readonly List<Item> items;
|
||||
|
||||
private uint cur_egg_fragment_selection;
|
||||
private readonly List<EggFragment> egg_fragments;
|
||||
|
||||
public Model(byte[] save)
|
||||
{
|
||||
if (save == null || save.Length != SAVE_FILE_SIZE)
|
||||
public Model(byte[] save_file)
|
||||
{
|
||||
if(save_file.Length != SAVE_FILE_SIZE)
|
||||
throw new SystemException("Invalid save file size.");
|
||||
_save_file = save_file;
|
||||
}
|
||||
save_file = save;
|
||||
_character = new Character(save_file);
|
||||
|
||||
cur_monster_selection = 0;
|
||||
monsters = null;
|
||||
items = null;
|
||||
cur_egg_fragment_selection = 0;
|
||||
egg_fragments = null;
|
||||
}
|
||||
|
||||
|
||||
public static uint byte_to_uint(byte b)
|
||||
{
|
||||
return (uint) (b) & 0xFF;
|
||||
}
|
||||
|
||||
public static void write_byte(byte[]arr, uint offset, uint val)
|
||||
{
|
||||
if(offset < arr.Length)
|
||||
arr[offset] = (byte)(val&0xFF);
|
||||
else
|
||||
{
|
||||
throw new SystemException("Buffer overflowed - Offset " + offset);
|
||||
}
|
||||
}
|
||||
|
||||
public static uint byte_to_uint16_le(byte[] arr, uint offset)
|
||||
{
|
||||
if (arr.Length < offset + 2)
|
||||
@ -105,5 +91,37 @@ namespace MHSEC_G
|
||||
}
|
||||
return name.ToString();
|
||||
}
|
||||
|
||||
public static void write_unicode_string(byte[] arr, uint offset, string str, uint length)
|
||||
{
|
||||
if (length < str.Length || arr.Length < offset + length)
|
||||
throw new SystemException("Unicode string write - potential buffer overflow.");
|
||||
|
||||
Array.Clear(arr, (int) offset, (int)length*2);
|
||||
for (uint i = 0; i < str.Length; i ++)
|
||||
{
|
||||
write_uint16_le(arr, offset + i*2, str.ElementAt((int) i));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
public static bool parse_hex_string(string val, out uint result)
|
||||
{
|
||||
result = 0;
|
||||
try
|
||||
{
|
||||
result = Convert.ToUInt32(val, 16);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
catch (OverflowException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,453 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.ComponentModel;
|
||||
using System.Windows;
|
||||
using MHSEC_G.Annotations;
|
||||
|
||||
namespace MHSEC_G
|
||||
{
|
||||
class Monster
|
||||
public class Monster : INotifyPropertyChanged
|
||||
{
|
||||
private const uint OFFSETA_MONSTER = 0xA150;
|
||||
private const uint SIZE_MONSTER = 0x478;
|
||||
private const uint OFFSETR_MONSTER_GENE = 0x424;
|
||||
private const uint SIZE_MONSTER_GENE = 0x4;
|
||||
private const uint OFFSETR_MONSTER_EXP = 0xE0;
|
||||
public const uint LIMIT_MONSTER_EXP = 0xFFFFFF;
|
||||
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_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 string spe
|
||||
{
|
||||
get { return Model.byte_to_uint(_model.save_file[_offset + OFFSETR_MONSTER_SPE]).ToString("X2"); }
|
||||
set
|
||||
{
|
||||
uint parsed;
|
||||
if (Model.parse_hex_string(value,out parsed) && parsed <= 0xFF)
|
||||
{
|
||||
_model.save_file[_offset + OFFSETR_MONSTER_SPE] = (byte)(parsed & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Species must be at most 0xFF.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(hiv));
|
||||
}
|
||||
}
|
||||
|
||||
public uint atk
|
||||
{
|
||||
get { return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_ATK); }
|
||||
set
|
||||
{
|
||||
if (value <= 0xFFFF)
|
||||
{
|
||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_ATK, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Atk must be at most " + UInt16.MaxValue, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(atk));
|
||||
}
|
||||
}
|
||||
public uint def
|
||||
{
|
||||
get { return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_DEF); }
|
||||
set
|
||||
{
|
||||
if (value <= 0xFFFF)
|
||||
{
|
||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_DEF, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Def must be at most " + UInt16.MaxValue, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(def));
|
||||
}
|
||||
}
|
||||
|
||||
public uint hp
|
||||
{
|
||||
get { return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_HP); }
|
||||
set
|
||||
{
|
||||
if (value <= 0xFFFF)
|
||||
{
|
||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_HP, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("HP must be at most " + UInt16.MaxValue, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(hp));
|
||||
}
|
||||
}
|
||||
|
||||
public uint hiv
|
||||
{
|
||||
get { return Model.byte_to_uint(_model.save_file[_offset + OFFSETR_MONSTER_HIV]); }
|
||||
set
|
||||
{
|
||||
if (value <= 0xFF)
|
||||
{
|
||||
_model.save_file[_offset + OFFSETR_MONSTER_HIV] = (byte) (value & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("IV must be at most 255.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(hiv));
|
||||
}
|
||||
}
|
||||
|
||||
public uint aiv
|
||||
{
|
||||
get { return Model.byte_to_uint(_model.save_file[_offset + OFFSETR_MONSTER_AIV]); }
|
||||
set
|
||||
{
|
||||
if (value <= 0xFF)
|
||||
{
|
||||
_model.save_file[_offset + OFFSETR_MONSTER_AIV] = (byte)(value & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("IV must be at most 255.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(aiv));
|
||||
}
|
||||
}
|
||||
public uint div
|
||||
{
|
||||
get { return Model.byte_to_uint(_model.save_file[_offset + OFFSETR_MONSTER_DIV]); }
|
||||
set
|
||||
{
|
||||
if (value <= 0xFF)
|
||||
{
|
||||
_model.save_file[_offset + OFFSETR_MONSTER_DIV] = (byte)(value & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("IV must be at most 255.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(div));
|
||||
}
|
||||
}
|
||||
public uint hpu
|
||||
{
|
||||
get { return Model.byte_to_uint(_model.save_file[_offset + OFFSETR_MONSTER_HPU]); }
|
||||
set
|
||||
{
|
||||
if (value <= 0xFF)
|
||||
{
|
||||
_model.save_file[_offset + OFFSETR_MONSTER_HPU] = (byte)(value & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Power up must be at most 255.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(hpu));
|
||||
}
|
||||
}
|
||||
public uint apu
|
||||
{
|
||||
get { return Model.byte_to_uint(_model.save_file[_offset + OFFSETR_MONSTER_APU]); }
|
||||
set
|
||||
{
|
||||
if (value <= 0xFF)
|
||||
{
|
||||
_model.save_file[_offset + OFFSETR_MONSTER_APU] = (byte)(value & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Power up must be at most 255.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(apu));
|
||||
}
|
||||
}
|
||||
public uint dpu
|
||||
{
|
||||
get { return Model.byte_to_uint(_model.save_file[_offset + OFFSETR_MONSTER_DPU]); }
|
||||
set
|
||||
{
|
||||
if (value <= 0xFF)
|
||||
{
|
||||
_model.save_file[_offset + OFFSETR_MONSTER_DPU] = (byte)(value & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Power up must be at most 255.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(dpu));
|
||||
}
|
||||
}
|
||||
|
||||
public string full_name
|
||||
{
|
||||
get { return name.Length == 0 ? "" : name + " [Lv." + level + "]"; }
|
||||
}
|
||||
|
||||
public string name
|
||||
{
|
||||
get { return Model.read_unicode_string(_model.save_file, _offset + OFFSETR_MONSTER_NAME, LIMIT_MONSTER_NAME); }
|
||||
set
|
||||
{
|
||||
if (value.Length <= 10 && value.Length > 0)
|
||||
{
|
||||
Model.write_unicode_string(_model.save_file, _offset + OFFSETR_MONSTER_NAME, value, 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Name must be 1-10 characters.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(name));
|
||||
OnPropertyChanged(nameof(full_name));
|
||||
}
|
||||
}
|
||||
|
||||
public uint exp
|
||||
{
|
||||
get { return Model.byte_to_uint32_le(_model.save_file, _offset + OFFSETR_MONSTER_EXP); }
|
||||
set
|
||||
{
|
||||
if (value <= LIMIT_MONSTER_EXP)
|
||||
{
|
||||
Model.write_uint32_le(_model.save_file, _offset + OFFSETR_MONSTER_EXP, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Exp must be at most " + LIMIT_MONSTER_EXP, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(exp));
|
||||
}
|
||||
}
|
||||
|
||||
public uint level
|
||||
{
|
||||
get { return Model.byte_to_uint(_model.save_file[_offset + OFFSETR_MONSTER_LEVEL]); }
|
||||
set
|
||||
{
|
||||
if (value <= LIMIT_MONSTER_LEVEL)
|
||||
{
|
||||
_model.save_file[_offset + OFFSETR_MONSTER_LEVEL] = (byte)(value & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Level must be at most " + LIMIT_MONSTER_LEVEL, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(level));
|
||||
OnPropertyChanged(nameof(full_name));
|
||||
}
|
||||
}
|
||||
|
||||
public string gene1
|
||||
{
|
||||
get { return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_GENE + 0 * SIZE_MONSTER_GENE).ToString("X4"); }
|
||||
set
|
||||
{
|
||||
uint parsed;
|
||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
||||
{
|
||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_GENE + 0 * SIZE_MONSTER_GENE, parsed);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Malformed gene value - must be 0x0 to 0xFFFF.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(gene2));
|
||||
}
|
||||
}
|
||||
|
||||
public string gene2
|
||||
{
|
||||
get { return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_GENE + 1 * SIZE_MONSTER_GENE).ToString("X4"); }
|
||||
set
|
||||
{
|
||||
uint parsed;
|
||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
||||
{
|
||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_GENE + 1*SIZE_MONSTER_GENE, parsed);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Malformed gene value - must be 0x0 to 0xFFFF.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(gene2));
|
||||
}
|
||||
}
|
||||
public string gene3
|
||||
{
|
||||
get { return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_GENE + 2 * SIZE_MONSTER_GENE).ToString("X4"); }
|
||||
set
|
||||
{
|
||||
uint parsed;
|
||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
||||
{
|
||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_GENE + 2 * SIZE_MONSTER_GENE, parsed);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Malformed gene value - must be 0x0 to 0xFFFF.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(gene3));
|
||||
}
|
||||
}
|
||||
public string gene4
|
||||
{
|
||||
get { return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_GENE + 3 * SIZE_MONSTER_GENE).ToString("X4"); }
|
||||
set
|
||||
{
|
||||
uint parsed;
|
||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
||||
{
|
||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_GENE + 3 * SIZE_MONSTER_GENE, parsed);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Malformed gene value - must be 0x0 to 0xFFFF.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(gene4));
|
||||
}
|
||||
}
|
||||
public string gene5
|
||||
{
|
||||
get { return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_GENE + 4 * SIZE_MONSTER_GENE).ToString("X4"); }
|
||||
set
|
||||
{
|
||||
uint parsed;
|
||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
||||
{
|
||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_GENE + 4 * SIZE_MONSTER_GENE, parsed);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Malformed gene value - must be 0x0 to 0xFFFF.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(gene5));
|
||||
}
|
||||
}
|
||||
public string gene6
|
||||
{
|
||||
get { return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_GENE + 5 * SIZE_MONSTER_GENE).ToString("X4"); }
|
||||
set
|
||||
{
|
||||
uint parsed;
|
||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
||||
{
|
||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_GENE + 5 * SIZE_MONSTER_GENE, parsed);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Malformed gene value - must be 0x0 to 0xFFFF.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(gene6));
|
||||
}
|
||||
}
|
||||
public string gene7
|
||||
{
|
||||
get { return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_GENE + 6 * SIZE_MONSTER_GENE).ToString("X4"); }
|
||||
set
|
||||
{
|
||||
uint parsed;
|
||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
||||
{
|
||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_GENE + 6 * SIZE_MONSTER_GENE, parsed);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Malformed gene value - must be 0x0 to 0xFFFF.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(gene7));
|
||||
}
|
||||
}
|
||||
public string gene8
|
||||
{
|
||||
get { return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_GENE + 7 * SIZE_MONSTER_GENE).ToString("X4"); }
|
||||
set
|
||||
{
|
||||
uint parsed;
|
||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
||||
{
|
||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_GENE + 7 * SIZE_MONSTER_GENE, parsed);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Malformed gene value - must be 0x0 to 0xFFFF.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(gene8));
|
||||
}
|
||||
}
|
||||
public string gene9
|
||||
{
|
||||
get { return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_GENE + 8 * SIZE_MONSTER_GENE).ToString("X4"); }
|
||||
set
|
||||
{
|
||||
uint parsed;
|
||||
if (Model.parse_hex_string(value, out parsed) && parsed <= 0xFFFF)
|
||||
{
|
||||
Model.write_uint16_le(_model.save_file, _offset + OFFSETR_MONSTER_GENE + 8 * SIZE_MONSTER_GENE, parsed);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Malformed gene value - must be 0x0 to 0xFFFF.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
OnPropertyChanged(nameof(gene9));
|
||||
}
|
||||
}
|
||||
|
||||
public Monster(uint offset, Model model)
|
||||
{
|
||||
_offset = offset;
|
||||
_model = model;
|
||||
}
|
||||
|
||||
public static List<Monster> read_all_monsters(Model model)
|
||||
{
|
||||
byte[] save = model.save_file;
|
||||
List<Monster> ret = new List<Monster>();
|
||||
for (uint i = OFFSETA_MONSTER; i < OFFSETA_MONSTE_END; i += SIZE_MONSTER)
|
||||
{
|
||||
if (save[i] != 0)
|
||||
{
|
||||
byte[] each = new byte[SIZE_MONSTER];
|
||||
Array.Copy(save, i, each, 0 ,SIZE_MONSTER);
|
||||
ret.Add(new Monster(i, model));
|
||||
}
|
||||
}
|
||||
|
||||
if (ret.Count == 0)
|
||||
{
|
||||
byte[] dummy = new byte[SIZE_MONSTER];
|
||||
Array.Clear(dummy, 0, (int)SIZE_MONSTER);
|
||||
// at least one monster
|
||||
ret.Add(new Monster(OFFSETA_MONSTER, model));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
[NotifyPropertyChangedInvocator]
|
||||
protected virtual void OnPropertyChanged(string propertyName)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,79 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using MHSEC_G.Annotations;
|
||||
|
||||
namespace MHSEC_G
|
||||
{
|
||||
public class ViewModel
|
||||
public class ViewModel : INotifyPropertyChanged
|
||||
{
|
||||
|
||||
private Model _model;
|
||||
private readonly Model _model;
|
||||
|
||||
public Model model
|
||||
{
|
||||
get { return _model;}
|
||||
set { _model = model; }
|
||||
}
|
||||
|
||||
private readonly Character _character;
|
||||
|
||||
public ViewModel(byte[] data)
|
||||
public Character character
|
||||
{
|
||||
_model = new Model(data);
|
||||
get { return _character; }
|
||||
}
|
||||
|
||||
private Monster _cur_monster_selection;
|
||||
private readonly ObservableCollection<Monster> _monsters;
|
||||
|
||||
public Monster cur_monster
|
||||
{
|
||||
get { return _cur_monster_selection; }
|
||||
set { _cur_monster_selection = value; OnPropertyChanged(nameof(cur_monster)); }
|
||||
}
|
||||
public ObservableCollection<Monster> monsters
|
||||
{
|
||||
get
|
||||
{
|
||||
return _monsters;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private readonly List<Item> _items;
|
||||
|
||||
public List<Item> items
|
||||
{
|
||||
get { return _items; }
|
||||
}
|
||||
|
||||
private uint cur_egg_fragment_selection;
|
||||
private readonly List<EggFragment> egg_fragments;
|
||||
|
||||
public ViewModel(byte[] save)
|
||||
{
|
||||
if (save == null || save.Length != Model.SAVE_FILE_SIZE)
|
||||
{
|
||||
throw new SystemException("Invalid save file size.");
|
||||
}
|
||||
|
||||
_model = new Model(save);
|
||||
_character = new Character(_model);
|
||||
_items = Item.read_all_items(_model);
|
||||
_monsters = new ObservableCollection<Monster>(Monster.read_all_monsters(_model));
|
||||
_cur_monster_selection = _monsters.ElementAt(0);
|
||||
|
||||
cur_egg_fragment_selection = 0;
|
||||
egg_fragments = null;
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
[NotifyPropertyChangedInvocator]
|
||||
protected virtual void OnPropertyChanged(string propertyName)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
BIN
MHSEC-G/MHSEC-G/idmap.txt
Normal file
BIN
MHSEC-G/MHSEC-G/idmap.txt
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user