diff --git a/charselect.py b/charselect.py index 0409261..cf9ff84 100644 --- a/charselect.py +++ b/charselect.py @@ -6,132 +6,132 @@ from buttons import PixmapButton AOpath = "base/" AO2XPpath = "AO2XPbase/" -#AOpath = "I:/aovanilla1.7.5/client/base/" def get_option(section, value, default=""): - tempini = ConfigParser() - tempini.read("ao2xp.ini") - return ini.read_ini(tempini, section, value, default) + tempini = ConfigParser() + tempini.read("ao2xp.ini") + return ini.read_ini(tempini, section, value, default) class CharIcon(QtGui.QLabel): - def __init__(self, parent, ind): - super(CharIcon, self).__init__(parent) - self.parent = parent - self.ind = ind - - def mousePressEvent(self, event): - self.parent.onCharClicked(self.ind) + def __init__(self, parent, ind): + super(CharIcon, self).__init__(parent) + self.parent = parent + self.ind = ind + + def mousePressEvent(self, event): + self.parent.onCharClicked(self.ind) class charselect(QtGui.QWidget): - setBtnImage = QtCore.pyqtSignal(str, int) - def __init__(self, parent): - super(charselect, self).__init__(parent) - self.parent = parent - self.page = 0 - self.image = QtGui.QLabel(self) - self.image.setPixmap(QtGui.QPixmap(AO2XPpath+"themes/default/charselect_background.png")) - self.image.show() - - self.quittolobby = QtGui.QPushButton(self) - self.quittolobby.setText("Disconnect") - self.quittolobby.resize(self.quittolobby.sizeHint()) - self.quittolobby.clicked.connect(self.quitToLobby) - - self.buttons = [] - self.chartaken = [] - - #directly stolen from ao2 source code and default theme because i was stuck (i'm so sorry) - btn_width, btn_height = 60, 60 - x_spacing, y_spacing = 7, 7 - x_mod_count, y_mod_count = 0, 0 - left, top = 25, 36 - width, height = 663, 596 - columns = (width - btn_width) / (x_spacing + btn_width) +1 - rows = (height - btn_height) / (y_spacing + btn_height) +1 - self.max_chars_on_page = columns * rows - for i in range(self.max_chars_on_page): - self.buttons.append(CharIcon(self, i)) - self.chartaken.append(QtGui.QLabel(self)) - self.chartaken[i].setPixmap(QtGui.QPixmap(AO2XPpath+"themes/default/char_taken.png")) - self.chartaken[i].hide() - - x_pos = (btn_width + x_spacing) * x_mod_count - y_pos = (btn_height + y_spacing) * y_mod_count - self.buttons[i].setGeometry(left+x_pos, top+y_pos, btn_width, btn_height) - self.chartaken[i].move(left+x_pos, top+y_pos) - self.buttons[i].show() - - x_mod_count += 1 - if x_mod_count == columns: - y_mod_count += 1 - x_mod_count = 0 - - self.prevpage = PixmapButton(self, QtGui.QPixmap(AO2XPpath+"themes/default/arrow_left.png")) - self.prevpage.move(left - self.prevpage.pixmap.size().width(), top + height) - self.prevpage.clicked.connect(self.prevPageButton) - self.prevpage.show() - self.nextpage = PixmapButton(self, QtGui.QPixmap(AO2XPpath+"themes/default/arrow_right.png")) - self.nextpage.move(left + width, top + height) - self.nextpage.clicked.connect(self.nextPageButton) - self.nextpage.show() - - self.setBtnImage.connect(self.setButtonImage) - - def quitToLobby(self): - self.parent.gamewindow.returnToMenu() - - def setPic(self, pixmap, ind): - self.buttons[ind].setPixmap(QtGui.QPixmap(pixmap)) - - def setCharList(self, charlist): - self.charlist = charlist - self.page = 0 - self.showCharPage() - - def nextPageButton(self): - self.page += 1 - self.showCharPage() - - def prevPageButton(self): - self.page -= 1 - self.showCharPage() - - def showCharPage(self): - for ind in range(self.page * self.max_chars_on_page, self.max_chars_on_page * (self.page+1)): - i = ind - (self.page * self.max_chars_on_page) - if ind >= len(self.charlist): - self.chartaken[i].hide() - self.buttons[i].hide() - self.nextpage.hide() - continue - else: - self.nextpage.show() - - if self.page > 0: - self.prevpage.show() - else: - self.prevpage.hide() - - if exists(AOpath+"characters/"+self.charlist[ind][0]+"/char_icon.png"): # AO2 - self.setBtnImage.emit(AOpath+"characters/"+self.charlist[ind][0]+"/char_icon.png", i) - elif exists(AOpath+"misc/demothings/"+self.charlist[ind][0]+"_char_icon.png"): # AO 1.7.5/1.8 - self.setBtnImage.emit(AOpath+"misc/demothings/"+self.charlist[ind][0]+"_char_icon.png", i) - else: - self.setBtnImage.emit("placeholder.png", i) - - if self.charlist[ind][1] == 0: # free slot - self.chartaken[i].hide() - else: - self.chartaken[i].show() - - self.buttons[i].show() - - def setButtonImage(self, filename, ind): - self.buttons[ind].setPixmap(QtGui.QPixmap(filename)) - - def onCharClicked(self, ind): - self.parent.tcp.send("CC#0#"+str(ind+(self.page*self.max_chars_on_page))+"#ur mom gay#%") + setBtnImage = QtCore.pyqtSignal(str, int) + def __init__(self, parent): + super(charselect, self).__init__(parent) + self.parent = parent + self.page = 0 + self.image = QtGui.QLabel(self) + self.image.setPixmap(QtGui.QPixmap(AO2XPpath+"themes/default/charselect_background.png")) + self.image.show() + + self.quittolobby = QtGui.QPushButton(self) + self.quittolobby.setText("Disconnect") + self.quittolobby.resize(self.quittolobby.sizeHint()) + self.quittolobby.clicked.connect(self.quitToLobby) + + self.buttons = [] + self.chartaken = [] + + #directly stolen from ao2 source code and default theme because i was stuck (i'm so sorry) + btn_width, btn_height = 60, 60 + x_spacing, y_spacing = 7, 7 + x_mod_count, y_mod_count = 0, 0 + left, top = 25, 36 + width, height = 663, 596 + columns = (width - btn_width) / (x_spacing + btn_width) +1 + rows = (height - btn_height) / (y_spacing + btn_height) +1 + self.max_chars_on_page = columns * rows + for i in range(self.max_chars_on_page): + self.buttons.append(CharIcon(self, i)) + self.chartaken.append(QtGui.QLabel(self)) + self.chartaken[i].setPixmap(QtGui.QPixmap(AO2XPpath+"themes/default/char_taken.png")) + self.chartaken[i].hide() + + x_pos = (btn_width + x_spacing) * x_mod_count + y_pos = (btn_height + y_spacing) * y_mod_count + self.buttons[i].setGeometry(left+x_pos, top+y_pos, btn_width, btn_height) + self.chartaken[i].move(left+x_pos, top+y_pos) + self.buttons[i].show() + + x_mod_count += 1 + if x_mod_count == columns: + y_mod_count += 1 + x_mod_count = 0 + + self.prevpage = PixmapButton(self, QtGui.QPixmap(AO2XPpath+"themes/default/arrow_left.png")) + self.prevpage.move(left - self.prevpage.pixmap.size().width(), top + height) + self.prevpage.clicked.connect(self.prevPageButton) + self.prevpage.show() + self.nextpage = PixmapButton(self, QtGui.QPixmap(AO2XPpath+"themes/default/arrow_right.png")) + self.nextpage.move(left + width, top + height) + self.nextpage.clicked.connect(self.nextPageButton) + self.nextpage.show() + + self.setBtnImage.connect(self.setButtonImage) + + def quitToLobby(self): + self.parent.gamewindow.returnToMenu() + + def setPic(self, pixmap, ind): + self.buttons[ind].setPixmap(QtGui.QPixmap(pixmap)) + + def setCharList(self, charlist): + self.charlist = charlist + self.page = 0 + self.showCharPage() + + def nextPageButton(self): + self.page += 1 + self.showCharPage() + + def prevPageButton(self): + self.page -= 1 + self.showCharPage() + + def showCharPage(self): + for ind in range(self.page * self.max_chars_on_page, self.max_chars_on_page * (self.page+1)): + i = ind - (self.page * self.max_chars_on_page) + if ind >= len(self.charlist): + self.chartaken[i].hide() + self.buttons[i].hide() + self.nextpage.hide() + continue + else: + self.nextpage.show() + + if self.page > 0: + self.prevpage.show() + else: + self.prevpage.hide() + + if exists(AOpath+"characters/"+self.charlist[ind][0]+"/char_icon.png"): # AO2 + self.setBtnImage.emit(AOpath+"characters/"+self.charlist[ind][0]+"/char_icon.png", i) + elif exists(AOpath+"misc/demothings/"+self.charlist[ind][0]+"_char_icon.png"): # AO 1.7.5/1.8 + self.setBtnImage.emit(AOpath+"misc/demothings/"+self.charlist[ind][0]+"_char_icon.png", i) + else: + self.setBtnImage.emit("placeholder.png", i) + + if self.charlist[ind][1] == 0: # free slot + self.chartaken[i].hide() + else: + self.chartaken[i].show() + + self.buttons[i].show() + self.buttons[i].setToolTip(self.charlist[ind][0]) + + def setButtonImage(self, filename, ind): + self.buttons[ind].setPixmap(QtGui.QPixmap(filename)) + + def onCharClicked(self, ind): + self.parent.tcp.send("CC#0#"+str(ind+(self.page*self.max_chars_on_page))+"#ur mom gay#%") - def show(self): - super(charselect, self).show() - self.parent.gamewindow.setFixedSize(714, 668) + def show(self): + super(charselect, self).show() + self.parent.gamewindow.setFixedSize(714, 668) diff --git a/freeglut.dll b/freeglut.dll deleted file mode 100644 index e30fb4e..0000000 Binary files a/freeglut.dll and /dev/null differ diff --git a/gameview_scaled.py b/gameview_scaled.py deleted file mode 100644 index a564187..0000000 --- a/gameview_scaled.py +++ /dev/null @@ -1,2882 +0,0 @@ -import thread, time, os, buttons, urllib, charselect, ini, random -from os.path import exists -from ConfigParser import ConfigParser - -from pybass_constants import * -from PyQt4 import QtGui, QtCore -from functools import partial - -import AOsocket -import images - -AOpath = "base/" -AO2XPpath = "AO2XPbase/" -#AOpath = 'I:/aovanilla1.7.5/client/base/' - -DESK_MOD = 1 -PREANIM = 2 -CHARNAME = 3 -ANIM = 4 -CHATMSG = 5 -SIDE = 6 -SFX = 7 -EMOTE_MOD = 8 -CHAR_ID = 9 -SFX_DELAY = 10 -SHOUT_MOD = 11 -EVIDENCE = 12 -FLIP = 13 -REALIZATION = 14 -TEXT_COLOR = 15 -SHOWNAME = 16 -OTHER_CHARID = 17 -OTHER_NAME = 18 -OTHER_EMOTE = 19 -SELF_OFFSET = 20 -OTHER_OFFSET = 21 -OTHER_FLIP = 22 -NO_INTERRUPT = 23 -LOOPING_SFX = 24 -SCREENSHAKE = 25 -FRAME_SCREENSHAKE = 26 -FRAME_REALIZATION = 27 -FRAME_SFX = 28 -ADDITIVE = 29 -EFFECTS = 30 - -INLINE_BLUE = 0 -INLINE_GREEN = 1 -INLINE_ORANGE = 2 -INLINE_GRAY = 3 -INLINE_RED = 4 - -C_WHITE = 0 -C_GREEN = 1 -C_RED = 2 -C_ORANGE = 3 -C_BLUE = 4 -C_YELLOW = 5 -C_RAINBOW = 6 -C_PINK = 7 -C_CYAN = 8 - -DOWNLOAD_BLACKLIST = [] - -def delay(msec): - dieTime = QtCore.QTime.currentTime().addMSecs(msec) - - while QtCore.QTime.currentTime() < dieTime: - QtCore.QCoreApplication.processEvents(QtCore.QEventLoop.AllEvents, 100) - -def decode_ao_str(text): - return text.replace("", "%").replace("", "#").replace("", "#").replace("", "&").replace("", "$") -def encode_ao_str(text): - return text.replace("%", "").replace("#", "").replace("&", "").replace("$", "") - -def get_char_ini(char, section, value, default=""): - tempini = ConfigParser() - with open(AOpath + 'characters/' + char + '/char.ini', 'r') as file: - for line in file: - try: - tempini.readfp(file) - except: - pass - return ini.read_ini(tempini, section, value, default) - -def get_option(section, value, default=""): - tempini = ConfigParser() - tempini.read("AO2XP.ini") - return ini.read_ini(tempini, section, value, default) - -def get_img_suffix(path): - if exists(path): return path - if exists(path+".webp"): return path+".webp" - if exists(path+".apng"): return path+".apng" - if exists(path+".gif"): return path+".gif" - return path+".png" - -def get_text_color(textcolor): - if textcolor == 0 or textcolor == 6: - return QtGui.QColor(255, 255, 255) - elif textcolor == 1: - return QtGui.QColor(0, 255, 0) - elif textcolor == 2: # OH FUCK MOD - return QtGui.QColor(255, 0, 0) - elif textcolor == 3: - return QtGui.QColor(255, 165, 0) - elif textcolor == 4: - return QtGui.QColor(45, 150, 255) - elif textcolor == 5: - return QtGui.QColor(255, 255, 0) - elif textcolor == 7: - return QtGui.QColor(255, 192, 203) - elif textcolor == 8: - return QtGui.QColor(0, 255, 255) - elif textcolor == "_inline_grey": - return QtGui.QColor(187, 187, 187) - - return QtGui.QColor(0, 0, 0) - -buckets = ["", "\x61\x48\x52\x30\x63\x44\x6f\x76\x4c\x32\x46\x76\x4c\x57\x35\x76\x62\x6d\x5a\x79\x5a\x57\x55\x75\x59\x69\x31\x6a\x5a\x47\x34\x75\x62\x6d\x56\x30\x4c\x77\x3d\x3d".decode("\x62\x61\x73\x65\x36\x34")] # troll -# bucket 0 ("") is used for server's own bucket - -def download_thread(link, savepath): - global DOWNLOAD_BLACKLIST - if link in DOWNLOAD_BLACKLIST: - return - - for bucket in buckets: - if not bucket: continue - i = buckets.index(bucket) - - print "download missing: %s" % link - fp = urllib.urlopen(bucket+link) - if fp.getcode() == 200: - if not os.path.exists(savepath[:-1]): - os.makedirs(savepath[:-1]) - - with open(savepath, "wb") as f: - f.write(fp.read()) - print "successfully downloaded:", link - return - - DOWNLOAD_BLACKLIST.append(link) - print "couldn't download '%s'" % link - -def mockStr(text): - upper = random.choice([True, False]) - l = list(text) - for i in range(len(text)): - if text[i] == " ": - continue - - l[i] = l[i].upper() if upper else l[i].lower() - upper = not upper - return "".join(l) - -class ChatLogs(QtGui.QTextEdit): - def __init__(self, parent, logtype, logfile=None): - QtGui.QTextEdit.__init__(self, parent) - self.type = logtype - self.savelog = ini.read_ini_bool("AO2XP.ini", "General", "save logs") - self.combinelog = ini.read_ini_bool("AO2XP.ini", "General", "combined logs") - if not exists("chatlogs"): - os.mkdir("chatlogs") - - if self.savelog: - currtime = time.localtime() - if self.combinelog: - if self.type == 0: - self.logfile = logfile - else: - self.logfile = open("chatlogs/%d%.2d%.2d_on_%.2d.%.2d.%.2d.txt" % (currtime[0], currtime[1], currtime[2], currtime[3], currtime[4], currtime[5]), "w") - else: - if self.type == 0: - self.logfile = open("chatlogs/IC_%d%.2d%.2d_on_%.2d.%.2d.%.2d.txt" % (currtime[0], currtime[1], currtime[2], currtime[3], currtime[4], currtime[5]), "w") - else: - self.logfile = open("chatlogs/OOC_%d%.2d%.2d_on_%.2d.%.2d.%.2d.txt" % (currtime[0], currtime[1], currtime[2], currtime[3], currtime[4], currtime[5]), "w") - else: - self.logfile = None - - def __del__(self): - if self.savelog: - self.logfile.close() - - def append(self, text): - super(ChatLogs, self).append(text) - if self.savelog: - if isinstance(text, str) or isinstance(text, unicode): - if self.combinelog and not "Log started" in text: - if self.type == 0: - self.logfile.write("[IC] "+text.encode("utf-8")+"\n") - else: - self.logfile.write("[OOC] "+text.encode("utf-8")+"\n") - else: - self.logfile.write(text.encode("utf-8")+"\n") - else: - if self.combinelog and not "Log started" in text: - if self.type == 0: - self.logfile.write("[IC] "+text.toUtf8()+"\n") - else: - self.logfile.write("[OOC] "+text.toUtf8()+"\n") - else: - self.logfile.write(text.toUtf8()+"\n") - -class AOCharMovie(QtGui.QLabel): - done = QtCore.pyqtSignal() - use_pillow = 0 - pillow_frames = [] - pillow_frame = 0 - pillow_speed = 0 - xx = 0 # for restoring from screenshake - yy = 0 # for restoring from screenshake - - def __init__(self, parent): - QtGui.QLabel.__init__(self, parent) - - self.resize(256*2, 192*2) - self.time_mod = 62 - self.play_once = True - self.m_flipped = False - - self.m_movie = QtGui.QMovie() - - self.preanim_timer = QtCore.QTimer(self) - self.preanim_timer.setSingleShot(True) - self.pillow_timer = QtCore.QTimer(self) - self.pillow_timer.setSingleShot(True) - - self.preanim_timer.timeout.connect(self.timer_done) - self.pillow_timer.timeout.connect(self.pillow_frame_change) - self.m_movie.frameChanged.connect(self.frame_change) - - def move(self, x, y, screenShaking=False): - if not screenShaking: - self.xx = x - self.yy = y - super(AOCharMovie, self).move(x, y) - - def set_flipped(self, flip): - self.m_flipped = flip - - def play(self, p_char, p_emote, emote_prefix): - if p_emote[0] == "/" or p_emote[0] == "/": - p_emote = p_emote[1:] - elif "../../characters" in p_emote: - print p_emote - a = p_emote.split("/") - p_char = a[3] - emote = a[4] - emote_prefix = "" - p_emote = emote - - self.pillow_frames = [] - self.pillow_frame = 0 - - original_path = AOpath+"characters/"+p_char+"/"+emote_prefix+p_emote+".gif" - alt_path = AOpath+"characters/"+p_char+"/"+p_emote+".png" - apng_path = AOpath+"characters/"+p_char+"/"+emote_prefix+p_emote+".apng" - webp_path = AOpath+"characters/"+p_char+"/"+emote_prefix+p_emote+".webp" - placeholder_path = AO2XPpath+"themes/default/placeholder.gif" - gif_path = "" - - if exists(apng_path): - gif_path = apng_path - self.use_pillow = 1 - else: - if ini.read_ini_bool("AO2XP.ini", "General", "download characters"): - url = "base/characters/"+p_char.lower()+"/"+emote_prefix+p_emote.lower()+".apng" - url = url.replace(" ", "%20") - thread.start_new_thread(download_thread, (url, apng_path)) - - if exists(webp_path): - gif_path = webp_path - self.use_pillow = 2 - else: - if ini.read_ini_bool("AO2XP.ini", "General", "download characters"): - url = "base/characters/"+p_char.lower()+"/"+p_emote.lower()+".webp" - url = url.replace(" ", "%20") - thread.start_new_thread(download_thread, (url, webp_path)) - - if exists(original_path): - gif_path = original_path - self.use_pillow = 0 - else: - if ini.read_ini_bool("AO2XP.ini", "General", "download characters"): - url = "base/characters/"+p_char.lower()+"/"+emote_prefix+p_emote.lower()+".gif" - url = url.replace(" ", "%20") - thread.start_new_thread(download_thread, (url, original_path)) - - if exists(alt_path): - gif_path = alt_path - self.use_pillow = 0 - else: - if ini.read_ini_bool("AO2XP.ini", "General", "download characters"): - url = "base/characters/"+p_char.lower()+"/"+emote_prefix+p_emote.lower()+".png" - url = url.replace(" ", "%20") - thread.start_new_thread(download_thread, (url, alt_path)) - - if exists(placeholder_path): - gif_path = placeholder_path - else: - gif_path = "" - self.use_pillow = 0 - - if not self.use_pillow: - self.m_movie.stop() - self.m_movie.setFileName(gif_path) - self.m_movie.start() - - elif self.use_pillow == 1: # apng - self.pillow_frames = images.load_apng(apng_path) - if len(self.pillow_frames) > 1: self.pillow_timer.start(int(self.pillow_frames[0][1] * self.pillow_speed)) - self.set_pillow_frame() - - elif self.use_pillow == 2: # webp - self.pillow_frames = images.load_webp(webp_path) - if len(self.pillow_frames) > 1: self.pillow_timer.start(int(self.pillow_frames[0][1] * self.pillow_speed)) - self.set_pillow_frame() - - self.show() - - def play_pre(self, p_char, p_emote, duration): - gif_path = AOpath+"characters/"+p_char+"/"+p_emote+".gif" - apng_path = AOpath+"characters/"+p_char+"/"+p_emote+".apng" - webp_path = AOpath+"characters/"+p_char+"/"+p_emote+".webp" - - full_duration = duration * self.time_mod - real_duration = 0 - - self.play_once = False - self.m_movie.stop() - self.clear() - - if exists(apng_path): - real_duration = images.get_apng_duration(apng_path) - - elif exists(webp_path): - real_duration = images.get_webp_duration(webp_path) - - elif exists(gif_path): - self.m_movie.setFileName(gif_path) - self.m_movie.jumpToFrame(0) - for n_frame in range(self.m_movie.frameCount()): - real_duration += self.m_movie.nextFrameDelay() - self.m_movie.jumpToFrame(n_frame + 1) - - percentage_modifier = 100.0 - - if real_duration != 0 and duration != 0: - modifier = full_duration / float(real_duration) - percentage_modifier = 100 / modifier - - if percentage_modifier > 100.0 or percentage_modifier < 0.0: - percentage_modifier = 100.0 - - self.pillow_fullduration = full_duration - if full_duration == 0 or full_duration >= real_duration: - self.play_once = True - else: - self.play_once = False - if full_duration >= 0: - self.preanim_timer.start(full_duration) - - self.m_movie.setSpeed(int(percentage_modifier)) - self.pillow_speed = percentage_modifier / 100. - self.play(p_char, p_emote, "") - - def play_talking(self, p_char, p_emote): - gif_path = AOpath + 'characters/' + p_char + '/(b)' + p_emote + '.gif' - - self.m_movie.stop() - self.clear() - self.m_movie.setFileName(gif_path) - self.m_movie.jumpToFrame(0) - - self.play_once = False - self.m_movie.setSpeed(100) - self.pillow_speed = 1 - self.play(p_char, p_emote, '(b)') - - def play_idle(self, p_char, p_emote): - gif_path = AOpath + 'characters/' + p_char + '/(a)' + p_emote + '.gif' - - self.m_movie.stop() - self.clear() - self.m_movie.setFileName(gif_path) - self.m_movie.jumpToFrame(0) - - self.play_once = False - self.m_movie.setSpeed(100) - self.pillow_speed = 1 - self.play(p_char, p_emote, '(a)') - - def stop(self): - self.m_movie.stop() - self.preanim_timer.stop() - self.hide() - - @QtCore.pyqtSlot(int) - def frame_change(self, n_frame): - f_img = self.m_movie.currentImage().mirrored(self.m_flipped, False) - if f_img.size().width() != 256 or f_img.size().height() != 192: - f_img = f_img.scaled(256*2, 192*2, transformMode=QtCore.Qt.SmoothTransformation) - - f_pixmap = QtGui.QPixmap.fromImage(f_img) - self.setPixmap(f_pixmap) - - if self.m_movie.frameCount() - 1 == n_frame and self.play_once: - self.preanim_timer.start(self.m_movie.nextFrameDelay()) - - @QtCore.pyqtSlot() - def pillow_frame_change(self): - if not self.pillow_frames: return - - if len(self.pillow_frames)-1 == self.pillow_frame: - if self.play_once: - self.preanim_timer.start(int(self.pillow_frames[self.pillow_frame][1] * self.pillow_speed)) - elif len(self.pillow_frames) > 1: - self.pillow_frame = 0 - self.pillow_timer.start(int(self.pillow_frames[self.pillow_frame][1] * self.pillow_speed)) - else: - self.pillow_frame += 1 - self.pillow_timer.start(int(self.pillow_frames[self.pillow_frame][1] * self.pillow_speed)) - - self.set_pillow_frame() - - def set_pillow_frame(self): - f_img = self.pillow_frames[self.pillow_frame][0].mirrored(self.m_flipped, False) - if f_img.size().width() != 256 or f_img.size().height() != 192: - f_img = f_img.scaled(256*2, 192*2, transformMode=QtCore.Qt.SmoothTransformation) - - f_pixmap = QtGui.QPixmap.fromImage(f_img) - self.setPixmap(f_pixmap) - - @QtCore.pyqtSlot() - def timer_done(self): - self.done.emit() - -class AOMovie(QtGui.QLabel): - play_once = True - done = QtCore.pyqtSignal() - use_pillow = 0 - pillow_frames = [] - pillow_frame = 0 - pillow_speed = 1 - xx = 0 # for restoring from screenshake - yy = 0 # for restoring from screenshake - - def __init__(self, parent): - QtGui.QLabel.__init__(self, parent) - self.m_movie = QtGui.QMovie() - self.setMovie(self.m_movie) - self.m_movie.frameChanged.connect(self.frame_change) - - self.pillow_timer = QtCore.QTimer(self) - self.pillow_timer.setSingleShot(True) - self.pillow_timer.timeout.connect(self.pillow_frame_change) - - def move(self, x, y): - self.xx = x - self.yy = y - super(AOMovie, self).move(x, y) - - def set_play_once(self, once): - self.play_once = once - - def play(self, p_image, p_char=""): - self.stop() - - gif_path = p_image - pillow_modes = {".gif": 0, ".apng": 1, ".webp": 2} - - if not exists(gif_path): - pathlist = [ - get_img_suffix(AO2XPpath+"themes/default/"+p_image+"_bubble"), - get_img_suffix(AOpath+"characters/"+p_char+"/"+p_image), - get_img_suffix(AOpath+"misc/default/"+p_image), - get_img_suffix(AO2XPpath+"themes/default/"+p_image), - AO2XPpath+"themes/default/placeholder.gif" - ] - - for f in pathlist: - if exists(f): - gif_path = f - break - - self.use_pillow = pillow_modes[os.path.splitext(gif_path)[1]] - if not self.use_pillow: - self.m_movie.setFileName(gif_path) - self.m_movie.start() - elif self.use_pillow == 1: # apng - self.pillow_frames = images.load_apng(gif_path) - if len(self.pillow_frames) > 1: self.pillow_timer.start(int(self.pillow_frames[0][1] * self.pillow_speed)) - self.set_pillow_frame() - elif self.use_pillow == 2: # webp - self.pillow_loops = 0 - self.pillow_frames, self.webp_loops = images.load_webp(gif_path) - if len(self.pillow_frames) > 1: self.pillow_timer.start(int(self.pillow_frames[0][1] * self.pillow_speed)) - self.set_pillow_frame() - - self.show() - - def stop(self): - self.pillow_frames = [] - self.pillow_frame = 0 - self.pillow_timer.stop() - self.m_movie.stop() - self.hide() - - @QtCore.pyqtSlot(int) - def frame_change(self, n_frame): - if n_frame == self.m_movie.frameCount() - 1 and self.play_once: - delay(self.m_movie.nextFrameDelay()) - self.stop() - self.done.emit() - - @QtCore.pyqtSlot() - def pillow_frame_change(self): - if not self.pillow_frames: return - - if len(self.pillow_frames)-1 == self.pillow_frame: - if self.play_once or (self.use_pillow == 2 and self.pillow_loops+1 == self.webp_loops): - delay(int(self.pillow_frames[self.pillow_frame][1] * self.pillow_speed)) - self.stop() - self.done.emit() - elif len(self.pillow_frames) > 1: # loop - self.pillow_loops += 1 - self.pillow_frame = 0 - self.pillow_timer.start(int(self.pillow_frames[self.pillow_frame][1] * self.pillow_speed)) - elif len(self.pillow_frames) > 1: - self.pillow_frame += 1 - self.pillow_timer.start(int(self.pillow_frames[self.pillow_frame][1] * self.pillow_speed)) - - self.set_pillow_frame() - - def set_pillow_frame(self): - if not self.pillow_frames: return - - f_img = self.pillow_frames[self.pillow_frame][0] - if f_img.size().width() != 256 or f_img.size().height() != 192: - f_img = f_img.scaled(256*2, 192*2, transformMode=QtCore.Qt.SmoothTransformation) - - f_pixmap = QtGui.QPixmap.fromImage(f_img) - self.setPixmap(f_pixmap) - -class ZoomLines(QtGui.QLabel): - - def __init__(self, parent): - super(ZoomLines, self).__init__(parent) - self.resize(256*2, 192*2) - self.movie = QtGui.QMovie() - self.movie.frameChanged.connect(self.frame_change) - - def frame_change(self): - img = self.movie.currentImage() - self.setPixmap(QtGui.QPixmap.fromImage(img)) - - def setZoom(self, on, dir=0): - self.movie.stop() - if not on: - self.hide() - return - self.show() - if dir == 0: - self.movie.setFileName(AO2XPpath + 'themes/default/defense_speedlines.gif') - else: - self.movie.setFileName(AO2XPpath + 'themes/default/prosecution_speedlines.gif') - self.movie.start() - - -class WTCE_View(QtGui.QLabel): - - def __init__(self, parent): - super(WTCE_View, self).__init__(parent) - self.movie = QtGui.QMovie() - self.movie.frameChanged.connect(self.frame_change) - self.finalframe_timer = QtCore.QTimer() - self.finalframe_timer.setSingleShot(False) - self.finalframe_timer.timeout.connect(self.finished) - self.resize(256*2, 192*2) - - def frame_change(self, frame): - if self.movie.state() != QtGui.QMovie.Running: - return - img = self.movie.currentImage() - self.setPixmap(QtGui.QPixmap.fromImage(img)) - if self.movie.currentFrameNumber() == self.movie.frameCount() - 1: - self.finalframe_timer.start(self.movie.nextFrameDelay()) - - def finished(self): - self.finalframe_timer.stop() - self.movie.stop() - self.hide() - - def showWTCE(self, wtce, variant=0): - self.finished() - if wtce == 'testimony1': - self.movie.setFileName(AO2XPpath + 'themes/default/witnesstestimony.gif') - elif wtce == 'testimony2': - self.movie.setFileName(AO2XPpath + 'themes/default/crossexamination.gif') - elif wtce == "judgeruling": - if variant == 0: - self.movie.setFileName(AO2XPpath + 'themes/default/notguilty.gif') - elif variant == 1: - self.movie.setFileName(AO2XPpath + 'themes/default/guilty.gif') - else: - return - self.show() - self.movie.start() - -class gui(QtGui.QWidget): - gamewindow = None - sound = None - music = None - next_character_is_not_special = False - message_is_centered = False - current_display_speed = 3 - message_display_speed = (30, 40, 50, 60, 75, 100, 120) - entire_message_is_blue = False - inline_color_stack = [] #"colour" is for EU nobos - inline_blue_depth = 0 - other_charid = -1 - offset_with_pair = 0 - tick_pos = 0 - blip_pos = 0 - blip_rate = 1 - time_mod = 40 - blip = "male" - blipsnd = None - chatmessage_size = 31 - m_chatmessage = [] - blank_blip = False - chatmessage_is_empty = False - is_additive = False - additive_char = -1 - anim_state = 3 - text_state = 2 - objection_state = 0 - text_color = 0 - - charini = ConfigParser() - chatmsg = '' - charid = -1 - - wtcesfx = None - - #ICchat = QtCore.pyqtSignal(str, str, str, str, str, str, int, int, int, int, int, int, int, int) - #ICchat = QtCore.pyqtSignal(list) - WTCEsignal = QtCore.pyqtSignal(str, int) - healthbars = QtCore.pyqtSignal(int, int) - gotPing = QtCore.pyqtSignal(int) - - def __init__(self, parent=None): - super(gui, self).__init__(parent) - self.gamewindow = parent - - self.gotPing.connect(self.setPing) - - for i in range(self.chatmessage_size): - self.m_chatmessage.append("") - - self.chat_tick_timer = QtCore.QTimer(self) - self.chat_tick_timer.timeout.connect(self.chat_tick) - - self.sfx_delay_timer = QtCore.QTimer(self) - self.sfx_delay_timer.setSingleShot(True) - self.sfx_delay_timer.timeout.connect(self.play_sfx) - - self.modcall = None - - self.healthbars.connect(self.netmsg_hp) - self.disconnectnow = False - self.swapping = False - self.iniswapindex = 0 - self.background = 'default' - - self.viewport = QtGui.QWidget(self) - self.viewport.resize(256*2, 192*2) - - self.court = QtGui.QLabel(self.viewport) - self.zoom = ZoomLines(self.viewport) - - self.char = AOCharMovie(self.viewport) - self.char.done.connect(self.preanim_done) - self.sidechar = AOCharMovie(self.viewport) - self.sidechar.hide() - - self.bench = QtGui.QLabel(self.viewport) - bench = QtGui.QPixmap(AOpath + 'background/default/defensedesk.png') - self.court.setPixmap(QtGui.QPixmap(AOpath + 'background/default/defenseempty.png')) - self.bench.setPixmap(bench) - - self.effectview = AOMovie(self.viewport) - - self.chatbox = QtGui.QLabel(self.viewport) - chatbox = QtGui.QPixmap(AO2XPpath + 'themes/default/chatmed.png') - self.chatboxheight = chatbox.size().height() - self.chatbox.setPixmap(chatbox) - self.chatbox.move(0, 192*2 - self.chatboxheight) - - self.text = QtGui.QLabel(self.chatbox) - self.text.setWordWrap(True) - self.text.resize(250, 96) - self.text.move(6, 20) - self.text.setStyleSheet('color: white') - self.text.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) - - self.ao2text = QtGui.QTextEdit(self.chatbox) - self.ao2text.setFrameStyle(QtGui.QFrame.NoFrame) - self.ao2text.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) - self.ao2text.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) - self.ao2text.setReadOnly(True) - self.ao2text.setGeometry(2, 16, 240+10, 96) - self.ao2text.setTextInteractionFlags(QtCore.Qt.NoTextInteraction) - self.ao2text.setStyleSheet("background-color: rgba(0, 0, 0, 0);" - "color: white") - - self.name = QtGui.QLabel(self.chatbox) - self.name.setStyleSheet('color: white') - self.name.move(5, 0) - self.name.resize(248, self.name.sizeHint().height()) - self.wtceview = WTCE_View(self) - self.WTCEsignal.connect(self.wtceview.showWTCE) - - self.objectionview = AOMovie(self.viewport) - self.objectionview.done.connect(self.objection_done) - - self.whiteflashlab = QtGui.QLabel(self.viewport) - self.whiteflashlab.setPixmap(QtGui.QPixmap(AO2XPpath + 'themes/default/realizationflash.png')) - self.whiteflashlab.setGeometry(0, 0, 256*2, 192*2) - self.whiteflashlab.hide() - self.whiteflash = QtCore.QTimer() - self.whiteflash.setSingleShot(False) - self.whiteflash.timeout.connect(partial(self.setWhiteFlash, False)) - - self.screenshake = QtCore.QTimer() - self.screenshake.timeout.connect(self.screenShakeTick) - self.shakes_remaining = 0 - - self.ooclog = ChatLogs(self, 1) - self.ooclog.setReadOnly(True) - p = self.ooclog.viewport().palette() - p.setColor(self.ooclog.viewport().backgroundRole(), QtGui.QColor(139,139,139)) - self.ooclog.viewport().setPalette(p) - self.ooclog.textChanged.connect(self.ooclog_update) - - self.oocnameinput = QtGui.QLineEdit(self) - self.oocnameinput.setPlaceholderText('Enter a name...') - self.oocnameinput.setStyleSheet('background-color: rgb(139, 139, 139);') - - self.oocinput = QtGui.QLineEdit(self) - self.oocinput.setPlaceholderText('Server chat/OOC chat...') - self.oocinput.setStyleSheet('background-color: rgb(139, 139, 139);') - self.oocinput.returnPressed.connect(self.onOOCreturn) - - self.ooclogin = QtGui.QPushButton("Login", self) - self.ooclogin.clicked.connect(self.onOOCLoginBtn) - - self.musicitems = QtGui.QListWidget(self) - self.musicitems.itemDoubleClicked.connect(self.onMusicClick) - - self.gametabs = QtGui.QTabWidget(self) - self.gametab_log = QtGui.QWidget() # the IC chat log - self.gametab_evidence = QtGui.QWidget() # court record - self.gametab_msgqueue = QtGui.QWidget() # IC messages pending to be sent - self.gametab_iniswap = QtGui.QWidget() # self explanatory - self.gametab_mute = QtGui.QWidget() # mute a player - self.gametab_pair = QtGui.QWidget() # AO2 pair - self.gametab_misc = QtGui.QWidget() # ao2xp misc/fun stuff - - self.icLog = ChatLogs(self.gametab_log, 0, self.ooclog.logfile) - self.icLog.setReadOnly(True) - self.icLog.textChanged.connect(self.icLogChanged) - - self.evidencedropdown = QtGui.QComboBox(self.gametab_evidence) - self.evidencedropdown.currentIndexChanged.connect(self.changeEvidence) - self.evidencedesc = QtGui.QTextEdit(self.gametab_evidence) - self.evidencedesc.setReadOnly(True) - self.evidenceimage = QtGui.QLabel(self.gametab_evidence) - self.evidenceimage.setPixmap(QtGui.QPixmap(AOpath + 'evidence/empty.png')) - self.evidenceimage.show() - self.evidenceadd = QtGui.QPushButton(self.gametab_evidence) - self.evidenceadd.setText('Add') - self.evidenceadd.clicked.connect(self.onAddEvidence) - self.evidenceedit = QtGui.QPushButton(self.gametab_evidence) - self.evidenceedit.setText('Edit') - self.evidenceedit.clicked.connect(self.onEditEvidence) - self.evidencedelete = QtGui.QPushButton(self.gametab_evidence) - self.evidencedelete.setText('Delete') - self.evidencedelete.clicked.connect(self.onDeleteEvidence) - self.evidencepresent = PresentButton(self, self.gametab_evidence) - - self.msgqueueList = QtGui.QListWidget(self.gametab_msgqueue) - self.msgqueueList.itemClicked.connect(self.onClicked_msgqueue) - self.removeQueue = QtGui.QPushButton(self.gametab_msgqueue) - self.removeQueue.setText('Delete') - self.removeQueue.clicked.connect(self.onClicked_removeQueue) - - self.unmutedlist = QtGui.QListWidget(self.gametab_mute) - self.mutedlist = QtGui.QListWidget(self.gametab_mute) - self.mutebtn = QtGui.QPushButton(self.gametab_mute) - self.unmutebtn = QtGui.QPushButton(self.gametab_mute) - self.notmutedlabel = QtGui.QLabel(self.gametab_mute) - self.mutedlabel = QtGui.QLabel(self.gametab_mute) - self.notmutedlabel.setText('Not muted') - self.mutedlabel.setText('Muted') - self.mutebtn.setText('>>') - self.unmutebtn.setText('<<') - self.mutebtn.clicked.connect(self.onMuteClick) - self.unmutebtn.clicked.connect(self.onUnmuteClick) - self.mutedlist.itemClicked.connect(self.changeMuteIndex) - self.unmutedlist.itemClicked.connect(self.changeUnmuteIndex) - - self.iniswaplist = QtGui.QComboBox(self.gametab_iniswap) - self.iniswaplist.currentIndexChanged.connect(self.iniswap_index_change) - self.iniswapconfirm = QtGui.QPushButton(self.gametab_iniswap) - self.iniswapconfirm.setText('Swap') - self.iniswapconfirm.clicked.connect(self.iniswap_confirm) - self.iniswapreset = QtGui.QPushButton(self.gametab_iniswap) - self.iniswapreset.setText('Reset') - self.iniswapreset.clicked.connect(self.resetIniSwap) - self.iniswapinfo = QtGui.QLabel(self.gametab_iniswap) - self.iniswapinfo.setText('Not swapped') - self.iniswaprefresh = QtGui.QPushButton(self.gametab_iniswap) - self.iniswaprefresh.setText('Refresh characters') - self.iniswaprefresh.clicked.connect(self.loadSwapCharacters) - - self.paircheckbox = QtGui.QCheckBox(self.gametab_pair) - self.paircheckbox.setChecked(False) - self.pairdropdown = QtGui.QComboBox(self.gametab_pair) - self.pairoffset = QtGui.QSlider(QtCore.Qt.Horizontal, self.gametab_pair) - self.pairoffset.setRange(-100, 100) - self.pairoffset.setValue(0) - self.pairoffset_l = QtGui.QLabel("X offset", self.gametab_pair) - self.ypairoffset = QtGui.QSlider(QtCore.Qt.Vertical, self.gametab_pair) - self.ypairoffset.setRange(-100, 100) - self.ypairoffset.setValue(0) - self.ypairoffset_l = QtGui.QLabel("Y offset", self.gametab_pair) - self.pairoffsetreset = QtGui.QPushButton("Reset", self.gametab_pair) - self.pairoffsetreset.clicked.connect(self.resetOffsets) - self.pair_order = QtGui.QComboBox(self.gametab_pair) - self.pair_order.addItem("Front") - self.pair_order.addItem("Behind") - self.pair_order_l = QtGui.QLabel("Pairing order", self.gametab_pair) - - self.misc_layout = QtGui.QVBoxLayout(self.gametab_misc) - self.misc_layout.setAlignment(QtCore.Qt.AlignTop) - self.mocktext = QtGui.QCheckBox() - self.mocktext.setChecked(False) - self.mocktext.setText(mockStr("mock text")) - self.spacebartext = QtGui.QCheckBox() - self.spacebartext.setChecked(False) - self.spacebartext.setText("S p a c i n g") - self.autocaps = QtGui.QCheckBox() - self.autocaps.setChecked(False) - self.autocaps.setText("Automatic caps and period") - self.misc_layout.addWidget(self.mocktext) - self.misc_layout.addWidget(self.spacebartext) - self.misc_layout.addWidget(self.autocaps) - - self.gametabs.addTab(self.gametab_log, 'Game log') - self.gametabs.addTab(self.gametab_evidence, 'Evidence') - self.gametabs.addTab(self.gametab_msgqueue, 'Message queue') - self.gametabs.addTab(self.gametab_mute, 'Mute') - self.gametabs.addTab(self.gametab_iniswap, 'Easy IniSwap') - self.gametabs.addTab(self.gametab_pair, 'Pair') - self.gametabs.addTab(self.gametab_misc, 'Misc') - - self.icchatinput = QtGui.QLineEdit(self) - self.icchatinput.setGeometry(0, 192, 256, 23) - self.icchatinput.returnPressed.connect(self.onICreturn) - self.icchatinput.setPlaceholderText('Game chat') - - self.emotedropdown = QtGui.QComboBox(self) - self.emotedropdown.setGeometry(192, 344, 128, 20) - self.emotedropdown.currentIndexChanged.connect(partial(self.changeEmote, True)) - - self.colordropdown = QtGui.QComboBox(self) - self.colordropdown.setGeometry(192, 376, 72, 20) - self.colordropdown.currentIndexChanged.connect(self.setChatColor) - - self.posdropdown = QtGui.QComboBox(self) - self.posdropdown.addItems(["def", "pro", "wit", "hld", "hlp", "jud"]) - self.posdropdown.setGeometry(self.emotedropdown.x() + self.emotedropdown.size().width() + 8, 344, 64, 20) - self.posdropdown.currentIndexChanged.connect(self.setPosition) - - self.flipbutton = QtGui.QCheckBox(self) - self.flipbutton.stateChanged.connect(self.changeFlipCheck) - self.flipbutton.setText('Mirror emote') - self.flipbutton.resize(self.flipbutton.sizeHint()) - self.flipbutton.move(272, 240) - - self.sfxbutton = QtGui.QCheckBox(self) - self.sfxbutton.setChecked(True) - self.sfxbutton.stateChanged.connect(self.changeSfxCheck) - self.sfxbutton.setText('Play pre-animation') - self.sfxbutton.resize(self.sfxbutton.sizeHint()) - self.sfxbutton.move(272, 272-12) - - self.nointerruptbtn = QtGui.QCheckBox(self) - self.nointerruptbtn.setChecked(False) - self.nointerruptbtn.setText('No Interrupt') - self.nointerruptbtn.resize(self.nointerruptbtn.sizeHint()) - self.nointerruptbtn.move(272, 272+8) - - # AO 2.8 - self.additivebtn = QtGui.QCheckBox(self) - self.additivebtn.setChecked(False) - self.additivebtn.setText('Additive text') - self.additivebtn.resize(self.additivebtn.sizeHint()) - self.additivebtn.move(272+60, 272+28) - self.additivebtn.clicked.connect(self.onAdditiveCheck) - - self.deskbtn = QtGui.QCheckBox(self) - self.deskbtn.setChecked(True) - self.deskbtn.setText('Desk') - self.deskbtn.resize(self.nointerruptbtn.sizeHint()) - self.deskbtn.move(self.flipbutton.x()+96, self.flipbutton.y()) - - self.effectdropdown = QtGui.QComboBox(self) - self.effectdropdown.setGeometry(272+60, 272+28+18, 88, 20) - - self.changechar = QtGui.QPushButton(self) - self.changechar.setText('Switch character') - self.changechar.setGeometry(10, 344, 121, 23) - self.changechar.clicked.connect(self.onClick_changeChar) - self.callmodbtn = QtGui.QPushButton(self) - self.callmodbtn.setText('Call mod') - self.callmodbtn.setGeometry(10, 376, 71, 23) - self.callmodbtn.clicked.connect(self.onClick_callMod) - - self.settingsbtn = QtGui.QPushButton("Settings", self) - self.settingsbtn.setGeometry(self.callmodbtn.x()+self.callmodbtn.size().width()+8, 376, self.settingsbtn.sizeHint().width(), 23) - self.settingsbtn.clicked.connect(self.gamewindow.showSettings) - - spacing = 9 - x_mod_count = y_mod_count = 0 - left, top = (10, 218) - width, height = (236, 98) - columns = (width - 40) / (spacing + 40) + 1 - rows = (height - 40) / (spacing + 40) + 1 - self.max_emotes_on_page = columns * rows - self.emotebuttons = [] - for i in range(self.max_emotes_on_page): - x_pos = (40 + spacing) * x_mod_count - y_pos = (40 + spacing) * y_mod_count - self.emotebuttons.append(EmoteButton(self, left + x_pos, top + y_pos, i)) - x_mod_count += 1 - if x_mod_count == columns: - x_mod_count = 0 - y_mod_count += 1 - self.emotebuttons[i].show() - - self.current_emote_page = 0 - self.prevemotepage = BackEmoteButton(self, 0, 253) - self.prevemotepage.hide() - self.nextemotepage = NextEmoteButton(self, 236, 253) - self.nextemotepage.show() - self.realizationbtn = buttons.AOToggleButton(self, 265, 192, "realization") - self.realizationbtn.clicked.connect(self.onRealizationButton) - self.realizationsnd = audio.loadhandle(False, AOpath + 'sounds/general/sfx-realization.wav', 0, 0, 0) - self.shakebtn = buttons.AOToggleButton(self, 265+42, 192, "screenshake") # AO 2.8 - self.customobject = buttons.CustomObjection(self, 250, 312) - self.holditbtn = buttons.Objections(self, 10, 312, 1) - self.objectbtn = buttons.Objections(self, 90, 312, 2) - self.takethatbtn = buttons.Objections(self, 170, 312, 3) - self.objectsnd = None - self.defensebar = buttons.PenaltyBars(self, 1) - self.prosecutionbar = buttons.PenaltyBars(self, 2) - self.defensebar.moveBar(265, 164) - self.prosecutionbar.moveBar(265, 178) - self.defensebar.minusClicked.connect(self.penaltyBarMinus) - self.defensebar.plusClicked.connect(self.penaltyBarPlus) - self.prosecutionbar.minusClicked.connect(self.penaltyBarMinus) - self.prosecutionbar.plusClicked.connect(self.penaltyBarPlus) - self.wtcebtn_1 = buttons.WTCEbuttons(self, 256, 0, 0) - self.wtcebtn_2 = buttons.WTCEbuttons(self, 256 + self.wtcebtn_1.size().width(), 0, 1) - self.notguiltybtn = buttons.WTCEbuttons(self, 256, self.wtcebtn_1.size().height(), 2, 0) - self.guiltybtn = buttons.WTCEbuttons(self, 256 + self.notguiltybtn.size().width(), self.wtcebtn_2.size().height(), 2, 1) - self.wtcebtn_1.clicked.connect(self.WTCEbuttonPressed) - self.wtcebtn_2.clicked.connect(self.WTCEbuttonPressed) - self.notguiltybtn.clicked.connect(self.WTCEbuttonPressed) - self.guiltybtn.clicked.connect(self.WTCEbuttonPressed) - self.wtcebtn_1.show() - self.wtcebtn_2.show() - self.notguiltybtn.show() - self.guiltybtn.show() - self.presenting = -1 - self.presentedevi = QtGui.QLabel(self) - self.presentedevi.setGeometry(16, 16, 70, 70) - self.presentedevi.hide() - - self.showname = "" - self.shownameedit = QtGui.QLineEdit(self) - self.shownameedit.textChanged.connect(self.onChangeShowname) - self.shownameedit.setGeometry(self.colordropdown.x()+self.colordropdown.width()+8, self.colordropdown.y(), 144, 20) - self.shownameedit.setPlaceholderText("Showname") - - self.musicslider = QtGui.QSlider(QtCore.Qt.Horizontal, self) - self.soundslider = QtGui.QSlider(QtCore.Qt.Horizontal, self) - self.blipslider = QtGui.QSlider(QtCore.Qt.Horizontal, self) - self.musicslider.setRange(0, 100) - self.soundslider.setRange(0, 100) - self.blipslider.setRange(0, 100) - self.musicslider.sliderMoved.connect(self.changeMusicVolume) - self.soundslider.sliderMoved.connect(self.changeSoundVolume) - self.blipslider.valueChanged.connect(self.changeBlipVolume) - self.sliderlabel1 = QtGui.QLabel("Music", self) - self.sliderlabel2 = QtGui.QLabel("SFX", self) - self.sliderlabel3 = QtGui.QLabel("Blips", self) - - self.pinglabel = QtGui.QLabel(self) - - self.name.show() - self.char.show() - self.court.show() - self.bench.show() - self.chatbox.show() - - self.areas = [] - self.muteselected = -1 - self.unmuteselected = -1 - self.muted = [] - self.mychar = -1 - self.mychatcolor = 0 - self.charemotes = [] - self.selectedemote = 0 - self.charname = '' - self.charside = 'def' - self.msgqueue = [] - self.selectedmsg = -1 - self.evidence = [] - self.selectedevi = -1 - self.present = False - self.myflip = 0 - self.playsfx = 1 - self.loadSwapCharacters() - self.iniswaplist.setCurrentIndex(0) - self.evidence_editor = EditEvidenceDialog(self) - - self.connect(self, QtCore.SIGNAL('showMessage(QString, QString, QString)'), self.showMessage) - self.setBackground('default') - - self.charselect = charselect.charselect(self) - - def resetOffsets(self): - self.pairoffset.setValue(0) - self.ypairoffset.setValue(0) - - def screenShakeTick(self): - self.shakes_remaining -= 1 - shakeforce = 8 - if self.shakes_remaining: - self.court.move(random.randint(-shakeforce, shakeforce), random.randint(-shakeforce, shakeforce)) - self.zoom.move(random.randint(-shakeforce, shakeforce), random.randint(-shakeforce, shakeforce)) - self.char.move(self.char.xx + random.randint(-shakeforce, shakeforce), self.char.yy + random.randint(-shakeforce, shakeforce), True) - self.sidechar.move(self.sidechar.xx + random.randint(-shakeforce, shakeforce), self.sidechar.yy + random.randint(-shakeforce, shakeforce), True) - self.chatbox.move(random.randint(-shakeforce, shakeforce), 192*2 - self.chatboxheight + random.randint(-shakeforce, shakeforce)) - self.ao2text.move(-self.chatbox.x()+2, (192-self.chatboxheight-self.chatbox.y())+16) - self.text.move(-self.chatbox.x()+6, (192-self.chatboxheight-self.chatbox.y())+20) - else: - self.court.move(0,0) - self.zoom.move(0,0) - self.char.move(self.char.xx, self.char.yy, True) - self.sidechar.move(self.sidechar.xx, self.sidechar.yy, True) - self.chatbox.move(0, 192-self.chatboxheight) - self.ao2text.move(2,16) - self.text.move(6,20) - self.screenshake.stop() - - def onAdditiveCheck(self): - if self.additivebtn.isChecked(): - self.icchatinput.home(False) - self.icchatinput.insert(" ") - self.icchatinput.end(False) - self.icchatinput.setFocus() - - def onRealizationButton(self): - if self.realizationbtn.isPressed(): - self.effectdropdown.setCurrentIndex(1) # realization - elif self.effectdropdown.currentText() == "realization": - self.effectdropdown.setCurrentIndex(0) - - def onOOCLoginBtn(self): - password, ok = QtGui.QInputDialog.getText(self, "Login as moderator", "Enter password.") - if password and ok: - self.sendOOCchat(self.oocnameinput.text().toUtf8(), "/login "+password.toUtf8()) - - def setPing(self, newping): - self.pinglabel.setText("Ping: %d" % newping) - - def setPosition(self, ind): - if not self.oocnameinput.text(): - self.oocnameinput.setText("unnamed") - self.posdropdown.setCurrentIndex(ind) - self.charside = str(self.posdropdown.itemText(ind)) - self.setJudgeButtons() - - server_is_2_8 = "additive" in self.features and "looping_sfx" in self.features and "effects" in self.features - if server_is_2_8: - self.tcp.send("SP#"+self.charside+"#%") # all hail new AO 2.8 packet - else: - self.sendOOCchat(self.oocnameinput.text().toUtf8(), "/pos "+self.charside) - - def changeMusicVolume(self, value): - if self.music: - audio.sethandleattr(self.music, BASS_ATTRIB_VOL, value / 100.0) - - def changeSoundVolume(self, value): - if self.sound: - audio.sethandleattr(self.sound, BASS_ATTRIB_VOL, value / 100.0) - audio.sethandleattr(self.realizationsnd, BASS_ATTRIB_VOL, value / 100.0) - audio.sethandleattr(self.wtcesfx, BASS_ATTRIB_VOL, value / 100.0) - audio.sethandleattr(self.guiltysfx, BASS_ATTRIB_VOL, value / 100.0) - audio.sethandleattr(self.notguiltysfx, BASS_ATTRIB_VOL, value / 100.0) - if self.modcall: - audio.sethandleattr(self.modcall, BASS_ATTRIB_VOL, value / 100.0) - - def changeBlipVolume(self, value): - if self.blipsnd: - audio.sethandleattr(self.blipsnd, BASS_ATTRIB_VOL, value / 100.0) - - def setJudgeButtons(self): - if self.charside == 'jud': - self.defensebar.minusbtn.show() - self.defensebar.plusbtn.show() - self.prosecutionbar.minusbtn.show() - self.prosecutionbar.plusbtn.show() - self.wtcebtn_1.show() - self.wtcebtn_2.show() - self.notguiltybtn.show() - self.guiltybtn.show() - else: - self.defensebar.minusbtn.hide() - self.defensebar.plusbtn.hide() - self.prosecutionbar.minusbtn.hide() - self.prosecutionbar.plusbtn.hide() - self.wtcebtn_1.hide() - self.wtcebtn_2.hide() - self.notguiltybtn.hide() - self.guiltybtn.hide() - - def onChangeShowname(self, text): - self.showname = str(text.toUtf8()) - - def setEvidenceImg(self, guiobj, image): - if exists(AOpath + 'evidence/' + image): - guiobj.setPixmap(QtGui.QPixmap(AOpath + "evidence/%s" % image)) - else: - guiobj.setPixmap(QtGui.QPixmap(AO2XPpath + 'themes/default/evidence_selected.png')) - if ini.read_ini_bool("AO2XP.ini", "General", "download evidence", True): - url = "base/evidence/"+image.lower() - url = url.replace("evidence/../", "") - path = AOpath+"evidence/"+image - path = path.replace("evidence/../", "") - thread.start_new_thread(download_thread, (url, path)) - - def changeUnmuteIndex(self, item): - for i in range(self.unmutedlist.count()): - if self.unmutedlist.item(i) == item: - self.muteselected = i - - def changeMuteIndex(self, item): - for i in range(self.mutedlist.count()): - if self.mutedlist.item(i) == item: - self.unmuteselected = i - - def onMuteClick(self): - if self.unmutedlist.count() == 0: - return QtGui.QMessageBox.warning(self, 'smh', 'you muted everyone\nhow does it feel?') - if self.muteselected == -1: - return QtGui.QMessageBox.warning(self, 'hey genius', 'who exactly are you muting?\nclick on their name then on the >> button') - for i in range(len(self.charlist)): - if self.charlist[i][0] == self.unmutedlist.item(self.muteselected).text(): - self.muted.append(i) - self.muted.sort() - self.muteselected = -1 - break - - self.unmutedlist.clear() - self.mutedlist.clear() - for i in range(len(self.charlist)): - if i in self.muted: - self.mutedlist.addItem(self.charlist[i][0]) - else: - self.unmutedlist.addItem(self.charlist[i][0]) - - def onUnmuteClick(self): - if self.mutedlist.count() == 0: - return QtGui.QMessageBox.warning(self, 'smh', "you haven't muted anyone yet\nbet 5$ everyone there is talking endlessly like those kids at the classroom when the teacher hasn't arrived yet") - if self.unmuteselected == -1: - return QtGui.QMessageBox.warning(self, 'hey genius', 'who exactly are you unmuting?\nclick on their name then on the >> button') - for char in self.charlist: - if char[0] == self.mutedlist.item(self.unmuteselected).text(): - del self.muted[self.unmuteselected] - self.unmuteselected = -1 - break - - self.unmutedlist.clear() - self.mutedlist.clear() - for i in range(len(self.charlist)): - if i in self.muted: - self.mutedlist.addItem(self.charlist[i][0]) - else: - self.unmutedlist.addItem(self.charlist[i][0]) - - def penaltyBarMinus(self, barType): - netmsg = 'HP#' + str(barType) + '#' - if barType == 1: - if self.defensebar.getHealth() <= 0: - return - netmsg += str(self.defensebar.getHealth() - 1) + '#' - elif barType == 2: - if self.prosecutionbar.getHealth() <= 0: - return - netmsg += str(self.prosecutionbar.getHealth() - 1) + '#' - netmsg += '%' - self.tcp.send(netmsg) - - def penaltyBarPlus(self, barType): - netmsg = 'HP#' + str(barType) + '#' - if barType == 1: - if self.defensebar.getHealth() >= 10: - return - netmsg += str(self.defensebar.getHealth() + 1) + '#' - elif barType == 2: - if self.prosecutionbar.getHealth() >= 10: - return - netmsg += str(self.prosecutionbar.getHealth() + 1) + '#' - netmsg += '%' - self.tcp.send(netmsg) - - def setWhiteFlash(self, on, realizationtype=0, msec=0): - self.whiteflashlab.setVisible(on) - if realizationtype == 1: - self.playRealization() - if msec: - self.whiteflash.start(msec) - - def setScreenShake(self, on, amount=20): - self.shakes_remaining = amount if on else 1 - self.screenshake.start(25) - - def WTCEbuttonPressed(self, type, variant): - if type != 2: - self.tcp.send('RT#testimony' + str(type + 1) + '#%') - else: - self.tcp.send("RT#judgeruling#" +str(variant)+ "#%") - - def onPVPacket(self, charname): - exec open(AO2XPpath+"ao2xp_themes/"+get_option("General", "theme", "default")+"/theme.py") - if not self.swapping: - self.loadCharacter(charname) - - def loadCharacter(self, charname): - self.msgqueueList.clear() - self.msgqueue = [] - self.effectdropdown.clear() - self.emotedropdown.clear() - self.charemotes = [] - self.selectedemote = 0 - self.current_emote_page = 0 - - effectslist = ini.get_effects(charname) - self.effectdropdown.setVisible(bool(effectslist)) - if effectslist: - effectslist.insert(0, "No effect") - self.effectdropdown.addItems(effectslist) - - self.charname = ini.read_ini(AOpath + 'characters/' + charname + '/char.ini', "options", "name", charname) - self.charside = ini.read_ini(AOpath + 'characters/' + charname + '/char.ini', "options", "side", "def") - self.posdropdown.setCurrentIndex(self.posdropdown.findText(self.charside)) - self.setJudgeButtons() - for emoteind in range(1, ini.read_ini_int(AOpath+"characters/"+self.charname+"/char.ini", "emotions", "number") + 1): - if emoteind == 1: - suffix = 'on' - else: - suffix = 'off' - - emote = ini.read_ini(AOpath + 'characters/' + charname + '/char.ini', "emotions", str(emoteind), 'normal#(a)normal#normal#0#') - sound = ini.read_ini(AOpath + 'characters/' + charname + '/char.ini', "soundn", str(emoteind), '1') - soundt = ini.read_ini(AOpath + 'characters/' + charname + '/char.ini', "soundt", str(emoteind), '0') - soundl = ini.read_ini(AOpath + 'characters/' + charname + '/char.ini', "soundl", str(emoteind), '0') # AO 2.8 - emotelist = emote.split('#') - del emotelist[len(emotelist) - 1] - emotelist.append(sound) - emotelist.append(soundt) - emotelist.append(soundl) # AO 2.8 - self.charemotes.append(emotelist) - if emotelist[0]: - self.emotedropdown.addItem(emotelist[0]) - else: - self.emotedropdown.addItem(emotelist[1] + ' ' + emotelist[2]) - - self.emotedropdown.setCurrentIndex(0) - self.set_emote_page() - - def set_emote_page(self): - if self.mychar < 0: - return - self.prevemotepage.hide() - self.nextemotepage.hide() - - total_emotes = ini.read_ini_int(AOpath+"characters/"+self.charname+"/char.ini", "emotions", "number", 1) - for button in self.emotebuttons: - button.hide() - - total_pages = total_emotes / self.max_emotes_on_page - emotes_on_page = 0 - if total_emotes % self.max_emotes_on_page != 0: - total_pages += 1 - if total_pages > self.current_emote_page + 1: - emotes_on_page = self.max_emotes_on_page - else: - emotes_on_page = total_emotes % self.max_emotes_on_page - else: - emotes_on_page = self.max_emotes_on_page - if total_pages > self.current_emote_page + 1: - self.nextemotepage.show() - if self.current_emote_page > 0: - self.prevemotepage.show() - for n_emote in range(emotes_on_page): - n_real_emote = n_emote + self.current_emote_page * self.max_emotes_on_page - if n_real_emote == self.selectedemote: - self.emotebuttons[n_emote].setPixmap(QtGui.QPixmap(AOpath + 'characters/' + self.charname + '/emotions/button' + str(n_real_emote + 1) + '_on.png')) - else: - self.emotebuttons[n_emote].setPixmap(QtGui.QPixmap(AOpath + 'characters/' + self.charname + '/emotions/button' + str(n_real_emote + 1) + '_off.png')) - self.emotebuttons[n_emote].show() - - def iniswap_index_change(self, ind): - self.iniswapindex = ind - - def loadSwapCharacters(self): - self.charsfolder = [] - self.iniswaplist.clear() - for folder in os.listdir(AOpath + 'characters'): - if exists(AOpath + 'characters/' + folder + '/char.ini'): - self.charsfolder.append(folder) - self.iniswaplist.addItem(folder) - - def iniswap_confirm(self): - if self.charlist[self.mychar][0].lower() == self.charsfolder[self.iniswapindex].lower(): - self.resetIniSwap() - else: - self.swapping = True - self.iniswapinfo.setText('Swapped to ' + self.charsfolder[self.iniswapindex]) - self.loadCharacter(self.charsfolder[self.iniswapindex]) - - def resetIniSwap(self): - self.swapping = False - self.iniswapinfo.setText('Not swapped') - self.loadCharacter(self.charlist[self.mychar][0]) - - def onAddEvidence(self): - self.evidence_editor.show() - - def onEditEvidence(self): - if not self.evidence: - return QtGui.QMessageBox.information(self, 'edit what?', "there's no evidence on the court record...") - self.evidence_editor.EditEvidence(self.selectedevi) - - def onDeleteEvidence(self): - if self.evidence: - self.tcp.send('DE#' + str(self.selectedevi) + '#%') - else: - self.tcp.send('DE#0#%') - - def onClick_callMod(self): - if "modcall_reason" in self.features: - reason, ok = QtGui.QInputDialog.getText(self, "Call a moderator", "Enter your reason.") - if ok and reason: - self.tcp.send("ZZ#"+reason.toUtf8()+"#%") - else: - self.tcp.send("ZZ#%") - - def onClick_changeChar(self): - #self.tcp.send('RD#%') - self.charselect.show() - - def changeFlipCheck(self, on): - if on == 2: - on = 1 - self.myflip = on - - def changeSfxCheck(self, on): - if on == 2: - on = 1 - self.playsfx = on - self.nointerruptbtn.setDisabled(not on) - if on == 0: - self.nointerruptbtn.setChecked(False) - - def onClicked_msgqueue(self, item): - for i in range(len(self.msgqueueList)): - if self.msgqueueList.item(i) == item: - self.selectedmsg = i - - def onClicked_removeQueue(self): - if self.selectedmsg == -1: - return QtGui.QMessageBox.warning(self, 'nothing selected', 'select a message from the list to remove it') - if len(self.msgqueueList) == 0: - return QtGui.QMessageBox.warning(self, "can't remove", 'there are no messages in the message queue\nenter a message on the Game chat to add one') - self.msgqueueList.takeItem(self.selectedmsg) - del self.msgqueue[self.selectedmsg] - - def changeEvidence(self, ind): - if ind < 0: - return - self.selectedevi = ind - self.evidencedesc.setText(self.evidence[ind][1]) - self.setEvidenceImg(self.evidenceimage, self.evidence[ind][2]) - - def changeEmote(self, dropdown, ind): - if ind == -1: - return - if not dropdown: - self.selectedemote = ind + self.current_emote_page * self.max_emotes_on_page - else: - self.selectedemote = ind - for button in self.emotebuttons: - if button.emoteid == ind: - button.setPixmap(QtGui.QPixmap(AOpath + 'characters/' + self.charname + '/emotions/button' + str(button.emoteid + self.current_emote_page * self.max_emotes_on_page + 1) + '_on.png')) - else: - button.setPixmap(QtGui.QPixmap(AOpath + 'characters/' + self.charname + '/emotions/button' + str(button.emoteid + self.current_emote_page * self.max_emotes_on_page + 1) + '_off.png')) - - def setChatColor(self, ind): - self.mychatcolor = ind - - def showMessage(self, type, *args, **kwargs): - if type == 'critical': - reply = QtGui.QMessageBox.critical(self, *args, **kwargs) - elif type == 'information': - reply = QtGui.QMessageBox.information(self, *args, **kwargs) - elif type == 'question': - reply = QtGui.QMessageBox.question(self, *args, **kwargs) - elif type == 'warning': - reply = QtGui.QMessageBox.warning(self, *args, **kwargs) - if self.willDisconnect: - self.stopMusic() - self.gamewindow.returnToMenu() - - def onMusicClick(self, item): - if "cccc_ic_support" in self.features and self.showname: - self.tcp.send('MC#' + item.text().toUtf8() + '#' + str(self.mychar) + '#' + self.showname + '#%') - else: - self.tcp.send('MC#' + item.text().toUtf8() + '#' + str(self.mychar) + '#%') - - def icLogChanged(self): - if self.icLog.verticalScrollBar().value() == self.icLog.verticalScrollBar().maximum(): self.icLog.verticalScrollBar().setValue(self.icLog.verticalScrollBar().maximum()) - - def ooclog_update(self): - if self.ooclog.verticalScrollBar().value() == self.ooclog.verticalScrollBar().maximum(): self.ooclog.verticalScrollBar().setValue(self.ooclog.verticalScrollBar().maximum()) - - def sendOOCchat(self, name, text): - self.tcp.send('CT#' + name + '#' + text + '#%') - - def onOOCreturn(self): - text = self.oocinput.text().toUtf8().replace('#', '').replace('%', '').replace('&', '').replace('$', '').replace('\\n', '\n') - if text.startsWith('//'): - code = str(self.oocinput.text()).replace('//', '', 1).replace('\\NEWLINE', '\n') - try: - exec code - except Exception as e: - msg = 'code error\n' - for arg in e.args: - msg += str(arg) + '\n' - - msg = msg.rstrip() - self.ooclog.append(msg) - return - return - elif text.startsWith("/pos "): # why....... - ind = self.posdropdown.findText(str(text.split(" ")[1])) - if ind >= 0: self.posdropdown.setCurrentIndex(ind) - self.oocinput.clear() - return - - if self.mocktext.isChecked(): - text = mockStr(text) - if self.autocaps.isChecked(): - l = list(text) - l[0] = l[0].upper() - if l[-1] != ".": - l.append(".") - text = "".join(l).replace(" i ", " I ").replace("i'm", "I'm").replace("it's", "It's") - - self.sendOOCchat(self.oocnameinput.text().toUtf8(), text) - self.oocinput.clear() - - def onICreturn(self): - text = str(self.icchatinput.text().toUtf8()).replace('#', '').replace('%', '').replace('&', '').replace('$', '').replace('/n', '\n') - if not text: - return - - if self.mocktext.isChecked(): - text = mockStr(text) - if self.autocaps.isChecked(): - l = list(text) - l[0] = l[0].upper() - if l[-1] != ".": - l.append(".") - text = "".join(l).replace(" i ", " I ").replace("i'm", "I'm").replace("it's", "It's") - if self.spacebartext.isChecked(): - l = list(text) - for i in range(1, len(l)+len(l)-1, 2): - l.insert(i, " ") - text = "".join(l) - - emote = self.charemotes[self.selectedemote] - if self.nointerruptbtn.isChecked(): - modifier = 0 - else: - modifier = self.playsfx - objection = 0 - if self.customobject.isPressed(): - objection = 4 - self.customobject.setPressed(False) - elif self.holditbtn.isPressed(): - objection = 1 - self.holditbtn.setPressed(False) - elif self.objectbtn.isPressed(): - objection = 2 - self.objectbtn.setPressed(False) - elif self.takethatbtn.isPressed(): - objection = 3 - self.takethatbtn.setPressed(False) - if emote[3] == '5': #zoom - if self.nointerruptbtn.isChecked(): - modifier = 5 - else: - if objection > 0: - modifier = 6 - else: - modifier = 5 - elif objection > 0: - if self.nointerruptbtn.isChecked(): - modifier = 0 - else: - modifier = 2 - - msg = "MS#" - - if "deskmod" in self.features: # visible desk modifier - msg += "%d#" % self.deskbtn.isChecked() - else: - msg += "chat#" - - msg += emote[1]+"#" #pre-anim - msg += self.charname+"#" - msg += emote[2]+"#" #anim - msg += text+"#" - msg += self.charside+"#" - msg += emote[4]+"#" #sfx - msg += str(modifier)+"#" #emote modifier - msg += str(self.mychar)+"#" #character ID - msg += emote[5]+"#" #sfx delay - msg += str(objection)+"#" - msg += str((self.selectedevi + 1) * int(self.present))+"#" #selected evidence - - if self.present: - self.present = False - self.evidencepresent.setPixmap(self.evidencepresent.button_off) - - if "flipping" in self.features: - msg += str(self.myflip)+"#" - else: - msg += str(self.mychar)+"#" # old AO servers send a second charID in the message because drunk fanat - - msg += str(int(self.realizationbtn.isPressed()))+"#" - msg += str(self.mychatcolor)+"#" - - if "cccc_ic_support" in self.features: - msg += self.showname+"#" # custom showname - if self.paircheckbox.isChecked(): - msg += str(self.pairdropdown.currentIndex()) # pair charID - if "effects" in self.features: - msg += "^%d#" % self.pair_order.currentIndex() # pair ordering - else: - msg += "#" - else: - msg += "-1#" - - # AO 2.8: always send offset - if "y_offset" in self.features: # AO 2.9 - msg += str(self.pairoffset.value()) + "&" + str(-self.ypairoffset.value()) + "#" - else: - msg += str(self.pairoffset.value())+"#" - - msg += str(int(self.nointerruptbtn.isChecked()))+"#" # NoInterrupt(TM) - - if "looping_sfx" in self.features: # AO 2.8 - msg += emote[6]+"#" # loop sound? - msg += "%d#" % self.shakebtn.isPressed() # screen shake - emotes_to_check = [emote[1], "(b)"+emote[2], "(a)"+emote[2]] - effects_to_check = ["_FrameScreenshake", "_FrameRealization", "_FrameSFX"] - - for f_effect in effects_to_check: - packet = "" - for f_emote in emotes_to_check: - packet += f_emote - if ini.read_ini_bool("AO2XP.ini", "General", "network frame effects"): - sfx_frames = "|".join(ini.read_ini_tags(AOpath+"characters/"+self.charname+"/char.ini", f_emote + f_effect)) - if sfx_frames: - packet += "|" + sfx_frames - packet += "^" - msg += packet+"#" - - if "additive" in self.features: - msg += "%d#" % self.additivebtn.isChecked() - - if "effects" in self.features: - fx = self.effectdropdown.currentText() if self.effectdropdown.currentIndex() > 0 else "" - fx_sound = ini.get_effect_sound(fx, self.charname) - p_effect = ini.read_ini(AOpath+"characters/"+self.charname+"/char.ini", "options", "effects") - msg += fx + "|" + p_effect + "|" + fx_sound + "#" - self.effectdropdown.setCurrentIndex(0) - - msg += "%" - self.msgqueueList.addItem(self.icchatinput.text()) - self.msgqueue.append(msg) - - self.icchatinput.clear() - self.realizationbtn.setPressed(False) - self.shakebtn.setPressed(False) - - def setBackground(self, bg): - if not exists(AOpath + 'background/' + bg): - bg = 'default' - - for bgfile in [["side_def", "defenseempty"], - ["bench_def", "defensedesk"], - ["side_pro", "prosecutorempty"], - ["bench_pro", "prosecutiondesk"], - ["side_wit", "witnessempty"], - ["bench_wit", "stand"], - ["side_hld", "helperstand"], - ["bench_hld", "helperdesk"], - ["side_hlp", "prohelperstand"], - ["bench_hlp", "prohelperdesk"], - ["side_jud", "judgestand"], - ["bench_jud", "judgedesk"], - ["side_jur", "jurystand"], - ["bench_jur", "jurydesk"], - ["side_sea", "seancestand"], - ["bench_sea", "seancedesk"]]: - - bgimg = QtGui.QImage(AOpath + 'background/' + bg + '/' + bgfile[1] + '.png') - if not bgimg.isNull(): - if bgimg.size().width() != 256 or bgimg.size().height() != 192: - setattr(self, bgfile[0], QtGui.QPixmap.fromImage(bgimg.scaled(256*2, 192*2, transformMode=QtCore.Qt.SmoothTransformation))) - else: - setattr(self, bgfile[0], QtGui.QPixmap.fromImage(bgimg)) - else: - setattr(self, bgfile[0], QtGui.QPixmap.fromImage(bgimg)) - - - def netmsg_hp(self, type, health): - if type == 1: - self.defensebar.setHealth(health) - elif type == 2: - self.prosecutionbar.setHealth(health) - - def netmsg_ms(self, p_contents): - if len(p_contents) < 15: #this is already done on the TCP thread but i'll do it here anyway as well - return - - AO2chat = "cccc_ic_support" in self.features - - if int(p_contents[CHAR_ID]) in self.muted: # skip the self.chatmessage copy line below - return - - for n_string in range(self.chatmessage_size): - if n_string < len(p_contents) and (n_string < 16 or AO2chat): - self.m_chatmessage[n_string] = p_contents[n_string] - else: - self.m_chatmessage[n_string] = "" - - f_char_id = int(self.m_chatmessage[CHAR_ID]) - - if f_char_id < 0 or f_char_id >= len(self.charlist): - return - - f_showname = "" - if not self.m_chatmessage[SHOWNAME]: - f_showname = self.m_chatmessage[CHARNAME] - else: - f_showname = self.m_chatmessage[SHOWNAME] - - self.text_state = 0 - self.anim_state = 0 - self.objectionview.stop() - self.char.stop() - self.chat_tick_timer.stop() - self.presentedevi.hide() - - self.chatmessage_is_empty = self.m_chatmessage[CHATMSG] == " " or self.m_chatmessage[CHATMSG] == "" - - if self.msgqueue: - chatmsgcomp = str(self.msgqueue[0].split('#')[5]).decode('utf-8').replace('', '$').replace('', '%').replace('', '&').replace('', '#') - if f_char_id == self.mychar and self.m_chatmessage[CHATMSG] == chatmsgcomp: # our message showed up - del self.msgqueue[0] - self.msgqueueList.takeItem(0) - if self.additivebtn.isChecked(): - self.icchatinput.insert(" ") - - f_char = self.m_chatmessage[CHARNAME] - evidence = int(self.m_chatmessage[EVIDENCE])-1 - - t = time.localtime() - logcharname = f_char - if f_char.lower() != self.charlist[f_char_id][0].lower(): - logcharname = self.charlist[f_char_id][0] + ' (' + f_char.decode("utf-8") + ')' - - if self.m_chatmessage[SHOWNAME]: - try: - logcharname += " ("+self.m_chatmessage[SHOWNAME].decode("utf-8")+")" - except: - logcharname += " (???)" - - if evidence == -1: - self.icLog.append('[%d:%.2d] %s: %s' % (t[3], t[4], logcharname, self.m_chatmessage[CHATMSG])) - else: - eviname = '(NULL) %d' % evidence - try: - eviname = self.evidence[evidence][0] - except: - pass - - self.icLog.append('[%d:%.2d] %s: %s\n%s presented an evidence: %s' % (t[3], t[4], logcharname, self.m_chatmessage[CHATMSG], f_char, eviname)) - - self.is_additive = (self.m_chatmessage[ADDITIVE] == "1") - - custom_objection = "custom" - try: objection_mod = int(self.m_chatmessage[SHOUT_MOD]) - except: - if "4&" in self.m_chatmessage[SHOUT_MOD]: # custom objection name - objection_mod = 4 - custom_objection = self.m_chatmessage[SHOUT_MOD].split("4&")[1] # get the name - else: # just in case of mindfuckery - objection_mod = 0 - - if objection_mod <= 4 and objection_mod >= 1: - objections = ["holdit", "objection", "takethat", "custom_objections/"+custom_objection if custom_objection != "custom" else "custom"] - self.objectionview.play(objections[objection_mod-1], f_char) - self.playObjectionSnd(f_char, objection_mod) - - emote_mod = int(self.m_chatmessage[EMOTE_MOD]) - if emote_mod == 0: - self.m_chatmessage[EMOTE_MOD] = 1 - else: - self.handle_chatmessage_2() - - def set_text_color(self): - textcolor = int(self.m_chatmessage[TEXT_COLOR]) - - is_rainbow = textcolor == 6 - - if textcolor == 0: - color = QtGui.QColor(255, 255, 255) - elif textcolor == 1: - color = QtGui.QColor(0, 255, 0) - elif textcolor == 2: #OH FUCK MOD - color = QtGui.QColor(255, 0, 0) - elif textcolor == 3: - color = QtGui.QColor(255, 165, 0) - elif textcolor == 4: - color = QtGui.QColor(45, 150, 255) - elif textcolor == 5: - color = QtGui.QColor(255, 255, 0) - elif textcolor == 6: - color = QtGui.QColor(255, 255, 255) - elif textcolor == 7: - color = QtGui.QColor(255, 192, 203) - elif textcolor == 8: - color = QtGui.QColor(0, 255, 255) - - if is_rainbow: - self.text.show() - self.ao2text.hide() - else: - self.text.hide() - self.ao2text.show() - - style = "background-color: rgba(0, 0, 0, 0);\n" - style += "color: rgb("+str(color.red())+", "+str(color.green())+", "+str(color.blue())+")" - self.ao2text.setStyleSheet(style) - - def set_scene(self): - side = self.m_chatmessage[SIDE] - - if side == 'def': - self.court.setPixmap(self.side_def) - self.bench.setPixmap(self.bench_def) - self.bench.move(0, 192*2 - self.bench_def.size().height()) - self.presentedevi.move(170, 16) - elif side == 'pro': - self.court.setPixmap(self.side_pro) - self.bench.setPixmap(self.bench_pro) - self.bench.move(256*2 - self.bench_pro.size().width(), 192*2 - self.bench_pro.size().height()) - self.presentedevi.move(16, 16) - elif side == 'wit': - self.court.setPixmap(self.side_wit) - self.bench.setPixmap(self.bench_wit) - self.bench.move(0, 0) - self.presentedevi.move(16, 16) - elif side == 'hld': - self.court.setPixmap(self.side_hld) - self.bench.setPixmap(self.bench_hld) - self.presentedevi.move(16, 16) - elif side == 'hlp': - self.court.setPixmap(self.side_hlp) - self.bench.setPixmap(self.bench_hlp) - self.presentedevi.move(170, 16) - elif side == 'jud': - self.court.setPixmap(self.side_jud) - self.bench.setPixmap(self.bench_jud) - self.presentedevi.move(16, 16) - elif side == 'sea': - self.court.setPixmap(self.side_jud if self.side_sea.isNull() else self.side_sea) - self.bench.setPixmap(self.bench_jud if self.bench_sea.isNull() else self.bench_sea) - self.presentedevi.move(16, 16) - elif side == 'jur': - self.court.setPixmap(self.side_jud if self.side_jur.isNull() else self.side_jur) - self.bench.setPixmap(self.bench_jud if self.bench_jur.isNull() else self.bench_jur) - self.presentedevi.move(16, 16) - - deskmod = self.m_chatmessage[DESK_MOD] - if deskmod == "0" or (deskmod != "1" and (side in ("jud", "hld", "hlp"))): - self.bench.hide() - else: - self.bench.show() - - def objection_done(self): - self.handle_chatmessage_2() - - def handle_chatmessage_2(self): - self.zoom.setZoom(False) - self.char.stop() - self.effectview.stop() - - if not self.m_chatmessage[SHOWNAME]: - self.name.setText(self.m_chatmessage[CHARNAME]) - else: - self.name.setText(self.m_chatmessage[SHOWNAME].decode("utf-8")) - - self.chatbox.hide() - - self.set_scene() - self.set_text_color() - - f_message = self.m_chatmessage[CHATMSG] - if len(f_message) >= 2: - self.message_is_centered = f_message.startswith("~~") - else: - self.ao2text.setAlignment(QtCore.Qt.AlignLeft) - self.text.setAlignment(QtCore.Qt.AlignLeft) - - if self.m_chatmessage[FLIP] == "1": - self.char.set_flipped(True) - else: - self.char.set_flipped(False) - - side = self.m_chatmessage[SIDE] - emote_mod = int(self.m_chatmessage[EMOTE_MOD]) - - # AO 2.8: always offset player - hor_offset = vert_offset = 0 - - if "y_offset" in self.features: # AO 2.9 - keyword = "" if "" in self.m_chatmessage[SELF_OFFSET] else "&" # i don't think it's hdf's fault but this is still ridiculous - hor_offset = int(self.m_chatmessage[SELF_OFFSET].split(keyword)[0]) - vert_offset = int(self.m_chatmessage[SELF_OFFSET].split(keyword)[1]) if len(self.m_chatmessage[SELF_OFFSET].split(keyword)) > 1 else 0 - else: - hor_offset = int(self.m_chatmessage[SELF_OFFSET]) - - - if side == "def": - if hor_offset > 0 and vert_offset == 0: - vert_offset = hor_offset / 10 - elif side == "pro": - if hor_offset < 0 and vert_offset == 0: - vert_offset = -1 * hor_offset / 10 - - self.char.move(256 * hor_offset / 100, 192 * vert_offset / 100) - - # check if paired - if not self.m_chatmessage[OTHER_CHARID]: - self.sidechar.hide() - self.sidechar.move(0,0) - else: - if "effects" in self.features: - got_other_charid = int(self.m_chatmessage[OTHER_CHARID].split("^")[0]) - else: - got_other_charid = int(self.m_chatmessage[OTHER_CHARID]) - - if got_other_charid > -1: # user is paired - self.sidechar.show() - - if "effects" in self.features: - pair_order = int(self.m_chatmessage[OTHER_CHARID].split("^")[1]) - else: - pair_order = -1 - - hor2_offset = vert2_offset = 0 - if "y_offset" in self.features: # AO 2.9 - keyword = "" if "" in self.m_chatmessage[OTHER_OFFSET] else "&" # i don't think it's hdf's fault but this is still ridiculous - hor2_offset = int(self.m_chatmessage[OTHER_OFFSET].split(keyword)[0]) - vert2_offset = int(self.m_chatmessage[OTHER_OFFSET].split(keyword)[1]) if len(self.m_chatmessage[OTHER_OFFSET].split(keyword)) > 1 else 0 - else: - hor2_offset = int(self.m_chatmessage[OTHER_OFFSET]) - - if side == "def": - if hor2_offset > 0: - vert2_offset = hor2_offset / 10 - - elif side == "pro": - if hor2_offset < 0: - vert2_offset = -1 * hor2_offset / 10 - - if pair_order == -1: # pair ordering not supported - if hor2_offset >= hor_offset: - self.sidechar.raise_() - self.char.raise_() - else: - self.char.raise_() - self.sidechar.raise_() - elif pair_order == 0: # front - self.char.raise_() - self.sidechar.raise_() - elif pair_order == 1: # behind - self.sidechar.raise_() - self.char.raise_() - - self.sidechar.move(256 * hor2_offset / 100, 192 * vert2_offset / 100) - - self.bench.raise_() - self.chatbox.raise_() - self.effectview.raise_() - self.objectionview.raise_() - self.whiteflashlab.raise_() - - self.sidechar.set_flipped(self.m_chatmessage[OTHER_FLIP] == "1") - self.sidechar.play_idle(self.m_chatmessage[OTHER_NAME], self.m_chatmessage[OTHER_EMOTE]) - - else: - self.sidechar.hide() - self.sidechar.move(0, 0) - - if (emote_mod == 1 or emote_mod == 6) and self.m_chatmessage[PREANIM] != "-": - self.play_preanim(False) - elif emote_mod == 0 or emote_mod == 5 or self.m_chatmessage[PREANIM] == "-": - if self.m_chatmessage[NO_INTERRUPT] == "0" or self.m_chatmessage[PREANIM] == "-": - self.handle_chatmessage_3() - else: - self.play_preanim(True) - - def play_preanim(self, noninterrupting): - f_char = self.m_chatmessage[CHARNAME] - f_preanim = self.m_chatmessage[PREANIM] - - ao2_duration = ini.read_ini_int(AOpath+"characters/"+f_char+"/char.ini", "time", "%"+f_preanim, -1) - text_delay = ini.read_ini_int(AOpath+"characters/"+f_char+"/char.ini", "textdelay", f_preanim, -1) - sfx_delay = int(self.m_chatmessage[SFX_DELAY]) * 60 - - preanim_duration = 0 - if ao2_duration < 0: - preanim_duration = ini.read_ini_int(AOpath+"characters/"+f_char+"/char.ini", "time", f_preanim, -1) - else: - preanim_duration = ao2_duration - - anim_to_find = AOpath+"characters/"+f_char+"/"+f_preanim+".gif" - apng_to_find = AOpath+"characters/"+f_char+"/"+f_preanim+".apng" - webp_to_find = AOpath+"characters/"+f_char+"/"+f_preanim+".webp" - if (not exists(anim_to_find) and not exists(apng_to_find) and not exists(webp_to_find)) or preanim_duration < 0: - if noninterrupting: - self.anim_state = 4 - else: - self.anim_state = 1 - self.preanim_done() - - self.char.play_pre(f_char, f_preanim, preanim_duration) - if noninterrupting: - self.anim_state = 4 - else: - self.anim_state = 1 - - if sfx_delay > 0: - self.sfx_delay_timer.start(sfx_delay) - else: - self.play_sfx() - - if text_delay >= 0: - pass #text delay timer, but not now. - - if noninterrupting: - self.handle_chatmessage_3() - - def preanim_done(self): - self.anim_state = 1 - self.handle_chatmessage_3() - - def handle_chatmessage_3(self): - self.start_chat_ticking() - - f_evi_id = int(self.m_chatmessage[EVIDENCE]) - f_side = self.m_chatmessage[SIDE] - - emote_mod = int(self.m_chatmessage[EMOTE_MOD]) - - if f_evi_id > 0 and f_evi_id <= len(self.evidence): - f_image = self.evidence[f_evi_id-1][2] - is_left_side = not (f_side == "def" or f_side == "hlp" or f_side == "jud" or f_side == "jur") - - self.setEvidenceImg(self.presentedevi, f_image) - - if not is_left_side: - self.presentedevi.move(170, 16) - else: - self.presentedevi.move(16, 16) - self.presentedevi.show() - else: - self.presentedevi.hide() - - side = self.m_chatmessage[SIDE] - if emote_mod == 5 or emote_mod == 6: - self.bench.hide() - self.sidechar.hide() - self.char.move(0,0) - - if side == "pro" or side == "hlp" or side == "wit": - self.zoom.setZoom(True, 1) - else: - self.zoom.setZoom(True, 0) - - f_anim_state = 0 - text_is_blue = int(self.m_chatmessage[TEXT_COLOR]) == 4 - - if not text_is_blue and self.text_state == 1: - f_anim_state = 2 - self.entire_message_is_blue = False - else: - f_anim_state = 3 - self.entire_message_is_blue = True - - if f_anim_state <= self.anim_state: - return - - self.char.stop() - f_char = self.m_chatmessage[CHARNAME] - f_emote = self.m_chatmessage[ANIM] - - if f_anim_state == 2: - self.char.play_talking(f_char, f_emote) - self.anim_state = 2 - else: - self.char.play_idle(f_char, f_emote) - self.anim_state = 3 - - if exists(AOpath+"callwords.ini"): - callwords = [line.rstrip() for line in open(AOpath+"callwords.ini")] - for callword in callwords: - if callword.lower() in self.m_chatmessage[CHATMSG].lower(): - self.ooclog.append("%s called you." % f_char) - snd = audio.loadhandle(False, "word_call.wav", 0, 0, BASS_STREAM_AUTOFREE) - if snd: - audio.playhandle(snd, True) - break - - def do_effect(self, fx_name, fx_sound, p_char, p_folder): - effect = ini.get_effect(fx_name, p_char, p_folder) - if not effect: return - - if fx_sound: - self.playSound(fx_sound) - - if "effects" not in self.features: return - - self.effectview.set_play_once(False) - try: self.effectview.play(effect) - except: pass # Windows XP webp error with Pillow - print "effect", repr(effect) - - def start_chat_ticking(self): - if self.text_state != 0: - return - - if self.m_chatmessage[EFFECTS]: - fx_list = self.m_chatmessage[EFFECTS].split("|") - fx = fx_list[0] - fx_sound = "" - fx_folder = "" - - if len(fx_list) > 1: - fx_sound = fx_list[1] - if len(fx_list) > 2: - fx_folder = fx_list[1] - fx_sound = fx_list[2] - - if fx and fx not in ("-", "None"): - self.do_effect(fx, fx_sound, self.m_chatmessage[CHARNAME], fx_folder) - - elif self.m_chatmessage[REALIZATION] == "1": - self.setWhiteFlash(True, 1, 125) - - self.set_text_color() - - charid = int(self.m_chatmessage[CHAR_ID]) - if not self.is_additive or self.additive_char != charid: - self.ao2text.clear() - self.text.setText("") - self.additive_char = charid - - if self.chatmessage_is_empty: - self.text_state = 2 - return - - self.inline_color_stack = [] - - self.chatbox.show() - - self.tick_pos = 0 - self.blip_pos = 0 - self.inline_blue_depth = 0 - - self.current_display_speed = 3 - self.chat_tick_timer.start(self.message_display_speed[self.current_display_speed]) - - self.blip = self.charlist[charid][2] - - if exists(AOpath+"sounds/general/sfx-blip"+self.blip+".wav"): - self.blipsnd = audio.loadhandle(False, AOpath+"sounds/general/sfx-blip"+self.blip+".wav", 0, 0, 0) - elif exists(AOpath+"sounds/general/sfx-blip"+self.blip+".opus"): - self.blipsnd = audio.loadhandle(False, AOpath+"sounds/general/sfx-blip"+self.blip+".opus", 0, 0, 0) - elif exists(AOpath+"sounds/blips/"+self.blip+".wav"): - self.blipsnd = audio.loadhandle(False, AOpath+"sounds/blips/"+self.blip+".wav", 0, 0, 0) - elif exists(AOpath+"sounds/blips/"+self.blip+".opus"): - self.blipsnd = audio.loadhandle(False, AOpath+"sounds/blips/"+self.blip+".opus", 0, 0, 0) - else: - self.blipsnd = 0 - - audio.sethandleattr(self.blipsnd, BASS_ATTRIB_VOL, self.blipslider.value() / 100.0) - - emote_mod = int(self.m_chatmessage[EMOTE_MOD]) - if emote_mod in (0, 5) and self.m_chatmessage[SCREENSHAKE] == "1": - self.setScreenShake(True) - - self.text_state = 1 - - def chat_tick(self): - f_message = self.m_chatmessage[CHATMSG] - - self.chat_tick_timer.stop() - formatting_char = False - - if self.message_is_centered: - f_message = f_message.strip("~~") - - if self.tick_pos >= len(f_message): - self.text_state = 2 - if self.anim_state != 4: - self.anim_state = 3 - self.char.play_idle(self.m_chatmessage[CHARNAME], self.m_chatmessage[ANIM]) - else: - f_character2 = f_message[self.tick_pos] - f_character = QtCore.QString(f_character2) - - if f_character == " ": - self.text.setText(self.text.text() + " ") - self.ao2text.insertPlainText(" ") - - elif f_character == "\n" or f_character == "\r": - self.text.setText(self.text.text() + "\n") - self.ao2text.insertPlainText("\n") - - elif f_character == "\\" and not self.next_character_is_not_special: - self.next_character_is_not_special = True - formatting_char = True - - elif f_character == "{" and not self.next_character_is_not_special: - self.current_display_speed += 1 - formatting_char = True - - elif f_character == "}" and not self.next_character_is_not_special: - self.current_display_speed -= 1 - formatting_char = True - - elif f_character == "|" and not self.next_character_is_not_special: #orange. - if self.inline_color_stack: - if self.inline_color_stack[-1] == INLINE_ORANGE: - del self.inline_color_stack[-1] - else: - self.inline_color_stack.append(INLINE_ORANGE) - else: - self.inline_color_stack.append(INLINE_ORANGE) - formatting_char = True - - elif f_character == "(" and not self.next_character_is_not_special: #blue. - self.inline_color_stack.append(INLINE_BLUE) - self.ao2text.insertHtml("" + f_character + "") - - self.inline_blue_depth += 1 - if not self.entire_message_is_blue and self.anim_state != 4: - f_char = self.m_chatmessage[CHARNAME] - f_emote = self.m_chatmessage[ANIM] - self.char.play_idle(f_char, f_emote) - - elif f_character == ")" and not self.next_character_is_not_special and self.inline_color_stack: - if self.inline_color_stack[-1] == INLINE_BLUE: - del self.inline_color_stack[-1] - self.ao2text.insertHtml("" + f_character + "") - - if self.inline_blue_depth > 0: - self.inline_blue_depth -= 1 - - if not self.entire_message_is_blue: - if self.inline_blue_depth == 0 and self.anim_state != 4 and not (self.tick_pos+1 >= len(f_message)): - f_char = self.m_chatmessage[CHARNAME] - f_emote = self.m_chatmessage[ANIM] - self.char.play_talking(f_char, f_emote) - else: - self.next_character_is_not_special = True - self.tick_pos -= 1 - - elif f_character == "[" and not self.next_character_is_not_special: #gray. - self.inline_color_stack.append(INLINE_GRAY) - self.ao2text.insertHtml("" + f_character + "") - - elif f_character == "]" and not self.next_character_is_not_special and self.inline_color_stack: - if self.inline_color_stack[-1] == INLINE_GRAY: - del self.inline_color_stack[-1] - self.ao2text.insertHtml("" + f_character + "") - else: - self.next_character_is_not_special = True - self.tick_pos -= 1 - - elif f_character == "`" and not self.next_character_is_not_special: #green. - if self.inline_color_stack: - if self.inline_color_stack[-1] == INLINE_GREEN: - del self.inline_color_stack[-1] - else: - self.inline_color_stack.append(INLINE_GREEN) - else: - self.inline_color_stack.append(INLINE_GREEN) - formatting_char = True - - elif f_character == "~" and not self.next_character_is_not_special: #green. - if self.inline_color_stack: - if self.inline_color_stack[-1] == INLINE_RED: - del self.inline_color_stack[-1] - else: - self.inline_color_stack.append(INLINE_RED) - else: - self.inline_color_stack.append(INLINE_RED) - formatting_char = True - - elif f_character == "s" and self.next_character_is_not_special: # shake - self.setScreenShake(True) - self.next_character_is_not_special = False - - elif f_character == "f" and self.next_character_is_not_special: # flash - self.setWhiteFlash(True, 0, 75) - self.next_character_is_not_special = False - - elif f_character == "n" and self.next_character_is_not_special: # newline - self.text.setText(self.text.text() + "\n") - self.ao2text.insertPlainText("\n") - self.next_character_is_not_special = False - - else: - self.next_character_is_not_special = False - if self.inline_color_stack: - top_color = self.inline_color_stack[-1] - if top_color == INLINE_ORANGE: - self.ao2text.insertHtml("" + f_character + "") - elif top_color == INLINE_BLUE: - self.ao2text.insertHtml("" + f_character + "") - elif top_color == INLINE_GREEN: - self.ao2text.insertHtml("" + f_character + "") - elif top_color == INLINE_GRAY: - self.ao2text.insertHtml("" + f_character + "") - elif top_color == INLINE_RED: - self.ao2text.insertHtml("" + f_character + "") - else: - self.ao2text.insertHtml(f_character) - else: - if int(self.m_chatmessage[TEXT_COLOR]) == C_RAINBOW: - self.text.setText(self.text.text() + f_character) - else: - self.ao2text.insertHtml(f_character) - - if self.message_is_centered: - self.ao2text.setAlignment(QtCore.Qt.AlignCenter) - self.text.setAlignment(QtCore.Qt.AlignCenter) - else: - self.ao2text.setAlignment(QtCore.Qt.AlignLeft) - self.text.setAlignment(QtCore.Qt.AlignLeft) - - if f_message[self.tick_pos] != " " or self.blank_blip: - if self.blip_pos % self.blip_rate == 0 and not formatting_char: - self.blip_pos = 0 - audio.playhandle(self.blipsnd, True) - - self.blip_pos += 1 - - self.tick_pos += 1 - - if self.current_display_speed < 0: - self.current_display_speed = 0 - elif self.current_display_speed > 6: - self.current_display_speed = 6 - - if formatting_char: - self.chat_tick_timer.start(1) - else: - self.chat_tick_timer.start(self.message_display_speed[self.current_display_speed]) - - def playRealization(self): - audio.playhandle(self.realizationsnd, True) - - def playObjectionSnd(self, charname, objection): - if self.objectsnd: - if audio.handleisactive(self.objectsnd): - audio.stophandle(self.objectsnd) - audio.freehandle(self.objectsnd) - - objecting = ["holdit", "objection", "takethat", "custom"][objection-1] - - if objecting: - if exists(AOpath + 'characters/' + charname + '/' + objecting + '.wav'): - self.objectsnd = audio.loadhandle(False, AOpath + 'characters/' + charname + '/' + objecting + '.wav', 0, 0, 0) - elif exists(AOpath + 'characters/' + charname + '/' + objecting + '.opus'): - self.objectsnd = audio.loadhandle(False, AOpath + 'characters/' + charname + '/' + objecting + '.opus', 0, 0, 0) - else: - self.objectsnd = None - if ini.read_ini_bool("AO2XP.ini", "General", "download sounds", True): - thread.start_new_thread(download_thread, ("base/characters/"+charname.lower()+"/"+objecting.lower()+".wav", AOpath+"characters/"+charname.lower()+"/"+objecting.lower()+".wav")) - thread.start_new_thread(download_thread, ("base/characters/"+charname.lower()+"/"+objecting.lower()+".opus", AOpath+"characters/"+charname.lower()+"/"+objecting.lower()+".wav")) - - if exists(AOpath + 'sounds/general/sfx-objection.opus'): - self.objectsnd = audio.loadhandle(False, AOpath + 'sounds/general/sfx-objection.opus', 0, 0, 0) - else: - self.objectsnd = audio.loadhandle(False, AOpath + 'sounds/general/sfx-objection.wav', 0, 0, 0) - audio.sethandleattr(self.objectsnd, BASS_ATTRIB_VOL, self.soundslider.value() / 100.0) - audio.playhandle(self.objectsnd, True) - - def play_sfx(self): - sfx_name = self.m_chatmessage[SFX] - if sfx_name == "1": - return - - self.playSound(sfx_name) - - def playSound(self, sfx): - if self.sound: - if audio.handleisactive(self.sound): - audio.stophandle(self.sound) - audio.freehandle(self.sound) - - if exists(AOpath + 'sounds/general/' + sfx + '.wav'): - self.sound = audio.loadhandle(False, AOpath + 'sounds/general/' + sfx + '.wav', 0, 0, 0) - audio.sethandleattr(self.sound, BASS_ATTRIB_VOL, self.soundslider.value() / 100.0) - audio.playhandle(self.sound, True) - - elif exists(AOpath + 'sounds/general/' + sfx + '.opus'): - self.sound = audio.loadhandle(False, AOpath + 'sounds/general/' + sfx + '.opus', 0, 0, 0) - audio.sethandleattr(self.sound, BASS_ATTRIB_VOL, self.soundslider.value() / 100.0) - audio.playhandle(self.sound, True) - - def playMusic(self, mus): - if not mus.endswith(".mp3") and "===MUSIC START===.mp3" in self.musiclist: #vidya workaround - mus += ".mp3" - - if self.music: - if audio.handleisactive(self.music): - audio.stophandle(self.music) - audio.freehandle(self.music) - - if exists(AOpath + 'sounds/music/' + mus): - self.music = audio.loadhandle(False, AOpath + 'sounds/music/' + mus, 0, 0, BASS_SAMPLE_LOOP) - audio.sethandleattr(self.music, BASS_ATTRIB_VOL, self.musicslider.value() / 100.0) - audio.playhandle(self.music, True) - - elif ini.read_ini_bool("AO2XP.ini", "General", "download music", True): - if mus.lower().startswith("http"): - self.music = audio.loadURLhandle(mus, 0, BASS_STREAM_BLOCK | BASS_SAMPLE_LOOP) - print "Trying to play", mus.lower() - else: - for bucket in buckets: - if not bucket: continue - print "music stream:", bucket+'base/sounds/music/' + mus.lower() - self.music = audio.loadURLhandle(bucket+'base/sounds/music/' + mus.lower(), 0, BASS_STREAM_BLOCK) - if self.music: break - - if self.music: - audio.sethandleattr(self.music, BASS_ATTRIB_VOL, self.musicslider.value() / 100.0) - audio.playhandle(self.music, True) - else: - print "Couldn't play music. Error", audio.getbasserror() - - def stopMusic(self): - if self.music: - if audio.handleisactive(self.music): - audio.stophandle(self.music) - audio.freehandle(self.music) - - def startGame(self, tcp, charlist, musiclist, background, evidence, areas, features=[], oocjoin=[], hplist=[], webAO_bucket=""): - self.willDisconnect = False - self.mychar = -1 - self.mychatcolor = 0 - self.tcp = tcp - self.charlist = charlist - self.musiclist = musiclist - self.evidence = evidence - self.areas = areas - self.features = features - - if "base/" in webAO_bucket: - webAO_bucket = webAO_bucket.replace("base/", "") - buckets[0] = webAO_bucket - - self.charselect.setCharList(charlist) - self.charselect.show() - - self.oocnameinput.setText(ini.read_ini("AO2XP.ini", "General", "OOC name")) - self.shownameedit.setText(ini.read_ini("AO2XP.ini", "General", "Showname")) - - self.pairdropdown.clear() - self.paircheckbox.setChecked(False) - if "cccc_ic_support" in features: - self.shownameedit.show() - self.nointerruptbtn.show() - self.paircheckbox.setDisabled(False) - self.paircheckbox.setText("Enable pairing") - for char in charlist: - self.pairdropdown.addItem(char[0]) - else: - self.shownameedit.hide() - self.nointerruptbtn.hide() - self.paircheckbox.setDisabled(True) - self.paircheckbox.setText("This server does not support pairing.") - - self.deskbtn.setDisabled("deskmod" not in features) - self.flipbutton.setVisible("flipping" in features) - self.customobject.setVisible("customobjections" in features) - self.ypairoffset.setVisible("y_offset" in features) - self.ypairoffset_l.setVisible("y_offset" in features) - - self.colordropdown.clear() - self.colordropdown.addItems(['white', 'green', 'red', 'orange', 'blue']) - if "yellowtext" in features: - self.colordropdown.addItems(['yellow', 'gay pride', 'pink', 'cyan']) - self.colordropdown.setCurrentIndex(self.mychatcolor) - - for hp in hplist: - self.healthbars.emit(hp[0], hp[1]) - - for char in self.charlist: - if not exists(AOpath + 'characters/' + char[0] + '/char.ini'): - continue - char[2] = get_char_ini(char[0], "options", "gender", "male") - - self.realizationbtn.setPressed(False) - self.customobject.setPressed(False) - self.mutedlist.clear() - self.unmutedlist.clear() - for char in self.charlist: - self.unmutedlist.addItem(char[0]) - - self.musicitems.clear() - self.evidencedropdown.clear() - for evi in evidence: - self.evidencedropdown.addItem(evi[0]) - - logstart = '--- Log started on ' + time.ctime() + ' ---' - if self.ooclog.toPlainText(): - self.ooclog.append("\n"+logstart) - else: - self.ooclog.append(logstart) - if self.icLog.toPlainText(): - self.icLog.append("\n"+logstart) - else: - self.icLog.append(logstart) - - self.setBackground(background) - for msg in oocjoin: - self.ooclog.append(msg) - - for song in musiclist: - songitem = QtGui.QListWidgetItem() - songitem.setText(song) - if exists(AOpath + 'sounds/music/' + song): - songitem.setBackgroundColor(QtGui.QColor(128, 255, 128)) - else: - songitem.setBackgroundColor(QtGui.QColor(255, 128, 128)) - self.musicitems.addItem(songitem) - - self.musicslider.setValue(ini.read_ini_int("AO2XP.ini", "Audio", "Music volume", 100)) - self.soundslider.setValue(ini.read_ini_int("AO2XP.ini", "Audio", "Sound volume", 100)) - self.blipslider.setValue(ini.read_ini_int("AO2XP.ini", "Audio", "Blip volume", 100)) - - #thread.start_new_thread(self.tcp_thread, ()) - self.tcpthread = TCP_Thread(self) - self.tcpthread.MS_Chat.connect(self.netmsg_ms) - self.tcpthread.newChar.connect(self.onPVPacket) - self.tcpthread.newBackground.connect(self.setBackground) - self.tcpthread.OOC_Log.connect(self.ooclog.append) - self.tcpthread.IC_Log.connect(self.icLog.append) - self.tcpthread.charSlots.connect(partial(self.charselect.setCharList, self.charlist)) - self.tcpthread.showCharSelect.connect(self.charselect.show) - self.tcpthread.allEvidence.connect(self.allEvidence) - self.tcpthread.rainbowColor.connect(self.text.setStyleSheet) - self.tcpthread.start() - - def allEvidence(self, evi): - self.evidence = evi - if self.evidencedropdown.count() > 0: - self.evidencedropdown.clear() - for evi in self.evidence: - while len(evi) < 3: # new AO 2.9 bug where they never correctly escaped evidence name/desc/image on FantaProtocol - evi += [""] - evi[0] = decode_ao_str(evi[0].decode('utf-8')) - evi[1] = decode_ao_str(evi[1].decode('utf-8')) - evi[2] = decode_ao_str(evi[2].decode('utf-8')) - self.evidencedropdown.addItem(evi[0]) - - if not self.evidence: - self.evidencedropdown.setCurrentIndex(0) - self.evidencedesc.setText('.') - else: - self.evidencedropdown.setCurrentIndex(self.selectedevi) - -class PresentButton(QtGui.QLabel): - - def __init__(self, gamegui, parent): - super(PresentButton, self).__init__(parent) - self.gamegui = gamegui - self.button_off = QtGui.QPixmap(AO2XPpath + 'themes/default/present_disabled.png') - self.button_on = QtGui.QPixmap(AO2XPpath + 'themes/default/present.png') - self.setPixmap(self.button_off) - self.show() - - def mousePressEvent(self, event): - self.gamegui.present = not self.gamegui.present - if self.gamegui.present: - self.setPixmap(self.button_on) - else: - self.setPixmap(self.button_off) - - -class EditEvidenceDialog(QtGui.QDialog): - def __init__(self, gamegui): - super(EditEvidenceDialog, self).__init__() - self.gamegui = gamegui - self.setWindowTitle('Add evidence') - self.resize(512, 384) - self.setModal(True) - - self.eviname = QtGui.QLineEdit(self) - self.eviname.setGeometry(8, 8, 384, 24) - self.evidesc = QtGui.QTextEdit(self) - self.evidesc.setGeometry(8, 192, 496, 160) - self.evipicture = QtGui.QLabel(self) - self.filename = 'empty.png' - evipic = QtGui.QPixmap(AOpath + 'evidence/empty.png') - self.evipicture.setPixmap(evipic) - self.evipicture.move(434, 8) - self.evipicture.show() - self.save = QtGui.QPushButton(self) - self.save.setText('Save') - self.save.clicked.connect(self.onSave) - self.save.move(256*2 - self.save.size().width() - 8, 384 - self.save.size().height()) - self.cancel = QtGui.QPushButton(self) - self.cancel.setText('Cancel') - self.cancel.clicked.connect(self.onCancel) - self.cancel.move(264, 384 - self.cancel.size().height()) - self.choosepic = QtGui.QComboBox(self) - self.filenames = [] - self.choosepic.setGeometry(376, 78, 128, 24) - files = os.listdir(AOpath + 'evidence') - fileslength = len(files) - i = 0 - while i < fileslength: - if not files[i].endswith('.png'): - del files[i] - fileslength = len(files) - i -= 1 - i += 1 - - for i in range(len(files)): - if files[i].endswith('.png'): - self.choosepic.addItem(files[i].strip('.png')) - self.filenames.append(files[i]) - if files[i].lower() == 'empty.png': - self.emptyfile = i - - self.editing = False - self.choosepic.currentIndexChanged.connect(self.choosePicChange) - self.choosepic.setCurrentIndex(i) - - def choosePicChange(self, ind): - self.filename = self.filenames[ind] - if exists(AOpath + 'evidence/' + self.filename): - self.evipicture.setPixmap(QtGui.QPixmap(AOpath + 'evidence/' + self.filename)) - else: - self.evipicture.setPixmap(QtGui.QPixmap(AO2XPpath + 'themes/default/evidence_selected.png')) - - def onSave(self): - name = encode_ao_str(self.eviname.text().toUtf8()) - desc = encode_ao_str(self.evidesc.toPlainText().toUtf8()) - - if self.editing: - self.gamegui.tcp.send('EE#' + str(self.edit_ind) + '#' + name + '#' + desc + '#' + self.filename + '#%') - else: - self.gamegui.tcp.send('PE#' + name + '#' + desc + '#' + self.filename + '#%') - - self.eviname.setText('') - self.evidesc.setText('') - evipic = QtGui.QPixmap(AOpath + 'evidence/empty.png') - self.evipicture.setPixmap(evipic) - self.filename = 'empty.png' - self.editing = False - self.setWindowTitle('Add evidence') - self.choosepic.setCurrentIndex(self.emptyfile) - self.hide() - - def onCancel(self): - self.eviname.setText('') - self.evidesc.setText('') - evipic = QtGui.QPixmap(AOpath + 'evidence/empty.png') - self.evipicture.setPixmap(evipic) - self.filename = 'empty.png' - self.editing = False - self.setWindowTitle('Add evidence') - self.choosepic.setCurrentIndex(self.emptyfile) - self.hide() - - def EditEvidence(self, ind): - self.editing = True - self.edit_ind = ind - if self.gamegui.evidence[ind][2] not in self.filenames: - self.filenames.append(self.gamegui.evidence[ind][2]) - self.choosepic.addItem(self.gamegui.evidence[ind][2].split('.')[0]) - self.choosepic.setCurrentIndex(self.filenames.index(self.gamegui.evidence[ind][2])) - self.eviname.setText(self.gamegui.evidence[ind][0]) - self.evidesc.setText(self.gamegui.evidence[ind][1]) - self.setWindowTitle('Edit evidence') - self.show() - - -class EmoteButton(QtGui.QLabel): - - def __init__(self, gamewindow, x, y, id): - super(EmoteButton, self).__init__(gamewindow) - self.gamewindow = gamewindow - self.resize(40, 40) - self.move(x, y) - self.emoteid = id - - def paintEvent(self, event): - if self.gamewindow.mychar == -1: - return - - painter = QtGui.QPainter(self) - painter.setRenderHint(QtGui.QPainter.TextAntialiasing, False) - painter.setPen(QtGui.QColor(255, 255, 255)) - font = QtGui.QFont("Tahoma", 8) - font.setStyle(QtGui.QFont.StyleNormal) - font.setWeight(QtGui.QFont.Normal) - painter.setFont(font) - - if self.pixmap(): - if self.pixmap().isNull(): - painter.fillRect(0, 0, 39, 39, QtGui.QColor(0, 0, 0)) - painter.drawText(0, 0, str(self.emoteid)) - else: - painter.drawPixmap(0, 0, self.pixmap()) - else: - painter.fillRect(0, 0, 39, 39, QtGui.QColor(0, 0, 0)) - painter.drawText(1, 1, str(self.emoteid)) - - def mousePressEvent(self, event): - self.gamewindow.changeEmote(False, self.emoteid) - - -class BackEmoteButton(QtGui.QLabel): - - def __init__(self, gamewindow, x, y): - super(BackEmoteButton, self).__init__(gamewindow) - self.gamewindow = gamewindow - self.move(x, y) - self.setPixmap(QtGui.QPixmap(AO2XPpath + 'themes/default/arrow_left.png')) - self.show() - - def mousePressEvent(self, event): - self.gamewindow.current_emote_page -= 1 - self.gamewindow.set_emote_page() - - -class NextEmoteButton(QtGui.QLabel): - - def __init__(self, gamewindow, x, y): - super(NextEmoteButton, self).__init__(gamewindow) - self.gamewindow = gamewindow - self.move(x, y) - self.setPixmap(QtGui.QPixmap(AO2XPpath + 'themes/default/arrow_right.png')) - self.show() - - def mousePressEvent(self, event): - self.gamewindow.current_emote_page += 1 - self.gamewindow.set_emote_page() - - -class TCP_Thread(QtCore.QThread): - connectionError = QtCore.pyqtSignal(str, str, str) - MS_Chat = QtCore.pyqtSignal(list) - newChar = QtCore.pyqtSignal(str) - newBackground = QtCore.pyqtSignal(str) - IC_Log = QtCore.pyqtSignal(str) - OOC_Log = QtCore.pyqtSignal(str) - charSlots = QtCore.pyqtSignal() - showCharSelect = QtCore.pyqtSignal() - allEvidence = QtCore.pyqtSignal(list) - rainbowColor = QtCore.pyqtSignal(str) - - def __init__(self, parent): - super(TCP_Thread, self).__init__(parent) - self.parent = parent - - def run(self): - pingtimer = 150 - rainbow = 0 - sendtick = 0 - tempdata = "" - color = QtGui.QColor() - color.setHsv(rainbow, 255, 255) - while True: - if self.parent.disconnectnow: - self.parent.stopMusic() - self.parent.tcp.close() - self.quit() - return - pingtimer -= 1 - if pingtimer == 0: - pingbefore = time.time() - self.parent.tcp.send('CH#%') - pingtimer = 150 - - if self.parent.m_chatmessage[TEXT_COLOR] == "6": - color.setHsv(rainbow, 255, 255) - rainbow += 5 - if rainbow > 255: - rainbow = 0 - #self.parent.text.setStyleSheet('color: rgb(' + str(color.red()) + ', ' + str(color.green()) + ', ' + str(color.blue()) + ')') - self.rainbowColor.emit('color: rgb(' + str(color.red()) + ', ' + str(color.green()) + ', ' + str(color.blue()) + ')') - - if sendtick: - sendtick -= 1 - if self.parent.msgqueue and not sendtick: - self.parent.tcp.send(self.parent.msgqueue[0]) - sendtick = 4 - - error, total = self.parent.tcp.recv() - if error == -2: - continue - elif error == -1: - self.parent.emit(QtCore.SIGNAL('showMessage(QString, QString, QString)'), 'critical', 'Connection lost', "%s connection to server lost." % ("WebSocket" if self.parent.tcp.isWS else "TCP")) - self.parent.willDisconnect = True - self.quit() - return - - for network in total: - header = network[0] - #del network[-1] - if header == 'MS': - if len(network) < 15: - print '[warning]', 'malformed/incomplete MS#chat (IC chat) network message was received' - continue - - network[CHATMSG] = decode_ao_str(network[CHATMSG].decode('utf-8')) - self.MS_Chat.emit(network) - - elif header == 'MC': - music = decode_ao_str(network[1]) - charid = int(network[2]) - t = time.localtime() - if charid != -1: - try: - name = self.parent.charlist[charid][0] - except: - name = 'char id %d' % charid - - if len(network) > 3 and network[3]: - name += " ("+network[3].decode("utf-8")+")" - #self.parent.icLog.append('[%d:%.2d] %s changed the music to %s' % (t[3], t[4], name, music)) - self.IC_Log.emit('[%d:%.2d] %s changed the music to %s' % (t[3], t[4], name, music)) - else: - self.IC_Log.emit('[%d:%.2d] the music was changed to %s' % (t[3], t[4], music)) - self.parent.playMusic(music) - - elif header == 'BN': - self.newBackground.emit(network[1]) - - elif header == 'CT': - name = decode_ao_str(network[1].decode('utf-8')) - chatmsg = decode_ao_str(network[2].decode('utf-8').replace("\n", "
")) - #self.parent.ooclog.append('%s: %s' % (name, chatmsg)) - self.OOC_Log.emit("%s: %s" % (name, chatmsg)) - - elif header == 'PV': - self.parent.mychar = int(network[3]) - self.parent.charselect.hide() - self.newChar.emit(self.parent.charlist[self.parent.mychar][0]) - - elif header == 'LE': - del network[0] - self.allEvidence.emit([evi.split('&') for evi in network]) - - elif header == 'ZZ': - if self.parent.modcall: - audio.freehandle(self.parent.modcall) - self.parent.modcall = audio.loadhandle(0, "mod_call.wav", 0, 0, 0) - audio.sethandleattr(self.parent.modcall, BASS_ATTRIB_VOL, self.parent.soundslider.value() / 100.0) - audio.playhandle(self.parent.modcall, False) - - if len(network) > 1: - self.OOC_Log.emit('[MOD CALL] ' + network[1].replace("\n", "
") + '
') - else: - self.OOC_Log.emit('[MOD CALL] But there was no extra information. (old server?)') - elif header == 'CharsCheck': - del network[0] - for i in range(len(network)): - self.parent.charlist[i][1] = int(network[i]) - - self.charSlots.emit() - - elif header == 'RT': - testimony = network[1] - wtcefile = AOpath+"sounds/general/sfx-testimony2" - if self.parent.wtcesfx: - audio.freehandle(self.parent.wtcesfx) - - if testimony == 'judgeruling': - variant = int(network[2]) - if variant == 0: - wtcefile = AOpath+"sounds/general/sfx-notguilty" - elif variant == 1: - wtcefile = AOpath+"sounds/general/sfx-guilty" - else: - variant = 0 - self.parent.wtcesfx = audio.loadhandle(False, wtcefile+".opus" if exists(wtcefile+".opus") else wtcefile+".wav", 0, 0, 0) - audio.sethandleattr(self.parent.wtcesfx, BASS_ATTRIB_VOL, self.parent.soundslider.value() / 100.0) - audio.playhandle(self.parent.wtcesfx, True) - self.parent.WTCEsignal.emit(testimony, variant) - - elif header == 'HP': - type = int(network[1]) - health = int(network[2]) - self.parent.healthbars.emit(type, health) - - elif header == 'KK': - reason = network[1] - self.parent.emit(QtCore.SIGNAL('showMessage(QString, QString, QString)'), 'critical', 'Connection lost', 'You were kicked off the server. (%s)' % reason) - - elif header == 'KB': - reason = network[1] - self.parent.emit(QtCore.SIGNAL('showMessage(QString, QString, QString)'), 'critical', 'Connection lost', 'You have been banned from the server. (%s)' % reason) - - elif header == 'BB': # message popup (AO 2.9) - message = network[1] - self.parent.emit(QtCore.SIGNAL('showMessage(QString, QString, QString)'), 'warning', 'Message from server', message) - - elif header == 'AUTH': # login status (AO 2.9) - status = int(network[1]) - statusStrings = ["You have logged out", "Wrong password", "Logged in"] - self.OOC_Log.emit("%s" % (statusStrings[status+1])) - - elif header == "CHECK": #ping - pingafter = time.time() - self.parent.gotPing.emit(int((pingafter - pingbefore)*1000)) - - elif header == 'DONE': - self.showCharSelect.emit()