Пример #1
0
    def save(self):
        """
        Save this camera action to the cutscene.
        """
        print("Saving")
        cameraSlide = Camera()
        cameraSlide.setPlace(self.locationO.currentText())
        print("...")
        try:
            (int)(self.lx.text())
            (int)(self.ly.text())
            (int)(self.lz.text())
            (int)(self.cx.text())
            (int)(self.cy.text())
            (int)(self.cz.text())
        except ValueError:
            popup(
                "Camera position (x, y, z) and look direction (x, y, z) must be entered as whole numbers",
                "Critical")
            return

        cameraSlide.setLookAt(((int)(self.lx.text()), (int)(self.ly.text()),
                               (int)(self.lz.text())))
        cameraSlide.setCameraPosition(
            ((int)(self.cx.text()), (int)(self.cy.text()),
             (int)(self.cz.text())))
        self.op.op.link.addItem(cameraSlide, self.op.op.i)
        print("Saved")
        self.op.op.linkstored.setLink(self.op.op.link, self.op.op.level,
                                      self.op.op.angle)
        self.op.op.linkstored.save()
        self.op.updateElementList()
        popup("Saved!", "Information")
Пример #2
0
    def save(self):
        """
        Save this movement action to the cutscene.
        """
        print("Saving")
        moveSlide = Movement()
        moveSlide.setSubject(self.speaker.currentText())
        moveSlide.setAnimation(self.ani.currentText())
        print("...")
        try:
            (int)(self.lx.text())
            (int)(self.ly.text())
        except ValueError:
            popup("Destination coordinates (x, y) must be entered as integers",
                  "Critical")
            return

        moveSlide.setDestination(
            ((int)(self.lx.text()), (int)(self.ly.text())))
        self.op.op.link.addItem(moveSlide, self.op.op.i)
        print("Saved")
        self.op.op.linkstored.setLink(self.op.op.link, self.op.op.level,
                                      self.op.op.angle)
        self.op.op.linkstored.save()
        self.op.updateElementList()
        popup("Saved!", "Information")
Пример #3
0
 def export(self):
     """
     Export the story-creator data files to a user-selected locaion.
     """
     fileBrowser = QFileDialog()
     fileBrowser.setFileMode(QFileDialog.Directory)
     fileBrowser.setViewMode(QFileDialog.Detail)
     fileBrowser.setOption(QFileDialog.ShowDirsOnly, True)
     if fileBrowser.exec_():
         paths = fileBrowser.selectedFiles()
     else:
         print("Cancelled")
         return
     print("Copying data to " + str(paths[0]) + "/exportdata")
     try:
         copytree(json_reader.buildPath("data"),
                  str(paths[0]) + "/exportdata")
     except OSError as e:
         print(e)
         popup(
             "Error in copying files. There is a file in the selected directory that has the same name "
             "as a Story Creator file.\n\nFiles are copied to " +
             str(paths[0]) + "/exportdata" + ". Please "
             "ensure this directory does not already exist.", "Critical")
         return
     print("Successfully copied files")
     popup("Files exported successfully!", "Information")
Пример #4
0
    def viewF(self, graph):
        """
        Toggle between the list and graph views of the social link.

        :param bool graph: whether the graph view should be displayed
        """
        if graph:
            if len(self.link.getIDs()) == 0:
                popup("Nothing to show!", "Information")
                return
            self.graphicview = PrettySL(self.mainframe, self)
            self.listview.close()
            if self.cc:
                self.cc.close()
            self.view.setText("List View")
            self.grid.addWidget(self.graphicview, 0, 0, 1, 4)
            self.graphicview.show()
            self.view.clicked.disconnect()
            self.view.clicked.connect(lambda: self.viewF(False))
        else:
            if self.cc:
                self.cc.show()
            else:
                self.listview = SLBase(self.mainframe, self)
            if self.graphicview:
                self.graphicview.close()
            self.view.setText("Graphic View")
            self.grid.addWidget(self.listview, 0, 0, 1, 4)
            self.listview.show()
            self.view.clicked.disconnect()
            self.view.clicked.connect(lambda: self.viewF(True))
        self.mainframe.center()
