feat: add support for Demon's Souls-style packs
This commit is contained in:
parent
62c579c42d
commit
c933a550ca
@ -10,9 +10,12 @@ public class Pack {
|
||||
|
||||
public string Name { get; init; }
|
||||
public Guid Id { get; init; }
|
||||
public string[] Templates { get; init; }
|
||||
public string[] Conjunctions { get; init; }
|
||||
public List<WordList> Words { get; init; }
|
||||
|
||||
[JsonConverter(typeof(TemplateConverter))]
|
||||
public ITemplate[] Templates { get; init; }
|
||||
|
||||
public string[]? Conjunctions { get; init; }
|
||||
public List<WordList>? Words { get; init; }
|
||||
|
||||
internal static void UpdatePacks() {
|
||||
Task.Run(async () => {
|
||||
@ -29,6 +32,52 @@ public class Pack {
|
||||
}
|
||||
}
|
||||
|
||||
public interface ITemplate {
|
||||
public string Template { get; }
|
||||
public string[]? Words { get; }
|
||||
}
|
||||
|
||||
public class BasicTemplate : ITemplate {
|
||||
public string Template { get; init; }
|
||||
public string[]? Words => null;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class WordListTemplate : ITemplate {
|
||||
public string Template { get; init; }
|
||||
public string[] Words { get; init; }
|
||||
}
|
||||
|
||||
public class TemplateConverter : JsonConverter<ITemplate>
|
||||
{
|
||||
public override ITemplate? ReadJson(JsonReader reader, Type objectType, ITemplate? existingValue, bool hasExistingValue, JsonSerializer serializer) {
|
||||
if (reader.TokenType == JsonToken.String) {
|
||||
var template = reader.ReadAsString();
|
||||
if (template == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new BasicTemplate {
|
||||
Template = template,
|
||||
};
|
||||
} else if (reader.TokenType == JsonToken.StartObject) {
|
||||
return serializer.Deserialize<WordListTemplate>(reader);
|
||||
} else {
|
||||
throw new JsonReaderException("unexpected template kind");
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, ITemplate? value, JsonSerializer serializer) {
|
||||
if (value is BasicTemplate basic) {
|
||||
serializer.Serialize(writer, basic.Template);
|
||||
} else if (value is WordListTemplate wordList) {
|
||||
serializer.Serialize(writer, wordList);
|
||||
} else {
|
||||
throw new JsonWriterException("unexpected template kind");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class WordList {
|
||||
public string Name { get; init; }
|
||||
|
@ -104,6 +104,21 @@ internal class Write : ITab {
|
||||
ImGui.EndCombo();
|
||||
}
|
||||
|
||||
void DrawSpecificWordPicker(string id, WordListTemplate template, ref (int, int) x) {
|
||||
var preview = x == (-1, -1) ? "" : template.Words[x.Item2];
|
||||
if (!ImGui.BeginCombo(id, preview)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var wordIdx = 0; wordIdx < template.Words.Length; wordIdx++) {
|
||||
if (ImGui.Selectable(template.Words[wordIdx], x == (-1, wordIdx))) {
|
||||
x = (-1, wordIdx);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.EndCombo();
|
||||
}
|
||||
|
||||
void DrawWordPicker(string id, IReadOnlyList<WordList> words, ref (int, int) x) {
|
||||
var preview = x == (-1, -1) ? "" : words[x.Item1].Words[x.Item2];
|
||||
if (!ImGui.BeginCombo(id, preview)) {
|
||||
@ -149,12 +164,13 @@ internal class Write : ITab {
|
||||
var preview = new StringBuilder();
|
||||
|
||||
var template1 = pack.Templates[this._part1];
|
||||
var word1 = this._word1 == (-1, -1) ? placeholder : pack.Words[this._word1.Item1].Words[this._word1.Item2];
|
||||
preview.Append(string.Format(template1, word1));
|
||||
var wordList1 = template1.Words ?? pack.Words?[this._word1.Item1].Words;
|
||||
var word1 = this._word1 == (-1, -1) ? placeholder : wordList1?[this._word1.Item2];
|
||||
preview.Append(string.Format(template1.Template, word1));
|
||||
|
||||
if (this._conj != -1) {
|
||||
var conj = pack.Conjunctions[this._conj];
|
||||
var isPunc = conj.Length == 1 && char.IsPunctuation(conj[0]);
|
||||
var conj = pack.Conjunctions?[this._conj];
|
||||
var isPunc = conj?.Length == 1 && char.IsPunctuation(conj[0]);
|
||||
if (isPunc) {
|
||||
preview.Append(conj);
|
||||
preview.Append('\n');
|
||||
@ -166,8 +182,9 @@ internal class Write : ITab {
|
||||
|
||||
if (this._part2 != -1) {
|
||||
var template2 = pack.Templates[this._part2];
|
||||
var word2 = this._word2 == (-1, -1) ? placeholder : pack.Words[this._word2.Item1].Words[this._word2.Item2];
|
||||
preview.Append(string.Format(template2, word2));
|
||||
var wordList2 = template2.Words ?? pack.Words?[this._word2.Item1].Words;
|
||||
var word2 = this._word2 == (-1, -1) ? placeholder : wordList2?[this._word2.Item2];
|
||||
preview.Append(string.Format(template2.Template, word2));
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,18 +199,48 @@ internal class Write : ITab {
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
DrawPicker("Template##part-1", pack.Templates, ref this._part1);
|
||||
if (this._part1 > -1 && pack.Templates[this._part1].Contains("{0}")) {
|
||||
var templateStrings = pack.Templates
|
||||
.Select(template => template.Template)
|
||||
.ToArray();
|
||||
|
||||
DrawPicker("Template##part-1", templateStrings, ref this._part1);
|
||||
if (this._part1 > -1 && pack.Templates[this._part1].Template.Contains("{0}")) {
|
||||
switch (pack.Templates[this._part1]) {
|
||||
case BasicTemplate basic: {
|
||||
if (pack.Words != null) {
|
||||
DrawWordPicker("Word##word-1", pack.Words, ref this._word1);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case WordListTemplate wordListTemplate: {
|
||||
DrawSpecificWordPicker("Word##word-1", wordListTemplate, ref this._word1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pack.Conjunctions != null) {
|
||||
DrawPicker("Conjunction##conj", pack.Conjunctions, ref this._conj);
|
||||
}
|
||||
|
||||
if (this._conj != -1) {
|
||||
DrawPicker("Template##part-2", pack.Templates, ref this._part2);
|
||||
if (this._part2 > -1 && pack.Templates[this._part2].Contains("{0}")) {
|
||||
DrawPicker("Template##part-2", templateStrings, ref this._part2);
|
||||
if (this._part2 > -1 && pack.Templates[this._part2].Template.Contains("{0}")) {
|
||||
switch (pack.Templates[this._part2]) {
|
||||
case BasicTemplate basic: {
|
||||
if (pack.Words != null) {
|
||||
DrawWordPicker("Word##word-2", pack.Words, ref this._word2);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case WordListTemplate wordListTemplate: {
|
||||
DrawSpecificWordPicker("Word##word-2", wordListTemplate, ref this._word2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui.BeginCombo("Glyph", $"{this._glyph + 1}")) {
|
||||
@ -301,7 +348,7 @@ internal class Write : ITab {
|
||||
|
||||
var pack = Pack.All[this._pack];
|
||||
|
||||
if (this._part1 == -1 || !pack.Templates[this._part1].Contains("{0}")) {
|
||||
if (this._part1 == -1 || !pack.Templates[this._part1].Template.Contains("{0}")) {
|
||||
this._word1 = (-1, -1);
|
||||
}
|
||||
|
||||
@ -309,7 +356,7 @@ internal class Write : ITab {
|
||||
this._part2 = -1;
|
||||
}
|
||||
|
||||
if (this._part2 == -1 || !pack.Templates[this._part2].Contains("{0}")) {
|
||||
if (this._part2 == -1 || !pack.Templates[this._part2].Template.Contains("{0}")) {
|
||||
this._word2 = (-1, -1);
|
||||
}
|
||||
}
|
||||
@ -321,7 +368,7 @@ internal class Write : ITab {
|
||||
|
||||
var pack = Pack.All[this._pack];
|
||||
var template1 = pack.Templates[this._part1];
|
||||
var temp1Variable = template1.Contains("{0}");
|
||||
var temp1Variable = template1.Template.Contains("{0}");
|
||||
|
||||
switch (temp1Variable) {
|
||||
case true when this._word1 == (-1, -1):
|
||||
@ -339,7 +386,7 @@ internal class Write : ITab {
|
||||
}
|
||||
|
||||
var template2 = pack.Templates[this._part2];
|
||||
var temp2Variable = template2.Contains("{0}");
|
||||
var temp2Variable = template2.Template.Contains("{0}");
|
||||
|
||||
switch (temp2Variable) {
|
||||
case true when this._word2 == (-1, -1):
|
||||
|
693
server/packs/demons-souls.yaml
Normal file
693
server/packs/demons-souls.yaml
Normal file
@ -0,0 +1,693 @@
|
||||
name: Demon's Souls (PS3)
|
||||
id: 9ad0d0aa-a1e0-48ff-a1e9-d305b26f4e72
|
||||
visible: true
|
||||
order: 7
|
||||
|
||||
word-refs:
|
||||
rewards: &rewards
|
||||
- "a weapon"
|
||||
- "armor"
|
||||
- "a ring"
|
||||
- "ore"
|
||||
- "a recovery item"
|
||||
- "an item"
|
||||
- "Souls"
|
||||
- "a valuable weapon"
|
||||
- "valuable armor"
|
||||
- "a valuable ring"
|
||||
- "valuable ore"
|
||||
- "a valuable recovery item"
|
||||
- "a valuable item"
|
||||
- "a strange weapon"
|
||||
- "strange armor"
|
||||
- "a strange ring"
|
||||
- "strange ore"
|
||||
- "a strange recovery item"
|
||||
- "a strange item"
|
||||
- "a Hardstone"
|
||||
- "a Sharpstone"
|
||||
- "a Clearstone"
|
||||
- "a Greystone"
|
||||
- "a Bladestone"
|
||||
- "a Dragonstone"
|
||||
- "a Suckerstone"
|
||||
- "a Mercurystone"
|
||||
- "a Marrowstone"
|
||||
- "a Spiderstone"
|
||||
- "a Moonlightstone"
|
||||
- "a Darkmoonstone"
|
||||
- "a Faintstone"
|
||||
- "a Cloudstone"
|
||||
- "a Meltstone"
|
||||
- "sparkly things"
|
||||
- "twinkly things"
|
||||
- "true love"
|
||||
attacks: &attacks
|
||||
- "blunt attacks"
|
||||
- "slash attacks"
|
||||
- "pierce attacks"
|
||||
- "one-handed attacks"
|
||||
- "two-handed attacks"
|
||||
- "daggers"
|
||||
- "straight swords"
|
||||
- "large swords"
|
||||
- "very large swords"
|
||||
- "curved swords"
|
||||
- "katanas"
|
||||
- "rapiers"
|
||||
- "axes"
|
||||
- "large axes"
|
||||
- "hammers"
|
||||
- "large hammers"
|
||||
- "fist weapons"
|
||||
- "spears"
|
||||
- "pole weapons"
|
||||
- "strong weapons"
|
||||
- "magic weapons"
|
||||
- "flame weapons"
|
||||
- "bows"
|
||||
- "arrows"
|
||||
- "crossbows"
|
||||
- "bolts"
|
||||
- "projectiles"
|
||||
- "spells"
|
||||
- "miracles"
|
||||
- "shields"
|
||||
- "large shields"
|
||||
- "fire"
|
||||
- "bleed attacks"
|
||||
- "poison"
|
||||
- "plague"
|
||||
- "decay"
|
||||
- "Soul drain"
|
||||
- "staggering attacks"
|
||||
- "guard breaks"
|
||||
- "dodges"
|
||||
- "shield guards"
|
||||
- "parries"
|
||||
- "knockback attacks"
|
||||
- "clockwise dodges"
|
||||
- "counterclockwise dodges"
|
||||
- "pincer attacks"
|
||||
- "divide and conquer tactics"
|
||||
- "luring tactics"
|
||||
- "power pushes"
|
||||
- "preemptive strikes"
|
||||
- "standard attacks"
|
||||
- "attrition"
|
||||
- "observation"
|
||||
- "stealthy footsteps"
|
||||
- "nothing"
|
||||
- "willpower"
|
||||
- "luck"
|
||||
roles: &roles
|
||||
- "Beginners"
|
||||
- "Veterans"
|
||||
- "Confident ones"
|
||||
- "Cowards"
|
||||
- "Challengers"
|
||||
- "Soldiers"
|
||||
- "Knights"
|
||||
- "Hunters"
|
||||
- "Priests"
|
||||
- "Magicians"
|
||||
- "Wanderers"
|
||||
- "Barbarians"
|
||||
- "Thieves"
|
||||
- "Temple Knights"
|
||||
- "Royalty"
|
||||
terms: &terms
|
||||
- "Item"
|
||||
- "Footsteps"
|
||||
- "At your feet"
|
||||
- "Head"
|
||||
- "Safe place"
|
||||
- "Good guy"
|
||||
- "Crossbow"
|
||||
- "At some point..."
|
||||
- "Someday..."
|
||||
- "One-way road"
|
||||
- "Nasty guy"
|
||||
- "Up"
|
||||
- "Ascending stairs"
|
||||
- "Ascending ladder"
|
||||
- "Movement"
|
||||
- "Cloudstone"
|
||||
- "Liar"
|
||||
- "Singing voice"
|
||||
- "Luck"
|
||||
- "While casting..."
|
||||
- "Sharpstone"
|
||||
- "Plague"
|
||||
- "Beware the plague"
|
||||
- "Ed's Grindstone"
|
||||
- "MP recovery item"
|
||||
- "Ranged attack"
|
||||
- "Large axe"
|
||||
- "Large shield"
|
||||
- "Large hammer"
|
||||
- "Strong attack"
|
||||
- "Coward"
|
||||
- "Knockback"
|
||||
- "Try falling through..."
|
||||
- "Axe"
|
||||
- "Lure it out"
|
||||
- "Yourself"
|
||||
- "While turning..."
|
||||
- "Dodge"
|
||||
- "HP recovery item"
|
||||
- "While recovering..."
|
||||
- "Fist weapon"
|
||||
- "Firebomb"
|
||||
- "Key"
|
||||
- "If you get the key..."
|
||||
- "Hidden passage"
|
||||
- "Single-handed"
|
||||
- "Katana"
|
||||
- "Divide and conquer"
|
||||
- "Paralysis"
|
||||
- "Archstone"
|
||||
- "Shard of Archstone"
|
||||
- "Widow's Lotus"
|
||||
- "Hunter"
|
||||
- "Deceptive cuteness"
|
||||
- "Poor guy"
|
||||
- "Cuteness"
|
||||
- "Observation"
|
||||
- "Misunderstanding"
|
||||
- "Willpower"
|
||||
- "Dangerous foe"
|
||||
- "Knight"
|
||||
- "Miracle"
|
||||
- "Royalty"
|
||||
- "Royal Lotus"
|
||||
- "Valuable item"
|
||||
- "Valuable recovery item"
|
||||
- "Valuable ore"
|
||||
- "Valuable treasure"
|
||||
- "Valuable weapon"
|
||||
- "Valuable armor"
|
||||
- "Valuable ring"
|
||||
- "Carelessness"
|
||||
- "Formidable foe"
|
||||
- "Critical attack"
|
||||
- "Curved sword"
|
||||
- "Twinkly stuff"
|
||||
- "Spiderstone"
|
||||
- "Darkness"
|
||||
- "Black Phantom"
|
||||
- "Black Turpentine"
|
||||
- "Moonstone"
|
||||
- "Bloodstain"
|
||||
- "Crystal Lizard"
|
||||
- "Kick"
|
||||
- "Primeval Demon"
|
||||
- "After attacking..."
|
||||
- "During your attack..."
|
||||
- "Hardstone"
|
||||
- "Ore"
|
||||
- "In your heart"
|
||||
- "Terrifying foe"
|
||||
- "Pole weapon"
|
||||
- "If you go on ahead..."
|
||||
- "Rapier"
|
||||
- "Slash attack"
|
||||
- "Battle of attrition"
|
||||
- "Confident one"
|
||||
- "Down"
|
||||
- "Descending stairs"
|
||||
- "Descending ladder"
|
||||
- "Thrust attack"
|
||||
- "Stealthy footsteps"
|
||||
- "Perimeter"
|
||||
- "V.I.P."
|
||||
- "Bleeding"
|
||||
- "Bleeding resistance"
|
||||
- "Front"
|
||||
- "Item burden"
|
||||
- "Beginner"
|
||||
- "Sticky White Stuff"
|
||||
- "True love"
|
||||
- "Priest"
|
||||
- "Temple Knight"
|
||||
- "Mercurystone"
|
||||
- "Marrowstone"
|
||||
- "Suckerstone"
|
||||
- "Overhead"
|
||||
- "Stamina"
|
||||
- "World Tendency"
|
||||
- "Great view"
|
||||
- "Below"
|
||||
- "Narrow corridor"
|
||||
- "Preemptive strike"
|
||||
- "Reinforcement"
|
||||
- "Equipment burden"
|
||||
- "Soul"
|
||||
- "Soul drain"
|
||||
- "If Soul tendency is black..."
|
||||
- "If Soul tendency is white..."
|
||||
- "Soul Remains"
|
||||
- "Side"
|
||||
- "Sniper's perch"
|
||||
- "Standard attack"
|
||||
- "Large sword"
|
||||
- "Horde of foes"
|
||||
- "Treasure"
|
||||
- "Blunt attack"
|
||||
- "Barrage attack"
|
||||
- "Shield"
|
||||
- "Guard"
|
||||
- "Guard break"
|
||||
- "Dagger"
|
||||
- "Power push"
|
||||
- "Terrain"
|
||||
- "Challenger"
|
||||
- "Straight sword"
|
||||
- "Darkmoonstone"
|
||||
- "Hammer"
|
||||
- "Strong weapon"
|
||||
- "Tough guy"
|
||||
- "Adversary"
|
||||
- "Escape"
|
||||
- "Thief"
|
||||
- "Poison"
|
||||
- "Very large sword"
|
||||
- "Poison swamp"
|
||||
- "Poison resistance"
|
||||
- "Anywhere"
|
||||
- "Closed door"
|
||||
- "Closed gate"
|
||||
- "Rush"
|
||||
- "Projectile"
|
||||
- "Door"
|
||||
- "Greystone"
|
||||
- "Escape route"
|
||||
- "Remaining HP"
|
||||
- "Remaining MP"
|
||||
- "Rear"
|
||||
- "Back Side"
|
||||
- "Stone of Ephemeral Eyes"
|
||||
- "Pincer attack"
|
||||
- "Chest"
|
||||
- "Parry"
|
||||
- "Savage"
|
||||
- "Sparkly"
|
||||
- "Light"
|
||||
- "Faintstone"
|
||||
- "Left"
|
||||
- "Counterclockwise"
|
||||
- "Open area"
|
||||
- "Sneak attack"
|
||||
- "Intense pursuit"
|
||||
- "Weapon"
|
||||
- "Dead end"
|
||||
- "Corrosion"
|
||||
- "Staggering attack"
|
||||
- "Bolt"
|
||||
- "Soldier"
|
||||
- "Soldier's Lotus"
|
||||
- "Veteran"
|
||||
- "If you disguise yourself..."
|
||||
- "Strange item"
|
||||
- "Strange recovery item"
|
||||
- "Strange ore"
|
||||
- "Strange foe"
|
||||
- "Strange weapon"
|
||||
- "Strange armor"
|
||||
- "Strange ring"
|
||||
- "Armor"
|
||||
- "Roar"
|
||||
- "Wanderer"
|
||||
- "Howl"
|
||||
- "Other"
|
||||
- "Fire"
|
||||
- "Fire defense"
|
||||
- "Flame weapon"
|
||||
- "Magician"
|
||||
- "Ambush"
|
||||
- "Turpentine"
|
||||
- "Spell"
|
||||
- "Magic defense"
|
||||
- "Magic weapon"
|
||||
- "Trick road"
|
||||
- "Invisible foe"
|
||||
- "Right"
|
||||
- "Clockwise"
|
||||
- "Augite of Guidance"
|
||||
- "Clearstone"
|
||||
- "Illusion"
|
||||
- "Ignore"
|
||||
- "Message"
|
||||
- "Merchant"
|
||||
- "Sounds"
|
||||
- "Gate"
|
||||
- "Arrow"
|
||||
- "Bladestone"
|
||||
- "Spear"
|
||||
- "Friend"
|
||||
- "Ring"
|
||||
- "Bow"
|
||||
- "Lava"
|
||||
- "Meltstone"
|
||||
- "Pay attention"
|
||||
- "Weak guy"
|
||||
- "Fall"
|
||||
- "Rhythm"
|
||||
- "Dragonstone"
|
||||
- "Two-handed attack"
|
||||
- "Lever"
|
||||
- "If you use the lever..."
|
||||
- "Combo attack"
|
||||
- "After combo"
|
||||
- "During combo"
|
||||
- "Crossroads"
|
||||
|
||||
templates:
|
||||
- template: 'Beware of {0} ahead.'
|
||||
words:
|
||||
- "the ceiling"
|
||||
- "the floor"
|
||||
- "the rear area"
|
||||
- "a fall"
|
||||
- "the bloodstain"
|
||||
- "the message"
|
||||
- "a World Tendency event"
|
||||
- "the poison swamp"
|
||||
- "the lava"
|
||||
- "the crossroads"
|
||||
- "a trick road"
|
||||
- "the sounds"
|
||||
- "the footsteps"
|
||||
- "the singing voice"
|
||||
- "the darkness"
|
||||
- "the light"
|
||||
- "a distraction"
|
||||
- "not using caution"
|
||||
- "misunderstanding what's"
|
||||
- "an illusion"
|
||||
- "the liar"
|
||||
- "the adversary"
|
||||
- "the formidable foe"
|
||||
- "the horde of foes"
|
||||
- "the dangerous foe"
|
||||
- "the invisible foe"
|
||||
- "the bizarre foe"
|
||||
- "the terrifying foe"
|
||||
- "the cute foe"
|
||||
- "the Black Phantom"
|
||||
- "the bow-users"
|
||||
- "ranged attacks"
|
||||
- "the spell-users"
|
||||
- "the miracle-users"
|
||||
- "fire"
|
||||
- "bleeding"
|
||||
- "poison"
|
||||
- "plague"
|
||||
- "paralysis"
|
||||
- "corrosion"
|
||||
- "Soul drain"
|
||||
- "your remaining HP"
|
||||
- "your remaining MP"
|
||||
- "your stamina"
|
||||
- "your equipment burden"
|
||||
- "your item burden"
|
||||
|
||||
- template: 'Beware of the enemy''s {0}.'
|
||||
words:
|
||||
- "ambush"
|
||||
- "sneak attack"
|
||||
- "barrage"
|
||||
- "reinforcements"
|
||||
- "escape"
|
||||
- "intense pursuit"
|
||||
- "movement"
|
||||
- "rhythm"
|
||||
- "perimeter"
|
||||
- "terrain"
|
||||
- "strong attacks"
|
||||
- "critical attacks"
|
||||
- "combo attacks"
|
||||
- "rush"
|
||||
- "staggering attacks"
|
||||
- "guard break"
|
||||
- "evasion"
|
||||
- "guard"
|
||||
- "parries"
|
||||
- "knockback"
|
||||
- "kick"
|
||||
- "roar"
|
||||
- "howl"
|
||||
- "bows"
|
||||
- "ranged attacks"
|
||||
- "spells"
|
||||
- "miracles"
|
||||
- "fire attacks"
|
||||
- "bloodletting"
|
||||
- "poison"
|
||||
- "plague"
|
||||
- "paralysis"
|
||||
- "decay"
|
||||
- "Soul drain"
|
||||
- "cuteness"
|
||||
|
||||
- template: 'There''s {0} ahead.'
|
||||
words:
|
||||
- "treasure"
|
||||
- "valuable treasure"
|
||||
- "keys"
|
||||
- "an Archstone"
|
||||
- "bloodstains"
|
||||
- "messages"
|
||||
- "a lever"
|
||||
- "a door"
|
||||
- "a gate"
|
||||
- "a closed door"
|
||||
- "a closed gate"
|
||||
- "an escape route"
|
||||
- "a dead end"
|
||||
- "a one-way road"
|
||||
- "a hidden passage"
|
||||
- "a fall"
|
||||
- "ascending stairs"
|
||||
- "descending stairs"
|
||||
- "a ladder up"
|
||||
- "a ladder down"
|
||||
- "a narrow place"
|
||||
- "an open place"
|
||||
- "a safe place"
|
||||
- "a sniper's perch"
|
||||
- "a great view"
|
||||
|
||||
- template: 'A {0} lies in wait ahead.'
|
||||
words:
|
||||
- "merchant"
|
||||
- "V.I.P."
|
||||
- "friend"
|
||||
- "good guy"
|
||||
- "poor guy"
|
||||
- "bad guy"
|
||||
- "tough guy"
|
||||
- "weak guy"
|
||||
- "liar"
|
||||
- "villain"
|
||||
- "formidable foe"
|
||||
- "horde of foes"
|
||||
- "dangerous foe"
|
||||
- "hidden foe"
|
||||
- "strange foe"
|
||||
- "terrifying foe"
|
||||
- "cute foe"
|
||||
- "Black Phantom"
|
||||
- "Crystal Lizard"
|
||||
- "Primeval Demon"
|
||||
|
||||
- template: 'You''ll find {0} past here.'
|
||||
words: *rewards
|
||||
|
||||
- template: 'You''ll get {0} from the next foe.'
|
||||
words: *rewards
|
||||
|
||||
- template: 'If you {0}, you can proceed.'
|
||||
words:
|
||||
- "get the key"
|
||||
- "use the lever"
|
||||
- "have white Soul tendency"
|
||||
- "have black Soul tendency"
|
||||
- "press on"
|
||||
- "keep trying"
|
||||
- "don't give up"
|
||||
- "disguise yourself"
|
||||
|
||||
- template: 'Use {0} on the next enemy.'
|
||||
words: *attacks
|
||||
|
||||
- template: 'Don''t bother with {0}.'
|
||||
words: *attacks
|
||||
|
||||
- template: 'The next enemy''s weakness is {0}.'
|
||||
words:
|
||||
- "its head"
|
||||
- "its feet"
|
||||
- "its back"
|
||||
- "its chest"
|
||||
- "its front"
|
||||
- "its side"
|
||||
- "its back"
|
||||
- "during its attack"
|
||||
- "after its attack"
|
||||
- "during its combo"
|
||||
- "after its combo"
|
||||
- "during its recovery"
|
||||
- "when it turns"
|
||||
- "when it chants"
|
||||
- "above"
|
||||
- "below"
|
||||
- "to the left"
|
||||
- "to the right"
|
||||
- "not what you think"
|
||||
- "anywhere"
|
||||
- "in your heart"
|
||||
- "you"
|
||||
|
||||
- template: 'Don''t go forward without {0}.'
|
||||
words:
|
||||
- "a dagger"
|
||||
- "a straight sword"
|
||||
- "a large sword"
|
||||
- "a very large sword"
|
||||
- "a curved sword"
|
||||
- "a katana"
|
||||
- "a rapier"
|
||||
- "an axe"
|
||||
- "a large axe"
|
||||
- "a hammer"
|
||||
- "a large hammer"
|
||||
- "a fist weapon"
|
||||
- "a spear"
|
||||
- "a pole weapon"
|
||||
- "a strong weapon"
|
||||
- "a magic weapon"
|
||||
- "a flame weapon"
|
||||
- "a bow"
|
||||
- "arrows"
|
||||
- "a crossbow"
|
||||
- "bolts"
|
||||
- "projectiles"
|
||||
- "spells"
|
||||
- "miracles"
|
||||
- "a shield"
|
||||
- "a large shield"
|
||||
- "spell resistance"
|
||||
- "fire defense"
|
||||
- "bleed resistance"
|
||||
- "poison resistance"
|
||||
- "plague resistance"
|
||||
- "recovery items"
|
||||
- "a Soldier's Lotus"
|
||||
- "a Royal Lotus"
|
||||
- "a Widow's Lotus"
|
||||
- "MP recovery items"
|
||||
- "a grindstone"
|
||||
- "a Stone of Ephemeral Eyes"
|
||||
- "a Splinter of Archstone"
|
||||
- "an Augite of Guidance"
|
||||
- "Soul remains"
|
||||
- "Turpentine"
|
||||
- "Black Turpentine"
|
||||
- "Sticky White Stuff"
|
||||
- "Firebombs"
|
||||
|
||||
- template: "You'll need a Soul Level of {0} ahead."
|
||||
words:
|
||||
- '1'
|
||||
- '2'
|
||||
- '3'
|
||||
- '4'
|
||||
- '5'
|
||||
- '6'
|
||||
- '7'
|
||||
- '8'
|
||||
- '9'
|
||||
- '10'
|
||||
- '11'
|
||||
- '12'
|
||||
- '13'
|
||||
- '14'
|
||||
- '15'
|
||||
- '16'
|
||||
- '17'
|
||||
- '18'
|
||||
- '19'
|
||||
- '20'
|
||||
- '21'
|
||||
- '22'
|
||||
- '23'
|
||||
- '24'
|
||||
- '25'
|
||||
- '26'
|
||||
- '27'
|
||||
- '28'
|
||||
- '29'
|
||||
- '30'
|
||||
- '31'
|
||||
- '32'
|
||||
- '33'
|
||||
- '34'
|
||||
- '35'
|
||||
- '36'
|
||||
- '37'
|
||||
- '38'
|
||||
- '39'
|
||||
- '40'
|
||||
|
||||
- template: '{0} should go here first.'
|
||||
words: *roles
|
||||
|
||||
- template: '{0} should try this area later.'
|
||||
words: *roles
|
||||
|
||||
- "Watch out."
|
||||
- "Listen well."
|
||||
- "Think hard."
|
||||
- "Remember..."
|
||||
- "Don't stop!"
|
||||
- "Run straight through."
|
||||
- "Take a step forward."
|
||||
- "Watch yourself."
|
||||
- "This is it."
|
||||
- "The true Demon's Souls starts here."
|
||||
- "Welcome!"
|
||||
- "Hi!"
|
||||
- "Farewell!"
|
||||
- "Best of luck to you."
|
||||
- "There are demons nearby."
|
||||
- "It's safe here."
|
||||
- "It's not safe here."
|
||||
- "You can summon here."
|
||||
- "Requesting a challenger..."
|
||||
- "I'm in trouble – please recommend this message!"
|
||||
- "Write more messages!"
|
||||
- "Beware of false messages."
|
||||
- "Don't attack!"
|
||||
- "Attack!"
|
||||
- "I've got a good item..."
|
||||
- "If you press onward..."
|
||||
- "If you jump down from here..."
|
||||
- "Behind you!"
|
||||
- "If you read this message..."
|
||||
- "I'm lost..."
|
||||
- "This place again...?"
|
||||
- "Why is it always..."
|
||||
- "My heart's breaking..."
|
||||
- "Now I've done it..."
|
||||
- "I want to go home..."
|
||||
- "I want to be resurrected..."
|
||||
- "I've been in Soul form for so long..."
|
||||
- "If I only had some friends..."
|
||||
- "I told you so."
|
||||
- "This is no time to read messages!"
|
||||
- "Did you think there'd be a hint?"
|
||||
- "The answer is within you."
|
||||
|
||||
- template: "{0}"
|
||||
words: *terms
|
@ -27,8 +27,34 @@
|
||||
"templates": {
|
||||
"type": "array",
|
||||
"description": "An array of template strings, using {0} for where the chosen word should be inserted (if any).",
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "A template that should use the global word list defined at the root of this document."
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"description": "A template that should use its own word list defined on the template object.",
|
||||
"properties": {
|
||||
"template": {
|
||||
"type": "string",
|
||||
"description": "The template string, using {0} for where the chosen word should be inserted (if any)."
|
||||
},
|
||||
"words": {
|
||||
"type": "array",
|
||||
"description": "A list of words for this template specifically.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"template",
|
||||
"words"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"minItems": 1
|
||||
},
|
||||
@ -72,8 +98,6 @@
|
||||
"id",
|
||||
"visible",
|
||||
"order",
|
||||
"templates",
|
||||
"conjunctions",
|
||||
"words"
|
||||
"templates"
|
||||
]
|
||||
}
|
||||
|
@ -9,9 +9,36 @@ pub struct Pack {
|
||||
pub visible: bool,
|
||||
#[serde(default, skip_serializing)]
|
||||
pub order: u8,
|
||||
pub templates: Vec<String>,
|
||||
pub conjunctions: Vec<String>,
|
||||
pub words: Vec<WordList>,
|
||||
pub templates: Vec<Template>,
|
||||
pub conjunctions: Option<Vec<String>>,
|
||||
pub words: Option<Vec<WordList>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[serde(untagged)]
|
||||
pub enum Template {
|
||||
Basic(String),
|
||||
List {
|
||||
template: String,
|
||||
words: Vec<String>,
|
||||
},
|
||||
}
|
||||
|
||||
impl Template {
|
||||
pub fn template(&self) -> &str {
|
||||
match self {
|
||||
Self::Basic(template) => template,
|
||||
Self::List { template, .. } => template,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn requires_word(&self) -> bool {
|
||||
self.template().contains("{0}")
|
||||
}
|
||||
|
||||
pub fn format(&self, word: &str) -> String {
|
||||
self.template().replace("{0}", word)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
@ -21,27 +48,71 @@ pub struct WordList {
|
||||
}
|
||||
|
||||
impl Pack {
|
||||
pub fn format(&self, template_1_idx: usize, word_1_idx: Option<(usize, usize)>, conjunction: Option<usize>, template_2_idx: Option<usize>, word_2_idx: Option<(usize, usize)>) -> Option<String> {
|
||||
let template_1 = self.templates.get(template_1_idx)?;
|
||||
fn get_word(&self, list_idx: usize, word_idx: usize) -> Option<&str> {
|
||||
let words = self.words.as_ref()?;
|
||||
let list = words.get(list_idx)?;
|
||||
list.words
|
||||
.get(word_idx)
|
||||
.map(|word| word.as_str())
|
||||
}
|
||||
|
||||
if template_1.contains("{0}") && word_1_idx.is_none() {
|
||||
fn replace(
|
||||
&self,
|
||||
template: &Template,
|
||||
list_idx: usize,
|
||||
word_idx: usize,
|
||||
) -> Option<String> {
|
||||
let word = match template {
|
||||
Template::Basic(_) => self.get_word(list_idx, word_idx),
|
||||
Template::List { words, .. } => words
|
||||
.get(word_idx)
|
||||
.map(|word| word.as_str()),
|
||||
}?;
|
||||
|
||||
Some(template.format(word))
|
||||
}
|
||||
|
||||
fn partial_format(
|
||||
&self,
|
||||
template: &Template,
|
||||
word_idx: Option<(usize, usize)>,
|
||||
) -> Option<String> {
|
||||
let requires_word = template.requires_word();
|
||||
if requires_word && word_idx.is_none() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut formatted = if_chain::if_chain! {
|
||||
if template_1.contains("{0}");
|
||||
if let Some((w1_list, w1_word)) = word_1_idx;
|
||||
if_chain::if_chain! {
|
||||
if requires_word;
|
||||
if let Some((list_idx, word_idx)) = word_idx;
|
||||
then {
|
||||
let word_1 = self.words.get(w1_list)?.words.get(w1_word)?;
|
||||
template_1.replace("{0}", word_1)
|
||||
self.replace(template, list_idx, word_idx)
|
||||
} else {
|
||||
template_1.clone()
|
||||
Some(template.template().to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(conj_idx) = conjunction {
|
||||
if let Some(template_2_idx) = template_2_idx {
|
||||
let conj = self.conjunctions.get(conj_idx)?;
|
||||
pub fn format(
|
||||
&self,
|
||||
template_1_idx: usize,
|
||||
word_1_idx: Option<(usize, usize)>,
|
||||
conjunction: Option<usize>,
|
||||
template_2_idx: Option<usize>,
|
||||
word_2_idx: Option<(usize, usize)>,
|
||||
) -> Option<String> {
|
||||
let template_1 = self.templates.get(template_1_idx)?;
|
||||
let mut formatted = self.partial_format(template_1, word_1_idx)?;
|
||||
|
||||
if_chain::if_chain! {
|
||||
if let Some(conj_idx) = conjunction;
|
||||
if let Some(conjunctions) = &self.conjunctions;
|
||||
if let Some(template_2_idx) = template_2_idx;
|
||||
then {
|
||||
let template_2 = self.templates.get(template_2_idx)?;
|
||||
let append = self.partial_format(template_2, word_2_idx)?;
|
||||
|
||||
let conj = conjunctions.get(conj_idx)?;
|
||||
let is_punc = conj.len() == 1 && conj.chars().next().map(|x| x.is_ascii_punctuation()).unwrap_or(false);
|
||||
if is_punc {
|
||||
formatted.push_str(conj);
|
||||
@ -52,18 +123,6 @@ impl Pack {
|
||||
formatted.push(' ');
|
||||
}
|
||||
|
||||
let template_2 = self.templates.get(template_2_idx)?;
|
||||
let append = if_chain::if_chain! {
|
||||
if template_2.contains("{0}");
|
||||
if let Some((w2_list, w2_word)) = word_2_idx;
|
||||
then {
|
||||
let word_2 = self.words.get(w2_list)?.words.get(w2_word)?;
|
||||
template_2.replace("{0}", word_2)
|
||||
} else {
|
||||
template_2.clone()
|
||||
}
|
||||
};
|
||||
|
||||
formatted.push_str(&append);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user