Ejemplo n.º 1
0
 def getInventory(self):
     dLog(
         "inv getInventory: " + self.getItemId() + " " + str(self) +
         " -- " + str(self._inventory),
         Inventory._instanceDebug,
     )
     return self._inventory
Ejemplo n.º 2
0
    def getAttributesThatShouldntBeSaved(self):
        atts = []
        if hasattr(self, "attributesThatShouldntBeSaved"):
            atts += self.attributesThatShouldntBeSaved

        # Dont save empty inventories for rooms
        if self.getType() != "Room":
            return atts

        # everything below is for rooms only
        if hasattr(self, "_inventory"):
            if len(self.getInventory()) == 0:
                dLog(
                    "getAttributesThatShouldntBeSaved: adding _inventory "
                    + "to unsaved attributes",
                    self._instanceDebug,
                )
                atts.append("_inventory")
            else:
                dLog(
                    "getAttributesThatShouldntBeSaved: preserving room "
                    + "inventory (count="
                    + str(len(self.getInventory()))
                    + ")",
                    self._instanceDebug,
                )
        return atts
Ejemplo n.º 3
0
    def autoPopulateInventory(self):
        """ create creature inventory
           * randomly pick the number of items from the numOfItemsDropped list
           * for each of those, randomly pick an objNum from the itemCatalog
           * for each of those, load the object and add it to the inventory
           * typically run at creature load time
        """
        if not self._permanent:
            self.clearInventory()

        # Randomly select the itemCount
        itemCount = int(getRandomItemFromList(self._numOfItemsCarried))

        if not itemCount:  # 0 items carried
            return True

        for itemNum in range(1, itemCount + 1):  # +1 due to exclusive ranges
            itemId = getRandomItemFromList(self._itemCatalog)
            if not itemId:
                continue
            if "/" not in itemId:
                continue

            dLog("creature.autoPopulateInventory: obj = " + itemId)
            oType, oNum = itemId.split("/")
            obj1 = ObjectFactory(oType, oNum)
            obj1.load()
            self.addToInventory(obj1)
        return True
Ejemplo n.º 4
0
 def writePickleFile(self, filename):
     with open(filename, "wb") as outputfilehandle:
         try:
             pickle.dump(self, outputfilehandle, pickle.DEFAULT_PROTOCOL)
         except TypeError:
             dLog(self.debug(), self._debugStorage)
             traceback.print_exc()
Ejemplo n.º 5
0
    def readJsonFile(self, filename, logStr=""):
        logPrefix = "readJsonFile: "
        with open(filename, "r") as filehandle:
            loadedItem = filehandle.read()
            thawedDict = jsonpickle.decode(loadedItem)

            if isinstance(thawedDict, dict):
                logger.warn(logPrefix + "Loaded content is of type: " +
                            str(type(thawedDict)) + " which probably means " +
                            " that it was saved or loaded incorrectly")

                # filter out attributes that should be excluded
                for onevar in self.getAttributesThatShouldntBeSaved():
                    if hasattr(thawedDict, onevar):
                        dLog(
                            logPrefix + " ignoring " + logStr + "attribute " +
                            onevar + " during import",
                            self._debugStorage,
                        )
                        thawedDict = list(filter((onevar).__ne__, thawedDict))

            else:  # imported content is a known object (Creature, Char, etc)
                jsonDict = {}
                for onevar in vars(thawedDict):
                    # filter out attributes that should be excluded
                    if self.attributeShouldBeIgnored(onevar):
                        continue
                    jsonDict[onevar] = getattr(thawedDict, onevar)
                thawedDict = jsonDict

            return thawedDict
        return None
Ejemplo n.º 6
0
    def _castFails(self):
        """ do everything related to failed spells """

        msg = "Spell failed!  " + self.getFailedReason()
        self._spoolOut(msg)
        dLog("magic.castFails: " + msg, self._instanceDebug)
        if self.spellName == "turn":
            self.charObj.setVulnerable(True)