Пример #5
0
 def simulate(self):
     """
     Simulate this cutscene.
     Pops open the simulation model, which is modal.
     """
     if len(self.link.getIDs()) == 0:
         popup("Nothing to simulate!", "Information")
         return
     self.sim = Simulation(self.link, self.arcana, self.level, self.angle)
Пример #6
0
    def importF(self):
        """
        Import a file or set of files from disk into Story-Creator controlled directories.

        :raises AssertionError: with an object attempting to being loaded if the object cannot be loaded as a
                 Social Link, Character or Persona.
        """
        fileBrowser = QFileDialog()
        fileBrowser.setFileMode(QFileDialog.Directory)
        fileBrowser.setViewMode(QFileDialog.Detail)
        fileBrowser.setOption(QFileDialog.ShowDirsOnly, True)
        if fileBrowser.exec_():
            paths = fileBrowser.selectedFiles()
        else:
            print("Cancelled")
            return
        print("Copying data from " + str(paths[0]))
        files = os.listdir(str(paths[0]))
        print(files)
        for file in files:
            if file.endswith(".json"):
                print("Copying valid file " + file)
                if "_link" in file:
                    if self.checkOverwrite(file):
                        copy(os.path.join(str(paths[0]), file),
                             json_reader.buildPath("data"))
                else:
                    try:  # Ugly AF
                        # TODO omgf this is more than ugly AF
                        characterL = json_reader.readOne(
                            file[:len(file) - 5], 'chars')
                        assert "name" in characterL and "important" in characterL
                        if self.checkOverwrite(file, 'chars'):
                            copy(os.path.join(str(paths[0]), file),
                                 json_reader.buildPath("data/chars"))
                    except AssertionError:
                        print("Not a Character")
                        try:
                            personaL = json_reader.readOne(
                                file[:len(file) - 5], 'pers')
                            assert "name" in personaL and "arcana" in personaL
                            if self.checkOverwrite(file, 'pers'):
                                copy(os.path.join(str(paths[0]), file),
                                     json_reader.buildPath("data/pers"))
                        except AssertionError:
                            print("Not a Persona")
                            raise AssertionError(personaL)
        print("Successfully copied files")
        popup("Files imported successfully!", "Information")
Пример #7
0
 def save(self):
     """
     Validate all info and save to file on disk.
     """
     if os.path.exists(json_reader.buildPath("data/pers/"+self.nameT.text()+".json")):
         if not popup("Override existing Persona "+self.nameT.text()+"?", "Question"):
             return
     print("Saving")
     spellDeck = []
     for combobox in self.iSpellOs:
         spellDeck.append(combobox.currentText())
     stats = [self.strT.text(), self.magT.text(), self.endT.text(), self.agiT.text(), self.luckT.text()]
     res = [self.slashO.currentText(), self.strikeO.currentText(), self.pierceO.currentText(),
            self.fireO.currentText(), self.iceO.currentText(), self.elecO.currentText(),
            self.windO.currentText(), self.lightO.currentText(), self.darkO.currentText()]
     try:
         (int)(self.levelT.text())
         (int)(self.strT.text())
         (int)(self.magT.text())
         (int)(self.endT.text())
         (int)(self.agiT.text())
         (int)(self.luckT.text())
     except ValueError:
         popup("There is a number entry that isn't valid.\nEntries requiring numbers are:\nLEVEL\nSTR"
               "\nMAG\nEND\nAGI\nLUCK", "Critical")
         print("Not Saved")
         return
     if not (self.nameT.text() and not self.nameT.text().isspace()):
         popup("No name entered for your Persona. Name is a required field.", "Critical")
         print("No Name, not saved")
         return
     toWrite = Persona(
         self.nameT.text(),
         self.arcO.currentText(),
         self.levelT.text(),
         self.textT.toPlainText(),
         spellDeck,
         self.lsdic,
         stats,
         res,
         [self.listEL1.currentText(), self.listEL2.currentText()]
     )
     json_reader.writeOne(toWrite, 'pers')
     temp = self.nameT.text()
     if (temp not in [self.listP.item(i).text() for i in range(self.listP.count())]):
         self.listP.addItem(temp)
     self.loadPer(temp)
     print("Saved Persona")
