finished AO 2.8 effects

This commit is contained in:
Mauricio 2020-08-04 23:29:43 -04:00
parent 8f19e2ffef
commit b06afc30b7
17 changed files with 335 additions and 83 deletions

View File

@ -0,0 +1,4 @@
realization = sfx-realization
hearts = sfx-squee
reaction = sfx-reactionding
impact = sfx-fan

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 825 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 769 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -1,32 +1,32 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
import os import os
AOpath = "base\\" AOpath = "base/"
#AOpath = "I:\\aovanilla1.7.5\\client\\base\\" #AOpath = "I:/aovanilla1.7.5/client/base/"
class RealizationButton(QtGui.QLabel): class AOToggleButton(QtGui.QLabel):
pressed = False pressed = False
def __init__(self, parent, x, y): clicked = QtCore.pyqtSignal()
super(RealizationButton, self).__init__(parent)
def __init__(self, parent, x, y, btnname):
super(AOToggleButton, self).__init__(parent)
self.parent = parent self.parent = parent
self.setGeometry(x, y, 42, 42) self.notpressed_pix = QtGui.QPixmap(AOpath+"themes/default/%s.png" % btnname)
self.notpressed_pix = QtGui.QPixmap(AOpath+"themes\\default\\realization.png") self.pressed_pix = QtGui.QPixmap(AOpath+"themes/default/%s_pressed.png" % btnname)
self.pressed_pix = QtGui.QPixmap(AOpath+"themes\\default\\realization_pressed.png")
self.setPixmap(self.notpressed_pix) self.setPixmap(self.notpressed_pix)
self.setGeometry(x, y, self.notpressed_pix.size().width(), self.notpressed_pix.size().height())
self.show() self.show()
def setPressed(self, on): def setPressed(self, on):
self.pressed = on self.pressed = on
if on: self.setPixmap(self.pressed_pix if on else self.notpressed_pix)
self.setPixmap(self.pressed_pix)
else:
self.setPixmap(self.notpressed_pix)
def isPressed(self): def isPressed(self):
return self.pressed return self.pressed
def mousePressEvent(self, event): def mousePressEvent(self, event):
self.setPressed(not self.isPressed()) self.setPressed(not self.isPressed())
self.clicked.emit()
class CustomObjection(QtGui.QLabel): class CustomObjection(QtGui.QLabel):
pressed = False pressed = False
@ -34,8 +34,8 @@ class CustomObjection(QtGui.QLabel):
super(CustomObjection, self).__init__(parent) super(CustomObjection, self).__init__(parent)
self.parent = parent self.parent = parent
self.setGeometry(x, y, 76, 28) self.setGeometry(x, y, 76, 28)
self.notpressed_pix = QtGui.QPixmap(AOpath+"themes\\default\\custom.png") self.notpressed_pix = QtGui.QPixmap(AOpath+"themes/default/custom.png")
self.pressed_pix = QtGui.QPixmap(AOpath+"themes\\default\\custom_selected.png") self.pressed_pix = QtGui.QPixmap(AOpath+"themes/default/custom_selected.png")
self.setPixmap(self.notpressed_pix) self.setPixmap(self.notpressed_pix)
self.show() self.show()
@ -63,14 +63,14 @@ class WTCEbuttons(QtGui.QLabel):
super(WTCEbuttons, self).__init__(parent) super(WTCEbuttons, self).__init__(parent)
self.setGeometry(x, y, 85, 42) self.setGeometry(x, y, 85, 42)
if type == 0: if type == 0:
self.setPixmap(QtGui.QPixmap(AOpath+"themes\\default\\witnesstestimony.png")) self.setPixmap(QtGui.QPixmap(AOpath+"themes/default/witnesstestimony.png"))
elif type == 1: elif type == 1:
self.setPixmap(QtGui.QPixmap(AOpath+"themes\\default\\crossexamination.png")) self.setPixmap(QtGui.QPixmap(AOpath+"themes/default/crossexamination.png"))
elif type == 2: elif type == 2:
if variant == 0: if variant == 0:
self.setPixmap(QtGui.QPixmap(AOpath+"themes\\default\\notguilty.png")) self.setPixmap(QtGui.QPixmap(AOpath+"themes/default/notguilty.png"))
elif variant == 1: elif variant == 1:
self.setPixmap(QtGui.QPixmap(AOpath+"themes\\default\\guilty.png")) self.setPixmap(QtGui.QPixmap(AOpath+"themes/default/guilty.png"))
self.type = type self.type = type
self.variant = variant self.variant = variant
@ -86,14 +86,14 @@ class Objections(QtGui.QLabel):
self.type = type self.type = type
self.setGeometry(x, y, 76, 28) self.setGeometry(x, y, 76, 28)
if type == 1: if type == 1:
self.notpressed_pix = QtGui.QPixmap(AOpath+"themes\\default\\holdit.png") self.notpressed_pix = QtGui.QPixmap(AOpath+"themes/default/holdit.png")
self.pressed_pix = QtGui.QPixmap(AOpath+"themes\\default\\holdit_selected.png") self.pressed_pix = QtGui.QPixmap(AOpath+"themes/default/holdit_selected.png")
elif type == 2: elif type == 2:
self.notpressed_pix = QtGui.QPixmap(AOpath+"themes\\default\\objection.png") self.notpressed_pix = QtGui.QPixmap(AOpath+"themes/default/objection.png")
self.pressed_pix = QtGui.QPixmap(AOpath+"themes\\default\\objection_selected.png") self.pressed_pix = QtGui.QPixmap(AOpath+"themes/default/objection_selected.png")
elif type == 3: elif type == 3:
self.notpressed_pix = QtGui.QPixmap(AOpath+"themes\\default\\takethat.png") self.notpressed_pix = QtGui.QPixmap(AOpath+"themes/default/takethat.png")
self.pressed_pix = QtGui.QPixmap(AOpath+"themes\\default\\takethat_selected.png") self.pressed_pix = QtGui.QPixmap(AOpath+"themes/default/takethat_selected.png")
self.setPixmap(self.notpressed_pix) self.setPixmap(self.notpressed_pix)
self.show() self.show()
@ -162,15 +162,15 @@ class PenaltyBars(QtGui.QLabel):
self.resize(84, 14) self.resize(84, 14)
if type == 1: #defense bar. if type == 1: #defense bar.
for i in range(11): for i in range(11):
self.penaltybars.append(QtGui.QPixmap(AOpath+"themes\\default\\defensebar"+str(i)+".png")) self.penaltybars.append(QtGui.QPixmap(AOpath+"themes/default/defensebar"+str(i)+".png"))
side = "def" side = "def"
elif type == 2: #prosecution bar elif type == 2: #prosecution bar
for i in range(11): for i in range(11):
self.penaltybars.append(QtGui.QPixmap(AOpath+"themes\\default\\prosecutionbar"+str(i)+".png")) self.penaltybars.append(QtGui.QPixmap(AOpath+"themes/default/prosecutionbar"+str(i)+".png"))
side = "pro" side = "pro"
self.side = side self.side = side
self.minusbtn = PixmapButton(parent, QtGui.QPixmap(AOpath+"themes\\default\\"+side+"minus.png")) self.minusbtn = PixmapButton(parent, QtGui.QPixmap(AOpath+"themes/default/"+side+"minus.png"))
self.plusbtn = PixmapButton(parent, QtGui.QPixmap(AOpath+"themes\\default\\"+side+"plus.png")) self.plusbtn = PixmapButton(parent, QtGui.QPixmap(AOpath+"themes/default/"+side+"plus.png"))
self.minusbtn.clicked.connect(self.minusClick) self.minusbtn.clicked.connect(self.minusClick)
self.plusbtn.clicked.connect(self.plusClick) self.plusbtn.clicked.connect(self.plusClick)
self.setPixmap(self.penaltybars[10]) self.setPixmap(self.penaltybars[10])
@ -190,8 +190,8 @@ class PenaltyBars(QtGui.QLabel):
self.minusClicked.emit(self.type) self.minusClicked.emit(self.type)
def setHealth(self, health): def setHealth(self, health):
self.minusbtn.setPixmap(QtGui.QPixmap(AOpath+"themes\\default\\"+self.side+"minus.png")) self.minusbtn.setPixmap(QtGui.QPixmap(AOpath+"themes/default/"+self.side+"minus.png"))
self.plusbtn.setPixmap(QtGui.QPixmap(AOpath+"themes\\default\\"+self.side+"plus.png")) self.plusbtn.setPixmap(QtGui.QPixmap(AOpath+"themes/default/"+self.side+"plus.png"))
self.setPixmap(self.penaltybars[health]) self.setPixmap(self.penaltybars[health])
self.health = health self.health = health