Ejemplo n.º 7
0
 def panicIfNeeded(self, charObj):
     """ If character has less than X percent health remaining, run away """
     dLog("panicIfNeeded: " + str(charObj.getHitPointPercent()) + " <? 10",
          True)
     if charObj.getHitPoints() < 30 and charObj.getHitPointPercent() <= 10:
         self.charMsg(charObj, "Panic!  ")
         self.run(charObj)
         return True
     return False
Ejemplo n.º 8
0
    def load(self, requestedAttNames=[], logStr="", fileType="pickle"):
        """ load from persistant storage
              - load data into tmp object
              - iterate through the attributes assigning all, except the
                 ones that we specificly exclude, to the current object
              - values of excluded objects are not overwritten """
        if logStr != "":
            logStr += " "  # append a space for easy logging

        self.setDataFilename()
        # We may muck with the object data.  Before we do, store
        # the datafile info as a local variable so that there is no conflict.
        filename = self._datafile

        logPrefix = self.__class__.__name__ + " load: "

        if filename == "":
            logger.error(logPrefix + " Could not determine " +
                         "filename for loading " + logStr)
            return False

        dLog(logPrefix + "Loading " + filename + "...", self._debugStorage)

        if self.dataFileExists():
            # read the persisted content
            if re.search("\\.json$", filename):
                loadedDict = self.readJsonFile(filename, logStr)
            else:
                loadedDict = self.readPickleFile(filename, logStr)

            if not loadedDict:
                logger.error("storage.load - Could not get loaded instance")

            # Add attributes to current class object, based on revised list
            self.addAttributesToSelf(loadedDict, requestedAttNames, logStr)

            dLog(
                logPrefix + " loaded " + logStr + str(self.getId()) + " - " +
                self.describe(),
                self._debugStorage,
            )

            self.initTmpAttributes()
            self.fixAttributes()
            self.postLoad()
            if self.isValid():
                return True
            else:
                logger.error(logPrefix + logStr + str(self.getId()) +
                             " is not valid")
        else:
            logger.warning(logPrefix + " " + logStr +
                           "datafile doesn't exist at " + self._datafile)
        return False
Ejemplo n.º 9
0
 def attributeShouldBeIgnored(self, attName, logStr=""):
     """ Return True if given attribute should be ignored """
     logPrefix = "attributeShouldBeIgnored: "
     if attName in self.getAttributesThatShouldntBeSaved():
         dLog(
             logPrefix + " ignoring " + logStr + "attribute " + attName +
             " during import",
             self._debugStorage,
         )
         return True
     return False
Ejemplo n.º 10
0
 def displayItems(self, charObj):  # noqa C901
     """ show items in current room """
     buf = self.describeInvAsList(
         showDm=charObj.isDm(),
         showHidden=charObj.canSeeHidden(),
         showInvisible=charObj.canSeeInvisible(),
         sortList=False,
     )
     dLog("displayItems:" + buf, False)
     if buf != "":
         buf = "You see " + buf
     return buf
Ejemplo n.º 11
0
 def writeJSonFile(self, filename):
     jsonpickle.set_encoder_options("json",
                                    sort_keys=True,
                                    indent=4,
                                    ensure_ascii=False)
     frozen = jsonpickle.encode(self, max_depth=10)
     with open(filename, "w") as filehandle:
         try:
             filehandle.write(frozen)
             # json.dump(frozen, filehandle)
         except TypeError:
             dLog(self.debug(), self._debugStorage)
             traceback.print_exc()
Ejemplo n.º 12
0
    def getHitMsg(self, atkDict, damage):
        """ return the hit message based on the attacker and target """
        logPrefix = "combat.hitMsg: "

        msg = (atkDict["msgPrefix"] + atkDict["attackerSubject"] + " " +
               atkDict["attackerVerb"] + " " + atkDict["targetSubject"] +
               " for " + str(damage) + " damage.\n")

        # Construct separate message where all subjects are identified by name
        debugMsg = (atkDict["attackerName"] + " hits " +
                    atkDict["targetName"] + " for " + str(damage) + " damage")
        dLog(logPrefix + debugMsg, self._instanceDebug)

        return msg