Пример #8
0
 def deleteangle(self):
     """
     Completely delete a certain level/angle combo. This will remove all info, the cutscene, etc.
     Dangerous.
     """
     if not popup(
             "WARNING!!!\n\nThis will COMPLETELY ERASE this cutscene. It is HIGHLY RECOMMENDED that "
             "you back up your data by going to the Support/Contact page and choose \"Export\".",
             "Warning"):
         return
     link = SocialLink(self.arcSel.currentText())
     print(link.cutscenes)
     key = self.levelOM.currentText()[self.levelOM.currentText().index(" ")+1:] + \
           "_" + \
           self.angleOM.currentText()[self.angleOM.currentText().index(" ")+1:]
     print(key)
     if key in link.cutscenes:
         link.cutscenes.pop(key)
         link.save()
     self.angleOM.removeItem(self.angleOM.currentIndex())
     if self.angleOM.count() == 0:
         self.angleOM.addItem("No angles")
         self.delang.close()
     print(link.cutscenes)
     print("Deleted")
Пример #9
0
 def save(self):
     """
     Save this action into the cutscene.
     """
     print("Saving")
     infoSlide = Info()
     print("...")
     infoSlide.setText(self.infoBox.toPlainText())
     print(self.op.op.i)
     self.op.op.link.addItem(infoSlide, self.op.op.i)
     print("Saved")
     self.op.op.linkstored.setLink(self.op.op.link, self.op.op.level,
                                   self.op.op.angle)
     self.op.op.linkstored.save()
     self.op.updateElementList()
     popup("Saved!", "Information")
Пример #10
0
 def addAngle(self):
     """
     Add a potential angle to this link/level.
     """
     try:
         (int)(self.newAng.text())
         if self.angs[0] == "No angles":
             self.angleOM.clear()
             self.delang = QPushButton(self, text="Delete Angle")
             self.delang.clicked.connect(self.deleteangle)
             self.grid.addWidget(self.delang, 4, 2, 1, 2)
         self.angleOM.addItem("Angle " + str(self.newAng.text()))
         self.angleOM.setCurrentIndex(self.angleOM.count() - 1)
         self.newAng.clear()
     except ValueError:
         popup("The Angle must be an integer", "Critical")
Пример #11
0
 def addLS(self):
     """
     Add a learned spell to the list, based on what was entered.
     """
     print("Adding learned spell")
     chosenSpell = self.lsSpellO.currentText()
     if (int)(self.lslevel.text()) <= (int)(self.levelT.text()):
         popup("You cannot add a spell at an earlier level than the Persona's base level", "Critical")
         return
     if chosenSpell != "":
         print("Ok")
         self.lsdic[chosenSpell] = self.lslevel.text()
         self.listLS.addItem(chosenSpell + " at level " + self.lslevel.text())
         self.lslevel.setText("")
         self.lsSpellO.setCurrentIndex(0)
         return
     popup("You must choose a spell", "Critical")
