Skip to content

Stage 0.4 Damage Procedure

neuront edited this page Jan 31, 2012 · 1 revision

Code review: https://github.com/neuront/sgs/commit/301a8e2e042d02b636839d7e6aba13c610719c0d

伤害过程框架

游戏规则

https://github.com/neuront/sgs/wiki/Damage-Procedure-Specification

数据结构

内核中的伤害类型 core.src.damage.Damage 包括下面的基本属性

  • source: 伤害来源
  • victim: 伤害目标
  • action: 造成伤害的动作
  • cards: 造成伤害的卡牌
  • category: 伤害类型
  • point: 伤害点数

伤害结算过程中, 这些属性可能被修改.

进行结算

构造 core.src.damage.Damage 实例时, 需要传入伤害前结算步骤列表和伤害后步骤列表.

调用 core.src.damage.Damage 实例的方法 operate 开始结算伤害. 结算伤害时, 顺序执行伤害前步骤, 实际产生伤害 (调用 `core.src.game_control.GameControl.

调用 core.src.damage.Damage 实例的方法 interrupt 将会中断 (并非中止) 此伤害过程, 传入的参数应该是一个无参函数, 这个函数在中断后立即执行.

中断后, 如果伤害需要继续结算, 则调用 core.src.damage.Damage 实例的方法 resume 将恢复伤害过程结算. 伤害将会从中断的步骤之后的第一个步骤继续.

如, 拥有天香技能的角色可以在发动天香的时机中断伤害结算. 如果决定发动天香, 则中止目前的伤害结算, 并创建新的伤害过程; 否则, 继续恢复当前的伤害结算.

与伤害结算相关的技能步骤实现参考

藤甲 (伤害部分)

def one_more_fire_damage(damage):
    if damage.category == 'fire':
        damage.point += 1

承受火属性伤害时, 伤害点数 +1

绝情

def to_vigor_lost(damage, game_control):
    damage.cancel(lambda: game_control.vigor_lost(damage.victim, damage.point))

中断伤害, 中断后, 调用 game_controlvigor_lost 方法直接造成体力流失. 也就是说伤害结算将在此步骤结束.

天香

def ask_damage_tranfer(damage, game_control):
    damage.cancel(lambda:
            game_control.push_frame(_AskHeavenlyScent(game_control, damage)))

结算到此步骤时, 立即中断结算, 并在动作栈中压入询问是否发动天香的帧

class _AskHeavenlyScent(DiscardCards):
    def __init__(self, game_control, damage):
        DiscardCards.__init__(
              self, game_control, damage.victim,
              lambda cards_ids: _check_one_heart_card(game_control, cards_ids),
              lambda gc, a: _damage_transfer(gc, a, damage))

    def react(self, args):
        cards = args['discard']
        if len(cards) > 0:
            targets_ids = args['targets']
            checking.only_one_target(targets_ids)
            checking.forbid_target_self(self.player.player_id, targets_ids[0])
        return DiscardCards.react(self, args)

该帧类型继承自弃牌帧, react 函数中除了弃牌帧需要的参数外, 如果有弃牌 (即, 选择发动天香) 需要指定参数 'targets'. 而该帧退栈后, 调用的 _damage_transfer 方法实现如下

def _damage_transfer(game_control, args, damage):
    if len(args['discard']) > 0:
        target = game_control.player_by_id(args['targets'][0])
        Damage(damage.source, target, damage.action, damage.cards,
               damage.category, damage.point,
               [target.actions_before_damaged['equip']['trigger'],
                target.actions_before_damaged['equip']['ability']],
               damage.source.after_damaging_actions() +
               target.after_damaged_actions()).resume(game_control)
    else:
        damage.resume(game_control)

如果弃了一张红桃花色手牌, 并指定了天香目标, 则原伤害中止, 构造新的伤害对象进行结算, 否则恢复原伤害结算.

由于目前尚未实现体力, 因此天香转移伤害的目标在伤害结算后摸牌未实现.

狂骨

def regain_vigor(damage, game_control):
    if game_control.distance_between(damage.source, damage.victim) <= 1:
        game_control.vigor_regain(damage.source, damage.point)

如果伤害来源到目标距离不超过 1, 则调用 game_controlvigor_regain 方法回复一点体力.

设计修正

弃牌动作由弃牌帧 core.src.action_frames.DiscardCardsreact 方法在完成卡牌验证后调用, 不再需要在传入的 on_result 函数中进行.

Clone this wiki locally