Ejemplo n.º 13
0
 def _selfCriteriaAreMet(self):
     logPrefix = "magic.selfCriteria: Failed - "
     cName = self.charObj.getName()
     if self.levelRequired < 1:
         msg = "You can't cast " + self.spellName
         self.failedReason += msg + "\n"
         dLog(logPrefix + msg + ", " + cName, self._instanceDebug)
         return False
     if self.charObj.getLevel() < self.levelRequired:
         msg = ("a level " + str(self.charObj.getLevel()) + " " +
                self.charObj.getClassName() + " can not cast " +
                self.spellName + " which requires level " +
                str(self.levelRequired))
         self.failedReason += msg + "\n"
         dLog(logPrefix + msg + ", " + cName, self._instanceDebug)
         return False
     if self.limitedNumberPerDay and not self.charObj.getLimitedSpellCount(
     ):
         msg = "You have used all of your limited spells for today"
         self.failedReason += msg + "\n"
         dLog(logPrefix + msg + ", " + cName, self._instanceDebug)
         return False
     if self._requiresmana and self.charObj.getMana() < self.mana:
         msg = "You don't have enough mana for that"
         self.failedReason += msg + "\n"
         dLog(
             logPrefix + msg + "(char=" + str(self.charObj.getMana()) +
             " spell=" + str(self.mana) + ")" + ", " + cName,
             self._instanceDebug,
         )
         return False
     return True
Ejemplo n.º 14
0
 def _targetCriteriaAreMet(self):
     logPrefix = "magic.targetCriteria: Failed - "
     cName = self.charObj.getName()
     if self.targetObj.isMagic():
         msg = "magical target can not be affected by spell"
         self.failedReason += msg + "\n"
         dLog(logPrefix + msg + ", " + cName, self._instanceDebug)
         return False
     spellTargets = SpellDict[self.spellName]["spellTargets"]
     if self.targetObj.getType() not in spellTargets:
         msg = (self.targetObj.getType() + " is not a valid target for " +
                "spell " + self.spellName)
         self.failedReason += msg + "\n"
         dLog(logPrefix + msg + ", " + cName, self._instanceDebug)
         return False
     return True
Ejemplo n.º 15
0
 def cmdloop(self):
     """ cmd method override - Lobby cmd loop
         requires user to be authenticated """
     stop = False
     line = ""
     self.preloop()
     while not stop:
         if self.client.promptForCommand(self.getCmdPrompt()):  # send/rcv
             line = self.client.getInputStr()
             self._lastinput = line
             dLog("LOBBY cmd = " + line, self.lobbyObj.debug())
             self.precmd(line)
             stop = self.onecmd(line)
             self.postcmd(stop, line)
         else:
             stop = True
     self.postloop()
Ejemplo n.º 16
0
 def loadPermanents(self):
     """ Load/instanciate permanents, and add them to the tmp lists """
     idsOfPermsInRoom = [x.getItemId() for x in self.getInventory()]
     permList = self.getPermanentList()
     for perm in self.getPermanents(permList):
         permId = perm.getItemId()
         if permId not in idsOfPermsInRoom:
             dLog(
                 "loadPermanents: loading perm =" + str(permId), self._instanceDebug
             )
             self.addToInventory(perm)
         else:
             dLog(
                 "loadPermanents: perm " + str(permId) + " already exists in room",
                 self._instanceDebug,
             )
     return True
Ejemplo n.º 17
0
    def applyCritOrDD(self, damage, target, notify=[]):
        logPrefix = "applyCritOrDD: "
        buf = ""

        if self.checkForCrit():
            buf = "Critical Damage!\n"
            damage = max(1, damage) * 3  # critical hit
            dLog(logPrefix + "critical damage (*3)", self._instanceDebug)
        elif self.checkForDD(target):
            buf = "Double Damage!\n"
            damage = max(1, damage) * 2  # double damage
            dLog(logPrefix + "double damage (*2)", self._instanceDebug)

        if buf != "":
            for recipient in notify:
                if recipient.getType() == "Character":
                    self.charMsg(recipient, buf)
        return damage
