Example #1
0
def readWheelsAndGroups(xmlCtx, section):
    """Reads sections 'wheels/group' and 'wheels/wheel' for each chassis.
    :param xmlCtx: tuple(root ctx or None, path to section).
    :param section: instance of DataSection.
    :return: tuple(sequence of groups, sequence of wheels).
    """
    wheelGroups = []
    wheels = []
    defSyncAngle = section.readFloat('wheels/leadingWheelSyncAngle', 60)
    for sname, subsection in _xml.getChildren(xmlCtx, section, 'wheels'):
        if sname == 'group':
            ctx = (xmlCtx, 'wheels/group')
            group = chassis_components.WheelGroup(
                isLeft=_xml.readBool(ctx, subsection, 'isLeft'),
                template=_xml.readNonEmptyString(ctx, subsection, 'template'),
                count=_xml.readInt(ctx, subsection, 'count', 1),
                startIndex=subsection.readInt('startIndex', 0),
                radius=_xml.readPositiveFloat(ctx, subsection, 'radius'))
            wheelGroups.append(group)
        elif sname == 'wheel':
            ctx = (xmlCtx, 'wheels/wheel')
            w = chassis_components.Wheel(
                isLeft=_xml.readBool(ctx, subsection, 'isLeft'),
                radius=_xml.readPositiveFloat(ctx, subsection, 'radius'),
                nodeName=_xml.readNonEmptyString(ctx, subsection, 'name'),
                isLeading=subsection.readBool('isLeading', False),
                leadingSyncAngle=subsection.readFloat('syncAngle',
                                                      defSyncAngle))
            wheels.append(w)

    return (tuple(wheelGroups), tuple(wheels))
Example #2
0
def _readProjectionDecalSlot(ctx, subsection, slotType):
    descr = shared_components.ProjectionDecalSlotDescription(
        slotType=slotType,
        slotId=_xml.readInt(ctx, subsection, 'slotId'),
        position=_xml.readVector3OrNone(ctx, subsection, 'position'),
        rotation=_xml.readVector3OrNone(ctx, subsection, 'rotation'),
        scale=_xml.readVector3OrNone(ctx, subsection, 'scale'),
        scaleFactors=_xml.readVector3(
            ctx, subsection, 'scaleFactors',
            c11n_constants.DEFAULT_DECAL_SCALE_FACTORS),
        doubleSided=_xml.readBool(ctx, subsection, 'doubleSided', False),
        hiddenForUser=_xml.readBool(ctx, subsection, 'hiddenForUser', False),
        canBeMirroredVertically=_xml.readBool(ctx, subsection,
                                              'verticalMirror', False),
        showOn=_xml.readIntOrNone(ctx, subsection, 'showOn'),
        tags=readOrderedTagsOrEmpty(ctx, subsection,
                                    _customizationSlotTagsValidator),
        clipAngle=_xml.readFloat(ctx, subsection, 'clipAngle',
                                 c11n_constants.DEFAULT_DECAL_CLIP_ANGLE),
        anchorShift=_xml.readFloat(ctx, subsection, 'anchorShift',
                                   c11n_constants.DEFAULT_DECAL_ANCHOR_SHIFT))
    _verifySlotId(ctx, slotType, descr.slotId)
    _verifyMatchingSlotSettings(ctx, descr)
    if descr.showOn is not None:
        availableShowOnRegions = c11n_constants.ApplyArea.HULL | c11n_constants.ApplyArea.TURRET | c11n_constants.ApplyArea.GUN
        if descr.showOn | availableShowOnRegions != availableShowOnRegions:
            _xml.raiseWrongSection(ctx, 'showOn')
    if subsection.has_key('compatibleModels'):
        descr.compatibleModels = _xml.readTupleOfStrings(
            ctx, subsection, 'compatibleModels')
    if subsection.has_key('itemId'):
        descr.itemId = _xml.readInt(ctx, subsection, 'itemId')
    if subsection.has_key('options'):
        descr.options = _xml.readNonNegativeInt(ctx, subsection, 'options')
    return descr
Example #3
0
def readGroundNodesAndGroups(xmlCtx, section):
    """Reads section 'groundNodes' for each chassis if it has.
    :param xmlCtx: tuple(root ctx or None, path to section).
    :param section: instance of DataSection.
    :return: tuple(sequence of groups, sequence of nodes).
    """
    if section['groundNodes'] is None:
        return (component_constants.EMPTY_TUPLE,
                component_constants.EMPTY_TUPLE)
    else:
        groundGroups = []
        groundNodes = []
        for sname, subsection in _xml.getChildren(xmlCtx, section,
                                                  'groundNodes'):
            if sname == 'group':
                ctx = (xmlCtx, 'groundNodes/group')
                group = chassis_components.GroundNodeGroup(
                    isLeft=_xml.readBool(ctx, subsection, 'isLeft'),
                    minOffset=_xml.readFloat(ctx, subsection, 'minOffset'),
                    maxOffset=_xml.readFloat(ctx, subsection, 'maxOffset'),
                    template=_xml.readNonEmptyString(ctx, subsection,
                                                     'template'),
                    count=_xml.readInt(ctx, subsection, 'count', 1),
                    startIndex=subsection.readInt('startIndex', 0))
                groundGroups.append(group)
            elif sname == 'node':
                ctx = (xmlCtx, 'groundNodes/node')
                groundNode = chassis_components.GroundNode(
                    name=_xml.readNonEmptyString(ctx, subsection, 'name'),
                    isLeft=_xml.readBool(ctx, subsection, 'isLeft'),
                    minOffset=_xml.readFloat(ctx, subsection, 'minOffset'),
                    maxOffset=_xml.readFloat(ctx, subsection, 'maxOffset'))
                groundNodes.append(groundNode)

        return (tuple(groundGroups), tuple(groundNodes))
