コード例 #1
0
def Trigger(players, conditions=[], actions=[]):
    conditions = ut.FlattenList(conditions)
    actions = ut.FlattenList(actions)

    ut.ep_assert(type(players) is list)
    ut.ep_assert(type(conditions) is list)
    ut.ep_assert(type(actions) is list)
    ut.ep_assert(len(conditions) <= 16)
    ut.ep_assert(len(actions) <= 64)
    peff = bytearray(28)
    for p in players:
        peff[EncodePlayer(p)] = 1

    b = b''.join(conditions + [bytes(20 * (16 - len(conditions)))] + actions +
                 [bytes(32 * (64 - len(actions)))] + [b'\x04\0\0\0'] +
                 [bytes(peff)])
    ut.ep_assert(len(b) == 2400)
    return b
コード例 #2
0
ファイル: eudprint.py プロジェクト: phu54321/eudplib
def f_dbstr_print(dst, *args):
    """Print multiple string / number to dst.

    :param dst: Destination address (Not EPD player)
    :param args: Things to print

    """
    if ut.isUnproxyInstance(dst, DBString):
        dst = dst.GetStringMemoryAddr()

    args = ut.FlattenList(args)
    for arg in args:
        if ut.isUnproxyInstance(arg, bytes):
            dst = f_dbstr_addstr(dst, c.Db(arg + b'\0'))
        elif ut.isUnproxyInstance(arg, str):
            dst = f_dbstr_addstr(dst, c.Db(ut.u2b(arg) + b'\0'))
        elif ut.isUnproxyInstance(arg, DBString):
            dst = f_dbstr_addstr(dst, arg.GetStringMemoryAddr())
        elif ut.isUnproxyInstance(arg, int):
            # int and c.EUDVariable should act the same if possible.
            # EUDVariable has a value of 32bit unsigned integer.
            # So we adjust arg to be in the same range.
            dst = f_dbstr_addstr(dst, c.Db(
                ut.u2b(str(arg & 0xFFFFFFFF)) + b'\0'))
        elif ut.isUnproxyInstance(arg, c.EUDVariable):
            dst = f_dbstr_adddw(dst, arg)
        elif c.IsConstExpr(arg):
            dst = f_dbstr_adddw(dst, arg)
        elif ut.isUnproxyInstance(arg, hptr):
            dst = f_dbstr_addptr(dst, arg._value)
        else:
            raise ut.EPError(
                'Object wit unknown parameter type %s given to f_eudprint.'
                % type(arg)
            )

    return dst
コード例 #3
0
def EUDBranch(conditions, ontrue, onfalse):
    """Branch by whether conditions is satisfied or not.

    :param conditions: Nested list of conditions.
    :param ontrue: When all conditions are true, this branch is taken.
    :param onfalse: When any of the conditions are false, this branch is taken.
    """
    conditions = ut.FlattenList(conditions)
    conditions = list(map(PatchCondition, conditions))

    if len(conditions) == 0:
        c.RawTrigger(nextptr=ontrue)  # Just jump
        return

    # Check all conditions
    for i in range(0, len(conditions), 16):
        subontrue = c.Forward()
        subonfalse = onfalse
        _EUDBranchSub(conditions[i:i + 16], subontrue, subonfalse)

        if i + 16 < len(conditions):
            subontrue << c.NextTrigger()
        else:
            subontrue << ontrue
コード例 #4
0
ファイル: triggerdef.py プロジェクト: phu54321/eudplib
def Trigger(conditions=None, actions=None, preserved=True):
    """General easy-to-use trigger

    :param conditions: List of conditions. If there are none, trigger will
        always execute.
    :param actions: List of actions. If there are none, trigger will have no
        actions.
    :param preserved: Is trigger preserved? True by default.

    .. note::
        This is 'extended' trigger. All conditions and variables can contain
        `EUDVariable` object, and there may be more than 16 conditions and 64
        actions. Trigger internally uses `RawTrigger`.
    """

    ut.ep_assert(isinstance(preserved, bool), 'preserved should be bool')

    if conditions is None:
        conditions = []
    if actions is None:
        actions = None

    conditions = ut.FlattenList(conditions)
    actions = ut.FlattenList(actions)

    # Normal
    if len(conditions) <= 16 and len(actions) <= 64:
        patched_conds = []
        for cond in conditions:
            patched_conds.append(PatchCondition(cond))

        patched_actions = []
        for act in actions:
            patched_actions.append(PatchAction(act))

        c.RawTrigger(conditions=patched_conds,
                     actions=patched_actions,
                     preserved=preserved)

    else:
        # Extended trigger
        condts = []
        cend = c.Forward()

        # Check conditions
        for i in range(0, len(conditions), 16):
            conds = conditions[i:i + 16]
            cts = c.Forward()

            patched_conds = []
            for cond in conds:
                patched_conds.append(PatchCondition(cond))

            nextcond = c.Forward()
            cts << c.RawTrigger(nextptr=cend,
                                conditions=patched_conds,
                                actions=c.SetNextPtr(cts, nextcond))
            nextcond << c.NextTrigger()

            condts.append(cts)

        skipt = c.Forward()
        if not preserved:
            a = c.RawTrigger()
            c.RawTrigger(actions=c.SetNextPtr(a, skipt))

        # Execute actions
        for i in range(0, len(actions), 64):
            acts = actions[i:i + 64]
            patched_actions = []
            for act in acts:
                patched_actions.append(PatchAction(act))

            c.RawTrigger(actions=patched_actions)

        if not preserved:
            skipt << c.NextTrigger()

        # Revert conditions
        cend << c.NextTrigger()
        for i in range(0, len(condts), 64):
            c.RawTrigger(
                actions=[c.SetNextPtr(cts, cend) for cts in condts[i:i + 64]])
