Compare commits
4 Commits
db6ddea0ed
...
04999e80e9
Author | SHA1 | Date | |
---|---|---|---|
04999e80e9 | |||
5c742b01fb | |||
88545b2ca0 | |||
e4738b6d9b |
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,5 +1,7 @@
|
|||||||
|
AO2XPbase/allicons/
|
||||||
base/
|
base/
|
||||||
chatlogs/
|
chatlogs/
|
||||||
|
logs/
|
||||||
pybass/
|
pybass/
|
||||||
build/
|
build/
|
||||||
dist/
|
dist/
|
||||||
|
25
README.md
25
README.md
@ -1,10 +1,25 @@
|
|||||||
# AO2XP
|
# AO2XP
|
||||||
|
|
||||||
This is an alternative Attorney Online 2 client, developed in Python 2.7, specifically made for older computers running Windows XP that cannot run the latest version of the AO2 client. It should also work on Linux.
|
This is an alternative Attorney Online 2 client, developed in Python 2.7, specifically made for older computers running Windows XP that cannot run the latest version of the AO2 client. It should also work on Linux and later versions of Windows.
|
||||||
|
|
||||||
Run `AO2XP.py` to launch the client.
|
Run `quicksetup.py` to install the required libraries and then `AO2XP.py` to launch the client.
|
||||||
You may run `quicksetup.py` to install the required libraries.
|
|
||||||
|
|
||||||
If you want midis, place a soundfount file named `gm.sf2` in the root AO2XP directory.
|
|
||||||
|
|
||||||
Originally by Headshot#7237 and currently maintained by cidoku.
|
Originally by Headshot#7237 and currently maintained by cidoku.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
Features added since the last commit of [Headshot's AO2XP](https://github.com/headshot2017/AO2XP):
|
||||||
|
- Incoming message queue
|
||||||
|
- Persistent private evidence
|
||||||
|
- Exporting/importing evidence to/from a file
|
||||||
|
- Slide animations
|
||||||
|
- Player and area lists
|
||||||
|
- Search boxes on music list and character select
|
||||||
|
- Join a server automatically on launch
|
||||||
|
- Pick a character and join an area automatically on join
|
||||||
|
- Demo recording and playback with a seekbar, no need to send messages to OOC
|
||||||
|
- Pair with players directly from the player list
|
||||||
|
- Playing music over HTTPS (on systems where the BASS library can't do it on its own)
|
||||||
|
- FLAC music support
|
||||||
|
- MIDI music support (needs a soundfount file named `gm.sf2` in the root AO2XP directory)
|
||||||
|
- Module music support (MOD, XM, IT, S3M)
|
||||||
|
- Unicode support everywhere
|
||||||
|
81
buttons.py
81
buttons.py
@ -199,3 +199,84 @@ class PenaltyBars(QtGui.QLabel):
|
|||||||
|
|
||||||
def getHealth(self):
|
def getHealth(self):
|
||||||
return self.health
|
return self.health
|
||||||
|
|
||||||
|
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)
|
||||||
|
self.gamegui.icchat_focus()
|
||||||
|
|
||||||
|
class EmoteButton(QtGui.QLabel):
|
||||||
|
clicked = QtCore.pyqtSignal()
|
||||||
|
|
||||||
|
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
|
||||||
|
self.path = ''
|
||||||
|
|
||||||
|
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():
|
||||||
|
button_img = QtGui.QPixmap(self.path + '_off.png')
|
||||||
|
painter.setOpacity(0.5)
|
||||||
|
painter.drawPixmap(0, 0, button_img)
|
||||||
|
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)
|
||||||
|
self.clicked.emit()
|
||||||
|
|
||||||
|
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()
|
||||||
|
90
gameview.py
90
gameview.py
@ -1029,7 +1029,7 @@ class gui(QtGui.QWidget):
|
|||||||
self.evidenceswitchglobal.setToolTip('Switch to the global inventory')
|
self.evidenceswitchglobal.setToolTip('Switch to the global inventory')
|
||||||
self.evidenceswitchglobal.clicked.connect(self.onSwitchInventory)
|
self.evidenceswitchglobal.clicked.connect(self.onSwitchInventory)
|
||||||
|
|
||||||
self.evidencepresent = PresentButton(self, self.gametab_evidence)
|
self.evidencepresent = buttons.PresentButton(self, self.gametab_evidence)
|
||||||
|
|
||||||
self.privatedropdown.hide()
|
self.privatedropdown.hide()
|
||||||
self.evidencemoveglobal.hide()
|
self.evidencemoveglobal.hide()
|
||||||
@ -1216,7 +1216,7 @@ class gui(QtGui.QWidget):
|
|||||||
for i in range(self.max_emotes_on_page):
|
for i in range(self.max_emotes_on_page):
|
||||||
x_pos = (40 + spacing) * x_mod_count
|
x_pos = (40 + spacing) * x_mod_count
|
||||||
y_pos = (40 + spacing) * y_mod_count
|
y_pos = (40 + spacing) * y_mod_count
|
||||||
button = EmoteButton(self, left + x_pos, top + y_pos, i)
|
button = buttons.EmoteButton(self, left + x_pos, top + y_pos, i)
|
||||||
button.clicked.connect(self.icchat_focus)
|
button.clicked.connect(self.icchat_focus)
|
||||||
self.emotebuttons.append(button)
|
self.emotebuttons.append(button)
|
||||||
x_mod_count += 1
|
x_mod_count += 1
|
||||||
@ -1226,9 +1226,9 @@ class gui(QtGui.QWidget):
|
|||||||
self.emotebuttons[i].show()
|
self.emotebuttons[i].show()
|
||||||
|
|
||||||
self.current_emote_page = 0
|
self.current_emote_page = 0
|
||||||
self.prevemotepage = BackEmoteButton(self, 520, 253+190-28)
|
self.prevemotepage = buttons.BackEmoteButton(self, 520, 253+190-28)
|
||||||
self.prevemotepage.hide()
|
self.prevemotepage.hide()
|
||||||
self.nextemotepage = NextEmoteButton(self, 282 + 516, 253+190-28)
|
self.nextemotepage = buttons.NextEmoteButton(self, 282 + 516, 253+190-28)
|
||||||
self.nextemotepage.show()
|
self.nextemotepage.show()
|
||||||
|
|
||||||
self.realizationbtn = buttons.AOToggleButton(self, 265 + 164, 192 + 304, "realization")
|
self.realizationbtn = buttons.AOToggleButton(self, 265 + 164, 192 + 304, "realization")
|
||||||
@ -2068,6 +2068,7 @@ class gui(QtGui.QWidget):
|
|||||||
self.playerList.clear()
|
self.playerList.clear()
|
||||||
self.playerKick.setDisabled(True)
|
self.playerKick.setDisabled(True)
|
||||||
self.playerBan.setDisabled(True)
|
self.playerBan.setDisabled(True)
|
||||||
|
self.demo_recorder = None
|
||||||
self.ooclogin.setText("Lo&gin")
|
self.ooclogin.setText("Lo&gin")
|
||||||
self.login = False
|
self.login = False
|
||||||
self.privateinv = False
|
self.privateinv = False
|
||||||
@ -3754,23 +3755,6 @@ class TCP_Thread(QtCore.QThread):
|
|||||||
def stop(self):
|
def stop(self):
|
||||||
self.stop_now = True
|
self.stop_now = True
|
||||||
|
|
||||||
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)
|
|
||||||
self.gamegui.icchat_focus()
|
|
||||||
|
|
||||||
class EditEvidenceDialog(QtGui.QDialog):
|
class EditEvidenceDialog(QtGui.QDialog):
|
||||||
def __init__(self, gamegui):
|
def __init__(self, gamegui):
|
||||||
super(EditEvidenceDialog, self).__init__()
|
super(EditEvidenceDialog, self).__init__()
|
||||||
@ -3910,67 +3894,3 @@ class EditEvidenceDialog(QtGui.QDialog):
|
|||||||
|
|
||||||
def setTitle(self):
|
def setTitle(self):
|
||||||
self.setWindowTitle('Add evidence' if not self.gamegui.privateinv else "Add evidence to private inventory")
|
self.setWindowTitle('Add evidence' if not self.gamegui.privateinv else "Add evidence to private inventory")
|
||||||
|
|
||||||
class EmoteButton(QtGui.QLabel):
|
|
||||||
clicked = QtCore.pyqtSignal()
|
|
||||||
|
|
||||||
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
|
|
||||||
self.path = ''
|
|
||||||
|
|
||||||
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():
|
|
||||||
button_img = QtGui.QPixmap(self.path + '_off.png')
|
|
||||||
painter.setOpacity(0.5)
|
|
||||||
painter.drawPixmap(0, 0, button_img)
|
|
||||||
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)
|
|
||||||
self.clicked.emit()
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
16
options.py
16
options.py
@ -234,6 +234,11 @@ class Settings(QtGui.QDialog):
|
|||||||
|
|
||||||
self.savebtn.setFocus()
|
self.savebtn.setFocus()
|
||||||
|
|
||||||
|
# If they're different from the respective checkbox on save, tell the gui to start/stop logging
|
||||||
|
self.savelogs_state = False
|
||||||
|
self.combinelogs_state = False
|
||||||
|
self.savedemos_state = False
|
||||||
|
|
||||||
def showSettings(self):
|
def showSettings(self):
|
||||||
if exists("AO2XP.ini"):
|
if exists("AO2XP.ini"):
|
||||||
self.inifile.read("AO2XP.ini")
|
self.inifile.read("AO2XP.ini")
|
||||||
@ -292,6 +297,10 @@ class Settings(QtGui.QDialog):
|
|||||||
for line in f:
|
for line in f:
|
||||||
self.callwords_edit.append(line.rstrip().decode("utf-8"))
|
self.callwords_edit.append(line.rstrip().decode("utf-8"))
|
||||||
|
|
||||||
|
self.savelogs_state = self.savetolog.isChecked()
|
||||||
|
self.combinelogs_state = self.savetolog_combine.isChecked()
|
||||||
|
self.savedemos_state = self.savedemos.isChecked()
|
||||||
|
|
||||||
self.tabs.setCurrentIndex(0)
|
self.tabs.setCurrentIndex(0)
|
||||||
self.show()
|
self.show()
|
||||||
|
|
||||||
@ -333,10 +342,13 @@ class Settings(QtGui.QDialog):
|
|||||||
f.write(self.callwords_edit.toPlainText().toUtf8())
|
f.write(self.callwords_edit.toPlainText().toUtf8())
|
||||||
|
|
||||||
self.gamewindow.gamewidget.text_wait_time = self.textstaytime.value()
|
self.gamewindow.gamewidget.text_wait_time = self.textstaytime.value()
|
||||||
self.gamewindow.gamewidget.ooclog.set_logfiles()
|
|
||||||
self.gamewindow.gamewidget.icLog.set_logfiles(self.gamewindow.gamewidget.ooclog.logfile)
|
|
||||||
self.gamewindow.gamewidget.slide_enabled = self.enableslide.isChecked()
|
self.gamewindow.gamewidget.slide_enabled = self.enableslide.isChecked()
|
||||||
|
|
||||||
|
if not (self.savelogs_state == self.savetolog.isChecked() and self.combinelogs_state == self.savetolog_combine.isChecked()):
|
||||||
|
self.gamewindow.gamewidget.ooclog.set_logfiles()
|
||||||
|
self.gamewindow.gamewidget.icLog.set_logfiles(self.gamewindow.gamewidget.ooclog.logfile)
|
||||||
|
|
||||||
|
if not self.savedemos_state == self.savedemos.isChecked():
|
||||||
if self.savedemos.isChecked():
|
if self.savedemos.isChecked():
|
||||||
self.gamewindow.gamewidget.start_demo_recorder()
|
self.gamewindow.gamewidget.start_demo_recorder()
|
||||||
else:
|
else:
|
||||||
|
Loading…
Reference in New Issue
Block a user