Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added listpatch support for LVPM #1034

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion OpenKh.Kh2/BaseTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace OpenKh.Kh2
{
internal class BaseTable<T>
public class BaseTable<T>
where T : class
{
[Data] public int Version { get; set; }
Expand Down Expand Up @@ -90,4 +90,22 @@ public static void Write(Stream stream, IEnumerable<T> items)
BinaryMapping.WriteObject(stream, item);
}
}

public class BaseList<T>
where T : class
{
public static List<T> Read(Stream stream, int count)
{
return Enumerable.Range(0, count)
.Select(_ => BinaryMapping.ReadObject<T>(stream))
.ToList();
}

public static void Write(Stream stream, IEnumerable<T> items)
{
var itemList = items as IList<T> ?? items.ToList();
foreach (var item in itemList)
BinaryMapping.WriteObject(stream, item);
}
}
}
34 changes: 25 additions & 9 deletions OpenKh.Kh2/Battle/Lvpm.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
using System.Collections.Generic;
using System.IO;
using Xe.BinaryMapper;

namespace OpenKh.Kh2.Battle
{
public class Lvpm
{
public ushort HpMultiplier { get; set; } // (Hp * HpMultiplier + 99) / 100
public ushort Strength { get; set; }
public ushort Defense { get; set; }
public ushort MaxStrength { get; set; }
public ushort MinStrength { get; set; }
public ushort Experience { get; set; }
[Data] public ushort HpMultiplier { get; set; } // (Hp * HpMultiplier + 99) / 100
[Data] public ushort Strength { get; set; }
[Data] public ushort Defense { get; set; }
[Data] public ushort MaxStrength { get; set; }
[Data] public ushort MinStrength { get; set; }
[Data] public ushort Experience { get; set; }

public static List<Lvpm> Read(Stream stream) => BaseTable<Lvpm>.Read(stream);
//Default
public static List<Lvpm> Read(Stream stream) => BaseList<Lvpm>.Read(stream, 99);

public static void Write(Stream stream, IEnumerable<Lvpm> items) =>
BaseTable<Lvpm>.Write(stream, 2, items);
//Override for having a custom amount of entries
public static List<Lvpm> Read(Stream stream, int count) => BaseList<Lvpm>.Read(stream, count);

public static void Write(Stream stream, IEnumerable<Lvpm> items) => BaseList<Lvpm>.Write(stream, items);

public Lvpm() { }

public Lvpm(ushort HP, ushort Str, ushort Def, ushort MaxStr, ushort MinStr, ushort Exp)
{
HpMultiplier = HP;
Strength = Str;
Defense = Def;
MaxStrength = MaxStr;
MinStrength = MinStr;
Experience = Exp;
}
}
}
45 changes: 45 additions & 0 deletions OpenKh.Kh2/Battle/LvpmHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System.Collections.Generic;

namespace OpenKh.Kh2.Battle
{
public class LvpmHelper
{
public ushort Level { get; set; } //Dummy ID to make lvpm listpatchable
public ushort HpMultiplier { get; set; } // (Hp * HpMultiplier + 99) / 100
public ushort Strength { get; set; }
public ushort Defense { get; set; }
public ushort MaxStrength { get; set; }
public ushort MinStrength { get; set; }
public ushort Experience { get; set; }

public LvpmHelper() { }

public LvpmHelper(ushort level, ushort hpMultiplier, ushort strength, ushort defense, ushort maxStrength, ushort minStrength, ushort experience)
{
Level = level;
HpMultiplier = hpMultiplier;
Strength = strength;
Defense = defense;
MaxStrength = maxStrength;
MinStrength = minStrength;
Experience = experience;
}

public static Lvpm ConvertLvpmHelperToLvpm(LvpmHelper lvl)
{
return new Lvpm(lvl.HpMultiplier, lvl.Strength, lvl.Defense, lvl.MaxStrength, lvl.MinStrength, lvl.Experience);
}

public static List<LvpmHelper> ConvertLvpmListToHelper(List<Lvpm> lvpmList)
{
ushort Id = 0;
var helperList = new List<LvpmHelper>();
foreach (var lvpm in lvpmList)
{
helperList.Add(new LvpmHelper(Id, lvpm.HpMultiplier, lvpm.Strength, lvpm.Defense, lvpm.MaxStrength, lvpm.MinStrength, lvpm.Experience));
Id++;
}
return helperList;
}
}
}
13 changes: 13 additions & 0 deletions OpenKh.Patcher/PatcherProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,19 @@ private static void PatchList(Context context, List<AssetFile> sources, Stream s
Kh2.Battle.Atkp.Write(stream.SetPosition(0), atkpList);
break;

case "lvpm":
var lvpmList = Kh2.Battle.Lvpm.Read(stream);
var moddedLvpm = deserializer.Deserialize<List<Kh2.Battle.LvpmHelper>>(sourceText);
var helperList = Kh2.Battle.LvpmHelper.ConvertLvpmListToHelper(lvpmList);

foreach (var level in moddedLvpm)
{
var oldLvpm = helperList.First(x => x.Level == level.Level);
lvpmList[helperList.IndexOf(oldLvpm)] = Kh2.Battle.LvpmHelper.ConvertLvpmHelperToLvpm(level);
}
Kh2.Battle.Lvpm.Write(stream.SetPosition(0), lvpmList);
break;

case "objentry":
var objEntryList = Kh2.Objentry.Read(stream).ToDictionary(x => x.ObjectId, x => x);
var moddedObjEntry = deserializer.Deserialize<Dictionary<uint, Kh2.Objentry>>(sourceText);
Expand Down
101 changes: 101 additions & 0 deletions OpenKh.Tests/Patcher/PatcherTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1870,6 +1870,107 @@ void ListPatchAtkpTest()
});
}