Пример #12
0
 def saveinfo(self):
     """
     Set the info in the social link object and save it.
     """
     try:
         for angle, data in self.reqs.textboxes.items():
             (int)(data.text())
             if data.text() != "":
                 if self.level.currentText(
                 ) not in self.link.requiredPoints:
                     self.link.requiredPoints[self.level.currentText()] = {}
                 if angle not in self.link.requiredPoints[
                         self.level.currentText()]:
                     self.link.requiredPoints[
                         self.level.currentText()][angle] = {}
                 self.link.requiredPoints[
                     self.level.currentText()][angle]['points'] = int(
                         data.text())
         for angle, data in self.reqs.courages.items():
             self.link.requiredPoints[
                 self.level.currentText()][angle]['courage'] = int(
                     data.currentText())
         for angle, data in self.reqs.charms.items():
             self.link.requiredPoints[
                 self.level.currentText()][angle]['charm'] = int(
                     data.currentText())
         for angle, data in self.reqs.acads.items():
             self.link.requiredPoints[
                 self.level.currentText()][angle]['acad'] = int(
                     data.currentText())
         for angle, data in self.reqs.ultis.items():
             self.link.finalpersona[angle] = data.currentText()
         self.link.pseudoname = self.pseudoname.text()
         self.link.info = self.aitext.toPlainText()
         if self.linklevel:
             if str(self.linklevel) + "_" + str(
                     self.linkangle) not in self.link.cutinfo:
                 self.link.cutinfo[str(self.linklevel) + "_" +
                                   str(self.linkangle)] = ""
             self.link.cutinfo[str(self.linklevel) + "_" + str(
                 self.linkangle)] = self.titext.toPlainText()
     except ValueError:
         popup("Points must be integers.\nNot saved.", "Critical")
         return
     self.link.save()
     popup("Saved", "Information")
Пример #13
0
 def begin(self):
     """
     Enter the social link cutscene editor.
     """
     if self.angleOM.currentText() == "No angles":
         popup(
             "An Angle must be selected.\nCreate angles by entering a number in the text box below and "
             "clicking \"Add Angle\"", "Critical")
         return
     enter_level = str(self.levelOM.currentText()
                       )[str(self.levelOM.currentText()).index(" ") + 1:]
     enter_angle = str(self.angleOM.currentText()
                       )[str(self.angleOM.currentText()).index(" ") + 1:]
     print("Entered SL creation mode for arcana " +
           str(self.arcSel.currentText()))
     self.mainframe.changeState(
         SLFrame(self.mainframe, self, str(self.arcSel.currentText()),
                 int(enter_level), int(enter_angle)))
Пример #14
0
 def back(self):
     """
     Return to the higher-level cutscene container view...
     """
     if not popup("Return to list main menu?\n(Lose any unsaved changes)",
                  "Warning"):
         return
     self.close()
     self.op.cc = None
     self.op.viewF(False)
Пример #15
0
    def send(self):
        """
        Send entered text as email to me via SMTP.
        """
        if str(self.body.toPlainText()) == "" or \
           str(self.body.toPlainText()).isspace() or \
           str(self.subject.text()) == "" or \
           str(self.subject.text()).isspace():
            popup("Please enter a message and subject.", "Critical")
            return
        msg = MIMEMultipart()
        body = MIMEText(
            str(self.body.toPlainText() + "\n\nSent by " + self.semT.text()))
        msg.attach(body)
        msg['From'] = str(self.semT.text())
        msg['To'] = "*****@*****.**"
        msg['Subject'] = str(self.subject.text())
        if self.addFiles.isChecked():
            print("Adding files")
            fileNames = glob(json_reader.buildPath("data/*.json")) + \
                        glob(json_reader.buildPath("data/pers/*.json")) + \
                        glob(json_reader.buildPath("data/chars/*.json"))
            print(fileNames)
            for file in fileNames:
                part = MIMEBase('application', "octet-stream")
                part.set_payload(open(file, "rb").read())
                part.add_header(
                    'Content-Disposition',
                    'attachment; filename="%s"' % file[file.rfind("/"):])
                msg.attach(part)

        serv = smtplib.SMTP("smtp.live.com", 587)
        serv.set_debuglevel(1)
        serv.ehlo()
        serv.starttls()
        serv.ehlo()
        serv.login("*****@*****.**", 'PersonaX')
        try:
            serv.sendmail(msg['From'], msg['To'], msg.as_string())
            print("Message sent successfully")
            popup("Email was sent! Thank you!", "Information")
            serv.quit()
            return
        except smtplib.SMTPSenderRefused:
            popup(
                "You must provide your email address so that we may contact you if needed.\n\nYour email "
                "address will not be shared with any third parties.",
                "Critical")
            serv.quit()
            return
        except Exception as e:  #pylint: disable=broad-except
            print(e)
            popup("Email failed to send, but not sure why...", "Critical")