Example #4
0
def readWheelsAndGroups(xmlCtx, section):
    wheelGroups = []
    wheels = []
    wheelId = 0
    defSyncAngle = section.readFloat('wheels/leadingWheelSyncAngle', 60)
    for sname, subsection in _xml.getChildren(xmlCtx, section, 'wheels'):
        if sname == 'group':
            ctx = (xmlCtx, 'wheels/group')
            group = chassis_components.WheelGroup(isLeft=_xml.readBool(ctx, subsection, 'isLeft'), template=intern(_xml.readNonEmptyString(ctx, subsection, 'template')), count=_xml.readInt(ctx, subsection, 'count', 1), startIndex=subsection.readInt('startIndex', 0), radius=_xml.readPositiveFloat(ctx, subsection, 'radius'))
            wheelGroups.append(group)
        if sname == 'wheel':
            from items.vehicles import _readHitTester, _readArmor
            ctx = (xmlCtx, 'wheels/wheel[{}]'.format(wheelId))
            radiusKey = 'radius' if subsection.has_key('radius') else 'geometry/radius'
            index = _xml.readIntOrNone(ctx, subsection, 'index')
            actualIndex = wheelId if index is None else index
            w = chassis_components.Wheel(index=index, isLeft=_xml.readBool(ctx, subsection, 'isLeft'), radius=_xml.readPositiveFloat(ctx, subsection, radiusKey), nodeName=intern(_xml.readNonEmptyString(ctx, subsection, 'name')), isLeading=subsection.readBool('isLeading', False), leadingSyncAngle=subsection.readFloat('syncAngle', defSyncAngle), hitTesterManager=_readHitTester(ctx, subsection, 'hitTester', optional=True), materials=_readArmor(ctx, subsection, 'armor', optional=True, index=actualIndex), position=subsection.readVector3('wheelPos', (0, 0, 0)))
            if IS_EDITOR:
                w.editorData.defSyncAngle = defSyncAngle
            wheels.append(w)
            wheelId += 1

    wheelIndices = [ wheel.index for wheel in wheels ]
    if sorted(wheelIndices) == range(len(wheels)):
        sortedWheels = [None] * len(wheels)
        for wheel in wheels:
            sortedWheels[wheel.index] = wheel

        wheels = sortedWheels
    elif wheelIndices == [None] * len(wheels):
        pass
    else:
        LOG_ERROR('Invalid wheel index detected', xmlCtx, wheels)
    return (tuple(wheelGroups), tuple(wheels))
Example #5
0
def readGroundNodesAndGroups(xmlCtx, section, cache):
    if section['groundNodes'] is None:
        return (component_constants.EMPTY_TUPLE,
         component_constants.EMPTY_TUPLE,
         False,
         None)
    else:
        groundGroups = []
        groundNodes = []
        for sname, subsection in _xml.getChildren(xmlCtx, section, 'groundNodes'):
            if sname == 'group':
                ctx = (xmlCtx, 'groundNodes/group')
                group = chassis_components.GroundNodeGroup(isLeft=_xml.readBool(ctx, subsection, 'isLeft'), minOffset=_xml.readFloat(ctx, subsection, 'minOffset'), maxOffset=_xml.readFloat(ctx, subsection, 'maxOffset'), nodesTemplate=intern(_xml.readNonEmptyString(ctx, subsection, 'template')), affectedWheelsTemplate=_xml.readStringOrNone(ctx, subsection, 'affectedWheelsTemplate'), nodesCount=_xml.readInt(ctx, subsection, 'count', 1), startIndex=subsection.readInt('startIndex', 0), collisionSamplesCount=subsection.readInt('collisionSamplesCount', 1), hasLiftMode=_xml.readBool(ctx, subsection, 'hasLiftMode', False))
                groundGroups.append(group)
            if sname == 'node':
                ctx = (xmlCtx, 'groundNodes/node')
                groundNode = chassis_components.GroundNode(nodeName=intern(_xml.readNonEmptyString(ctx, subsection, 'name')), affectedWheelName=_xml.readStringOrEmpty(ctx, subsection, 'affectedWheelName'), isLeft=_xml.readBool(ctx, subsection, 'isLeft'), minOffset=_xml.readFloat(ctx, subsection, 'minOffset'), maxOffset=_xml.readFloat(ctx, subsection, 'maxOffset'), collisionSamplesCount=_xml.readInt(ctx, subsection, 'collisionSamplesCount', 1), hasLiftMode=_xml.readBool(ctx, subsection, 'hasLiftMode', False))
                groundNodes.append(groundNode)

        activePostmortem = _xml.readBool(xmlCtx, section, 'groundNodes/activePostmortem', False)
        lodSettingsSection = section['groundNodes/lodSettings']
        if lodSettingsSection is not None:
            lodSettings = shared_readers.readLodSettings(xmlCtx, section['groundNodes'], cache)
        else:
            lodSettings = None
        return (tuple(groundGroups),
         tuple(groundNodes),
         activePostmortem,
         lodSettings)
Example #6
0
def readWheelsAndGroups(xmlCtx, section):
    wheelGroups = []
    wheels = []
    defSyncAngle = section.readFloat('wheels/leadingWheelSyncAngle', 60)
    for sname, subsection in _xml.getChildren(xmlCtx, section, 'wheels'):
        if sname == 'group':
            ctx = (xmlCtx, 'wheels/group')
            group = chassis_components.WheelGroup(
                isLeft=_xml.readBool(ctx, subsection, 'isLeft'),
                template=intern(
                    _xml.readNonEmptyString(ctx, subsection, 'template')),
                count=_xml.readInt(ctx, subsection, 'count', 1),
                startIndex=subsection.readInt('startIndex', 0),
                radius=_xml.readPositiveFloat(ctx, subsection, 'radius'))
            wheelGroups.append(group)
        if sname == 'wheel':
            ctx = (xmlCtx, 'wheels/wheel')
            w = chassis_components.Wheel(
                isLeft=_xml.readBool(ctx, subsection, 'isLeft'),
                radius=_xml.readPositiveFloat(ctx, subsection, 'radius'),
                nodeName=intern(
                    _xml.readNonEmptyString(ctx, subsection, 'name')),
                isLeading=subsection.readBool('isLeading', False),
                leadingSyncAngle=subsection.readFloat('syncAngle',
                                                      defSyncAngle))
            wheels.append(w)

    return (tuple(wheelGroups), tuple(wheels))
