Skip to content

Commit

Permalink
Merge pull request #171 from gabeyk9/main
Browse files Browse the repository at this point in the history
my last code pull for a while
  • Loading branch information
balt-dev authored Aug 10, 2024
2 parents d13ecac + 8fea1c6 commit 6666170
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/cogs/global.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ async def render_tiles(self, ctx: Context, *, objects: str, rule: bool):
passes = 0
while last_tiles != tiles and passes < 50:
last_tiles = tiles
tiles, _ = ctx.bot.macro_handler.parse_macros(tiles, False, user_macros)
tiles, _ = ctx.bot.macro_handler.parse_macros(tiles, False, user_macros, "r" if rule else "t")
tiles = tiles.strip()
passes += 1

Expand Down
9 changes: 5 additions & 4 deletions src/cogs/macros.py
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ def title(text: str):

self.builtins = dict(sorted(self.builtins.items(), key=lambda tup: tup[0]))

def parse_macros(self, objects: str, debug_info: bool, macros=None, init=True) -> tuple[Optional[str], Optional[list[str]]]:
def parse_macros(self, objects: str, debug_info: bool, macros=None, cmd="x", init=True) -> tuple[Optional[str], Optional[list[str]]]:
if init:
self.debug = []
self.variables = {}
Expand All @@ -482,7 +482,7 @@ def parse_macros(self, objects: str, debug_info: bool, macros=None, init=True) -
try:
objects = (
objects[:match.start()] +
self.parse_term_macro(terminal, macros, self.found, debug_info) +
self.parse_term_macro(terminal, macros, self.found, cmd, debug_info) +
objects[match.end():]
)
except errors.FailedBuiltinMacro as err:
Expand All @@ -494,7 +494,7 @@ def parse_macros(self, objects: str, debug_info: bool, macros=None, init=True) -
self.debug.append(f"[Out] {objects}")
return objects, self.debug if len(self.debug) else None

def parse_term_macro(self, raw_variant, macros, step = 0, debug_info = False) -> str:
def parse_term_macro(self, raw_variant, macros, step = 0, cmd = "x", debug_info = False) -> str:
raw_macro, *macro_args = re.split(r"(?<!(?<!\\)\\)/", raw_variant)
if raw_macro in self.builtins:
try:
Expand All @@ -505,12 +505,13 @@ def parse_term_macro(self, raw_variant, macros, step = 0, debug_info = False) ->
elif raw_macro in macros:
macro = macros[raw_macro].value
macro = macro.replace("$#", str(len(macro_args)))
macro = macro.replace("$!", cmd)
macro_args = ["/".join(macro_args), *macro_args]
arg_amount = 0
iters = None
while iters != 0 and arg_amount <= constants.MACRO_ARG_LIMIT:
iters = 0
matches = [*re.finditer(r"\$(-?\d+|#)", macro)]
matches = [*re.finditer(r"\$(-?\d+|#|!)", macro)]
for match in reversed(matches):
iters += 1
arg_amount += 1
Expand Down
72 changes: 63 additions & 9 deletions src/cogs/variants.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ async def rotate(sprite, angle: float, expand: Optional[bool] = False):
(padding,
padding,
(0, 0)))
image_center = tuple(np.array(sprite.shape[1::-1]) / 2)
image_center = tuple(np.array(sprite.shape[1::-1]) / 2 - 0.5)
rot_mat = cv2.getRotationMatrix2D(image_center, -angle, 1.0)
return cv2.warpAffine(sprite, rot_mat, sprite.shape[1::-1], flags=cv2.INTER_NEAREST)