Пример #16
0
 def lightConnect(self):
     """
     Create a relationship between the current action and another.
     """
     if not self.checkCached():
         popup("Please save this action before linking it to a new one",
               "Information")
         return
     if self.next.currentText() == "New element":
         self.op.link.addRelation(self.op.i, self.op.link.size())
         print("Linked to index " + str(self.op.link.size()))
         self.op.i = self.op.link.size()
         self.load = 0
         self.changeFrame(0)
         self.updateElementList()
     else:
         self.op.link.addRelation(
             self.op.i, self.actions.index(self.next.currentText()))
         print("Linked to index " +
               str(self.actions.index(self.next.currentText())))
     self.populateExistingConnections()
Пример #17
0
 def remove(self):
     """
     Remove a character from the list, and remove them from disk.
     """
     if not popup("Are you certain you want to completely remove this character?\n(Cannot be undone)",
                  "Warning"):
         return
     print("Removing character " + self.allChars.currentText())
     json_reader.deleteChar(self.allChars.currentText())
     self.allChars.removeItem(self.allChars.currentIndex())
     self.allChars.setCurrentIndex(self.allChars.count()-1)
     self.loadChar("New")
Пример #18
0
 def save(self):
     """
     Save a character to disk from the information entered in the GUI.
     """
     if self.nameT.text() in ["New", ""]:
         popup("Sorry, your character cannot be called \""+self.nameT.text()+"\". That is a reserved "
               "keyword (and it's also a dumb name)", "Critical")
         return
     print("Saving")
     try:
         toWrite = Character(self.nameT.text(), self.infoT.toPlainText(), self.importantB.isChecked())
     except UnicodeEncodeError as e:
         print(e)
         print(type(e))
         popup("Sorry, unicode characters are not supported.", "Critical")
         return
     json_reader.writeOne(toWrite, 'chars')
     if toWrite.getName() not in [self.allChars.itemText(i) for i in range(self.allChars.count())]:
         self.allChars.insertItem(self.allChars.count()-1, self.nameT.text())
         self.allChars.setCurrentIndex(self.allChars.count()-2)
     print("Saved")
Пример #19
0
 def new(self):
     """
     Open an empty Persona edit view.
     """
     if self.createFrame and not popup("Override any unsaved changes?", "Warning"):
         return
     if self.createFrame:
         self.createFrame.close()
     self.buttonFrame.close()
     self.initUI(False)
     self.createFrame.show()
     self.mainframe.center()
     print("Created")
Пример #20
0
 def remove(self):
     """
     Remove a created Persona from the list and delete the file on disk.
     """
     if self.listP.currentItem().text() == "":
         return
     if not popup(
             "Are you certain you want to completely remove this Persona?\n(Cannot be undone)", "Warning"
         ):
         return
     print("Removing Persona " + self.listP.currentItem().text())
     json_reader.deletePer(self.listP.currentItem().text())
     self.listP.takeItem(
         [self.listP.item(i).text() for i in range(self.listP.count())].index(
             self.listP.currentItem().text())
     )
Пример #21
0
    def checkOverwrite(self, filepath, ctype=''):
        """
        Confirm with user if file should be overwritten.

        :param str filepath: path to file that could be overwritten
        :param str ctype: chars or pers if the file represents either type
        """
        if ctype:
            ctype = ctype + "/"
        if os.path.exists(os.path.join(json_reader.buildPath("data"),
                                       filepath)):
            if popup(
                    "File " + filepath[:len(filepath) - 5] +
                    " already exists. Overwrite?", "Warning"):
                os.remove(
                    json_reader.buildPath("data/%s%s" % (ctype, filepath)))
