def f_wread_cp(cpo, subp): w = c.EUDVariable() k = c.EUDVariable() cs.DoActions([ [[] if cpo is 0 else c.SetMemory(0x6509B0, c.Add, cpo)], w.SetNumber(0), k.SetNumber(0), ]) cs.EUDSwitch(subp) for i in range(3): cs.EUDSwitchCase()(i) for j in range(31, -1, -1): if 8 * i <= j < 8 * (i + 2): c.RawTrigger(conditions=c.Deaths(c.CurrentPlayer, c.AtLeast, 2**j, 0), actions=[ c.SetDeaths(c.CurrentPlayer, c.Subtract, 2**j, 0), k.AddNumber(2**j), w.AddNumber(2**(j - 8 * i)) ]) else: c.RawTrigger(conditions=c.Deaths(c.CurrentPlayer, c.AtLeast, 2**j, 0), actions=[ c.SetDeaths(c.CurrentPlayer, c.Subtract, 2**j, 0), k.AddNumber(2**j), ]) if j == 8 * i: break c.SeqCompute([(c.EncodePlayer(c.CurrentPlayer), c.Add, k)]) cs.EUDBreak() if cs.EUDSwitchCase()(3): dw0 = cpm.f_dwread_cp(0) dw1 = cpm.f_dwread_cp(1) w << dwm.f_dwbreak(dw0)[5] + dwm.f_dwbreak(dw1)[2] * 256 cs.EUDEndSwitch() cs.DoActions([ [[] if cpo is 0 else c.SetMemory(0x6509B0, c.Add, -cpo)], ]) return w
def f_wwrite_cp(cpo, subp, w): k = c.EUDVariable() cs.DoActions([ [[] if cpo is 0 else c.SetMemory(0x6509B0, c.Add, cpo)], k.SetNumber(0), ]) cs.EUDSwitch(subp) for i in range(3): cs.EUDSwitchCase()(i) for j in range(31, -1, -1): if 8 * (i + 2) <= j: c.RawTrigger(conditions=c.Deaths(c.CurrentPlayer, c.AtLeast, 2**j, 0), actions=[ c.SetDeaths(c.CurrentPlayer, c.Subtract, 2**j, 0), k.AddNumber(2**j), ]) else: c.RawTrigger(conditions=c.Deaths(c.CurrentPlayer, c.AtLeast, 2**j, 0), actions=[ c.SetDeaths(c.CurrentPlayer, c.Subtract, 2**j, 0), ]) if j == 8 * i: break c.SeqCompute([ (c.CurrentPlayer, c.Add, k), (c.CurrentPlayer, c.Add, w * (256**i)), ]) cs.EUDBreak() if cs.EUDSwitchCase()(3): b0, b1 = dwm.f_dwbreak(w)[2:4] f_bwrite_cp(0, 3, b0) f_bwrite_cp(1, 0, b1) cs.EUDEndSwitch() cs.DoActions([ [[] if cpo is 0 else c.SetMemory(0x6509B0, c.Add, -cpo)], ])
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()
def f_bread_cp(cpo, subp): b = c.EUDVariable() k = c.EUDVariable() cs.DoActions([ [[] if cpo is 0 else c.SetMemory(0x6509B0, c.Add, cpo)], b.SetNumber(0), k.SetNumber(0), ]) cs.EUDSwitch(subp) for i in range(4): cs.EUDSwitchCase()(i) for j in range(31, -1, -1): if 8 * i <= j < 8 * (i + 1): c.RawTrigger(conditions=c.Deaths(c.CurrentPlayer, c.AtLeast, 2**j, 0), actions=[ c.SetDeaths(c.CurrentPlayer, c.Subtract, 2**j, 0), k.AddNumber(2**j), b.AddNumber(2**(j - 8 * i)) ]) else: c.RawTrigger(conditions=c.Deaths(c.CurrentPlayer, c.AtLeast, 2**j, 0), actions=[ c.SetDeaths(c.CurrentPlayer, c.Subtract, 2**j, 0), k.AddNumber(2**j), ]) if j == 8 * i: break c.SeqCompute([(c.EncodePlayer(c.CurrentPlayer), c.Add, k)]) cs.EUDBreak() cs.EUDEndSwitch() cs.DoActions([ [[] if cpo is 0 else c.SetMemory(0x6509B0, c.Add, -cpo)], ]) return b
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()