#save-file #ii #section #diablo #quests #d2s #waypoints

halbu

《暗黑破坏神II》存档文件解析库

1 个不稳定版本

0.1.0 2023年9月4日

#285 in 游戏

MIT 许可证

130KB
3.5K SLoC

Halbu

用 Rust 编写的 .d2s 文件解析库。

⚠ NPC 和物品部分尚未支持。

注释,其中包含有关 D2R 的有用信息,特别是关于任务的信息。

此库使用 log crate 记录解析错误。

用法

use halbu::{quests::QuestFlag, waypoints::Waypoint, Class, Save};

fn main() {
    // The name Halbu is a node to the first hero editor I used, Jamella Editor
    let save_file = std::fs::read("C:\\Users\\Example\\Saved Games\\Diablo II Resurrected\\Jamella.d2s").unwrap();

    let mut save = Save::parse(&save_file);

    // Change class, name, etc
    save.character.class = Class::Paladin;
    save.character.name = String::from("Halbu");
    save.character.level = 47;
    save.attributes.level.value = 47;
    // Warning: save.character.level and save.attributes.level must
    // be the same or the game won't load!
    println!(
        "{0}, Level {1} {2}",
        save.character.name, save.character.level, save.character.class
    );

    // Change mercenary stats
    // Refer to notes.md for a table with name/variant ID
    save.character.mercenary.name_id = 3;
    save.character.mercenary.variant_id = 34;

    // Set an attribute
    save.attributes.strength.value = 156;

    // Attribute names are taken from itemstatcosts.txt
    save.attributes.newskills.value = 5;

    // Some attributes are stored as fixed point numbers in 21 bits,
    // where the first 13 bits are the integer part and the last 8 the decimal
    // For those attributes (Current/Max HP, Mana & Stamina), you must multiply
    // the value by 256 to get the value you want
    save.attributes.maxmana.value = 200 * 256;
    println!(
        "Max mana: {}",
        save.attributes.maxmana.value as f64 / 256f64
    );

    // Acquire all waypoints in an act
    save.waypoints.normal.act1.set_all(true);
    println!("Normal:\n{}", save.waypoints.normal.act1);

    // Set all waypoints in a difficulty
    // Warning: Not a good idea to set Rogue Encampment to false
    save.waypoints.hell.set_all(false);

    // Get/set whether a specific waypoint is acquired
    // Waypoints are a numbered 0-8 (0-2 for Act IV)
    save.waypoints.hell.act4.set_num(1, true);
    println!("Hell Act IV WP 1: {}", save.waypoints.hell.act4.get_num(1));

    save.waypoints.hell.act4.set(Waypoint::CityOfTheDamned, false);
    println!(
        "Hell Act IV WP 1: {}",
        save.waypoints.hell.act4.get(Waypoint::CityOfTheDamned)
    );

    // Set all skills to 20
    save.skills.set_all(20);
    println!("{}", save.skills);

    // Set the skill points of a given skill to 0
    save.skills.set(17, 0);
    println!("Skillpoints: {}", save.skills.get(17));

    // A quest is a struct with a single member State which is a hashset

    // Clear all flags
    // Warning: The quest numbers may not be what you think! Refer to notes.md.
    save.quests.hell.act1.q1.state.clear();
    println!("Hell Act I Q1 State: {}", save.quests.hell.act1.q1);

    // The flag names are from D2MOO. Refer to notes.md for a flagname <> bit # table.
    save.quests.hell.act1.q1.state.insert(QuestFlag::RewardGranted);
    println!(
        "Hell Act I Q1 Completed: {}",
        save.quests.hell.act1.q1.state.contains(&QuestFlag::RewardGranted)
    );
    // Save the file
    // Warning: The file name must match the character's name!
    std::fs::write("C:\\Users\\Example\\Saved Games\\Diablo II Resurrected\\Halbu.d2s", save.to_bytes()).unwrap();
}

资源

以下资源帮助我理解 .d2s 格式。感谢他们的作者所做的努力!

依赖项

~2.1–3MB
~49K SLoC