Example #7
0
def readGroundNodesAndGroups(xmlCtx, section):
    if section['groundNodes'] is None:
        return (component_constants.EMPTY_TUPLE,
                component_constants.EMPTY_TUPLE)
    else:
        groundGroups = []
        groundNodes = []
        for sname, subsection in _xml.getChildren(xmlCtx, section,
                                                  'groundNodes'):
            if sname == 'group':
                ctx = (xmlCtx, 'groundNodes/group')
                group = chassis_components.GroundNodeGroup(
                    isLeft=_xml.readBool(ctx, subsection, 'isLeft'),
                    minOffset=_xml.readFloat(ctx, subsection, 'minOffset'),
                    maxOffset=_xml.readFloat(ctx, subsection, 'maxOffset'),
                    template=intern(
                        _xml.readNonEmptyString(ctx, subsection, 'template')),
                    count=_xml.readInt(ctx, subsection, 'count', 1),
                    startIndex=subsection.readInt('startIndex', 0))
                groundGroups.append(group)
            if sname == 'node':
                ctx = (xmlCtx, 'groundNodes/node')
                groundNode = chassis_components.GroundNode(
                    name=intern(
                        _xml.readNonEmptyString(ctx, subsection, 'name')),
                    isLeft=_xml.readBool(ctx, subsection, 'isLeft'),
                    minOffset=_xml.readFloat(ctx, subsection, 'minOffset'),
                    maxOffset=_xml.readFloat(ctx, subsection, 'maxOffset'))
                groundNodes.append(groundNode)

        return (tuple(groundGroups), tuple(groundNodes))
def readTrackSplineParams(xmlCtx, section):
    trackSplineParams = None
    if IS_EDITOR:
        if not section.has_key('trackThickness'):
            return
    if section['trackNodes'] is not None:
        ctx = (xmlCtx, 'trackNodes')
        trackSplineParams = chassis_components.TrackSplineParams(
            thickness=_xml.readFloat(ctx, section, 'trackThickness'),
            maxAmplitude=_xml.readFloat(ctx, section,
                                        'trackNodes/maxAmplitude'),
            maxOffset=_xml.readFloat(ctx, section, 'trackNodes/maxOffset'),
            gravity=_xml.readFloat(ctx, section, 'trackNodes/gravity'))
        if IS_EDITOR:
            trackSplineParams.editorData._enable = _xml.readBool(
                ctx, section, 'trackNodes/enable', True)
            trackSplineParams.editorData.elasticity = _xml.readFloat(
                ctx, section, 'trackNodes/elasticity', 1500.0)
            trackSplineParams.editorData.linkBones = _xml.readBool(
                ctx, section, 'trackNodes/linkBones', False)
    elif section['splineDesc'] is not None or section[
            'physicalTracks'] is not None:
        trackSplineParams = chassis_components.TrackSplineParams(
            thickness=_xml.readFloat(xmlCtx, section, 'trackThickness'),
            maxAmplitude=component_constants.ZERO_FLOAT,
            maxOffset=component_constants.ZERO_FLOAT,
            gravity=component_constants.ZERO_FLOAT)
    return trackSplineParams
Example #9
0
 def _readConfig(self, xmlCtx, section):
     self.delay = _xml.readPositiveFloat(xmlCtx, section, 'delay')
     self.modelName = _xml.readString(xmlCtx, section, 'modelName')
     if IS_CLIENT:
         self.soundEvent = _xml.readString(xmlCtx, section, 'wwsoundEvent')
     self.speed = _xml.readInt(xmlCtx, section, 'speed')
     self.heights = _xml.readTupleOfPositiveInts(xmlCtx, section, 'heights', 2)
     self.areaLength = _xml.readPositiveFloat(xmlCtx, section, 'areaLength')
     self.areaWidth = _xml.readPositiveFloat(xmlCtx, section, 'areaWidth')
     self.antepositions = _xml.readTupleOfFloats(xmlCtx, section, 'antepositions')
     self.lateropositions = _xml.readTupleOfFloats(xmlCtx, section, 'lateropositions')
     self.bombingMask = tuple((bool(v) for v in _xml.readTupleOfInts(xmlCtx, section, 'bombingMask')))
     if not len(self.antepositions) == len(self.lateropositions) == len(self.bombingMask):
         _xml.raiseWrongSection(xmlCtx, 'bombers number mismatch')
     self.waveFraction = _xml.readPositiveFloat(xmlCtx, section, 'waveFraction')
     self.bombsNumber = _xml.readNonNegativeInt(xmlCtx, section, 'bombsNumber')
     self.shellCompactDescr = _xml.readInt(xmlCtx, section, 'shellCompactDescr')
     self.tracerKind = _xml.readInt(xmlCtx, section, 'tracerKind')
     self.piercingPower = _xml.readTupleOfPositiveInts(xmlCtx, section, 'piercingPower', 2)
     self.gravity = _xml.readPositiveFloat(xmlCtx, section, 'gravity')
     self.areaVisual = _xml.readStringOrNone(xmlCtx, section, 'areaVisual')
     self.areaColor = _xml.readIntOrNone(xmlCtx, section, 'areaColor')
     self.areaMarker = _xml.readStringOrNone(xmlCtx, section, 'areaMarker')
     self.reusable = _xml.readBool(xmlCtx, section, 'reusable')
     self.cooldownTime = _xml.readNonNegativeFloat(xmlCtx, section, 'cooldownTime') if self.reusable else 0.0
     self.deployTime = _xml.readNonNegativeFloat(xmlCtx, section, 'deployTime')
Example #10
0
def _readHintSection(xmlCtx, section, flags):
    hintID = sub_parsers.parseID(xmlCtx, section, 'Specify a hint ID')
    if 'item-id' in section.keys():
        itemID = sub_parsers.parseID(xmlCtx, section['item-id'],
                                     'Specify a item ID')
    else:
        _xml.raiseWrongXml(xmlCtx, section.name, 'Specify a item ID')
        return
    tags = section.keys()
    text = translation(_xml.readString(xmlCtx, section, 'text'))
    if 'arrow' in tags:
        subSec = section['arrow']
        direction = _xml.readString(xmlCtx, subSec, 'direction')
        if direction not in _AVAILABLE_DIRECTIONS:
            _xml.raiseWrongXml(
                xmlCtx, section,
                'Arrow direction {} is invalid.'.format(direction))
        arrow = _ArrowProps(direction, _xml.readBool(xmlCtx, subSec, 'loop'))
    else:
        arrow = None
    if 'padding' in tags:
        subSec = section['padding']
        padding = _Padding(_xml.readFloat(xmlCtx, subSec, 'left'),
                           _xml.readFloat(xmlCtx, subSec, 'top'),
                           _xml.readFloat(xmlCtx, subSec, 'right'),
                           _xml.readFloat(xmlCtx, subSec, 'bottom'))
    else:
        padding = None
    hint = chapter.ChainHint(hintID, itemID, text,
                             section.readBool('has-box', True), arrow, padding)
    hint.setActions(
        sub_parsers.parseActions(
            xmlCtx, _xml.getSubsection(xmlCtx, section, 'actions'), flags))
    return hint