Ejemplo n.º 18
0
    def applyDamage(self, charObj, attacker, target, damage, attackCmd):
        """ apply damage to target or player """
        logPrefix = "combat.applyDamage: "
        if damage:
            # Parse attackers/targets to get a set of attack/target words
            atkDict = self.getattackMsgDict(charObj, attacker, target,
                                            attackCmd)

            # Display the message about the hit
            self.charMsg(charObj, self.getHitMsg(atkDict, damage))

        if target.damageIsLethal(damage):
            debugMsg = (atkDict["attackerName"] + " does lethal damage to " +
                        atkDict["targetSubject"])
            dLog(logPrefix + debugMsg, self._instanceDebug)

        if isinstance(target, Character):
            self.applyPlayerDamage(charObj, attacker, damage)
        else:
            self.applyCreatureDamage(charObj, target, damage, attackCmd)
Ejemplo n.º 19
0
    def addAttributesToSelf(self, loadedDict, requestedAttNames=[], logStr=""):
        """ Add attributes to current class object """
        logPrefix = "addAttributesToSelf: "

        if not isinstance(loadedDict, dict):
            logger.error(logPrefix + "loadedDict is not a dict." +
                         "  Its of type " + str(type(loadedDict)))

        for key, value in zip(loadedDict.keys(), loadedDict.values()):
            # If specific attributes are requested, skip all attributes that
            # do not match.
            if len(requestedAttNames) > 0:
                if key not in requestedAttNames:
                    continue

            setattr(self, key, value)
            buf = "imported " + logStr + "attribute " + key
            if (isinstance(value, str) or isinstance(value, int)
                    or isinstance(value, list)):
                buf += "=" + str(value)
            dLog(logPrefix + " " + buf + "\n", self._debugStorage)
Ejemplo n.º 20
0
    def _promptForChant(self):
        """ Prompts player for chant.  Returns true if chant is correct """
        if self.chant == "":
            # empty chant means none is required
            return True

        if self.givenChant == "":
            prompt = "Enter Chant: "
            playerInput = self.charObj.client.promptForInput(prompt)
        else:
            playerInput = self.givenChant

        # Test if chant is correct
        if playerInput.lower() == self.chant.lower():
            return True

        msg = "The divine are unimpressed with your chant"
        self.failedReason += msg + "\n"

        dLog("_promptForChant Failed: bad chant", self._instanceDebug)
        return False
Ejemplo n.º 21
0
    def creatureAttacksPlayer(self, creatureObj, charObj=None):
        """ single creature attacks a player """
        logPrefix = "combat.creatureAttacksPlayer: "
        if not charObj:
            charObj = creatureObj.getCurrentlyAttacking()

        dLog(
            logPrefix + creatureObj.describe() + " is attacking " +
            charObj.getName(),
            self._instanceDebug,
        )

        if not charObj:
            return False

        # toDa: right now, creatures are sticky, but they should adhere to
        # attackLast
        if charObj != creatureObj.getCurrentlyAttacking():
            creatureObj.setCurrentlyAttacking(charObj)  # initiate attack

        if not creatureObj.canAttack():
            dLog(
                logPrefix + creatureObj.getName() + " can't attack " +
                charObj.getName(),
                self._instanceDebug,
            )
            return False

        secs = random.randint(self._creatureMinSecsBetweenAttacks,
                              self._creatureMaxSecsBetweenAttacks)
        dLog(logPrefix + "setting creature secs to  " + str(secs),
             self._instanceDebug)

        creatureObj.setSecondsUntilNextAttack(secs)
        creatureObj.setLastAttack()

        if self.misses(creatureObj, charObj):  # if creature doesn't hit
            self.charMsg(charObj, creatureObj.describe() + " misses you!\n")
            # notify other players in the room
            damage = 0
            # see if we need to bump the dodge percentage
            if creatureObj.getLevel() >= charObj.getLevel():
                charObj.rollToBumpSkillForLevel("_dodge", percentChance=3)
        elif creatureObj.fumbles():
            self.charMsg(charObj, creatureObj.describe() + " fumbles!\n")
            damage = 0
        else:
            # calculate attack damage
            damage = self.attackDamage(creatureObj, charObj)

        # reduce charges of armor/shield protection
        charObj.decreaseChargeOfEquippedProtection()

        self.applyDamage(charObj,
                         creatureObj,
                         charObj,
                         damage,
                         attackCmd="attack")
        return None
