ㅋㅋㅋㅋㅋ 시발.. 체력바가 노가다란다 ㅠㅠㅠㅠㅠㅠ
from eudplib import *
CP = EPD(0x6509B0)
HPBAR_WIDTH = 4
HPBAR_HEIGHT = 4
unitsize_bottom = EUDVArray(228)()
br = EUDByteReader()
def zero_max_shields_and_hp():
"""
다양한 초기화 트리거...
실드 안 쓰는 유닛은 최대 실드를 0으로 설정한다.
절대무적이거나 최대체력이 2500(하이브)보다 높으면 1로 설정한다.
유닛의 아래 크기를 배열에 저장한다. 체력바가 유닛 중심보다 얼마나 아래로 내려와야할지 구하는 용도.
"""
HAS_SHIELDS = EPD(0x6647B0)
SHIELD_AMOUNT = 0x660E00
MAX_HP = EPD(0x662350)
SPECIAL_ABILITY_FLAGS = 0x664080
UNITSIZE_RIGHT_BOTTOM = EPD(0x6617CC)
unit_id = EUDLightVariable()
set_max_shields = Forward()
set_max_hp = [Forward() for _ in range(2)]
set_unitsize_bottom = [Forward() for _ in range(2)]
br.seekepd(HAS_SHIELDS)
if EUDWhile()(unit_id <= 227):
has_shields = br.readbyte()
RawTrigger(
conditions=has_shields.Exactly(0),
actions=[
set_max_shields << SetMemoryX(SHIELD_AMOUNT, SetTo, 0, 0xFFFF)
]
)
DoActions([set_max_hp[0] << SetMemoryEPD(CP, SetTo, MAX_HP)])
RawTrigger(
conditions=Deaths(CurrentPlayer, AtLeast, 0x9C401, 0), # > 2500
actions=SetDeaths(CurrentPlayer, SetTo, 1, 0),
)
RawTrigger(
conditions=[
set_max_hp[1] << MemoryX(SPECIAL_ABILITY_FLAGS, AtLeast, 1, 1 << 29)
],
actions=SetDeaths(CurrentPlayer, SetTo, 1, 0),
)
temp = EUDVariable()
DoActions([
set_unitsize_bottom[0] << SetMemoryEPD(CP, SetTo, UNITSIZE_RIGHT_BOTTOM),
temp.SetNumber(0)
])
for a in range(9):
b = a + 16
RawTrigger(
conditions=DeathsX(CurrentPlayer, AtLeast, 1, 0, 2**b),
actions=temp.AddNumber(2**a)
)
VProc(temp, [
set_unitsize_bottom[1] << SetMemory(temp._varact + 16, SetTo, EPD(unitsize_bottom) + 87),
unit_id.AddNumber(1),
SetMemory(set_max_shields, SetTo, 0xFFFF0000),
SetMemory(set_max_hp[0] + 20, Add, 1),
SetMemory(set_max_hp[1] + 4, Add, 1),
SetMemory(set_unitsize_bottom[0] + 20, Add, 2),
SetMemory(set_unitsize_bottom[1] + 20, Add, 18),
])
RawTrigger(
conditions=unit_id.ExactlyX(0, 1),
actions=[
SetMemory(set_max_shields, SetTo, 0xFFFF),
SetMemory(set_max_shields + 16, Add, 1),
]
)
EUDEndWhile()
def zero_current_shields(epd):
"""실드 안 쓰는 유닛은 현재 실드를 0으로 설정한다."""
current_shields = epd + 0x60 // 4
if EUDIf()(MemoryEPD(current_shields, Exactly, 0x6400)): # 100
f_dwwrite_epd(current_shields, 0)
EUDEndIf()
def zero_current_hp(epd):
"""현재 체력이 2500(하이브)보다 높으면 1로 설정한다."""
current_hp = epd + 0x8 // 4
if EUDIf()(MemoryEPD(current_hp, AtLeast, 0x9C401)): # > 2500
f_dwwrite_epd(current_hp, 1)
EUDEndIf()
def onPluginStart():
DoActions([
# Scanner Sweep의 유닛기제 & 팔레트 설정
SetMemoryX(0x661558, SetTo, 1 << 17, 1 << 17),
])
zero_max_shields_and_hp()
for ptr, epd in EUDLoopUnit2():
zero_current_shields(epd)
zero_current_hp(epd)
f_setcurpl(Player1)
SCAN_VISION = 0x663259
SCANHIT_IMAGE = 0x666458
IMAGE425_ISCRIPT = 0x66F2EC # 이미지 [425] Unknown425
IMAGE232_ISCRIPT = 0x66EFE8 # 이미지 [232] Nuke Beam
IMAGECOORD_DIFF = 20
def set_scanhit_image(img):
"""Scanner Sweep Hit 스프라이트가 사용할 이미지를 설정한다."""
return SetMemoryX(SCANHIT_IMAGE, SetTo, img, 0xFFFF)
def prepare_hpbar():
"""스캔 시야 0으로 설정, 스캔이 쓸 이미지의 iscript를 250번으로 설정해 1 프레임 후 사라지게 한다."""
DoActions([
SetMemoryX(SCAN_VISION, SetTo, 0, 0xFF00),
set_scanhit_image(425), # 이미지 [425] Unknown425
SetMemory(IMAGE425_ISCRIPT, SetTo, 250),
SetMemory(IMAGE232_ISCRIPT, SetTo, 250),
])
def finish_hpbar():
"""스캔 시야, 이미지, iscript 원상복구"""
DoActions([
SetMemoryX(SCAN_VISION, SetTo, 0xA00, 0xFF00),
set_scanhit_image(546), # 이미지 [546] Scanner Sweep Hit
SetMemory(IMAGE425_ISCRIPT, SetTo, 277), # iscript [277] Unknown277
SetMemory(IMAGE232_ISCRIPT, SetTo, 73), # iscript [73] Nuke Beam
])
def draw_hpbar():
"""
체력바를 그린다.
현재 (체력 + 실드) 100마다 빨간 점 1개, 10마다 초록 점 1개를 그린다.
"""
LOC_L = EPD(0x58DC60) + 5 * GetLocationIndex("loc")
LOC_T = LOC_L + 1
for ptr, epd in EUDLoopUnit2():
# 실드와 체력이 10 미만이면 생략한다.
current_hp, current_shields = EUDCreateVariables(2)
VProc(epd, [
epd.QueueAddTo(current_shields),
current_shields.SetNumber(0x60 // 4),
])
VProc(epd, [
epd.QueueAddTo(current_hp),
current_hp.SetNumber(0x8 // 4),
])
EUDContinueIf([
MemoryEPD(current_hp, AtMost, 0x9FF),
MemoryEPD(current_shields, AtMost, 0x9FF)
])
hp_pool = EUDLightVariable()
VProc(current_hp, [
hp_pool.SetNumber(0),
current_hp.QueueAssignTo(CP),
])
for a in range(12): # 2500(하이브) < 4095
b = a + 8
RawTrigger(
conditions=DeathsX(CurrentPlayer, AtLeast, 1, 0, 2**b),
actions=hp_pool.AddNumber(2**a)
)
# 실드가 1 미만이면 계산을 생략한다.
VProc(current_shields, current_shields.QueueAssignTo(CP))
skip_shields = Forward()
EUDJumpIf(Deaths(CurrentPlayer, AtMost, 0xFF, 0), skip_shields)
for a in range(10): # 750(넥서스) < 1023
b = a + 8
RawTrigger(
conditions=DeathsX(CurrentPlayer, AtLeast, 1, 0, 2**b),
actions=hp_pool.AddNumber(2**a)
)
skip_shields << NextTrigger()
hpbar_position = EUDVariable()
unit_id = epd + 0x64 // 4
get_unitsize_bottom, get_position = Forward(), Forward()
VProc(unit_id, [
unit_id.QueueAssignTo(CP),
SetNextPtr(get_unitsize_bottom, unitsize_bottom),
SetMemory(get_unitsize_bottom + 328 + 16, SetTo, EPD(unitsize_bottom) + 1),
SetMemory(get_unitsize_bottom + 360 + 16, SetTo, EPD(unitsize_bottom) + 86),
])
for a in range(8):
b = 2**a
RawTrigger(
conditions=DeathsX(CurrentPlayer, AtLeast, 1, 0, b),
actions=[
SetMemory(get_unitsize_bottom + 4, Add, 72 * b),
SetMemory(get_unitsize_bottom + 328 + 16, Add, 18 * b),
SetMemory(get_unitsize_bottom + 360 + 16, Add, 18 * b),
]
)
get_unitsize_bottom << RawTrigger(
nextptr=unitsize_bottom,
actions=[
SetNextPtr(unitsize_bottom, get_position),
SetMemory(unitsize_bottom + 328 + 16, SetTo, EPD(hpbar_position.getValueAddr()))
]
)
get_position << NextTrigger()
position = EUDVariable()
VProc(epd, [
SetMemoryEPD(CP, SetTo, EncodePlayer(Player1)), # CP 캐시랑 일치시킨다.
epd.QueueAddTo(position),
position.SetNumber(0x28 // 4),
])
pos_x, pos_y = f_posread_epd(position)
set_right_bottom, nptr = Forward(), Forward()
RawTrigger(
nextptr=pos_x.GetVTable(),
actions=[
pos_x.QueueAssignTo(LOC_L),
SetNextPtr(pos_x.GetVTable(), pos_y.GetVTable()),
pos_y.QueueAssignTo(LOC_T),
SetNextPtr(pos_y.GetVTable(), hpbar_position.GetVTable()),
hpbar_position.QueueAddTo(LOC_T),
SetNextPtr(hpbar_position.GetVTable(), set_right_bottom),
]
)
set_right_bottom << RawTrigger(
nextptr=pos_x.GetVTable(),
actions=[
SetMemory(pos_x._varact + 16, Add, 2), # 오른쪽
SetMemory(pos_y._varact + 16, Add, 2), # 아래
SetMemory(hpbar_position._varact + 16, Add, 2), # 아래
SetNextPtr(hpbar_position.GetVTable(), nptr),
]
)
nptr << NextTrigger()
counter = EUDLightVariable()
initial_offset = int(round(4.5 * HPBAR_WIDTH))
DoActions([
counter.SetNumber(0),
SetMemoryEPD(LOC_L, Subtract, initial_offset),
SetMemoryEPD(LOC_L + 2, Subtract, initial_offset),
])
MOVELOC_START, MOVELOC_END = Forward(), Forward()
cont_100, cont_10 = Forward(), Forward()
PushTriggerScope()
MOVELOC_START << RawTrigger(
actions=[
CreateUnit(1, "Scanner Sweep", "loc", Player1),
SetMemoryEPD(LOC_L, Add, HPBAR_WIDTH),
SetMemoryEPD(LOC_L + 2, Add, HPBAR_WIDTH),
counter.AddNumber(1),
RemoveUnit("Scanner Sweep", Player1),
]
)
MOVELOC_END << RawTrigger(
nextptr=cont_10,
conditions=counter.AtLeast(10),
actions=[
counter.SubtractNumber(10),
SetMemoryEPD(LOC_L, Subtract, 10 * HPBAR_WIDTH),
SetMemoryEPD(LOC_L + 2, Subtract, 10 * HPBAR_WIDTH),
SetMemoryEPD(LOC_T, Add, HPBAR_HEIGHT),
SetMemoryEPD(LOC_T + 2, Add, HPBAR_HEIGHT),
]
)
PopTriggerScope()
if EUDIf()(hp_pool >= 201): # 체력+실드가 200보다 크면 빨간점을 쓴다.
DoActions([
set_scanhit_image(232),
SetMemoryEPD(LOC_T, Add, IMAGECOORD_DIFF),
SetMemoryEPD(LOC_T + 2, Add, IMAGECOORD_DIFF),
SetNextPtr(MOVELOC_END, cont_100)
])
if EUDWhile()(hp_pool >= 100):
RawTrigger(
nextptr=MOVELOC_START,
actions=hp_pool.SubtractNumber(100)
)
cont_100 << NextTrigger()
EUDEndWhile()
DoActions([
set_scanhit_image(425),
SetMemoryEPD(LOC_T, Subtract, IMAGECOORD_DIFF),
SetMemoryEPD(LOC_T + 2, Subtract, IMAGECOORD_DIFF),
SetNextPtr(MOVELOC_END, cont_10)
])
EUDEndIf()
if EUDWhile()(hp_pool >= 10):
RawTrigger(
nextptr=MOVELOC_START,
actions=hp_pool.SubtractNumber(10)
)
cont_10 << NextTrigger()
EUDEndWhile()
def EUDTurbo():
DoActions(SetMemory(0x6509A0, SetTo, 0))
def afterTriggerExec():
f_setcurpl(Player1)
prepare_hpbar()
draw_hpbar()
finish_hpbar()
EUDTurbo()
주석처리 해논거 복붙해가서 똑같이 쓰면 끝난다..
댓글 영역
획득법
① NFT 발행
작성한 게시물을 NFT로 발행하면 일주일 동안 사용할 수 있습니다. (최초 1회)
② NFT 구매
다른 이용자의 NFT를 구매하면 한 달 동안 사용할 수 있습니다. (구매 시마다 갱신)
사용법
디시콘에서지갑연결시 바로 사용 가능합니다.