コード例 #5
0
    def __init__(self,
                 prevptr=None,
                 nextptr=None,
                 conditions=None,
                 actions=None,
                 *args,
                 preserved=True,
                 trigSection=None):
        super().__init__()

        # Register trigger to global table
        global _trgCounter
        _trgCounter += 1
        _RegisterTrigger(self)  # This should be called before (1)

        # Set linked list pointers
        if prevptr is None:
            prevptr = 0
        if nextptr is None:
            nextptr = NextTrigger()  # (1)

        self._prevptr = prevptr
        self._nextptr = nextptr

        # Uses normal condition/action initialization
        if trigSection is None:
            # Normalize conditions/actions
            if conditions is None:
                conditions = []
            conditions = ut.FlattenList(conditions)
            conditions = list(map(_bool2Cond, conditions))

            if actions is None:
                actions = []
            actions = ut.FlattenList(actions)

            ut.ep_assert(len(conditions) <= 16, 'Too many conditions')
            ut.ep_assert(len(actions) <= 64, 'Too many actions')

            # Register condition/actions to trigger
            for i, cond in enumerate(conditions):
                cond.CheckArgs(i)
                cond.SetParentTrigger(self, i)

            for i, act in enumerate(actions):
                act.CheckArgs(i)
                act.SetParentTrigger(self, i)

            self._conditions = conditions
            self._actions = actions
            self.preserved = preserved

        # Uses trigger segment for initialization
        # NOTE : player information is lost inside eudplib.
        else:
            self._conditions = [
                Db(trigSection[i * 20:i * 20 + 20]) for i in range(16)
            ]
            self._actions = [
                Db(trigSection[320 + i * 32:320 + i * 32 + 32])
                for i in range(64)
            ]
            self.preserved = bool(trigSection[320 + 2048] & 4)
コード例 #6
0
ファイル: ptrigger.py プロジェクト: phu54321/eudplib
def PTrigger(players, conditions=None, actions=None):
    """Execute trigger by player basis

    :param players: Players the trigger should execute with. When Current
        Player specifies any of the players, trigger will execute.
    :param conditions: List of conditions. If all conditions are met, then
        actions will be executed.
    :param actions: List of actions.
    """

    InitPTrigger()

    players = ut.FlattenList(players)
    effp = [False] * 8

    # Trigger is never executed if it has no effplayers.
    if len(players) == 0:
        return

    # Check whose the player is executed to.
    for player in players:
        player = c.EncodePlayer(player)

        if 0 <= player <= 7:
            effp[player] = True

        elif 0x12 <= player <= 0x15:  # Force 1 ~ 4
            forceIndex = player - 0x12
            for p in range(8):
                if _pinfos[p].force == forceIndex:
                    effp[p] = True

        elif player == 0x11:  # All players
            for p in range(8):
                effp[p] = True
            break

    # Create player table!
    dbb = b''.join([b'\0\0\0\0' if eff is False else b'aaaa' for eff in effp])
    if dbb in _pdbtable:
        pdb = _pdbtable[dbb]

    else:
        pdb = c.Db(dbb)
        _pdbtable[dbb] = pdb

    # effplayer[p] is True  -> Memory(EPD(pdb) + p) == b'aaaa'
    # effplayer[p] is False -> Memory(EPD(pdb) + p) == b'\0\0\0\0'

    # Create triggers
    offset_curpl = 0x6509B0
    t1, t2, tc, t3 = c.Forward(), c.Forward(), c.Forward(), c.Forward()

    t1 << c.RawTrigger(nextptr=t3,
                       conditions=c.Memory(offset_curpl, c.AtMost, 7),
                       actions=[
                           c.SetNextPtr(t1, t2),
                           c.SetMemory(offset_curpl, c.Add, ut.EPD(pdb))
                       ])

    t2 << c.RawTrigger(nextptr=t3,
                       conditions=c.Deaths(c.CurrentPlayer, c.Exactly,
                                           ut.b2i4(b'aaaa'), 0),
                       actions=[
                           c.SetNextPtr(t2, tc),
                           c.SetMemory(offset_curpl, c.Subtract, ut.EPD(pdb)),
                       ])

    tc << c.NextTrigger()

    Trigger(conditions, actions)

    c.RawTrigger(actions=[
        c.SetNextPtr(t2, t3),
        c.SetMemory(offset_curpl, c.Add, ut.EPD(pdb))
    ])

    t3 << c.RawTrigger(actions=[
        c.SetNextPtr(t1, t3),
        c.SetMemory(offset_curpl, c.Subtract, ut.EPD(pdb))
    ])
コード例 #7
0
ファイル: basicstru.py プロジェクト: phu54321/eudplib
def DoActions(actions, preserved=True):
    tg.Trigger(actions=ut.FlattenList(actions), preserved=preserved)