mirror of
https://github.com/ModOrganizer2/modorganizer-basic_games.git
synced 2026-07-27 14:07:29 -07:00
Merge pull request #114 from ModOrganizer2/bs_saves
Add save parsing for Blade & Sorcery
This commit is contained in:
@@ -1,18 +1,199 @@
|
||||
from pathlib import Path
|
||||
import json
|
||||
import os
|
||||
from typing import List
|
||||
|
||||
from PyQt6.QtCore import QDateTime, QDir, QLocale, Qt
|
||||
from PyQt6.QtGui import QFont
|
||||
|
||||
import mobase
|
||||
|
||||
from PyQt6.QtWidgets import QSizePolicy, QVBoxLayout, QFormLayout, QLabel, QStyle
|
||||
from ..basic_features.basic_save_game_info import (
|
||||
BasicGameSaveGame,
|
||||
BasicGameSaveGameInfo
|
||||
)
|
||||
|
||||
from ..basic_game import BasicGame
|
||||
|
||||
|
||||
class BaSGame(BasicGame):
|
||||
class BaSSaveGame(BasicGameSaveGame):
|
||||
def __init__(self, filepath):
|
||||
super().__init__(filepath)
|
||||
self._filepath = Path(filepath)
|
||||
with open(self._filepath, "rb") as save:
|
||||
save_data = json.load(save)
|
||||
self._gameMode: str = save_data["gameModeId"]
|
||||
self._gender = "Male" if save_data["creatureId"] == "PlayerDefaultMale" else "Female"
|
||||
self._ethnicity: str = save_data["ethnicGroupId"]
|
||||
h, m, s = save_data["playTime"].split(":")
|
||||
self._elapsed = (int(h), int(m), float(s))
|
||||
f_stat = self._filepath.stat()
|
||||
self._created = f_stat.st_ctime
|
||||
self._modified = f_stat.st_mtime
|
||||
|
||||
def getName(self) -> str:
|
||||
return f"{self.getPlayerSlug()} - {self._gameMode}"
|
||||
|
||||
def getCreationTime(self) -> QDateTime:
|
||||
return QDateTime.fromSecsSinceEpoch(int(self._created))
|
||||
|
||||
def getModifiedTime(self) -> QDateTime:
|
||||
return QDateTime.fromSecsSinceEpoch(int(self._modified))
|
||||
|
||||
def getPlayerSlug(self) -> str:
|
||||
return f"{self._gender} {self._ethnicity}"
|
||||
|
||||
def getElapsed(self) -> str:
|
||||
return f"{self._elapsed[0]} hours, {self._elapsed[1]} minutes, {int(self._elapsed[2])} seconds"
|
||||
|
||||
def getGameMode(self) -> str:
|
||||
return self._gameMode
|
||||
|
||||
|
||||
class BaSSaveGameInfoWidget(mobase.ISaveGameInfoWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.resize(400, 125)
|
||||
sizePolicy = QSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Minimum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
|
||||
self.setSizePolicy(sizePolicy)
|
||||
self._verticalLayout = QVBoxLayout()
|
||||
self._verticalLayout.setObjectName("verticalLayout")
|
||||
self._formLayout = QFormLayout()
|
||||
self._formLayout.setObjectName("formLayout")
|
||||
self._formLayout.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.AllNonFixedFieldsGrow)
|
||||
|
||||
self._label = QLabel()
|
||||
self._label.setObjectName("label")
|
||||
font = QFont()
|
||||
font.setItalic(True)
|
||||
self._label.setFont(font)
|
||||
self._label.setText("Character")
|
||||
|
||||
self._formLayout.setWidget(0, QFormLayout.ItemRole.LabelRole, self._label)
|
||||
|
||||
self._label_2 = QLabel()
|
||||
self._label_2.setObjectName("label_2")
|
||||
self._label_2.setFont(font)
|
||||
self._label_2.setText("Game Mode")
|
||||
|
||||
self._formLayout.setWidget(1, QFormLayout.ItemRole.LabelRole, self._label_2)
|
||||
|
||||
self._label_3 = QLabel()
|
||||
self._label_3.setObjectName("label_4")
|
||||
self._label_3.setFont(font)
|
||||
self._label_3.setText("Created At")
|
||||
|
||||
self._formLayout.setWidget(2, QFormLayout.ItemRole.LabelRole, self._label_3)
|
||||
|
||||
self._label_4 = QLabel()
|
||||
self._label_4.setObjectName("label_4")
|
||||
self._label_4.setFont(font)
|
||||
self._label_4.setText("Last Saved")
|
||||
|
||||
self._formLayout.setWidget(3, QFormLayout.ItemRole.LabelRole, self._label_4)
|
||||
|
||||
self._label_5 = QLabel()
|
||||
self._label_5.setObjectName("label_3")
|
||||
self._label_5.setFont(font)
|
||||
self._label_5.setText("Session Duration")
|
||||
|
||||
self._formLayout.setWidget(4, QFormLayout.ItemRole.LabelRole, self._label_5)
|
||||
|
||||
font1 = QFont()
|
||||
font1.setBold(True)
|
||||
|
||||
self._characterLabel = QLabel()
|
||||
self._characterLabel.setObjectName("characterLabel")
|
||||
self._characterLabel.setFont(font1)
|
||||
self._characterLabel.setText("")
|
||||
|
||||
self._formLayout.setWidget(0, QFormLayout.ItemRole.FieldRole, self._characterLabel)
|
||||
|
||||
self._gameModeLabel = QLabel()
|
||||
self._gameModeLabel.setObjectName("gameModeLabel")
|
||||
self._gameModeLabel.setFont(font1)
|
||||
self._gameModeLabel.setText("")
|
||||
|
||||
self._formLayout.setWidget(1, QFormLayout.ItemRole.FieldRole, self._gameModeLabel)
|
||||
|
||||
self._dateLabel = QLabel()
|
||||
self._dateLabel.setObjectName("dateLabel")
|
||||
self._dateLabel.setFont(font1)
|
||||
self._dateLabel.setText("")
|
||||
|
||||
self._formLayout.setWidget(2, QFormLayout.ItemRole.FieldRole, self._dateLabel)
|
||||
|
||||
self._sessionLabel = QLabel()
|
||||
self._sessionLabel.setObjectName("sessionLabel")
|
||||
self._sessionLabel.setFont(font1)
|
||||
self._sessionLabel.setText("")
|
||||
|
||||
self._formLayout.setWidget(3, QFormLayout.ItemRole.FieldRole, self._sessionLabel)
|
||||
|
||||
self._elapsedTimeLabel = QLabel()
|
||||
self._elapsedTimeLabel.setObjectName("elapsedTimeLabel")
|
||||
self._elapsedTimeLabel.setFont(font1)
|
||||
self._elapsedTimeLabel.setText("")
|
||||
|
||||
self._formLayout.setWidget(4, QFormLayout.ItemRole.FieldRole, self._elapsedTimeLabel)
|
||||
|
||||
self._verticalLayout.addLayout(self._formLayout)
|
||||
|
||||
self.setLayout(self._verticalLayout)
|
||||
self.setWindowFlags(Qt.WindowType.ToolTip | Qt.WindowType.BypassGraphicsProxyWidget)
|
||||
self.setWindowOpacity(
|
||||
self.style().styleHint(QStyle.StyleHint.SH_ToolTipLabel_Opacity) / 255.0
|
||||
)
|
||||
|
||||
def setSave(self, save: mobase.ISaveGame):
|
||||
assert isinstance(save, BaSSaveGame)
|
||||
self._characterLabel.setText(save.getPlayerSlug())
|
||||
self._gameModeLabel.setText(save.getGameMode())
|
||||
t = save.getCreationTime().toLocalTime()
|
||||
self._dateLabel.setText(QLocale.system().toString(t.date(), QLocale.FormatType.ShortFormat)
|
||||
+ " " + QLocale.system().toString(t.time()))
|
||||
s = save.getModifiedTime().toLocalTime()
|
||||
self._sessionLabel.setText(QLocale.system().toString(s.date(), QLocale.FormatType.ShortFormat)
|
||||
+ " " + QLocale.system().toString(s.time()))
|
||||
self._elapsedTimeLabel.setText(save.getElapsed())
|
||||
self.resize(0, 125)
|
||||
|
||||
|
||||
class BaSSaveGameInfo(BasicGameSaveGameInfo):
|
||||
def getSaveGameWidget(self, parent=None):
|
||||
return BaSSaveGameInfoWidget(parent)
|
||||
|
||||
|
||||
class BaSGame(BasicGame):
|
||||
Name = "Blade & Sorcery Plugin"
|
||||
Author = "R3z Shark"
|
||||
Version = "0.1.0"
|
||||
Author = "R3z Shark & Silarn"
|
||||
Version = "0.5.0"
|
||||
|
||||
GameName = "Blade & Sorcery"
|
||||
GameShortName = "bladeandsorcery"
|
||||
GameBinary = "BladeAndSorcery.exe"
|
||||
GameDataPath = r"BladeAndSorcery_Data\StreamingAssets\Mods"
|
||||
GameDataPath = r"BladeAndSorcery_Data\\StreamingAssets\\Mods"
|
||||
GameDocumentsDirectory = "%DOCUMENTS%/My Games/BladeAndSorcery"
|
||||
GameSavesDirectory = "%GAME_DOCUMENTS%/Saves/Default"
|
||||
GameSaveExtension = "chr"
|
||||
GameSteamId = 629730
|
||||
GameSupportURL = (
|
||||
r"https://github.com/ModOrganizer2/modorganizer-basic_games/wiki/"
|
||||
"Game:-Blade-&-Sorcery"
|
||||
)
|
||||
|
||||
def init(self, organizer: mobase.IOrganizer) -> bool:
|
||||
BasicGame.init(self, organizer)
|
||||
self._featureMap[mobase.SaveGameInfo] = BaSSaveGameInfo()
|
||||
return True
|
||||
|
||||
def listSaves(self, folder: QDir) -> List[mobase.ISaveGame]:
|
||||
ext = self._mappings.savegameExtension.get()
|
||||
return [
|
||||
BaSSaveGame(path)
|
||||
for path in Path(folder.absolutePath()).glob(f"*.{ext}")
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user