Пример #22
0
 def removeRelation(self):
     """
     Remove a relation, which will also delete the uniquely dependant subtree.
     """
     if not self.existing_connections.currentItem() or \
        not popup("Are you sure you want to remove this relation? Any elements with a unique dependancy "
                  "on this relation will also be deleted.\nIt is highly recommended you take a look at "
                  "the graphical view of the tree in order to see the potential effects of the deletion.",
                  "Warning"):
         return
     self.op.link.delRelation(
         self.op.i,
         self.actions.index(self.existing_connections.currentItem().text()))
     self.populateExistingConnections()
     self.updateElementList()
     self.op.linkstored.save()
Пример #23
0
 def edit(self):
     """
     Switch to edit view, also loads the selected Persona.
     """
     try:
         if self.listP.currentItem().text() != "":
             if self.createFrame and not popup("Override any unsaved changes?", "Warning"):
                 return
             self.loadPer(self.listP.currentItem().text())
     except AttributeError:  # To initialize createFrame UI before load
         if self.listP.currentItem().text() != "":
             temp = self.listP.currentItem().text()
             self.buttonFrame.close()
             self.initUI(False)
             self.loadPer(temp)
         else:
             return
     self.createFrame.show()
     self.mainframe.center()
     print("Changed to edit frame")
Пример #24
0
 def deleteSubtree(self):
     """
     Delete the subtree of the current selected index.
     """
     if not popup(
             "Are you certain you want to delete this item and it's subtree?\n(Everything in red and"
             " yellow will be deleted)", "Warning"):
         return
     self.graph.delItem(self.lastButtonPressed)
     self.lab.close()
     self.initData()
     self.lastButtonPressed = None
     self.delete.close()
     self.delete = None
     self.subtree = []
     self.needsRefresh = True
     self.idLabel.close()
     self.edit.clicked.disconnect()
     self.edit.close()
     self.op.linkstored.save()
     self.tree.close()
     self.tree = TreeWidget(self, self.actionObjs, self.actionIDs,
                            self.table)
     self.grid.addWidget(self.tree, 0, 0, 10, 3)
Пример #25
0
 def save(self):
     """
     Save this speak action to the cutscene.
     """
     print("Saving")
     print("...")
     speakSlide = Speak()
     speakSlide.setText(self.infoBox.toPlainText())
     speakSlide.setSpeaker(self.speaker.currentText())
     speakSlide.emotion = self.emotion.currentText()
     for i in range(len(self.pointvec)):
         if self.pointvar[i].currentText() != "":
             try:
                 amount = (int)(self.pointvec[i].text())
                 speakSlide.putPoints(self.pointvar[i].currentText(),
                                      amount)
             except ValueError:
                 popup(
                     "All Points must be integers.\nTo discard one line, empty the text field and set "
                     "the arcana to blank.", "Critical")
                 print("Amount must be an integer")
     for i in range(len(self.anglevec)):
         if self.anglevar[i].currentText() != "":
             try:
                 amount = (int)(self.anglevec[i].text())
                 speakSlide.putAngle(self.anglevar[i].currentText(), amount)
             except ValueError:
                 popup(
                     "All Points and Angles must be integers.\nTo discard one line, set empty the text "
                     "field and set the arcana to blank.", "Critical")
                 print("Amount must be an integer")
     self.op.op.link.addItem(speakSlide, self.op.op.i)
     print("Saved")
     self.op.op.linkstored.setLink(self.op.op.link, self.op.op.level,
                                   self.op.op.angle)
     self.op.op.linkstored.save()
     self.op.updateElementList()
     popup("Saved!", "Information")