Ejemplo n.º 22
0
    def cast(self, roomObj):
        """ Returns true if spell was successfully cast """
        logPrefix = "magic.cast: "
        # Do everything that comes before the spell's affects
        self._preCastTasks()

        if not self.charObj.canAttack():
            msg = "You can't attack"
            self.failedReason += msg + "\n"
            dLog(
                logPrefix + self.charObj.getName() + " can't attack",
                self._instanceDebug,
            )
            return False

        if not self.succeeded:
            self._castFails()
            return False

        self._spoolOut("You cast " + self.spellName + "\n")

        if self.spellType == "health":
            self.targetObj.addHP(self.getHealth())
        elif self.spellType == "room":
            self.targetObj.joinRoom(self.getRoom())
        elif self.spellType == "damage":
            self.inflictDamage()
        elif self.spellType == "alteration":
            self.alterations()
        elif self.spellType == "info":
            self.infos()
        elif self.spellType == "ask":
            self.ask()
        else:
            self._spoolOut("not implemented yet\n")

        self._postCastTasks()

        return True
Ejemplo n.º 23
0
    def setDataFilename(self, dfStr=""):
        """ sets the data file name.
            If no datafilename arg is provided, generate the datafile name
            based on the class and ID.  We can also override this method
            to use a different filename """
        id = ""
        logPrefix = __class__.__name__ + " setDataFilename: "

        if dfStr == "":
            # generate the data file name based on class and id
            try:
                id = self.getId()
            except AttributeError:
                pass

            if not id:
                logger.error(logPrefix + "Could not retrieve Id to " +
                             "generate filename")
                return False

            if id == "":
                logger.error(logPrefix + "ID is empty while generating " +
                             "datafile name")
                return False

            if hasattr(self, "_fileextension"):
                extension = self._fileextension
            else:
                extension = ".pickle"

            self._datafile = os.path.abspath(DATADIR + "/" +
                                             self.__class__.__name__ + "/" +
                                             str(id) + extension)
        else:
            # set data file name to name provided
            self._datafile = os.path.abspath(str(dfStr))

        dLog(logPrefix + "_datafile = " + self._datafile, self._debugStorage)
        return True
Ejemplo n.º 24
0
    def readyForEncounter(self):
        """ returns true if the room is ready for an encounter """
        debugPrefix = "Room readyForEncounter (" + str(self.getId()) + "): "

        # Room has no encounter time.  Will never be ready
        if not self._encounterRate:
            dLog(debugPrefix + "Room has no encounter rate", self._instanceDebug)
            return False

        # Room has no encounter list.  Will never be ready
        if not self._encounterList:
            dLog(debugPrefix + "Room has no creatureList", self._instanceDebug)
            return False

        # Check if the appropriate amount of time has pased
        if self._timeOfLastEncounter != getNeverDate():
            secsSinceLastEncounter = secsSinceDate(self._timeOfLastEncounter)
            pctRateAdj = (self._encounterRate - 100) / 100
            secsAdj = self._baseEncounterTime * pctRateAdj + random.randint(-5, 5)
            secsBetweenEncounters = self._baseEncounterTime - secsAdj
            timeLeft = int(secsBetweenEncounters - secsSinceLastEncounter)
            if timeLeft > 0:
                dLog(
                    debugPrefix
                    + "Encounter discarded due to time - "
                    + str(timeLeft)
                    + " secs left",
                    self._instanceDebug,
                )
                return False

        # % chance that room will have no encounter this time
        if random.randint(1, 5) == 5:
            self.setLastEncounter()
            dLog(debugPrefix + "Encounter randomly discarded", self._instanceDebug)
            return False

        dLog(debugPrefix + "Room is ready for encounter", self._instanceDebug)
        return True
