Exemple #1
0
def f_dbstr_addptr(dst, number):
    """Print number as string to dst.

    :param dst: Destination address (Not EPD player)
    :param number: DWORD to print

    :returns: dst + strlen(itoa(number))
    """
    bw1.seekoffset(dst)
    ch = [0] * 8

    # Get digits
    for i in range(8):
        number, ch[i] = c.f_div(number, 16)

    # print digits
    for i in range(7, -1, -1):
        if cs.EUDIf()(ch[i] <= 9):
            bw1.writebyte(ch[i] + b'0'[0])
        if cs.EUDElse()():
            bw1.writebyte(ch[i] + (b'A'[0] - 10))
        cs.EUDEndIf()
        dst += 1

    bw1.writebyte(0)  # EOS
    bw1.flushdword()

    return dst
Exemple #2
0
def EUDLoopTrigger(player):
    player = c.EncodePlayer(player)

    tbegin = tt.TrigTriggerBegin(player)
    if cs.EUDIfNot()(tbegin == 0):
        tend = tt.TrigTriggerEnd(player)
        for ptr, epd in EUDLoopList(tbegin, tend):
            yield ptr, epd
    cs.EUDEndIf()
Exemple #3
0
def EUDNot(cond):
    """ !cond

    :param conds: Condition to negate
    """

    v = c.EUDVariable()
    if cs.EUDIf()(cond):
        v << 0
    if cs.EUDElse()():
        v << 1
    cs.EUDEndIf()
    return v
Exemple #4
0
def EUDBinaryMin(cond, minv=0, maxv=0xFFFFFFFF):
    """ Find minimum x satisfying cond(x) using binary search

    :param cond: Test condition
    :param minv: Minimum value in domain
    :param maxv: Maximum value in domain

    Cond should be binary classifier, meaning that for some N
        for all x < N, cond(x) is false.
        for all x >= N, cond(x) is true
    Then EUDBinaryMin will find such N

    .. note:: If none of the value satisfies condition, then this
        function will return maxv.
    """
    x = c.EUDVariable()
    x << maxv

    if isinstance(minv, int) and isinstance(maxv, int):
        r = maxv - minv
        if r == 0:
            return minv

    else:
        r = None

    for i in range(31, -1, -1):
        if r and 2**i > r:
            continue

        if cs.EUDIf()([x >= 2**i]):
            cs.DoActions(x.SubtractNumber(2**i))
            if cs.EUDIfNot()([x >= minv, cond(x)]):
                cs.DoActions(x.AddNumber(2**i))
            cs.EUDEndIf()
        cs.EUDEndIf()

    return x
Exemple #5
0
def f_getcurpl():
    """Get current player value.

    eudplib internally caches the current player value, so this function uses
    that value if the value is valid. Otherwise, update the current player
    cache and return it.
    """
    cpcond = c.curpl.cpcacheMatchCond()
    cpcache = c.curpl.GetCPCache()
    if cs.EUDIfNot()(cpcond):
        _f_updatecpcache()
    cs.EUDEndIf()

    return cpcache
Exemple #6
0
def f_randomize():
    global _seed

    # Store switch 1
    sw1 = c.EUDVariable()
    if cs.EUDIf()(c.Switch("Switch 1", c.Set)):
        sw1 << c.EncodeSwitchAction(c.Set)
    if cs.EUDElse()():
        sw1 << c.EncodeSwitchAction(c.Clear)
    cs.EUDEndIf()

    _seed << 0
    dseed = c.EUDVariable()
    dseed << 1

    if cs.EUDLoopN()(32):
        cs.DoActions(c.SetSwitch("Switch 1", c.Random))
        if cs.EUDIf()(c.Switch("Switch 1", c.Set)):
            _seed += dseed
        cs.EUDEndIf()
        dseed += dseed
    cs.EUDEndLoopN()

    cs.DoActions(c.SetSwitch("Switch 1", sw1))