Example #11
0
def parseHint(xmlCtx, section):
    sectionInfo = dict()
    sectionInfo['hintID'] = parseID(xmlCtx, section, 'Specify a hint ID')
    if 'item-id' in section.keys():
        sectionInfo['itemID'] = parseID(xmlCtx, section['item-id'], 'Specify a item ID')
    else:
        _xml.raiseWrongXml(xmlCtx, section.name, 'Specify a item ID')
        return
    tags = section.keys()
    sectionInfo['text'] = translation(_xml.readString(xmlCtx, section, 'text'))
    if 'arrow' in tags:
        subSec = section['arrow']
        direction = _xml.readString(xmlCtx, subSec, 'direction')
        if direction not in _AVAILABLE_DIRECTIONS:
            _xml.raiseWrongXml(xmlCtx, section, 'Arrow direction {} is invalid.'.format(direction))
        positionValue = _xml.readFloat(xmlCtx, subSec, 'position-value', 0.5)
        textPadding = _xml.readFloat(xmlCtx, subSec, 'text-padding', 0)
        sectionInfo['arrow'] = _ArrowProps(direction, _xml.readBool(xmlCtx, subSec, 'loop'), positionValue, textPadding)
    else:
        sectionInfo['arrow'] = None
    if 'padding' in tags:
        subSec = section['padding']
        sectionInfo['padding'] = _Padding(_xml.readFloat(xmlCtx, subSec, 'left'), _xml.readFloat(xmlCtx, subSec, 'top'), _xml.readFloat(xmlCtx, subSec, 'right'), _xml.readFloat(xmlCtx, subSec, 'bottom'))
    else:
        sectionInfo['padding'] = None
    sectionInfo['hasBox'] = section.readBool('has-box', True)
    sectionInfo['conditions'] = _parseConditions(xmlCtx, section, [])
    sectionInfo['checked-ui-state'] = _parseNeededState(xmlCtx, section)
    sectionInfo['equalActions'] = section.readBool('equal-actions', False)
    sectionInfo['ignoreOutsideClick'] = section.readBool('ignore-outside-click', False)
    sectionInfo['updateRuntime'] = section.readBool('update-runtime', False)
    sectionInfo['hideImmediately'] = section.readBool('hide-immediately', False)
    sectionInfo['checkViewArea'] = section.readBool('check-view-area', False)
    return sectionInfo
Example #12
0
 def _readClientOnlyFromXml(self, target, xmlCtx, section):
     super(DecalXmlReader,
           self)._readClientOnlyFromXml(target, xmlCtx, section)
     if section.has_key('texture'):
         target.texture = section.readString('texture')
     if section.has_key('mirror'):
         target.isMirrored = ix.readBool(xmlCtx, section, 'mirror')
Example #13
0
 def _readConfig(self, xmlCtx, section):
     self.delay = _xml.readPositiveFloat(xmlCtx, section, 'delay')
     self.modelName = _xml.readString(xmlCtx, section, 'modelName')
     self.soundEvent = _xml.readString(xmlCtx, section, 'soundEvent')
     self.speed = _xml.readInt(xmlCtx, section, 'speed')
     self.heights = _xml.readTupleOfPositiveInts(xmlCtx, section, 'heights', 2)
     self.areaLength = _xml.readPositiveFloat(xmlCtx, section, 'areaLength')
     self.areaWidth = _xml.readPositiveFloat(xmlCtx, section, 'areaWidth')
     self.antepositions = _xml.readTupleOfFloats(xmlCtx, section, 'antepositions')
     self.lateropositions = _xml.readTupleOfFloats(xmlCtx, section, 'lateropositions')
     self.bombingMask = tuple((bool(v) for v in _xml.readTupleOfInts(xmlCtx, section, 'bombingMask')))
     if not len(self.antepositions) == len(self.lateropositions) == len(self.bombingMask):
         _xml.raiseWrongSection(xmlCtx, 'bombers number mismatch')
     self.waveFraction = _xml.readPositiveFloat(xmlCtx, section, 'waveFraction')
     self.bombsNumber = _xml.readNonNegativeInt(xmlCtx, section, 'bombsNumber')
     self.shellCompactDescr = _xml.readInt(xmlCtx, section, 'shellCompactDescr')
     self.tracerKind = _xml.readInt(xmlCtx, section, 'tracerKind')
     self.piercingPower = _xml.readTupleOfPositiveInts(xmlCtx, section, 'piercingPower', 2)
     self.gravity = _xml.readPositiveFloat(xmlCtx, section, 'gravity')
     self.areaVisual = _xml.readStringOrNone(xmlCtx, section, 'areaVisual')
     self.areaColor = _xml.readIntOrNone(xmlCtx, section, 'areaColor')
     self.areaMarker = _xml.readStringOrNone(xmlCtx, section, 'areaMarker')
     self.reusable = _xml.readBool(xmlCtx, section, 'reusable')
     self.cooldownTime = _xml.readNonNegativeFloat(xmlCtx, section, 'cooldownTime') if self.reusable else 0.0
     self.deployTime = _xml.readNonNegativeFloat(xmlCtx, section, 'deployTime')
Example #14
0
def parseHint(xmlCtx, section):
    sectionInfo = dict()
    sectionInfo['hintID'] = parseID(xmlCtx, section, 'Specify a hint ID')
    if 'item-id' in section.keys():
        sectionInfo['itemID'] = parseID(xmlCtx, section['item-id'], 'Specify a item ID')
    else:
        _xml.raiseWrongXml(xmlCtx, section.name, 'Specify a item ID')
        return
    tags = section.keys()
    sectionInfo['text'] = translation(_xml.readString(xmlCtx, section, 'text'))
    if 'arrow' in tags:
        subSec = section['arrow']
        direction = _xml.readString(xmlCtx, subSec, 'direction')
        if direction not in _AVAILABLE_DIRECTIONS:
            _xml.raiseWrongXml(xmlCtx, section, 'Arrow direction {} is invalid.'.format(direction))
        sectionInfo['arrow'] = _ArrowProps(direction, _xml.readBool(xmlCtx, subSec, 'loop'))
    else:
        sectionInfo['arrow'] = None
    if 'padding' in tags:
        subSec = section['padding']
        sectionInfo['padding'] = _Padding(_xml.readFloat(xmlCtx, subSec, 'left'), _xml.readFloat(xmlCtx, subSec, 'top'), _xml.readFloat(xmlCtx, subSec, 'right'), _xml.readFloat(xmlCtx, subSec, 'bottom'))
    else:
        sectionInfo['padding'] = None
    sectionInfo['hasBox'] = section.readBool('has-box', True)
    return sectionInfo