View File

@ -76,6 +76,13 @@ def get_option(section, value, default=""):
tempini.read("base/ao2xp.ini") tempini.read("base/ao2xp.ini")
return ini.read_ini(tempini, section, value, default) 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): def get_text_color(textcolor):
if textcolor == 0 or textcolor == 6: if textcolor == 0 or textcolor == 6:
return QtGui.QColor(255, 255, 255) return QtGui.QColor(255, 255, 255)
@ -278,7 +285,6 @@ class AOCharMovie(QtGui.QLabel):
elif self.use_pillow == 1: # apng elif self.use_pillow == 1: # apng
self.pillow_frames = images.load_apng(apng_path) self.pillow_frames = images.load_apng(apng_path)
#print apng_path, self.pillow_frames[0], int(self.pillow_frames[0][1] * self.pillow_speed) if len(self.pillow_frames[0]) > 1 else 0
if len(self.pillow_frames) > 1: self.pillow_timer.start(int(self.pillow_frames[0][1] * self.pillow_speed)) if len(self.pillow_frames) > 1: self.pillow_timer.start(int(self.pillow_frames[0][1] * self.pillow_speed))
self.set_pillow_frame() self.set_pillow_frame()
@ -409,43 +415,63 @@ class AOCharMovie(QtGui.QLabel):
class AOMovie(QtGui.QLabel): class AOMovie(QtGui.QLabel):
play_once = True play_once = True
done = QtCore.pyqtSignal() done = QtCore.pyqtSignal()
use_pillow = 0
pillow_frames = []
pillow_frame = 0
pillow_speed = 1
def __init__(self, parent): def __init__(self, parent):
QtGui.QLabel.__init__(self, parent) QtGui.QLabel.__init__(self, parent)
self.m_movie = QtGui.QMovie() self.m_movie = QtGui.QMovie()
self.setMovie(self.m_movie) self.setMovie(self.m_movie)
self.m_movie.frameChanged.connect(self.frame_change) 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 set_play_once(self, once): def set_play_once(self, once):
self.play_once = once self.play_once = once
def play(self, p_gif, p_char): def play(self, p_image, p_char=""):
self.m_movie.stop() self.stop()
gif_path = "" gif_path = p_image
pillow_modes = {".gif": 0, ".apng": 1, ".webp": 2}
custom_path = ""
if p_gif == "custom":
custom_path = AOpath+"characters/"+p_char+"/"+p_gif+".gif"
else:
custom_path = AOpath+"characters/"+p_char+"/"+p_gif+"_bubble.gif"
theme_path = AOpath+"themes/default/"+p_gif+".gif"
placeholder_path = AOpath+"themes/default/placeholder.gif"
if exists(custom_path):
gif_path = custom_path
elif exists(theme_path):
gif_path = theme_path
else:
gif_path = placeholder_path
self.m_movie.setFileName(gif_path)
if not exists(gif_path):
pathlist = [
get_img_suffix("base/characters/"+p_char+"/"+p_image),
get_img_suffix("base/misc/default/"+p_image),
get_img_suffix("base/themes/default/"+p_image),
"base/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() self.show()
self.m_movie.start()
def stop(self): def stop(self):
self.pillow_frames = []
self.pillow_frame = 0
self.pillow_timer.stop()
self.m_movie.stop() self.m_movie.stop()
self.hide() self.hide()
@ -456,6 +482,35 @@ class AOMovie(QtGui.QLabel):
self.stop() self.stop()
self.done.emit() 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, 192, transformMode=QtCore.Qt.SmoothTransformation)
f_pixmap = QtGui.QPixmap.fromImage(f_img)
self.setPixmap(f_pixmap)
class ZoomLines(QtGui.QLabel): class ZoomLines(QtGui.QLabel):
def __init__(self, parent): def __init__(self, parent):
@ -540,10 +595,11 @@ class gui(QtGui.QWidget):
time_mod = 40 time_mod = 40
blip = "male" blip = "male"
blipsnd = None blipsnd = None
chatmessage_size = 24 chatmessage_size = 31
m_chatmessage = [] m_chatmessage = []
blank_blip = False blank_blip = False
chatmessage_is_empty = False chatmessage_is_empty = False
is_additive = False
anim_state = 3 anim_state = 3
text_state = 2 text_state = 2
objection_state = 0 objection_state = 0
@ -636,10 +692,11 @@ class gui(QtGui.QWidget):
self.name.resize(248, self.name.sizeHint().height()) self.name.resize(248, self.name.sizeHint().height())
self.wtceview = WTCE_View(self) self.wtceview = WTCE_View(self)
self.WTCEsignal.connect(self.wtceview.showWTCE) self.WTCEsignal.connect(self.wtceview.showWTCE)
self.objectionview = AOMovie(self) self.objectionview = AOMovie(self)
self.objectionview.done.connect(self.objection_done) self.objectionview.done.connect(self.objection_done)
self.effectview = AOMovie(self)
self.whiteflashlab = QtGui.QLabel(self) self.whiteflashlab = QtGui.QLabel(self)
self.whiteflashlab.setPixmap(QtGui.QPixmap(AOpath + 'themes/default/realizationflash.png')) self.whiteflashlab.setPixmap(QtGui.QPixmap(AOpath + 'themes/default/realizationflash.png'))
self.whiteflashlab.setGeometry(0, 0, 256, 192) self.whiteflashlab.setGeometry(0, 0, 256, 192)
@ -805,9 +862,19 @@ class gui(QtGui.QWidget):
self.nointerruptbtn = QtGui.QCheckBox(self) self.nointerruptbtn = QtGui.QCheckBox(self)
self.nointerruptbtn.setChecked(False) self.nointerruptbtn.setChecked(False)
self.nointerruptbtn.setText('No Interrupt') self.nointerruptbtn.setText('No Interrupt')
self.nointerruptbtn.resize(self.sfxbutton.sizeHint()) self.nointerruptbtn.resize(self.nointerruptbtn.sizeHint())
self.nointerruptbtn.move(272, 272+8) 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.effectdropdown = QtGui.QComboBox(self)
self.effectdropdown.setGeometry(272+60, 272+28+18, 88, 20)
self.changechar = QtGui.QPushButton(self) self.changechar = QtGui.QPushButton(self)
self.changechar.setText('Switch character') self.changechar.setText('Switch character')
self.changechar.setGeometry(10, 344, 121, 23) self.changechar.setGeometry(10, 344, 121, 23)
@ -844,8 +911,10 @@ class gui(QtGui.QWidget):
self.prevemotepage.hide() self.prevemotepage.hide()
self.nextemotepage = NextEmoteButton(self, 236, 253) self.nextemotepage = NextEmoteButton(self, 236, 253)
self.nextemotepage.show() self.nextemotepage.show()
self.realizationbtn = buttons.RealizationButton(self, 265, 192) self.realizationbtn = buttons.AOToggleButton(self, 265, 192, "realization")
self.realizationbtn.clicked.connect(self.onRealizationButton)
self.realizationsnd = BASS_StreamCreateFile(False, AOpath + 'sounds/general/sfx-realization.wav', 0, 0, 0) self.realizationsnd = BASS_StreamCreateFile(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.customobject = buttons.CustomObjection(self, 250, 312)
self.holditbtn = buttons.Objections(self, 10, 312, 1) self.holditbtn = buttons.Objections(self, 10, 312, 1)
self.objectbtn = buttons.Objections(self, 90, 312, 2) self.objectbtn = buttons.Objections(self, 90, 312, 2)
@ -931,7 +1000,13 @@ class gui(QtGui.QWidget):
self.setBackground('default') self.setBackground('default')
self.charselect = charselect.charselect(self) self.charselect = charselect.charselect(self)
def onRealizationButton(self):
if self.realizationbtn.isPressed():
self.effectdropdown.setCurrentIndex(1) # realization
elif self.effectdropdown.currentText() == "realization":
self.effectdropdown.setCurrentIndex(0)
def onOOCLoginBtn(self): def onOOCLoginBtn(self):
password, ok = QtGui.QInputDialog.getText(self, "Login as moderator", "Enter password.") password, ok = QtGui.QInputDialog.getText(self, "Login as moderator", "Enter password.")
if password and ok: if password and ok:
@ -1091,6 +1166,7 @@ class gui(QtGui.QWidget):
def loadCharacter(self, charname): def loadCharacter(self, charname):
exec open("base/ao2xp_themes/"+get_option("General", "theme", "default")+"/theme.py") exec open("base/ao2xp_themes/"+get_option("General", "theme", "default")+"/theme.py")
self.effectdropdown.clear()
self.emotedropdown.clear() self.emotedropdown.clear()
self.msgqueueList.clear() self.msgqueueList.clear()
self.msgqueue = [] self.msgqueue = []
@ -1098,6 +1174,12 @@ class gui(QtGui.QWidget):
self.selectedemote = 0 self.selectedemote = 0
self.current_emote_page = 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.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.charside = ini.read_ini(AOpath + 'characters/' + charname + '/char.ini', "options", "side", "def")
self.posdropdown.setCurrentIndex(self.posdropdown.findText(self.charside)) self.posdropdown.setCurrentIndex(self.posdropdown.findText(self.charside))
@ -1111,10 +1193,12 @@ class gui(QtGui.QWidget):
emote = ini.read_ini(AOpath + 'characters/' + charname + '/char.ini', "emotions", str(emoteind), 'normal#(a)normal#normal#0#') 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') 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') 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('#') emotelist = emote.split('#')
del emotelist[len(emotelist) - 1] del emotelist[len(emotelist) - 1]
emotelist.append(sound) emotelist.append(sound)
emotelist.append(soundt) emotelist.append(soundt)
emotelist.append(soundl) # AO 2.8
self.charemotes.append(emotelist) self.charemotes.append(emotelist)
if emotelist[0]: if emotelist[0]:
self.emotedropdown.addItem(emotelist[0]) self.emotedropdown.addItem(emotelist[0])
@ -1366,7 +1450,8 @@ class gui(QtGui.QWidget):
else: else:
modifier = 2 modifier = 2
msg = "MS#chat#" msg = "MS#"
msg += "1#" # visible desk modifier
msg += emote[1]+"#" #pre-anim msg += emote[1]+"#" #pre-anim
msg += self.charname+"#" msg += self.charname+"#"
msg += emote[2]+"#" #anim msg += emote[2]+"#" #anim
@ -1393,18 +1478,50 @@ class gui(QtGui.QWidget):
if "cccc_ic_support" in self.features: if "cccc_ic_support" in self.features:
msg += self.showname+"#" # custom showname msg += self.showname+"#" # custom showname
msg += (str(self.pairdropdown.currentIndex()) if self.paircheckbox.isChecked() else "-1")+"#" # pair charID if self.paircheckbox.isChecked():
if "effects" in self.features: msg += str(self.pairdropdown.currentIndex())+"#" # pair charID
msg += "^%d#" % self.pair_order.currentIndex() # pair ordering if "effects" in self.features:
msg += "^%d#" % self.pair_order.currentIndex() # pair ordering
else:
msg += "-1#"
msg += str(self.pairoffset.value())+"#" # send this anyway; AO 2.8 msg += str(self.pairoffset.value())+"#" # send this anyway; AO 2.8
msg += str(int(self.nointerruptbtn.isChecked()))+"#" # NoInterrupt(TM) 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(AOpath+"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 += "%" msg += "%"
self.msgqueueList.addItem(self.icchatinput.text()) self.msgqueueList.addItem(self.icchatinput.text())
self.msgqueue.append(msg) self.msgqueue.append(msg)
self.icchatinput.clear() self.icchatinput.clear()
self.realizationbtn.setPressed(False) self.realizationbtn.setPressed(False)
self.shakebtn.setPressed(False)
def setBackground(self, bg): def setBackground(self, bg):
if not exists(AOpath + 'background/' + bg): if not exists(AOpath + 'background/' + bg):
@ -1433,7 +1550,7 @@ class gui(QtGui.QWidget):
AO2chat = "cccc_ic_support" in self.features AO2chat = "cccc_ic_support" in self.features
for n_string in range(self.chatmessage_size): for n_string in range(self.chatmessage_size):
if n_string < len(p_contents) and n_string < 16 or AO2chat: if n_string < len(p_contents) and (n_string < 16 or AO2chat):
self.m_chatmessage[n_string] = p_contents[n_string] self.m_chatmessage[n_string] = p_contents[n_string]
else: else:
self.m_chatmessage[n_string] = "" self.m_chatmessage[n_string] = ""
@ -1460,7 +1577,7 @@ class gui(QtGui.QWidget):
if self.msgqueue: if self.msgqueue:
chatmsgcomp = str(self.msgqueue[0].split('#')[5]).decode('utf-8').replace('<dollar>', '$').replace('<percent>', '%').replace('<and>', '&').replace('<num>', '#') chatmsgcomp = str(self.msgqueue[0].split('#')[5]).decode('utf-8').replace('<dollar>', '$').replace('<percent>', '%').replace('<and>', '&').replace('<num>', '#')
if f_char_id == self.mychar and self.m_chatmessage[CHATMSG] == chatmsgcomp: if f_char_id == self.mychar and self.m_chatmessage[CHATMSG] == chatmsgcomp: # our message showed up
del self.msgqueue[0] del self.msgqueue[0]
self.msgqueueList.takeItem(0) self.msgqueueList.takeItem(0)
@ -1488,8 +1605,17 @@ class gui(QtGui.QWidget):
pass 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.icLog.append('[%d:%.2d] %s: %s\n%s presented an evidence: %s' % (t[3], t[4], logcharname, self.m_chatmessage[CHATMSG], f_char, eviname))
objection_mod = int(self.m_chatmessage[SHOUT_MOD]) 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: if objection_mod <= 4 and objection_mod >= 1:
if objection_mod == 1: if objection_mod == 1:
@ -1499,7 +1625,10 @@ class gui(QtGui.QWidget):
elif objection_mod == 3: elif objection_mod == 3:
self.objectionview.play("takethat", f_char) self.objectionview.play("takethat", f_char)
elif objection_mod == 4: elif objection_mod == 4:
self.objectionview.play("custom", f_char) if custom_objection != "custom":
self.objectionview.play("custom_objections/"+custom_objection, f_char)
else:
self.objectionview.play(custom_objection, f_char)
self.playObjectionSnd(f_char, objection_mod) self.playObjectionSnd(f_char, objection_mod)
emote_mod = int(self.m_chatmessage[EMOTE_MOD]) emote_mod = int(self.m_chatmessage[EMOTE_MOD])
@ -1587,6 +1716,7 @@ class gui(QtGui.QWidget):
def handle_chatmessage_2(self): def handle_chatmessage_2(self):
self.zoom.setZoom(False) self.zoom.setZoom(False)
self.char.stop() self.char.stop()
self.effectview.stop()
if not self.m_chatmessage[SHOWNAME]: if not self.m_chatmessage[SHOWNAME]:
self.name.setText(self.m_chatmessage[CHARNAME]) self.name.setText(self.m_chatmessage[CHARNAME])
@ -1841,12 +1971,39 @@ class gui(QtGui.QWidget):
if snd: if snd:
BASS_ChannelPlay(snd, True) BASS_ChannelPlay(snd, True)
break 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)
self.effectview.play(effect)
def start_chat_ticking(self): def start_chat_ticking(self):
if self.text_state != 0: if self.text_state != 0:
return return
if self.m_chatmessage[REALIZATION] == "1": 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 != "-":
self.do_effect(fx, fx_sound, self.m_chatmessage[CHARNAME], fx_folder)
elif self.m_chatmessage[REALIZATION] == "1":
self.setWhiteFlash(True, 1, 125) self.setWhiteFlash(True, 1, 125)
self.ao2text.clear() self.ao2text.clear()
@ -1895,7 +2052,7 @@ class gui(QtGui.QWidget):
else: else:
f_character2 = f_message[self.tick_pos] f_character2 = f_message[self.tick_pos]
f_character = QtCore.QString(f_character2) f_character = QtCore.QString(f_character2)
if f_character == " ": if f_character == " ":
self.text.setText(self.text.text() + " ") self.text.setText(self.text.text() + " ")
self.ao2text.insertPlainText(" ") self.ao2text.insertPlainText(" ")
@ -1976,6 +2133,14 @@ class gui(QtGui.QWidget):
else: else:
self.inline_color_stack.append(INLINE_GREEN) self.inline_color_stack.append(INLINE_GREEN)
formatting_char = True formatting_char = True
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")
else: else:
self.next_character_is_not_special = False self.next_character_is_not_special = False
@ -2004,12 +2169,12 @@ class gui(QtGui.QWidget):
self.ao2text.setAlignment(QtCore.Qt.AlignLeft) self.ao2text.setAlignment(QtCore.Qt.AlignLeft)
self.text.setAlignment(QtCore.Qt.AlignLeft) self.text.setAlignment(QtCore.Qt.AlignLeft)
if f_message[self.tick_pos] != " " or self.blank_blip: if f_message[self.tick_pos] != " " or self.blank_blip:
if self.blip_pos % self.blip_rate == 0 and not formatting_char: if self.blip_pos % self.blip_rate == 0 and not formatting_char:
self.blip_pos = 0 self.blip_pos = 0
BASS_ChannelPlay(self.blipsnd, True) BASS_ChannelPlay(self.blipsnd, True)
self.blip_pos += 1 self.blip_pos += 1
self.tick_pos += 1 self.tick_pos += 1

