def add_to_frame(self, background, cur_time, in_break): AScorebar.animate(self) self.frame_index += self.settings.skin_ini.general[ "AnimationFramerate"] / self.settings.fps self.frame_index = self.frame_index % len(self.frames) self.drainhp(cur_time) self.hp = max(0, min(1, self.hp + self.step)) if self.step >= 0 and self.hp > self.healthprocessor.health_value: self.hp = self.healthprocessor.health_value elif self.step <= 0 and self.hp < self.healthprocessor.health_value: self.hp = self.healthprocessor.health_value img = self.frames[int(self.frame_index)] img = img.crop((0, 0, int(img.size[0] * self.hp), img.size[1])) if self.settings.settings["In-game interface"] or in_break: imageproc.add(img, background, self.x, self.y - self.h, alpha=self.alpha, topleft=True) if self.hasmarker: imageproc.add(self.marker, background, self.x + img.size[0], 16 * self.settings.scale - self.h, alpha=self.alpha)
def apply_continuoustrail(self, x_offset, y_offset): if not self.trail: self.trail = Trail(x=x_offset, y=y_offset) deltax = x_offset - self.trail.x deltay = y_offset - self.trail.y delta = math.sqrt(deltax**2 + deltay**2) n_cursor = delta / self.radius stepx, stepy = 0, 0 if n_cursor > 0: stepx = abs(deltax / n_cursor) xx = self.radius**2 - stepx**2 stepy = math.sqrt(max( 0, xx)) # avoid maths domain error temporary fix(?) count = 0 x, y = self.trail.x, self.trail.y while count < int(n_cursor): x += copysign(stepx, deltax) y += copysign(stepy, deltay) count += 1 imageproc.add(self.frames[self.frame_index], self.blank, int(x), int(y), channel=4) self.trail.set(x=x, y=y)
def drawname(self, background, x_offset, y_offset, text, alpha, size): imageproc.add(self.textimgs[text], background, x_offset, y_offset, alpha=alpha, topleft=True)
def add_to_frame(self, background): # source: https://osu.ppy.sh/help/wiki/Skinning/Interface#ranking-grades super().add_to_frame(background) if self.fade == self.FADEIN: imageproc.add(self.gradeframe, background, self.settings.width - 192 * self.settings.scale, self.y * self.settings.scale, self.alpha)
def add_to_frame(self, background): # source: https://osu.ppy.sh/help/wiki/Skinning/Interface#ranking-screen super().add_to_frame(background) if self.fade == self.FADEIN: imageproc.add(self.rankingreplay, background, self.settings.width - self.rankingreplay.size[0] / 2, 576 * self.settings.scale, self.alpha)
def add_to_frame(self, background): if not self.settings.settings["Show score meter"]: return AScorebar.animate(self) self.c += 60 / self.settings.fps self.np[:, :, :] = self.barthin s = self.bar_container.size self.bar_container.paste((255, 255, 255, 255), (s[0] // 2 - 1, 0, s[0] // 2 + 1, s[1])) img = self.bar_container imageproc.add(img, background, self.x_offset + self.w // 2, self.y, alpha=min(1, self.alpha * 2)) if self.c >= 6: a = self.barthin[:, :] - self.mask self.barthin[:, :] = a.clip(0, 255) self.c = 0 self.movearrow() imageproc.add(self.urarrow, background, self.x_offset + self.arrowx, self.y - self.arrowy, alpha=min(1, self.alpha * 2))
def drawname(self, background, y_offset, text, alpha): imageproc.add(self.nameimg[text], background, 0, y_offset + self.height * 0.15, alpha, topleft=True)
def prepare_rankingur(settings, ur): """ :param settings: Settings :param ur: [error -, error +, ur] :return: """ error_ = "{:.2f}".format(ur[0]) error = "{:.2f}".format(ur[1]) ur = "{:.2f}".format(ur[2]) text = ["Accuracy:", f"Error {error_}ms - {error}ms avg", f"Unstable Rate: {ur}"] scale = settings.scale * 1.3 width = int(scale * 350) height = int(width * 9 / 16 * len(text)/6) image = Image.new("RGBA", (width, height)) d = ImageDraw(image) rounded_rectangle(d, ((0, 0), (width, height)), 20, fill=(255, 255, 255, 200)) rounded_rectangle(d, ((2, 2), (width - 2, height - 2)), 15, fill=(0, 0, 0, 200)) texti = prepare_text(text, scale * 20, (255, 255, 255), settings) y = height * 0.025 for t in texti: imageproc.add(texti[t], image, width * 0.01, y, topleft=True) y += texti[t].size[1] + 5 * settings.scale image = image.resize((width // 2, height // 2)) return [image]
def add_to_frame(self, background, x_offset, y_offset, cursor_time, alpha=1): if not self.continuous: deltatime = abs(cursor_time - self.trail[-1].timeframe) # print(deltatime/self.updatetime) self.updatecooldown += 60 / self.settings.fps for i in range(int(self.updatecooldown)): self.apply_normaltrail(cursor_time, x_offset, y_offset) self.updatecooldown -= int(self.updatecooldown) for i in range(len(self.trail) - 1): self.frame_index = i super().add_to_frame(background, self.trail[i].x, self.trail[i].y) else: self.apply_continuoustrail(x_offset, y_offset) imageproc.add(self.blank, background, self.settings.width // 2, self.settings.height // 2) if self.prevtime == 0: self.prevtime = cursor_time deltatime = abs(cursor_time - self.prevtime) for i in range(round(deltatime / self.updatetime - 0.25)): imageproc.changealpha(self.blank, 0.92) self.prevtime = cursor_time
def add_to_frame(self, np_img, background, cur_time, scorebarh, scorebaralpha, inbreak): ratio = (cur_time - self.starttime) / max( self.endtime - self.starttime, 1) color = (125, 125, 125, 255) if ratio < 0: color = (80, 125, 80, 255) angle = 270 startangle = -360 + ratio * 360 endangle = -360 axes = (self.radius, self.radius) if self.settings.settings["In-game interface"] or inbreak: cv2.ellipse(np_img, (self.x, self.y), axes, angle, startangle, endangle, color, -1, cv2.LINE_AA) cv2.circle(np_img, (self.x, self.y), self.radius, (255, 255, 255, 255), thickness=1, lineType=cv2.LINE_AA) cv2.circle(np_img, (self.x, self.y), max(1, int(self.scale)), (255, 255, 255, 255), thickness=-1, lineType=cv2.LINE_AA) imageproc.add(self.overlayimg, background, self.x, self.y - scorebarh, alpha=scorebaralpha)
def prepare_particles(scale, settings): frames = {} for hit in [50, 100]: yimg = YImage(particleprefix + str(hit), settings, scale) yimg2 = YImage(hitprefix + str(hit), settings, scale) if yimg.imgfrom == ImageFrom.DEFAULT_X or yimg.imgfrom == ImageFrom.DEFAULT_X2 or yimg.imgfrom == ImageFrom.BLANK: continue fr = [] sizee = int(200 * scale) f = [[sizee / 2, sizee / 2, 100] for i in range(100)] for z in range(120): background = Image.new("RGBA", (sizee, sizee), (0, 0, 0, 0)) for b in range(len(f)): pos = f[b] x, y = pseudorandom(b) pos[0] += x * scale pos[1] += y * scale pos[2] -= max(1, (abs(x) + abs(y)) * 1.25) imageproc.add(yimg.img, background, pos[0], pos[1], alpha=max(0.0, min(1.0, pos[2] / 100)), channel=4) imageproc.add(yimg2.img, background, 60, 60) if z > 3: fr.append(background) # background.save(f"test{z}.png") frames[hit] = fr return frames
def add_to_frame(self, background, cur_time): if (self.settings.settings["Enable Strain Graph"]): self.update_progress(cur_time) imageproc.add(self.graph, background, self.x, self.y, alpha=self.alpha)
def draw_score(self, background): index = int(self.spinbonuses[3]) x = self.xstart(self.spinbonuses[0], self.spinbonuses[1], self.frames[0][index].size[0]-self.gap * (2.5 - index/10)) y = self.spinbonuses[2] for digit in self.spinbonuses[0]: digit = int(digit) img = self.frames[digit][index] imageproc.add(img, background, x, y) x += int(self.frames[digit][index].size[0] - self.gap * (2.5 - index/10))
def add_to_frame_bar(self, background): if not self.settings.settings["Show score meter"]: return img = self.urbar imageproc.add(img, background, self.x, self.y, alpha=min(1, self.alpha * 2))
def add_to_frame(self, background): if not self.drawing: return if self.fade == self.FADEOUT: imageproc.add(self.backgroundimg, background, 0, 0, alpha=self.alpha, topleft=True) if self.alpha < 0 and self.fade == self.FADEIN: imageproc.add(self.backgroundimg, background, 0, 0, alpha=1, topleft=True) super().add_to_frame(background)
def drawrpm(self, background, x_offset, y_offset, number, alpha): number = str(number)[::-1] x_start = x_offset for digit in number: digit = int(digit) imageproc.add(self.scoreframes[digit], background, x_start, y_offset, alpha=alpha) x_start -= self.scoreframes[digit].size[0]
def add_to_frame(self, background, x_offset, y_offset, alpha=1, topleft=False): imageproc.add(self.frames[int(self.frame_index)], background, x_offset, y_offset, alpha=alpha, topleft=topleft)
def add_to_frame(self, background): if not self.settings.settings["Show mods icon"]: return hasnc = Mod.Nightcore in self.mods x = self.x for mod in sortedmods: # if there is nightcore, then doubletime mod is present in the frozenset if mod == Mod.DoubleTime and hasnc: continue if mod in self.mods: imageproc.add(self.modframes[mod], background, x, self.y) x -= self.step_x
def add_to_frame(self, background, x_offset, y_offset, number, index=0): if not self.settings.settings["Always show key overlay"]: return number = str(number) n = len(number) - 1 index = max(0, min(len(self.frames[0]) - 1, index + n - 1)) x_start = x_offset - int(n / 2 * self.frames[0][index].size[0]) for digit in number: digit = int(digit) imageproc.add(self.frames[digit][index], background, x_start, y_offset) x_start += self.frames[digit][index].size[0]
def add_to_frame(self, background): super().add_to_frame(background) if self.fade == self.FADEIN: self.buttonindex += self.framerate * 1 / self.settings.fps self.buttonindex = self.buttonindex % len(self.buttonframes) imageproc.add(self.buttonframes[int(self.buttonindex)], background, 0, self.settings.height - self.buttonframes[int(self.buttonindex)].size[1], self.alpha, topleft=True)
def add_to_frame(self, background, inbreak, cursorx, cursory): if not self.hasfl: return AScorebar.animate(self) self.update_pos(cursorx, cursory) super().add_to_frame(background, self.x, self.y, alpha=self.alpha) if inbreak: imageproc.add(self.frames[self.BREAK], background, self.x, self.y) elif self.sliding: imageproc.add(self.blackshit, background, 0, 0, alpha=0.8, topleft=True)
def overlayapproach(circle, approach, alpha): maxwidth = max(approach.size[0], circle.size[0]) maxheight = max(approach.size[1], circle.size[1]) background = Image.new("RGBA", (maxwidth, maxheight)) background.paste(approach, (maxwidth // 2 - approach.size[0] // 2, maxheight // 2 - approach.size[1] // 2)) approach = background x1 = approach.size[0] // 2 y1 = approach.size[1] // 2 imageproc.add(circle, approach, x1, y1, channel=4) return imageproc.newalpha(approach, alpha / 100)
def ballinhole(follow, sliderball): if follow.size[0] < sliderball.size[0] or follow.size[1] < sliderball.size[ 1]: width, height = max(follow.size[0], sliderball.size[0]), max(follow.size[1], sliderball.size[1]) f = Image.new("RGBA", (width, height)) imageproc.add(follow, f, width // 2, height // 2) follow = f y1 = (follow.size[1] - sliderball.size[1]) // 2 x1 = (follow.size[0] - sliderball.size[0]) // 2 follow.paste(sliderball, (x1, y1), sliderball) return follow
def add_to_frame(self, background): super().add_to_frame(background) if self.fade == self.FADEIN: x = 1300 * self.settings.scale step_x = 60 * self.settings.scale hasnc = Mod.Nightcore in self.mods for mod in sortedmods: # if there is nightcore, then doubletime mod is present in the frozenset if mod == Mod.DoubleTime and hasnc: continue if mod in self.mods: imageproc.add(self.modframes[mod], background, x, 420 * self.settings.scale, self.alpha) x -= step_x
def add_to_frame(self, background): i = len(self.hitresults) while i > 0: i -= 1 score = self.hitresults[i][0] if self.hitresults[i][ 5] >= self.time * self.multiplieranimation[score]: del self.hitresults[i] if score == 0: self.misscount -= 1 if self.misscount == 0: # if there is no misscount then this is the last element so we can break break else: continue img = self.frames[score][int(self.hitresults[i][3])] x, y = self.hitresults[i][1], self.hitresults[i][2] imageproc.add(img, background, x, y, alpha=self.hitresults[i][4] / 100) if score == 0 and self.singleframemiss: current = self.settings.timeframe / self.settings.fps change = self.hitresults[i][6] - self.hitresults[i][2] duration = 1000 self.hitresults[i][2] = easingoutcubic(current, self.hitresults[i][2], change, duration) self.hitresults[i][3] = min( len(self.frames[score]) - 1, self.hitresults[i][3] + 1 * 60 / self.settings.fps) self.hitresults[i][5] += self.interval if self.hitresults[i][5] >= self.time - 1200: self.hitresults[i][4] = max( 0, self.hitresults[i][4] - 1.5 * 60 / self.settings.fps) else: self.hitresults[i][4] = min( 100, self.hitresults[i][4] + 20 * 60 / self.settings.fps)
def add_to_frame(self, background): # source: https://osu.ppy.sh/help/wiki/Skinning/Interface#ranking-screen super().add_to_frame(background) if self.fade == self.FADEIN: self.draw_score(self.accuracy, background, 325 * self.settings.scale, 552 * self.settings.scale, self.alpha) self.accuracyindex += 1000 / self.settings.fps self.accuracyindex = self.accuracyindex % len(self.accuracyframes) imageproc.add(self.accuracyframes[int(self.accuracyindex)], background, 291 * self.settings.scale, self.y * self.settings.scale, self.alpha, topleft=True)
def add_to_frame(self, background): """ :param background: numpy.array :return: """ if not self.settings.settings["Enable PP counter"]: return x = self.countersettings[self.prefix + "x"] * self.settings.scale y = self.countersettings[self.prefix + "y"] * self.settings.scale imageproc.add(self.background, background, x, y, alpha=self.countersettings[self.prefix + "Alpha"]) self.draw_number(background)
def add_to_frame(self, background, i, _): if self.spinners[i].starttime_left > 0: self.spinners[i].starttime_left -= self.interval self.spinners[i].alpha = min( 1, self.spinners[i].alpha + self.interval / 400) else: self.spinners[i].duration -= self.interval if 0 > self.spinners[i].duration > -200: self.spinners[i].alpha = max( 0, self.spinners[i].alpha - self.interval / 200) else: self.spinners[i].alpha = 1 img = self.frames[spinnerbackground] imageproc.add(img, background, self.width / 2 + self.moveright, self.height / 2 + self.movedown, alpha=self.spinners[i].alpha) img = self.frames[spinnercircle].rotate(self.spinners[i].angle) imageproc.add(img, background, self.width / 2 + self.moveright, self.height / 2 + self.movedown, alpha=self.spinners[i].alpha) height = self.frames[spinnermetre].size[1] y_start = height - self.spinners[i].index * height // 10 width = self.frames[spinnermetre].size[0] img = self.frames[spinnermetre].crop((0, y_start, width, height)) x = self.width / 2 + self.moveright - width / 2 y = 46 / 768 * self.height + y_start imageproc.add(img, background, x, y, alpha=self.spinners[i].alpha, topleft=True) img = self.frames[spinnerrpm] x = self.settings.width / 2 - 139 * self.settings.scale y = 712 / 768 * self.settings.height imageproc.add(img, background, x, y, alpha=self.spinners[i].alpha, topleft=True) rpm = int(self.spinners[i].rpm) self.drawrpm(background, x + 250 * self.settings.scale, y + 25 * self.settings.scale, rpm, self.spinners[i].alpha)
def prepare_playinggrade(scale, settings): frames = [] grades = ["XH", "SH", "X", "S", "A", "B", "C", "D"] for grade in grades: img = YImage(ranking + grade + "-small", settings, scale).img step = settings.timeframe/1000 * 60/settings.fps effects = grow(img, 1, 2, step * 0.05) effects = fadeout(effects, 1, 0, step * 0.05) for x in effects: imageproc.add(img, x, x.size[0]/2, x.size[1]/2, channel=4) effects.append(img) frames.append(effects) # frameshd = [YImage(ranking + "XH-small", settings, scale).img, YImage(ranking + "SH-small", settings, scale).img] # frameshd.extend(frames[2:]) framesnm = frames[2:] frameshd = frames[:2] + frames[4:] return framesnm, frameshd
def overlayhitcircle(overlay, circle, color, scale): color_circle = imageproc.add_color(circle, color) maxwidth = max(color_circle.size[0], overlay.size[0]) maxheight = max(color_circle.size[1], overlay.size[1]) background = Image.new("RGBA", (maxwidth, maxheight)) background.paste(color_circle, (maxwidth // 2 - color_circle.size[0] // 2, maxheight // 2 - color_circle.size[1] // 2)) color_circle = background overlay_img = overlay.copy() x1 = color_circle.size[0] // 2 y1 = color_circle.size[1] // 2 imageproc.add(overlay_img, color_circle, x1, y1, channel=4) return imageproc.change_size(color_circle, scale, scale)