Example #15
0
def parseHint(xmlCtx, section):
    sectionInfo = dict()
    sectionInfo['hintID'] = parseID(xmlCtx, section, 'Specify a hint ID')
    if 'item-id' in section.keys():
        sectionInfo['itemID'] = parseID(xmlCtx, section['item-id'], 'Specify a item ID')
    else:
        _xml.raiseWrongXml(xmlCtx, section.name, 'Specify a item ID')
        return
    tags = section.keys()
    sectionInfo['text'] = translation(_xml.readString(xmlCtx, section, 'text'))
    if 'arrow' in tags:
        subSec = section['arrow']
        direction = _xml.readString(xmlCtx, subSec, 'direction')
        if direction not in _AVAILABLE_DIRECTIONS:
            _xml.raiseWrongXml(xmlCtx, section, 'Arrow direction {} is invalid.'.format(direction))
        sectionInfo['arrow'] = _ArrowProps(direction, _xml.readBool(xmlCtx, subSec, 'loop'))
    else:
        sectionInfo['arrow'] = None
    if 'padding' in tags:
        subSec = section['padding']
        sectionInfo['padding'] = _Padding(_xml.readFloat(xmlCtx, subSec, 'left'), _xml.readFloat(xmlCtx, subSec, 'top'), _xml.readFloat(xmlCtx, subSec, 'right'), _xml.readFloat(xmlCtx, subSec, 'bottom'))
    else:
        sectionInfo['padding'] = None
    sectionInfo['hasBox'] = section.readBool('has-box', True)
    return sectionInfo
def readDeviceHealthParams(xmlCtx,
                           section,
                           subsectionName='',
                           withHysteresis=True):
    if subsectionName:
        section = _xml.getSubsection(xmlCtx, section, subsectionName)
        xmlCtx = (xmlCtx, subsectionName)
    component = shared_components.DeviceHealth(
        _xml.readInt(xmlCtx, section, 'maxHealth', 1),
        _xml.readNonNegativeFloat(xmlCtx, section, 'repairCost'),
        _xml.readInt(xmlCtx, section, 'maxRegenHealth', 0))
    if component.maxRegenHealth > component.maxHealth:
        _xml.raiseWrongSection(xmlCtx, 'maxRegenHealth')
    if not IS_CLIENT and not IS_BOT:
        component.healthRegenPerSec = _xml.readNonNegativeFloat(
            xmlCtx, section, 'healthRegenPerSec')
        component.healthBurnPerSec = _xml.readNonNegativeFloat(
            xmlCtx, section, 'healthBurnPerSec')
        if section.has_key('chanceToHit'):
            component.chanceToHit = _xml.readFraction(xmlCtx, section,
                                                      'chanceToHit')
        else:
            component.chanceToHit = None
        if withHysteresis:
            hysteresisHealth = _xml.readInt(xmlCtx, section,
                                            'hysteresisHealth', 0)
            if hysteresisHealth > component.maxRegenHealth:
                _xml.raiseWrongSection(xmlCtx, 'hysteresisHealth')
            component.hysteresisHealth = hysteresisHealth
        component.invulnerable = _xml.readBool(xmlCtx, section, 'invulnerable',
                                               False)
    return component
Example #17
0
def _readHintSection(xmlCtx, section, flags):
    hintID = sub_parsers.parseID(xmlCtx, section, 'Specify a hint ID')
    if 'item-id' in section.keys():
        itemID = sub_parsers.parseID(xmlCtx, section['item-id'], 'Specify a item ID')
    else:
        _xml.raiseWrongXml(xmlCtx, section.name, 'Specify a item ID')
        return
    tags = section.keys()
    text = translation(_xml.readString(xmlCtx, section, 'text'))
    if 'arrow' in tags:
        subSec = section['arrow']
        direction = _xml.readString(xmlCtx, subSec, 'direction')
        if direction not in _AVAILABLE_DIRECTIONS:
            _xml.raiseWrongXml(xmlCtx, section, 'Arrow direction {} is invalid.'.format(direction))
        arrow = _ArrowProps(direction, _xml.readBool(xmlCtx, subSec, 'loop'))
    else:
        arrow = None
    if 'padding' in tags:
        subSec = section['padding']
        padding = _Padding(_xml.readFloat(xmlCtx, subSec, 'left'), _xml.readFloat(xmlCtx, subSec, 'top'), _xml.readFloat(xmlCtx, subSec, 'right'), _xml.readFloat(xmlCtx, subSec, 'bottom'))
    else:
        padding = None
    hint = chapter.ChainHint(hintID, itemID, text, section.readBool('has-box', True), arrow, padding)
    hint.setActions(sub_parsers.parseActions(xmlCtx, _xml.getSubsection(xmlCtx, section, 'actions'), flags))
    return hint
Example #18
0
def _readPlayAnimationEffectSection(xmlCtx, section, _, conditions):
    itemID = parseID(xmlCtx, section, 'Specify an item ID')
    animType = _xml.readString(xmlCtx, section, 'type')
    waitForFinish = _xml.readBool(xmlCtx, section, 'wait_for_finish')
    return effects.PlayAnimationEffect(itemID,
                                       animType,
                                       waitForFinish,
                                       conditions=conditions)
 def _readClientOnlyFromXml(self, target, xmlCtx, section, cache=None):
     super(AttachmentXmlReader,
           self)._readClientOnlyFromXml(target, xmlCtx, section)
     target.modelName = ix.readStringOrNone(xmlCtx, section, 'modelName')
     target.sequenceId = ix.readIntOrNone(xmlCtx, section, 'sequenceId')
     target.attachmentLogic = ix.readStringOrNone(xmlCtx, section,
                                                  'attachmentLogic')
     target.initialVisibility = ix.readBool(xmlCtx, section,
                                            'initialVisibility', True)
Example #20
0
def _readGuiItemCriteria(xmlCtx, section, _):
    criteriaID = parseID(xmlCtx, section, 'Specify a criteria ID')
    itemID = None
    if 'item-id' in section.keys():
        itemID = parseID(xmlCtx, section['item-id'], 'Specify a item ID')
    else:
        _xml.raiseWrongXml(xmlCtx, section.name, 'Specify a item ID')
    return chapter.GuiItemCriteria(criteriaID, itemID,
                                   _xml.readString(xmlCtx, section, 'value'),
                                   _xml.readBool(xmlCtx, section, 'cached'))