View File

@ -73,7 +73,7 @@ def load_webp(file):
img.load() # strange thing with Pillow and animated webp's is that the img.info dictionary attr doesn't update unless you call a function like this img.load() # strange thing with Pillow and animated webp's is that the img.info dictionary attr doesn't update unless you call a function like this
frames.append([img.toqimage(), img.info["duration"]]) frames.append([img.toqimage(), img.info["duration"]])
return frames return frames, img.info["loop"]
def get_apng_duration(file): def get_apng_duration(file):
img = APNG.open(file) img = APNG.open(file)

85
ini.py
View File

@ -1,5 +1,6 @@
from ConfigParser import ConfigParser from ConfigParser import ConfigParser
from PyQt4.QtCore import QString from PyQt4.QtCore import QString
from os.path import exists
def read_ini(file, section, value, default=""): def read_ini(file, section, value, default=""):
if isinstance(file, str) or isinstance(file, QString): if isinstance(file, str) or isinstance(file, QString):
@ -44,4 +45,86 @@ def read_ini_int(file, section, value, default=0):
for c in conf.options(val): for c in conf.options(val):
if c.lower() == value.lower(): if c.lower() == value.lower():
return conf.getint(val, c) return conf.getint(val, c)
return default return default
def read_sectionless_ini(file, search, default=""):
if isinstance(file, QString): file = str(file)
if isinstance(search, QString): search = str(search)
with open(file) as f:
for keys in f.read().split("\n"):
if not keys or "=" not in keys: continue
key, value = keys.split("=")
if search.lower() == key.rstrip().lower():
return value.lstrip()
return default
# AO 2.8
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 read_ini_tags(file, target_tag):
if isinstance(file, str) or isinstance(file, QString):
conf = ConfigParser()
conf.read(str(file))
else:
conf = file
r_values = []
if target_tag:
try: keys = conf.options(target_tag)
except: return []
for key in keys:
value = conf.get(target_tag, key)
r_values.append(key+"="+value)
else:
for sect in conf.sections():
keys = conf.options(sect)
for key in keys:
value = conf.get(target_tag, key)
r_values.append(key+"="+value)
return r_values
def get_effect_sound(fx_name, char):
p_effect = read_ini("base/characters/"+char+"/char.ini", "options", "effects")
p_path = "base/misc/"+p_effect+"/effects.ini"
default_path = "base/themes/default/effects/effects.ini"
if exists(p_path):
return read_sectionless_ini(p_path, fx_name)
return read_sectionless_ini(default_path, fx_name)
def get_effects(char):
p_effect = read_ini("base/characters/"+char+"/char.ini", "options", "effects")
p_path = "base/misc/"+p_effect+"/effects.ini"
effects = ["realization", "hearts", "reaction", "impact"]
if not exists(p_path): return effects
lines = open(p_path).read().split("\n")
for line in lines:
effect = line.split("=")[0].rstrip()
if effect and effect not in effects:
effects.append(effect)
return effects
def get_effect(effect, char, folder):
p_effect = folder
if not p_effect: p_effect = read_ini("base/characters/"+char+"/char.ini", "options", "effects")
p_path = get_img_suffix("base/misc/"+p_effect+"/"+effect)
default_path = get_img_suffix("base/themes/default/effects/"+effect)
if not exists(p_path):
return default_path
return p_path