Exemple #7
0
def EUDOr(cond1, *conds):
    """ cond1 || cond2 || ... || condn

    .. warning:: Short circuiting is not supported

    :param conds: List of conditions
    """

    v = c.EUDVariable()
    if cs.EUDIf()(cond1):
        v << 1
    for cond in conds:
        if cs.EUDElseIf()(cond):
            v << 1
    if cs.EUDElse()():
        v << 0
    cs.EUDEndIf()
    return v
Exemple #8
0
def f_playerexist(player):
    """Check if player has not left the game.

    :returns: 1 if player exists, 0 if not.
    """
    pts = 0x51A280

    cs.EUDSwitch(player)
    for p in range(8):
        if cs.EUDSwitchCase()(p):
            if cs.EUDIf()(c.Memory(pts + p * 12 + 8, c.Exactly,
                                   ~(pts + p * 12 + 4))):
                c.EUDReturn(0)
            if cs.EUDElse()():
                c.EUDReturn(1)
            cs.EUDEndIf()

    if cs.EUDSwitchDefault()():
        c.EUDReturn(0)
    cs.EUDEndSwitch()
Exemple #9
0
def QueueGameCommand(data, size):
    """Queue game command to packet queue.

    Starcraft periodically boradcasts game packets to other player. Game
    packets are stored to queue, and this function add data to that queue, so
    that SC can boradcast it.

    :param data: Data to put in queue
    :param size: Size of data

    .. note::
        If packet queue is full, this function fails. This behavior is silent
        without any warning or error, since this behavior shouldn't happen in
        common situations. So **Don't use this function too much in a frame.**

    """
    prov_maxbuffer = f_dwread_epd(ut.EPD(0x57F0D8))
    cmdqlen = f_dwread_epd(ut.EPD(0x654AA0))
    if cs.EUDIfNot()(cmdqlen + size + 1 >= prov_maxbuffer):
        f_memcpy(0x654880 + cmdqlen, data, size)
        c.SetVariables(ut.EPD(0x654AA0), cmdqlen + size)
    cs.EUDEndIf()
Exemple #10
0
def EUDAnd(cond1, *conds):
    """ cond1 && cond2 && ... && condn

    .. note::
        This function computes AND value of various conditions.
        If you don't want to do much computation, you should better use
        plain list instead of this function.

    .. warning:: Short circuiting is not supported.

    :param conds: List of conditions
    """

    v = c.EUDVariable()
    if cs.EUDIfNot()(cond1):
        v << 0
    for cond in conds:
        if cs.EUDElseIfNot()(cond):
            v << 0
    if cs.EUDElse()():
        v << 1
    cs.EUDEndIf()
    return v