def _readProjectionDecalSlot(ctx, subsection, slotType):
    descr = shared_components.ProjectionDecalSlotDescription(
        slotType=slotType,
        slotId=_xml.readInt(ctx, subsection, 'slotId'),
        anchorPosition=_xml.readVector3OrNone(ctx, subsection,
                                              'anchorPosition'),
        anchorDirection=_xml.readVector3OrNone(ctx, subsection,
                                               'anchorDirection'),
        position=_xml.readVector3OrNone(ctx, subsection, 'position'),
        rotation=_xml.readVector3OrNone(ctx, subsection, 'rotation'),
        scale=_xml.readVector3OrNone(ctx, subsection, 'scale'),
        scaleFactors=_xml.readVector3(
            ctx, subsection, 'scaleFactors',
            c11n_constants.DEFAULT_DECAL_SCALE_FACTORS),
        doubleSided=_xml.readBool(ctx, subsection, 'doubleSided', False),
        canBeMirroredVertically=_xml.readBool(ctx, subsection,
                                              'verticalMirror', False),
        showOn=_xml.readIntOrNone(ctx, subsection, 'showOn'),
        tags=readOrderedTagsOrEmpty(ctx, subsection,
                                    _customizationSlotTagsValidator),
        clipAngle=_xml.readFloat(ctx, subsection, 'clipAngle',
                                 c11n_constants.DEFAULT_DECAL_CLIP_ANGLE))
    _verifySlotId(ctx, slotType, descr.slotId)
    if descr.showOn is not None:
        availableShowOnRegions = c11n_constants.ApplyArea.HULL | c11n_constants.ApplyArea.TURRET | c11n_constants.ApplyArea.GUN
        if descr.showOn | availableShowOnRegions != availableShowOnRegions:
            _xml.raiseWrongSection(ctx, 'showOn')
    if subsection.has_key('attachedPart'):
        attachedPartsData = _xml.readString(ctx, subsection, 'attachedPart')
        descr.attachedParts = defaultdict(set)
        for partData in attachedPartsData.split():
            pType, pName = partData.split(':')
            if pType != 'hull':
                descr.attachedParts[pType].add(pName)

    if subsection.has_key('compatibleModels'):
        descr.compatibleModels = _xml.readTupleOfStrings(
            ctx, subsection, 'compatibleModels')
    if subsection.has_key('itemId'):
        descr.itemId = _xml.readInt(ctx, subsection, 'itemId')
    if subsection.has_key('options'):
        descr.options = _xml.readNonNegativeInt(ctx, subsection, 'options')
    return descr
def _readPerkItem(xmlCtx, section, storage):
    perkID = _xml.readInt(xmlCtx, section, 'id', 1)
    name = _xml.readStringOrEmpty(xmlCtx, section, 'name')
    description = _xml.readNonEmptyString(xmlCtx, section, 'description')
    icon = _xml.readNonEmptyString(xmlCtx, section, 'icon')
    branchID = _xml.readInt(xmlCtx, section, 'branchID', 0)
    ultimative = section.readBool('ultimative', False)
    maxCount = _xml.readInt(xmlCtx, section, 'maxCount', 1)
    situational = _xml.readBool(xmlCtx, section, 'situational', False)
    perkItem = Perk(perkID, name, description, icon, branchID, ultimative, maxCount, situational)
    storage[perkID] = perkItem
Example #23
0
def _readStateComponent(xmlCtx, section):
    destructible = _xml.readBool(xmlCtx, section, 'destructible')
    physicsModel = _xml.readString(xmlCtx, section, 'physics_model')
    component = DestructibleEntityStateComponent(destructible, physicsModel)
    if IS_CLIENT:
        visualModel = _xml.readString(xmlCtx, section, 'visual_model')
        guiNodeName = section.readString('gui_node', '')
        if guiNodeName == '':
            guiNodeName = None
        component.setClientProperties(guiNodeName, visualModel)
    return (_xml.readString(xmlCtx, section, 'id'), component)
def readSoundSiegeModeStateChange(xmlCtx, section):
    pcOn = _xml.readStringOrEmpty(xmlCtx, section, 'soundStateChange/on')
    pcOff = _xml.readStringOrEmpty(xmlCtx, section, 'soundStateChange/off')
    npcOn = _xml.readStringOrEmpty(xmlCtx, section, 'soundStateChange/npcOn')
    npcOff = _xml.readStringOrEmpty(xmlCtx, section, 'soundStateChange/npcOff')
    return sound_components.SoundSiegeModeStateChange(
        on=pcOn,
        off=pcOff,
        npcOn=npcOn,
        npcOff=npcOff,
        isEngine=_xml.readBool(xmlCtx, section, 'soundStateChange/isEngine',
                               False))
def readTraces(xmlCtx, section, centerOffset, cache):
    return chassis_components.Traces(
        lodDist=shared_readers.readLodDist(xmlCtx, section, 'traces/lodDist',
                                           cache),
        bufferPrefs=intern(
            _xml.readNonEmptyString(xmlCtx, section, 'traces/bufferPrefs')),
        textureSet=intern(
            _xml.readNonEmptyString(xmlCtx, section, 'traces/textureSet')),
        centerOffset=centerOffset,
        size=_xml.readPositiveVector2(xmlCtx, section, 'traces/size'),
        activePostmortem=_xml.readBool(xmlCtx, section,
                                       'traces/activePostmortem', False))