Expand Down Expand Up @@ -617,6 +617,26 @@ async def meta(sprite, level: Optional[int] = 1, kernel: Optional[Literal["full"
else:
base[mask ^ (level < 0), ...] = 0
return base

@add_variant(no_function_name=True)
async def omni(sprite, type: Optional[Literal["pivot", "branching"]] = "branching", *, tile, wobble, renderer):
"""Gives the tile an overlay, like the omni text."""
opvalue = [0xcb, 0xab, 0x8b][wobble]
num = 3
if type == "pivot":
num = 1
nsprite = await meta(sprite, num)
sprite = await pad(sprite, num, num, num, num)
for i in range(nsprite.shape[0]):
for j in range(nsprite.shape[1]):
if nsprite[i, j, 3] == 0:
try:
nsprite[i, j] = sprite[i, j]
except:
pass
else:
nsprite[i, j, 3] = opvalue
return nsprite

@add_variant()
async def land(sprite, direction: Optional[Literal["left", "top", "right", "bottom"]] = "bottom"):
Expand Down Expand Up @@ -816,6 +836,29 @@ async def floodfill(sprite, color: Color, inside: Optional[bool] = True, *, tile
sprite[(sprite[:, :] == [0, 0, 0, 255]).all(2)] = color
return sprite

@add_variant("pf")
async def pointfill(sprite, color: Color, x: int, y: int, *, tile, wobble, renderer):
"""Floodfills a sprite starting at a given point."""
color = Color.parse(tile, renderer.palette_cache, color)
assert x >= 0 and y >= 0 and y < sprite.shape[0] and x < sprite.shape[1], f"Target point `{x},{y}` must be inside the sprite!"
target_color = sprite[y,x]
sprite[sprite[:, :, 3] == 0] = 0 # Optimal
sprite_alpha = sprite[:, :, :].copy() # Stores the alpha channel separately
not_color_mask = (sprite[:, :, 0] != target_color[0]) | (sprite[:, :, 1] != target_color[1]) | (sprite[:, :, 2] != target_color[2])
color_mask = (sprite[:, :, 0] == target_color[0]) & (sprite[:, :, 1] == target_color[1]) & (sprite[:, :, 2] == target_color[2])
sprite_alpha[not_color_mask] = 255
sprite_alpha[color_mask] = 0 # and now to override it
sprite_alpha = sprite_alpha[:, :, 3].copy() #???
sprite_flooded = cv2.floodFill(
image=sprite_alpha,
mask=None,
seedPoint=(x, y),
newVal=100
)[1]
mask = sprite_flooded == 100
sprite[mask] = color
return sprite

@add_variant("rm")
async def remove(sprite, color: Color, invert: Optional[bool] = False, *, tile, wobble, renderer):
"""Removes a certain color from the sprite. If invert is on, then it removes all but that color."""
Expand All @@ -825,6 +868,17 @@ async def remove(sprite, color: Color, invert: Optional[bool] = False, *, tile,
else:
sprite[(sprite[:, :, 0] == color[0]) & (sprite[:, :, 1] == color[1]) & (sprite[:, :, 2] == color[2])] = 0
return sprite

@add_variant("rp")
async def replace(sprite, color1: Color, color2: Color, invert: Optional[bool] = False, *, tile, wobble, renderer):
"""Replaces a certain color with a different color. If invert is on, then it replaces all but that color."""
color1 = Color.parse(tile, renderer.palette_cache, color1)
color2 = Color.parse(tile, renderer.palette_cache, color2)
if invert:
sprite[(sprite[:, :, 0] != color1[0]) | (sprite[:, :, 1] != color1[1]) | (sprite[:, :, 2] != color1[2])] = color2
else:
sprite[(sprite[:, :, 0] == color1[0]) & (sprite[:, :, 1] == color1[1]) & (sprite[:, :, 2] == color1[2])] = color2
return sprite

@add_variant()
async def clip(sprite, *, tile, wobble, renderer):
Expand Down Expand Up @@ -1061,20 +1115,20 @@ async def snip(sprite, x_y: list[int, int], u_v: list[int, int]):
return sprite

@add_variant()
async def croppoly(sprite, *x_y: list[int, int]):
async def croppoly(sprite, *x_y: list[int]):
"""Crops the sprite to the specified polygon."""
assert len(x_y) > 3, "Must have at least 3 points to define a polygon!"
pts = np.array([x_y], dtype=np.int32).reshape((1, -1, 2))[:, :, ::-1]
clip_poly = cv2.fillPoly(np.zeros(sprite.shape[:2], dtype=np.float32), pts, 1)
assert len(x_y) > 5, "Must have at least 3 points to define a polygon!"
pts = np.array(x_y, dtype=np.int32).reshape((1, -1, 2))[:, ::-1]
clip_poly = cv2.fillPoly(np.zeros(sprite.shape[1::-1], dtype=np.float32), pts, 1)
clip_poly = np.tile(clip_poly, (4, 1, 1)).T
return np.multiply(sprite, clip_poly, casting="unsafe").astype(np.uint8)

@add_variant()
async def snippoly(sprite, *x_y: list[int, int]):
async def snippoly(sprite, *x_y: list[int]):
"""Like croppoly, but also like snip. Snips the specified polygon out of the sprite."""
assert len(x_y) > 3, "Must have at least 3 points to define a polygon!"
pts = np.array([x_y], dtype=np.int32).reshape((1, -1, 2))[:, :, ::-1]
clip_poly = cv2.fillPoly(np.zeros(sprite.shape[:2], dtype=np.float32), pts, 1)
assert len(x_y) > 5, "Must have at least 3 points to define a polygon!"
pts = np.array(x_y, dtype=np.int32).reshape((1, -1, 2))[:, ::-1]
clip_poly = cv2.fillPoly(np.zeros(sprite.shape[1::-1], dtype=np.float32), pts, 1)
clip_poly = np.tile(clip_poly, (4, 1, 1)).T
return np.multiply(sprite, 1 - clip_poly, casting="unsafe").astype(np.uint8)

Expand Down

0 comments on commit 6666170

Please sign in to comment.