예제 #1
0
 def __init__(self):
     # Container for skill holders, for ease of
     # access
     # Format: {holder id: {holders}}
     self.__skillHolders = KeyedSet()
     # Set with holders which have any skill requirements
     # Format: {holders}
     self.__restrictedHolders = set()
예제 #2
0
파일: slotIndex.py 프로젝트: NiGhTTraX/Eos
 def __init__(self, slotIndexAttr, restrictionType):
     # This attribute's value on holder
     # represents their index of slot
     self.__slotIndexAttr = slotIndexAttr
     self.__restrictionType = restrictionType
     # All holders which possess index of slot
     # are stored in this container
     # Format: {slot index: {holders}}
     self.__slottedHolders = KeyedSet()
예제 #3
0
 def __init__(self, maxGroupAttr, restrictionType):
     # Attribute ID whose value contains group restriction
     # of holder
     self.__maxGroupAttr = maxGroupAttr
     self.__restrictionType = restrictionType
     # Container for all tracked holders, keyed
     # by their group ID
     # Format: {group ID: {holders}}
     self.__groupAll = KeyedSet()
     # Container for holders, which have max group
     # restriction to become operational
     # Format: {holders}
     self.__maxGroupRestricted = set()
예제 #4
0
파일: register.py 프로젝트: NiGhTTraX/Eos
    def __init__(self, fit):
        # Link tracker which is assigned to fit we're
        # keeping data for
        self._fit = fit

        # Keep track of holders belonging to certain location
        # Format: {location: {targetHolders}}
        self.__affecteeLocation = KeyedSet()

        # Keep track of holders belonging to certain location and group
        # Format: {(location, group): {targetHolders}}
        self.__affecteeLocationGroup = KeyedSet()

        # Keep track of holders belonging to certain location and having certain skill requirement
        # Format: {(location, skill): {targetHolders}}
        self.__affecteeLocationSkill = KeyedSet()

        # Keep track of affectors influencing all holders belonging to certain location
        # Format: {location: {affectors}}
        self.__affectorLocation = KeyedSet()

        # Keep track of affectors influencing holders belonging to certain location and group
        # Format: {(location, group): {affectors}}
        self.__affectorLocationGroup = KeyedSet()

        # Keep track of affectors influencing holders belonging to certain location and having certain skill requirement
        # Format: {(location, skill): {affectors}}
        self.__affectorLocationSkill = KeyedSet()

        # Keep track of affectors influencing holders directly
        # Format: {targetHolder: {affectors}}
        self.__activeDirectAffectors = KeyedSet()

        # Keep track of affectors which influence something directly,
        # but are disabled as their target location is not available
        # Format: {sourceHolder: {affectors}}
        self.__disabledDirectAffectors = KeyedSet()
예제 #5
0
 def __init__(self):
     # Container for skill holders
     # Format: {holder id: {holders}}
     self.__skillHolders = KeyedSet()
예제 #6
0
파일: map.py 프로젝트: NiGhTTraX/Eos
    def __calculate(self, attrId):
        """
        Run calculations to find the actual value of attribute.

        Positional arguments:
        attrId -- ID of attribute to be calculated

        Return value:
        Calculated attribute value

        Possible exceptions:
        BaseValueError -- attribute cannot be calculated, as its
        base value is not available
        """
        # Attribute object for attribute being calculated
        try:
            attrMeta = self.__holder._fit.eos._cacheHandler.getAttribute(
                attrId)
        # Raise error if we can't get to getAttribute method
        # or it can't find requested attribute
        except (AttributeError, AttributeFetchError) as e:
            raise AttributeMetaError(attrId) from e
        # Base attribute value which we'll use for modification
        try:
            result = self.__holder.item.attributes[attrId]
        # If attribute isn't available on base item,
        # base off its default value
        except KeyError:
            result = attrMeta.defaultValue
            # If original attribute is not specified and default
            # value isn't available, raise error - without valid
            # base we can't go on
            if result is None:
                raise BaseValueError(attrId)
        # Container for non-penalized modifiers
        # Format: {operator: [values]}
        normalMods = {}
        # Container for penalized modifiers
        # Format: {operator: [values]}
        penalizedMods = {}
        # Now, go through all affectors affecting our holder
        for affector in self.__holder._fit._linkTracker.getAffectors(
                self.__holder, attrId=attrId):
            try:
                sourceHolder, modifier = affector
                operator = modifier.operator
                # Decide if it should be stacking penalized or not, based on stackable property,
                # source item category and operator
                penalize = (attrMeta.stackable is False
                            and sourceHolder.item.categoryId
                            not in penaltyImmuneCategories
                            and operator in penalizableOperators)
                try:
                    modValue = sourceHolder.attributes[
                        modifier.sourceAttributeId]
                # Silently skip current affector: error should already
                # be logged by map before it raised KeyError
                except KeyError:
                    continue
                # Normalize operations to just three types:
                # assignments, additions, multiplications
                try:
                    normalizationFunc = normalizationMap[operator]
                # Raise error on any unknown operator types
                except KeyError as e:
                    raise OperatorError(operator) from e
                modValue = normalizationFunc(modValue)
                # Add value to appropriate dictionary
                if penalize is True:
                    modList = penalizedMods.setdefault(operator, [])
                else:
                    modList = normalMods.setdefault(operator, [])
                modList.append(modValue)
            # Handle operator type failure
            except OperatorError as e:
                msg = 'malformed modifier on item {}: unknown operator {}'.format(
                    sourceHolder.item.id, e.args[0])
                signature = (type(e), sourceHolder.item.id, e.args[0])
                self.__holder._fit.eos._logger.warning(
                    msg, childName='attributeCalculator', signature=signature)
                continue
        # When data gathering is complete, process penalized modifiers
        # They are penalized on per-operator basis
        for operator, modList in penalizedMods.items():
            penalizedValue = self.__penalizeValues(modList)
            modList = normalMods.setdefault(operator, [])
            modList.append(penalizedValue)
        # Calculate result of normal dictionary, according to operator order
        for operator in sorted(normalMods):
            modList = normalMods[operator]
            # Pick best modifier for assignments, based on highIsGood value
            if operator in assignments:
                result = max(modList) if attrMeta.highIsGood is True else min(
                    modList)
            elif operator in additions:
                for modVal in modList:
                    result += modVal
            elif operator in multiplications:
                for modVal in modList:
                    result *= modVal
        # If attribute has upper cap, do not let
        # its value to grow above it
        if attrMeta.maxAttributeId is not None:
            try:
                maxValue = self[attrMeta.maxAttributeId]
            # If max value isn't available, don't
            # cap anything
            except KeyError:
                pass
            else:
                result = min(result, maxValue)
                # Let map know that capping attribute
                # restricts current attribute
                if self._capMap is None:
                    self._capMap = KeyedSet()
                # Fill cap map with data: capping attribute and capped attribute
                self._capMap.addData(attrMeta.maxAttributeId, attrId)
        return result