def readLeveredSuspension(xmlCtx, section, cache):
    leveredSection = section['leveredSuspension']
    if leveredSection is None:
        return
    else:
        levers = []
        for sname, subsection in _xml.getChildren(xmlCtx, section,
                                                  'leveredSuspension'):
            if sname != 'lever':
                continue
            ctx = (xmlCtx, 'leveredSuspension/lever')
            limits = _xml.readVector2(ctx, subsection, 'limits')
            lever = chassis_components.SuspensionLever(
                startNodeName=intern(
                    _xml.readNonEmptyString(ctx, subsection, 'startNode')),
                jointNodeName=intern(
                    _xml.readNonEmptyString(ctx, subsection, 'jointNode')),
                trackNodeName=intern(
                    _xml.readNonEmptyString(ctx, subsection, 'trackNode')),
                minAngle=math.radians(limits.x),
                maxAngle=math.radians(limits.y),
                collisionSamplesCount=subsection.readInt(
                    'collisionSamplesCount', 1),
                hasLiftMode=_xml.readBool(ctx, subsection, 'hasLiftMode',
                                          False),
                affectedWheelName=_xml.readStringOrEmpty(
                    ctx, subsection, 'affectedWheelName'))
            levers.append(lever)

        ctx = (xmlCtx, 'leveredSuspension')
        leveredSuspensionConfig = chassis_components.LeveredSuspensionConfig(
            levers=levers,
            interpolationSpeedMul=_xml.readFloat(ctx, leveredSection,
                                                 'interpolationSpeedMul',
                                                 10.0),
            lodSettings=shared_readers.readLodSettings(ctx, leveredSection,
                                                       cache),
            activePostmortem=_xml.readBool(ctx, leveredSection,
                                           'activePostmortem', False))
        return leveredSuspensionConfig
Example #27
0
def readTutorialSettingSection(xmlCtx, section, flags):
    settingID = sub_parsers.parseID(xmlCtx, section, 'Specify a setting ID')
    settingName = None
    if 'setting-name' in section.keys():
        settingName = _xml.readString(xmlCtx, section, 'setting-name')
    else:
        _xml.raiseWrongXml(xmlCtx, section.name, 'Specify a setting name')
    settingValue = None
    if 'setting-value' in section.keys():
        settingValue = _xml.readBool(xmlCtx, section, 'setting-value')
    else:
        _xml.raiseWrongXml(xmlCtx, section.name, 'Specify a setting value')
    return chapter.TutorialSetting(settingID, settingName, settingValue)
Example #28
0
def _readSkinItem(pricesCache, cache, xmlCtx, section, storage):
    skinID = _xml.readInt(xmlCtx, section, 'id', 1)
    if skinID in storage:
        _xml.raiseWrongXml(xmlCtx, 'id', "duplicate id '%s'" % skinID)
    priceGroup = section.readString('priceGroup')
    tags = _readGroupTags((xmlCtx, 'tags'), section, 'tags')
    firstNameID = _xml.readStringOrEmpty(xmlCtx, section, 'firstName')
    lastNameID = _xml.readNonEmptyString(xmlCtx, section, 'lastName')
    description = _xml.readNonEmptyString(xmlCtx, section, 'description')
    iconID = _xml.readNonEmptyString(xmlCtx, section, 'icon')
    rarity = _xml.readInt(xmlCtx, section, 'rarity', 1)
    maxCount = _xml.readInt(xmlCtx, section, 'maxCount')
    soundSetID = section.readString('soundSet', crew_skins_constants.NO_CREW_SKIN_SOUND_SET)
    historical = _xml.readBool(xmlCtx, section, 'historical', False)
    realmsStr = section.readString('realms', '')
    realms = realmsStr.split()
    unexpectedRealms = set(realms) - REGIONAL_REALMS
    if unexpectedRealms:
        _xml.raiseWrongXml(xmlCtx, 'realms', "unknown realms '%s'" % unexpectedRealms)
    crewSkinItem = cc.CrewSkin(skinID, priceGroup, firstNameID, lastNameID, iconID, description, rarity, maxCount, tags, historical, soundSetID, realms)
    if section.has_key('filters'):
        filterSection = _xml.getSubsection(xmlCtx, section, 'filters')
        if filterSection.has_key('role'):
            roleName = filterSection.readString('role')
            if roleName not in skills_constants.ROLES:
                _xml.raiseWrongXml(xmlCtx, 'role', "unknown tankmanRole '%s'" % roleName)
            crewSkinItem.roleID = roleName if roleName else None
        if filterSection.has_key('nation'):
            nation = filterSection.readString('nation', '')
            if nation and nation not in nations.NAMES:
                _xml.raiseWrongXml(xmlCtx, 'nation', "unknown nation '%s'" % nation)
            crewSkinItem.nation = nation if nation else None
        if filterSection.has_key('sex'):
            sex = filterSection.readString('sex', '')
            if sex not in crew_skins_constants.TANKMAN_SEX.AVAILABLE:
                _xml.raiseWrongXml(xmlCtx, 'sex', "unknown tankman sex '%s'" % sex)
            crewSkinItem.sex = sex
    storage[skinID] = crewSkinItem
    groupsDict = cache.priceGroups
    itemToGroup = cache.itemToPriceGroup
    if crewSkinItem.priceGroup:
        if crewSkinItem.priceGroup not in cache.priceGroupNames:
            _xml.raiseWrongXml(xmlCtx, 'priceGroup', 'unknown price group %s for item %s' % (crewSkinItem.priceGroup, crewSkinItem.id))
        priceGroupId = cache.priceGroupNames[crewSkinItem.priceGroup]
        crewSkinItem.priceGroupTags = groupsDict[priceGroupId].tags
        itemToGroup[crewSkinItem.compactDescr] = groupsDict[priceGroupId].compactDescr
        itemNotInShop = section.readBool('notInShop', False)
        _copyPriceForItem(pricesCache, groupsDict[priceGroupId].compactDescr, crewSkinItem.compactDescr, itemNotInShop)
    else:
        _xml.raiseWrongXml(xmlCtx, 'priceGroup', 'no price for item %s' % crewSkinItem.id)
    return
def __readSettings():
    ctx = (None, DYNAMIC_OBJECTS_CONFIG_FILE + '/' + AREA_VISUAL_TAG)
    settings = ResMgr.openSection(DYNAMIC_OBJECTS_CONFIG_FILE)[AREA_VISUAL_TAG]
    return InspireVisualSettings(
        modelPath=_xml.readString(ctx, settings, 'visual'),
        color=int(_xml.readString(ctx, settings, 'color'), 0),
        enableAccurateCollision=_xml.readBool(ctx, settings,
                                              'enableAccrurateCollision'),
        maxUpdateInterval=max(
            MIN_UPDATE_INTERVAL,
            _xml.readFloat(ctx, settings, 'maxUpdateInterval')),
        overTerrainHeight=max(
            MIN_OVER_TERRAIN_HEIGHT,
            _xml.readFloat(ctx, settings, 'overTerrainHeight')))