[Fact]
void ListPatchLvpmTest()
{
var patcher = new PatcherProcessor();
var serializer = new Serializer();
var patch = new Metadata()
{
Assets = new List<AssetFile>()
{
new AssetFile()
{
Name = "00battle.bar",
Method = "binarc",
Source = new List<AssetFile>()
{
new AssetFile()
{
Name = "lvpm",
Method = "listpatch",
Type = "List",
Source = new List<AssetFile>()
{
new AssetFile()
{
Name = "LvpmList.yml",
Type = "lvpm"
}
}
}
}
}
}
};

File.Create(Path.Combine(AssetsInputDir, "00battle.bar")).Using(stream =>
{
var lvpmEntry = new List<Kh2.Battle.Lvpm>()
{
new Kh2.Battle.Lvpm
{
HpMultiplier = 89,
Strength = 77,
Defense = 88,
MaxStrength = 40,
MinStrength = 32,
Experience = 777
}
};

using var lvpmStream = new MemoryStream();
Kh2.Battle.Lvpm.Write(lvpmStream, lvpmEntry);
Bar.Write(stream, new Bar() {
new Bar.Entry()
{
Name = "lvpm",
Type = Bar.EntryType.List,
Stream = lvpmStream
}
});
});

File.Create(Path.Combine(ModInputDir, "LvpmList.yml")).Using(stream =>
{
var writer = new StreamWriter(stream);

var serializer = new Serializer();
var moddedLvpm = new List<Kh2.Battle.LvpmHelper>{
new Kh2.Battle.LvpmHelper
{
Level = 0,
HpMultiplier = 89,
Strength = 77,
Defense = 88,
MaxStrength = 40,
MinStrength = 32,
Experience = 777
}
};
writer.Write(serializer.Serialize(moddedLvpm));
writer.Flush();
});

patcher.Patch(AssetsInputDir, ModOutputDir, patch, ModInputDir, Tests: true);

AssertFileExists(ModOutputDir, "00battle.bar");

File.OpenRead(Path.Combine(ModOutputDir, "00battle.bar")).Using(stream =>
{
var binarc = Bar.Read(stream);
var lvpmStream = Kh2.Battle.Lvpm.Read(binarc[0].Stream, 1);
var helperList = Kh2.Battle.LvpmHelper.ConvertLvpmListToHelper(lvpmStream);
Assert.Equal(0, helperList[0].Level);
Assert.Equal(89, helperList[0].HpMultiplier);
Assert.Equal(77, helperList[0].Strength);
Assert.Equal(88, helperList[0].Defense);
Assert.Equal(40, helperList[0].MaxStrength);
Assert.Equal(32, helperList[0].MinStrength);
Assert.Equal(777, helperList[0].Experience);
});
}

[Fact]
public void ListPatchPrztTest()
{
Expand Down
12 changes: 12 additions & 0 deletions docs/tool/GUI.ModsManager/creatingMods.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ This document will focus on teaching you how to create mods using the OpenKH Mod
* [enmp](#enmp-source-example)
* [fmlv](#fmlv-source-example)
* [lvup](#lvup-source-example)
* [lvpm](#lvpm-source-example)
* [bons](#bons-source-example)
* [atkp](#atkp-source-example)
* [przt](#przt-source-example)
Expand Down Expand Up @@ -544,6 +545,17 @@ Sora:
SwordAbility: 577
```

### `lvpm` Source Example
```
- Level: 0
HpMultiplier: 100
Strength: 45
Defense: 26
MaxStrength: 16
MinStrength: 5
Experience: 3212
```

### `bons` Source Example
```
2:
Expand Down
Loading