Exemple #11
0
def f_atan2(y, x):
    signflags = c.EUDVariable()
    signflags << 0

    # Check x sign
    if cs.EUDIf()(x >= 0x80000000):
        x << -x
        signflags += 1  # set xsign
    cs.EUDEndIf()

    # Check y sign
    if cs.EUDIf()(y >= 0x80000000):
        y << -y
        signflags += 2  # set ysign
    cs.EUDEndIf()

    # Check x/y order
    if cs.EUDIf()(y >= x):
        z = c.EUDVariable()
        # Swap x, y so that y <= x
        z << x
        x << y
        y << z
        signflags += 4  # set xyabscmp
    cs.EUDEndIf()

    # To prevent overflow, we limit values of y and x.
    # atan value is maximized when x = y, then atan_value = 45 * x**3
    # 45 * x**3 <= 0xFFFFFFFF : x <= 456.99....
    if cs.EUDIf()(x >= 400):
        # Normalize below 400
        divn = x // 400 + 1
        x //= divn
        y //= divn
    cs.EUDEndIf()

    # Calculate arctan value
    # arctan(z) ~= z * (45 - (z-1) * (14 + 4*z)), 0 <= z <= 1
    # arctan(y/x) ~= y/x * (45 - (y-x)/x * (14x + 4y)/x))
    # arctan(y/x) ~= y * (45*x*x - (y-x)(14x+4y)) / (x*x*x)
    t1 = x * x
    t2 = y * (45 * t1 - (y - x) * (14 * x + 4 * y))
    t3 = x * t1
    atan_value = t2 // t3

    # Translate angles by sign flags
    #
    #      |  0 |  1 | xsign          |  0 |  1 | xsign
    # -----+----+----+-----      -----+----+----+-----
    #   0  |  0+|180-|             0  | 90-| 90+|
    # -----+----+----+           -----+----+----+
    #   1  |360-|180+|             1  |270+|270-|
    # -----+----+----+           -----+----+----+
    # ysign|      xyabscmp=0     ysign|      xyabscmp=1

    cs.EUDSwitch(signflags)
    cs.EUDSwitchCase()(0)  # xsign, ysign, xyabscmp = 0, 0, 0
    c.EUDReturn(atan_value)
    cs.EUDSwitchCase()(1)  # xsign, ysign, xyabscmp = 1, 0, 0
    c.EUDReturn(180 - atan_value)
    cs.EUDSwitchCase()(2)  # xsign, ysign, xyabscmp = 0, 1, 0
    c.EUDReturn(360 - atan_value)
    cs.EUDSwitchCase()(3)  # xsign, ysign, xyabscmp = 1, 1, 0
    c.EUDReturn(180 + atan_value)
    cs.EUDSwitchCase()(4)  # xsign, ysign, xyabscmp = 0, 0, 1
    c.EUDReturn(90 - atan_value)
    cs.EUDSwitchCase()(5)  # xsign, ysign, xyabscmp = 1, 0, 1
    c.EUDReturn(90 + atan_value)
    cs.EUDSwitchCase()(6)  # xsign, ysign, xyabscmp = 0, 1, 1
    c.EUDReturn(270 + atan_value)
    cs.EUDSwitchCase()(7)  # xsign, ysign, xyabscmp = 1, 1, 1
    c.EUDReturn(270 - atan_value)
    cs.EUDEndSwitch()
Exemple #12
0
def f_lengthdir(length, angle):
    # sin, cos table
    clist = []
    slist = []

    for i in range(91):
        cosv = math.floor(math.cos(math.pi / 180 * i) * 65536 + 0.5)
        sinv = math.floor(math.sin(math.pi / 180 * i) * 65536 + 0.5)
        clist.append(ut.i2b4(cosv))
        slist.append(ut.i2b4(sinv))

    cdb = c.Db(b''.join(clist))
    sdb = c.Db(b''.join(slist))

    # MAIN LOGIC

    if cs.EUDIf()(angle >= 360):
        angle << c.f_div(angle, 360)[1]
    cs.EUDEndIf()

    ldir_x, ldir_y = c.EUDVariable(), c.EUDVariable()  # cos, sin * 65536
    # sign of cos, sin
    csign, ssign = c.EUDLightVariable(), c.EUDLightVariable()
    tableangle = c.EUDVariable()

    # get cos, sin from table
    if cs.EUDIf()(angle <= 89):
        tableangle << angle
        csign << 1
        ssign << 1

    if cs.EUDElseIf()(angle <= 179):
        tableangle << 180 - angle
        csign << -1
        ssign << 1

    if cs.EUDElseIf()(angle <= 269):
        tableangle << angle - 180
        csign << -1
        ssign << -1

    if cs.EUDElse()():
        tableangle << 360 - angle
        csign << 1
        ssign << -1

    cs.EUDEndIf()

    tablecos = f_dwread_epd(ut.EPD(cdb) + tableangle)
    tablesin = f_dwread_epd(ut.EPD(sdb) + tableangle)

    # calculate lengthdir
    ldir_x << c.f_div(c.f_mul(tablecos, length), 65536)[0]
    ldir_y << c.f_div(c.f_mul(tablesin, length), 65536)[0]

    # restore sign of cos, sin
    if cs.EUDIf()(csign == -1):
        ldir_x << 0xFFFFFFFF - ldir_x + 1
    cs.EUDEndIf()

    if cs.EUDIf()(ssign == -1):
        ldir_y << 0xFFFFFFFF - ldir_y + 1
    cs.EUDEndIf()

    return ldir_x, ldir_y