Ejemplo n.º 25
0
    def engageTarget(self, charObj, target):
        """ Character locks on to creature and creature begins to defend
            * If both are already fighting each other, do nothing.  """
        logPrefix = "engageTarget: "

        if target.getCurrentlyAttacking() != charObj:
            if not isinstance(target, Character):
                # creature begins to attack player
                if target.attacksBack():
                    target.setLastAttack()
                    secs = int(
                        random.randint(
                            self._creatureMinSecsBetweenAttacks,
                            self._creatureMaxSecsBetweenAttacks,
                        ) / 2)
                    target.setSecondsUntilNextAttack(secs)
                    target.setCurrentlyAttacking(charObj)
                    dLog(
                        logPrefix + target.describe() + " engages " +
                        charObj.describe(),
                        self._instanceDebug,
                    )

        # attacker becomes locked on to target
        if charObj.getCurrentlyAttacking() != target:
            charObj.setCurrentlyAttacking(target)
            dLog(
                logPrefix + charObj.describe() + " engages " +
                target.describe(),
                self._instanceDebug,
            )
            self.othersInRoomMsg(
                charObj,
                charObj.getRoom(),
                charObj.getName() + " attacks " + target.describe() + "\n",
            )
Ejemplo n.º 26
0
    def removeNonPermanents(self, removeTmpPermFlag=False):
        """ remove any non permanents from inventory """
        logPrefix = "removeNonPermanents: " + str(self) + str(self.getItemId()) + ": "
        itemsInRoom = self.getInventory().copy()

        if removeTmpPermFlag:
            dLog(
                logPrefix
                + "inv= "
                + " ,".join(
                    [
                        x.getItemId() + "(" + str(x.persistsThroughOneRoomLoad()) + ")"
                        for x in itemsInRoom
                    ]
                ),
                self._instanceDebug,
            )

        for obj in itemsInRoom:
            if obj.persistsThroughOneRoomLoad():
                if removeTmpPermFlag:
                    # Do not remove object - let it be for one room load, but
                    # remove the property that permits this.
                    obj.setPersistThroughOneRoomLoad(False)
                    dLog(
                        logPrefix
                        + "Preserving tmpPermanent "
                        + str(obj.getItemId())
                        + " but removing persist flag",
                        self._instanceDebug,
                    )
            elif obj.isPermanent():
                # Object is permanent.  Don't remove it.
                dLog(
                    logPrefix + "Preserving permanent " + obj.getItemId(),
                    self._instanceDebug,
                )
            else:
                dLog(
                    logPrefix + "Removing non-permanent " + obj.getItemId(),
                    self._instanceDebug,
                )
                self.removeFromInventory(obj)
                self.save()
        return True
Ejemplo n.º 27
0
    def canAttack(self, allowOptOut=True):
        """ returns true if the creature is ready for an attack """
        debugPrefix = "Creature.canAttack (" + str(self.getId()) + "): "

        # Creature has no attack speed.  Will never be ready
        if not self.getAttackRate():
            dLog(debugPrefix + "Creature has no attack rate",
                 self._instanceDebug)
            return False

        # Check if the appropriate amount of time has pased
        timeLeft = int((self.getSecondsUntilNextAttack() /
                        (self.getAttackRate() / 100)) -
                       secsSinceDate(self.getLastAttackDate()))
        if timeLeft > 0:
            dLog(
                debugPrefix + "Attack discarded due to time - " +
                str(timeLeft) + " secs left",
                self._instanceDebug,
            )
            return False

        # % chance that creature does not attack
        if allowOptOut:
            randX = random.randint(1, 10)
            if randX == 1:
                self.setLastAttackDate()
                dLog(
                    debugPrefix + "Creature randomly chose not to attack (" +
                    str(randX) + " = 1)",
                    self._instanceDebug,
                )
                return False

        dLog(debugPrefix + "Creature is ready for attack", self._instanceDebug)
        return True
