是时候变得更强了——升级你的城堡

在战斗之后,假设获胜者现在有足够的经验点数进行升级。城堡的等级设计从1到10,每个等级需要不同的升级经验点数。

在core.move中添加所需的经验点常量:

/// 等级2-10所需的经验点数
const REQUIRED_EXP_LEVELS : vector<u64> = vector[100, 150, 225, 338, 507, 760, 1140, 1709, 2563];

在core.move中创建一个upgrade_castle函数并获取城堡数据:

/// 消耗经验池中的经验点来升级城堡
public(package) fun upgrade_castle(id: ID, game_store: &mut GameStore) {
    // 1. 获取城堡数据
    let castle_data = dynamic_field::borrow_mut<ID, CastleData>(&mut game_store.id, id);
}

消耗经验点并进行升级,重复这一过程直到达到最大等级,或经验点不足为止:

// 2. 如果经验足够,持续升级
let mut initial_level = castle_data.level;
let mut exp_level_map = REQUIRED_EXP_LEVELS;
while (castle_data.level < MAX_CASTLE_LEVEL) {
    let exp_required_at_current_level = *vector::borrow(&exp_level_map, castle_data.level - 1);
    if(castle_data.experience_pool < exp_required_at_current_level) {
        break
    };

    castle_data.experience_pool = castle_data.experience_pool - exp_required_at_current_level;
    castle_data.level = castle_data.level + 1;
};

/// 最大城堡等级
const MAX_CASTLE_LEVEL : u64 = 10;

如果城堡升级了,更新其基础经济力量、基础攻击和防御力量。需要重新计算它们。

基础经济力量通过其初始力量计算,每升一级增加20%。在core.move中:

/// 计算城堡的基础经济力量
fun calculate_castle_base_economic_power(castle_data: &CastleData): u64 {
    let initial_base_power = get_initial_economic_power(castle_data.size);
    let level = castle_data.level;
    math::divide_and_round_up(initial_base_power * 12 * math::pow(10, ((level - 1) as u8)), 10)
}

对于基础攻击力和基础防御力,除了每级增加20%,还有一个大小系数需要乘以。在 core.move 中:

/// 获取城堡大小系数
fun get_castle_size_factor(castle_size: u64): u64 {
    let factor;
    if (castle_size == CASTLE_SIZE_SMALL) {
        factor = CASTLE_SIZE_FACTOR_SMALL;
    } else if (castle_size == CASTLE_SIZE_MIDDLE) {
        factor = CASTLE_SIZE_FACTOR_MIDDLE;
    } else if (castle_size == CASTLE_SIZE_BIG) {
        factor = CASTLE_SIZE_FACTOR_BIG;
    } else {
        abort 0
    };
    factor
}

/// 城堡大小系数 - 小
const CASTLE_SIZE_FACTOR_SMALL : u64 = 2;
/// 城堡大小系数 - 中
const CASTLE_SIZE_FACTOR_MIDDLE : u64 = 3;
/// 城堡大小系数 - 大
const CASTLE_SIZE_FACTOR_BIG : u64 = 5;

然后计算攻击力/防御力:

/// 根据等级计算城堡的基础攻击力和基础防御力
/// 基础攻击力 = (城堡大小系数 * 初始攻击力 * (1.2 ^ (等级 - 1)))
/// 基础防御力 = (城堡大小系数 * 初始防御力 * (1.2 ^ (等级 - 1)))
fun calculate_castle_base_attack_defense_power(castle_data: &CastleData): (u64, u64) {
    let castle_size_factor = get_castle_size_factor(castle_data.size);
    let (initial_attack, initial_defense) = get_initial_attack_defense_power(castle_data.race);
    let attack_power = math::divide_and_round_up(castle_size_factor * initial_attack * 12 * math::pow(10, ((castle_data.level - 1) as u8)), 10);
    let defense_power = math::divide_and_round_up(castle_size_factor * initial_defense * 12 * math::pow(10, ((castle_data.level - 1) as u8)), 10);
    (attack_power, defense_power)
}

回到 upgrade_castle 函数:

// 3. 如果升级了,更新力量
if (castle_data.level > initial_level) {
    let base_economic_power = calculate_castle_base_economic_power(freeze(castle_data));
    castle_data.economy.base_power = base_economic_power;

    let (attack_power, defense_power) = calculate_castle_base_attack_defense_power(freeze(castle_data));
    castle_data.millitary.attack_power = attack_power;
    castle_data.millitary.defense_power = defense_power;
}

还记得freeze吗?如果需要,请查看“参数传递”一课。

检查完整的升级城堡函数:

/// 消耗经验池中的经验点来升级城堡
public(package) fun upgrade_castle(id: ID, game_store: &mut GameStore) {
    // 1. 获取城堡数据
    let castle_data = dynamic_field::borrow_mut<ID, CastleData>(&mut game_store.id, id);

    // 2. 如果经验足够,持续升级
    let initial_level = castle_data.level;
    let exp_level_map = REQUIRED_EXP_LEVELS;
    while (castle_data.level < MAX_CASTLE_LEVEL) {
        let exp_required_at_current_level = *vector::borrow(&exp_level_map, castle_data.level - 1);
        if(castle_data.experience_pool < exp_required_at_current_level) {
            break
        };

        castle_data.experience_pool = castle_data.experience_pool - exp_required_at_current_level;
        castle_data.level = castle_data.level + 1;
    };

    // 3. 如果升级了,更新力量
    if (castle_data.level > initial_level) {
        let base_economic_power = calculate_castle_base_economic_power(freeze(castle_data));
        castle_data.economy.base_power = base_economic_power;

        let (attack_power, defense_power) = calculate_castle_base_attack_defense_power(freeze(castle_data));
        castle_data.millitary.attack_power = attack_power;
        castle_data.millitary.defense_power = defense_power;
    }
}

最后,在 castle.move 中添加一个入口:

/// 升级城堡
entry fun upgrade_castle(castle: &Castle, game_store: &mut GameStore) {
    core::upgrade_castle(object::id(castle), game_store);
}