Example #30
0
 def _readConfig(self, xmlCtx, section):
     self.delay = _xml.readPositiveFloat(xmlCtx, section, 'delay')
     self.duration = _xml.readPositiveFloat(xmlCtx, section, 'duration')
     self.shotsNumber = _xml.readNonNegativeInt(xmlCtx, section, 'shotsNumber')
     self.areaRadius = _xml.readPositiveFloat(xmlCtx, section, 'areaRadius')
     self.shellCompactDescr = _xml.readInt(xmlCtx, section, 'shellCompactDescr')
     self.piercingPower = _xml.readTupleOfPositiveInts(xmlCtx, section, 'piercingPower', 2)
     self.areaVisual = _xml.readStringOrNone(xmlCtx, section, 'areaVisual')
     self.areaColor = _xml.readIntOrNone(xmlCtx, section, 'areaColor')
     self.areaMarker = _xml.readStringOrNone(xmlCtx, section, 'areaMarker')
     self.areaLength = self.areaWidth = self.areaRadius * 2
     self.reusable = _xml.readBool(xmlCtx, section, 'reusable')
     self.cooldownTime = _xml.readNonNegativeFloat(xmlCtx, section, 'cooldownTime') if self.reusable else 0.0
     self.deployTime = _xml.readNonNegativeFloat(xmlCtx, section, 'deployTime')
Example #31
0
 def _readConfig(self, xmlCtx, section):
     self.delay = _xml.readPositiveFloat(xmlCtx, section, 'delay')
     self.duration = _xml.readPositiveFloat(xmlCtx, section, 'duration')
     self.shotsNumber = _xml.readNonNegativeInt(xmlCtx, section, 'shotsNumber')
     self.areaRadius = _xml.readPositiveFloat(xmlCtx, section, 'areaRadius')
     self.shellCompactDescr = _xml.readInt(xmlCtx, section, 'shellCompactDescr')
     self.piercingPower = _xml.readTupleOfPositiveInts(xmlCtx, section, 'piercingPower', 2)
     self.areaVisual = _xml.readStringOrNone(xmlCtx, section, 'areaVisual')
     self.areaColor = _xml.readIntOrNone(xmlCtx, section, 'areaColor')
     self.areaMarker = _xml.readStringOrNone(xmlCtx, section, 'areaMarker')
     self.areaLength = self.areaWidth = self.areaRadius * 2
     self.reusable = _xml.readBool(xmlCtx, section, 'reusable')
     self.cooldownTime = _xml.readNonNegativeFloat(xmlCtx, section, 'cooldownTime') if self.reusable else 0.0
     self.deployTime = _xml.readNonNegativeFloat(xmlCtx, section, 'deployTime')
def _readMaterials(parentXmlCtx, section):
    materials = {}
    if IS_BASEAPP or IS_BOT:
        return materials
    else:
        for matName, (xmlCtx, matSection) in _xml.getItemsWithContext(
                parentXmlCtx, section):
            matKind = material_kinds.IDS_BY_NAMES.get(matName)
            if matKind is None:
                _xml.raiseWrongXml(xmlCtx, matName,
                                   'material kind name is unknown')
            if matKind in materials:
                _xml.raiseWrongXml(xmlCtx, matName, 'duplicate material kind')
            effectMaterialName = _xml.readString(xmlCtx, matSection,
                                                 'effectMaterial')
            effectMaterialIdx = EFFECT_MATERIAL_INDEXES_BY_NAMES.get(
                effectMaterialName)
            if effectMaterialIdx is None:
                _xml.raiseWrongXml(
                    xmlCtx, matName,
                    'Unknown effect material %s' % effectMaterialName)
            materials[matKind] = DestructibleMaterialInfo(
                kind=matKind,
                armor=_xml.readInt(xmlCtx, matSection, 'armor'),
                extra=None,
                vehicleDamageFactor=_xml.readFraction(xmlCtx, matSection,
                                                      'vehicleDamageFactor'),
                useHitAngle=_xml.readBool(xmlCtx, matSection, 'useHitAngle'),
                mayRicochet=_xml.readBool(xmlCtx, matSection, 'mayRicochet'),
                collideOnceOnly=True,
                checkCaliberForRichet=_xml.readBool(xmlCtx, matSection,
                                                    'checkCaliberForRichet'),
                checkCaliberForHitAngleNorm=_xml.readBool(
                    xmlCtx, matSection, 'checkCaliberForHitAngleNorm'),
                effectMaterialIdx=effectMaterialIdx)

        return materials
def readTerrainCircleSettings(xmlSection, xmlCtx, xmlTag):
    settings = xmlSection[xmlTag]
    return TerrainCircleSettings(
        modelPath=_xml.readString(xmlCtx, settings, 'visual'),
        color=int(_xml.readString(xmlCtx, settings, 'color'), 0),
        enableAccurateCollision=_xml.readBool(xmlCtx, settings,
                                              'enableAccurateCollision'),
        maxUpdateInterval=max(
            MIN_UPDATE_INTERVAL,
            _xml.readFloat(xmlCtx, settings, 'maxUpdateInterval')),
        overTerrainHeight=max(
            MIN_OVER_TERRAIN_HEIGHT,
            _xml.readFloat(xmlCtx, settings, 'overTerrainHeight')),
        cutOffYDistance=_xml.readFloat(xmlCtx, settings, 'cutOffYDistance',
                                       -1.0))
Example #34
0
 def _readFromXml(self, target, xmlCtx, section, cache=None):
     super(ProjectionDecalXmlReader,
           self)._readFromXml(target, xmlCtx, section)
     if 'mirror' in section.keys():
         target.canBeMirroredHorizontally = ix.readBool(
             xmlCtx, section, 'mirror')
     if 'onlyVerticalMirror' in target.tags:
         if target.canBeMirroredHorizontally:
             ix.raiseWrongXml(
                 xmlCtx, 'tags',
                 'mirror must be false when onlyVerticalMirror set')
         if 'disableVerticalMirror' in target.tags:
             ix.raiseWrongXml(
                 xmlCtx, 'tags',
                 'disableVerticalMirror and onlyVerticalMirror cannot be set at the same time'
             )
Example #35
0
def _readGuiItemCriteria(xmlCtx, section, _):
    criteriaID = parseID(xmlCtx, section, 'Specify a criteria ID')
    itemID = None
    if 'item-id' in section.keys():
        itemID = parseID(xmlCtx, section['item-id'], 'Specify a item ID')
    else:
        _xml.raiseWrongXml(xmlCtx, section.name, 'Specify a item ID')
    return chapter.GuiItemCriteria(criteriaID, itemID, _xml.readString(xmlCtx, section, 'value'), _xml.readBool(xmlCtx, section, 'cached'))