Ejemplo n.º 28
0
    def attackDamage(self, attackerObj, opponentObj, attackCmd="attack"):
        """ determine the amount of damage dealt by a creature or characters
            attack """
        logPrefix = "combat.AttackDamage: "

        dLog(
            logPrefix + "Calculating attackDamage for " +
            attackerObj.describe() + " attacking " + opponentObj.describe() +
            " with cmd " + attackCmd + "...",
            self._instanceDebug,
        )

        weaponDamage = attackerObj.getEquippedWeaponDamage()

        damagePercent = int(
            self.calcDmgPct(attackerObj, opponentObj, attackCmd=attackCmd) /
            100)

        damage = weaponDamage * damagePercent

        dLog(
            logPrefix + "weapon damage(" + str(weaponDamage) +
            ") * damagePercent(" + str(damagePercent) + ") = preAcDamage(" +
            str(damage) + ")",
            self._instanceDebug,
        )

        damage = opponentObj.acDamageReduction(damage)

        # check for crit or double damage
        damage = self.applyCritOrDD(damage, opponentObj,
                                    [attackerObj, opponentObj])

        damage = int(damage)
        dLog(logPrefix + "Total damage(" + str(damage) + ")",
             self._instanceDebug)
        return damage
Ejemplo n.º 29
0
 def setSpellAttributes(self):
     """ Set this instance's attributes based on the particular spell
         being cast and the corresponding values in SpellDict.
             * Special considerations:
               - levelRequired - set based on character's className
               - formulas, we execute them and store the result as
                 an attribute.  We get the attribute name from the
                 formulaResultAtt attribute.  Overly complicated?
                 Maybe, but the object comes out looking clean.
     """
     for att in SpellDict[self.spellName].keys():
         if att == "levelRequired":
             className = self.charObj.getClassName()
             setattr(self, att, SpellDict[self.spellName][att][className])
         elif att == "formula":
             attName = SpellDict[self.spellName]["formulaResultAtt"]
             if attName == "":
                 continue
             # execute formula and stick it in an attribute
             dLog("magic: formula = " + att, self._instanceDebug)
             dLog(
                 "magic: level=" + str(self.charObj.getLevel()) +
                 " - Int=" + str(self.charObj.getIntelligence()),
                 self._instanceDebug,
             )
             setattr(self, attName, eval(SpellDict[self.spellName][att]))
             dLog(
                 "magic: spell=" + self.spellName + " - damage=" +
                 str(getattr(self, attName)),
                 self._instanceDebug,
             )
         elif att == "formulaResultAtt":
             # This is used for formula results, so don't set it as att
             continue
         else:
             setattr(self, att, SpellDict[self.spellName][att])
Ejemplo n.º 30
0
    def save(self, logStr=""):
        """ save to persistant storage """
        if logStr != "":
            logStr += " "  # append a space for easy logging

        self.setDataFilename()
        # We are about to muck with the object data.  Before we do, store
        # the datafile info as a local variable so that there is no conflict.
        filename = self._datafile

        logPrefix = self.__class__.__name__ + " save: "
        if filename == "":
            logger.error(logPrefix + "Could not determine filename " +
                         " while saving " + logStr + str(self.getId()))
            return False
        if not self.isValid():  # if the instance we are saving is not valid
            logger.error(logPrefix + "Save aborted - " + logStr +
                         str(self.getId()) + " is not valid")
            return False

        # create directory
        path = Path(os.path.dirname(self._datafile))
        path.mkdir(parents=True, exist_ok=True)

        # some attributes should not be, or can not be pickled, so we
        # store the values before we save, then we will restore them
        # immediately after.
        tmpStore = {}
        for attName in self.getAttributesThatShouldntBeSaved() + [
                "_datafile",
                "_instanceDebug",
        ]:
            try:
                tmpStore[attName] = getattr(self, attName)
                if hasattr(self, attName):
                    delattr(self, attName)
                dLog(
                    logPrefix + "Ignoring " + attName + " during save",
                    self._debugStorage,
                )
            except AttributeError:
                dLog(
                    logPrefix + "Could not ignore " + attName + " during save",
                    self._debugStorage,
                )

        # persist content - create data file
        if re.search("\\.json$", filename):
            self.writeJSonFile(filename)
        else:
            self.writePickleFile(filename)

        # Restore attributes that we temporarily set aside when saving.
        for attName in tmpStore.keys():
            setattr(self, attName, tmpStore[attName])

        dLog(
            logPrefix + "saved " + logStr + " - " + str(self.getId()),
            self._debugStorage,
        )
        return True