def __loadVehicleCompound(self, vehicleDescr): vehicleName = vehicleDescr.name layout = self.__layouts.get(vehicleName, self.__layouts['default']) if vehicleName in self.__cachedCompound: _logger.debug('Loaded vehicle compound of "%s" from cache', vehicleName) BigWorld.buildBlueprint(self.__cachedCompound[vehicleName], _BLUEPRINT_BG_TEXTURE, layout.projections) self.__inProgress = None return elif vehicleName in self.__pendingCompound: _logger.debug('Vehicle compound of "%s" is loading at the moment.', vehicleName) return else: _logger.debug('Loading vehicle compound of "%s".', vehicleName) self.__pendingCompound.add(vehicleName) resources = (ma.prepareCompoundAssembler(vehicleDescr, ModelsSetParams( '', 'undamaged', []), BigWorld.camera().spaceID, lodIdx=layout.lodIdx, skipMaterials=True), ) BigWorld.loadResourceListBG( resources, makeCallbackWeak(self.__onResourcesLoaded, vehicleName)) return
def __setupTrackAssembler(self, entity): modelNames = getPartModelsFromDesc(self.__vehicleDesc, ModelsSetParams(None, 'destroyed')) compoundAssembler = BigWorld.CompoundAssembler() compoundAssembler.addRootPart(modelNames.chassis, TankPartNames.CHASSIS, entity.filter.groundPlacingMatrix) compoundAssembler.assemblerName = TankPartNames.CHASSIS compoundAssembler.spaceID = entity.spaceID return compoundAssembler
def __startBuild(self, vDesc, vState): self.__curBuildInd += 1 self.__vState = vState self.__resources = {} self.__vehicleStickers = None cfg = hangarCFG() if vState == 'undamaged': self.__currentEmblemsAlpha = cfg['emblems_alpha_undamaged'] self.__isVehicleDestroyed = False else: self.__currentEmblemsAlpha = cfg['emblems_alpha_damaged'] self.__isVehicleDestroyed = True self.__vDesc = vDesc resources = camouflages.getCamoPrereqs(self.__outfit, vDesc) splineDesc = vDesc.chassis.splineDesc if splineDesc is not None: resources.append(splineDesc.segmentModelLeft) resources.append(splineDesc.segmentModelRight) if splineDesc.leftDesc is not None: resources.append(splineDesc.leftDesc) if splineDesc.rightDesc is not None: resources.append(splineDesc.rightDesc) if splineDesc.segment2ModelLeft is not None: resources.append(splineDesc.segment2ModelLeft) if splineDesc.segment2ModelRight is not None: resources.append(splineDesc.segment2ModelRight) from vehicle_systems import model_assembler resources.append(model_assembler.prepareCompoundAssembler(self.__vDesc, ModelsSetParams(self.__outfit.modelsSet, self.__vState), self.__spaceId)) g_eventBus.handleEvent(CameraRelatedEvents(CameraRelatedEvents.VEHICLE_LOADING, ctx={'started': True, 'vEntityId': self.__vEntity.id}), scope=EVENT_BUS_SCOPE.DEFAULT) cfg = hangarCFG() gunScale = Math.Vector3(1.0, 1.0, 1.1) capsuleScale = Math.Vector3(1.5, 1.5, 1.5) loadedGunScale = cfg.get('cam_capsule_gun_scale', gunScale) if loadedGunScale is not None: gunScale = loadedGunScale loadedCapsuleScale = cfg.get('cam_capsule_scale', capsuleScale) if loadedCapsuleScale is not None: capsuleScale = loadedCapsuleScale bspModels = ((TankPartNames.getIdx(TankPartNames.CHASSIS), vDesc.chassis.hitTester.bspModelName), (TankPartNames.getIdx(TankPartNames.HULL), vDesc.hull.hitTester.bspModelName), (TankPartNames.getIdx(TankPartNames.TURRET), vDesc.turret.hitTester.bspModelName), (TankPartNames.getIdx(TankPartNames.GUN), vDesc.gun.hitTester.bspModelName), (TankPartNames.getIdx(TankPartNames.GUN) + 1, vDesc.hull.hitTester.bspModelName, capsuleScale), (TankPartNames.getIdx(TankPartNames.GUN) + 2, vDesc.turret.hitTester.bspModelName, capsuleScale), (TankPartNames.getIdx(TankPartNames.GUN) + 3, vDesc.gun.hitTester.bspModelName, gunScale)) collisionAssembler = BigWorld.CollisionAssembler(bspModels, self.__spaceId) resources.append(collisionAssembler) physicalTracksBuilders = vDesc.chassis.physicalTracks for name, builder in physicalTracksBuilders.iteritems(): resources.append(builder.createLoader('{0}PhysicalTrack'.format(name))) BigWorld.loadResourceListBG(tuple(resources), makeCallbackWeak(self.__onResourcesLoaded, self.__curBuildInd)) return
def __getModels(self): outfit = prepareBattleOutfit(self.outfitCD, self.__vehDescr, self.vehicleID) style = outfit.style if style is None: return (self.__vehDescr.turret.models.exploded, self.__vehDescr.gun.models.exploded) else: modelsSetParams = ModelsSetParams(style.modelsSet, ModelStates.EXPLODED, []) _, _, turretModel, gunModel = getPartModelsFromDesc( self.__vehDescr, modelsSetParams) return (turretModel, gunModel)
def updateSpawnList(self, spawnListData): toAdd = spawnListData.difference(self._spawnList) toRemove = self._spawnList.difference(spawnListData) for data in toAdd: vDesc = VehicleDescriptor(compactDescr=data.vehicleCD) prereqs = set(vDesc.prerequisites()) outfit = Outfit(component=getOutfitComponent(data.outfitCD), vehicleCD=data.vehicleCD) modelsSetParams = ModelsSetParams(outfit.modelsSet, ModelStates.UNDAMAGED, []) compoundAssembler = model_assembler.prepareCompoundAssembler( vDesc, modelsSetParams, BigWorld.camera().spaceID) prereqs.add(compoundAssembler) self._appearanceCache.loadResources(data.vehicleCD, list(prereqs)) for data in toRemove: self._appearanceCache.unloadResources(data.vehicleCD) self._spawnList = spawnListData _logger.debug('SpawnList cache updated=%s', spawnListData)
class CommonTankAppearance(ScriptGameObject): compoundModel = property(lambda self: self._compoundModel) boundEffects = property(lambda self: self.__boundEffects) fashions = property(lambda self: self.__fashions) fashion = property(lambda self: self.fashions.chassis) typeDescriptor = property(lambda self: self.__typeDesc if self._vehicle is None else self._vehicle.typeDescriptor) id = property(lambda self: self.__vID) isAlive = property(lambda self: self.__isAlive) isObserver = property(lambda self: self.__isObserver) outfit = property(lambda self: self.__outfit) renderMode = property(lambda self: self.__renderMode) def _setFashions(self, fashions, isTurretDetached=False): if IS_EDITOR and self.__fashions: for fashion in self.__fashions: if fashion: fashion.disowned() self.__fashions = fashions if isTurretDetached: self.compoundModel.setupFashions((fashions.chassis, fashions.hull)) else: self.compoundModel.setupFashions(fashions) def _setOutfit(self, outfitCD): self.__outfit = self._prepareOutfit(outfitCD) terrainMatKind = property(lambda self: self.__currTerrainMatKind) terrainGroundType = property(lambda self: self.__currTerrainGroundType) terrainEffectMaterialNames = property( lambda self: self.__terrainEffectMaterialNames) isInWater = property(lambda self: self.waterSensor.isInWater) isUnderwater = property(lambda self: self.waterSensor.isUnderWater) waterHeight = property(lambda self: self.waterSensor.waterHeight) damageState = property(lambda self: self.__currentDamageState) modelsSetParams = property( lambda self: ModelsSetParams(self.outfit.modelsSet, self.damageState. modelState, self.__attachments)) splineTracks = property(lambda self: self._splineTracks) isFlying = property(lambda self: self.flyingInfoProvider is not None and self.flyingInfoProvider.isFlying) isLeftSideFlying = property( lambda self: self.flyingInfoProvider is not None and self. flyingInfoProvider.isLeftSideFlying) isRightSideFlying = property( lambda self: self.flyingInfoProvider is not None and self. flyingInfoProvider.isRightSideFlying) trackScrollController = property(lambda self: self.__trackScrollCtl) wheelsState = property(lambda self: 0) burnoutLevel = property(lambda self: 0.0) wheelsGameObject = property(lambda self: self.__wheelsGameObject) filterRetrievers = property(lambda self: self.__filterRetrievers) filterRetrieverGameObjects = property( lambda self: self.__filterRetrieverGameObjects) allLodCalculators = property(lambda self: self.__allLodCalculators) transmissionSlip = property(lambda self: self._commonSlip) transmissionScroll = property(lambda self: self._commonScroll) vehicleStickers = property(lambda self: self._vehicleStickers) isTurretDetached = property(lambda self: self._isTurretDetached) _weaponEnergy = property(lambda self: self.__weaponEnergy) filter = AutoProperty() areaTriggerTarget = ComponentDescriptor() burnoutProcessor = ComponentDescriptor() c11nComponent = ComponentDescriptor() collisionObstaclesCollector = ComponentDescriptor() collisions = ComponentDescriptor() crashedTracksController = ComponentDescriptor() customEffectManager = ComponentDescriptor() detailedEngineState = ComponentDescriptor() dirtComponent = ComponentDescriptor() engineAudition = ComponentDescriptor() flyingInfoProvider = ComponentDescriptor() frictionAudition = ComponentDescriptor() gearbox = ComponentDescriptor() gunLinkedNodesAnimator = ComponentDescriptor() gunRecoil = ComponentDescriptor() gunRotatorAudition = ComponentDescriptor() hullAimingController = ComponentDescriptor() leveredSuspension = ComponentDescriptor() lodCalculator = ComponentDescriptor() shadowManager = ComponentDescriptor() siegeEffects = ComponentDescriptor() suspension = ComponentDescriptor() suspensionSound = ComponentDescriptor() swingingAnimator = ComponentDescriptor() terrainMatKindSensor = ComponentDescriptor() tessellationCollisionSensor = ComponentDescriptor() trackNodesAnimator = ComponentDescriptor() tracks = ComponentDescriptor() transform = ComponentDescriptor() vehicleTraces = ComponentDescriptor() waterSensor = ComponentDescriptor() wheelsAnimator = ComponentDescriptor() flagComponent = ComponentDescriptor() def __init__(self, spaceID): ScriptGameObject.__init__(self, spaceID, CgfTankNodes.TANK_ROOT) self._vehicle = None self.__wheelsGameObject = ScriptGameObject(spaceID, 'Tank.Wheels.Root') self.__filter = None self.__typeDesc = None self.crashedTracksController = None self.__currentDamageState = VehicleDamageState() self.__currTerrainMatKind = [-1] * MATKIND_COUNT self.__currTerrainGroundType = [-1] * MATKIND_COUNT self.__terrainEffectMaterialNames = [''] * MATKIND_COUNT self._chassisDecal = VehicleDecal(self) self.__splodge = None self.__boundEffects = None self._splineTracks = None self.flyingInfoProvider = self.createComponent( Vehicular.FlyingInfoProvider) self.__trackScrollCtl = BigWorld.PyTrackScroll() self.__trackScrollCtl.setFlyingInfo( DataLinks.createBoolLink(self.flyingInfoProvider, 'isLeftSideFlying'), DataLinks.createBoolLink(self.flyingInfoProvider, 'isRightSideFlying')) self.__weaponEnergy = 0.0 self.__outfit = None self.__systemStarted = False self.__isAlive = True self._isTurretDetached = False self.__isObserver = False self.__attachments = [] self.__modelAnimators = [] self.turretMatrix = None self.gunMatrix = None self.__allLodCalculators = [] self._commonScroll = 0.0 self._commonSlip = 0.0 self._compoundModel = None self.__fashions = None self.__filterRetrievers = [] self.__filterRetrieverGameObjects = [] self._vehicleStickers = None self._vehicleInfo = {} self.__vID = 0 self.__renderMode = None self.__frameTimestamp = 0 self.__periodicTimerID = None self.undamagedStateChildren = [] self.createComponent(VehicleAppearanceComponent, self) self._loadingQueue = [] return def prerequisites(self, typeDescriptor, vID, health, isCrewActive, isTurretDetached, outfitCD, renderMode=None): self.damageState.update(health, isCrewActive, False) self.__typeDesc = typeDescriptor self.__vID = vID self._isTurretDetached = isTurretDetached self.__updateModelStatus() self.__outfit = self._prepareOutfit(outfitCD) if self.damageState.isCurrentModelUndamaged: self.__attachments = camouflages.getAttachments( self.outfit, self.typeDescriptor) self.__renderMode = renderMode prereqs = self.typeDescriptor.prerequisites(True) prereqs.extend( camouflages.getCamoPrereqs(self.outfit, self.typeDescriptor)) prereqs.extend( camouflages.getModelAnimatorsPrereqs(self.outfit, self.spaceID)) prereqs.extend( camouflages.getAttachmentsAnimatorsPrereqs(self.__attachments, self.spaceID)) splineDesc = self.typeDescriptor.chassis.splineDesc modelsSet = self.outfit.modelsSet if IS_EDITOR: modelsSet = self.currentModelsSet if splineDesc is not None: for _, trackDesc in splineDesc.trackPairs.iteritems(): prereqs += trackDesc.prerequisites(modelsSet) modelsSetParams = self.modelsSetParams compoundAssembler = model_assembler.prepareCompoundAssembler( self.typeDescriptor, modelsSetParams, self.spaceID, self.isTurretDetached, renderMode=self.renderMode) prereqs.append(compoundAssembler) if renderMode == TankRenderMode.OVERLAY_COLLISION: self.damageState.update(0, isCrewActive, False) collisionAssembler = model_assembler.prepareCollisionAssembler( self.typeDescriptor, self.isTurretDetached, self.spaceID) prereqs.append(collisionAssembler) skin = modelsSetParams.skin if IS_EDITOR: skin = self.currentModelsSet physicalTracksBuilders = self.typeDescriptor.chassis.physicalTracks for name, builders in physicalTracksBuilders.iteritems(): for index, builder in enumerate(builders): prereqs.append( builder.createLoader( self.spaceID, '{0}{1}PhysicalTrack'.format(name, index), skin)) return prereqs def construct(self, isPlayer, resourceRefs): self.__isObserver = 'observer' in self.typeDescriptor.type.tags self._compoundModel = resourceRefs[self.typeDescriptor.name] self.removeComponentByType(GenericComponents.DynamicModelComponent) self.createComponent(GenericComponents.DynamicModelComponent, self._compoundModel) if not self._compoundModel.isValid(): _logger.error('compoundModel is not valid') if self.typeDescriptor.gun.edgeByVisualModel: self._compoundModel.setPartProperties( TankPartIndexes.GUN, PartProperties.HIGHLIGHTABLE | PartProperties.HIGHLIGHTBYVISUAL) self._compoundModel.setPartProperties( TankPartIndexes.CHASSIS, PartProperties.HIGHLIGHTABLE | PartProperties.HIGHLIGHTBYVISUAL) self.__boundEffects = bound_effects.ModelBoundEffects( self.compoundModel) isCurrentModelDamaged = self.damageState.isCurrentModelDamaged fashions = camouflages.prepareFashions(isCurrentModelDamaged) if not isCurrentModelDamaged: model_assembler.setupTracksFashion(self.typeDescriptor, fashions.chassis) self.collisions = self.createComponent( BigWorld.CollisionComponent, resourceRefs['collisionAssembler']) model_assembler.setupCollisions(self.typeDescriptor, self.collisions) self._setFashions(fashions, self.isTurretDetached) self._setupModels() if not isCurrentModelDamaged: modelsSet = self.outfit.modelsSet if IS_EDITOR: modelsSet = self.currentModelsSet self._splineTracks = model_assembler.setupSplineTracks( self.fashion, self.typeDescriptor, self.compoundModel, resourceRefs, modelsSet) self.crashedTracksController = CrashedTrackController( self.typeDescriptor, self.fashion, modelsSet) else: self.__trackScrollCtl = None self._chassisDecal.create() if self.modelsSetParams.state == 'undamaged': self.__modelAnimators = camouflages.getModelAnimators( self.outfit, self.typeDescriptor, self.spaceID, resourceRefs, self.compoundModel) self.__modelAnimators.extend( camouflages.getAttachmentsAnimators(self.__attachments, self.spaceID, resourceRefs, self.compoundModel)) self.transform = self.createComponent( GenericComponents.TransformComponent, Math.Vector3(0, 0, 0)) self.areaTriggerTarget = self.createComponent( Triggers.AreaTriggerTarget) self.__filter = model_assembler.createVehicleFilter( self.typeDescriptor) compoundModel = self.compoundModel if self.isAlive: self.detailedEngineState, self.gearbox = model_assembler.assembleDrivetrain( self, isPlayer) if not gEffectsDisabled(): self.customEffectManager = CustomEffectManager(self) if self.typeDescriptor.hasSiegeMode: self.siegeEffects = SiegeEffectsController(self, isPlayer) model_assembler.assembleVehicleAudition(isPlayer, self) self.detailedEngineState.onEngineStart = self._onEngineStart self.detailedEngineState.onStateChanged = self.engineAudition.onEngineStateChanged if isPlayer: turret = self.typeDescriptor.turret gunRotatorAudition = self.createComponent( Vehicular.GunRotatorAudition, turret.turretRotatorSoundManual, turret.weight / 1000.0, compoundModel.node(TankPartNames.TURRET)) gunRotatorAudition.vehicleMatrixLink = self.compoundModel.root gunRotatorAudition.damaged = lambda: self.turretDamaged() gunRotatorAudition.maxTurretRotationSpeed = lambda: self.maxTurretRotationSpeed( ) self.gunRotatorAudition = gunRotatorAudition self.frictionAudition = self.createComponent( Vehicular.FrictionAudition, TANK_FRICTION_EVENT) isLodTopPriority = isPlayer lodCalcInst = self.createComponent( Vehicular.LodCalculator, DataLinks.linkMatrixTranslation(compoundModel.matrix), True, VEHICLE_PRIORITY_GROUP, isLodTopPriority) self.lodCalculator = lodCalcInst self.allLodCalculators.append(lodCalcInst) lodLink = DataLinks.createFloatLink(lodCalcInst, 'lodDistance') lodStateLink = lodCalcInst.lodStateLink if IS_EDITOR: matrixBinding = None changeCamera = None else: matrixBinding = BigWorld.player( ).consistentMatrices.onVehicleMatrixBindingChanged changeCamera = BigWorld.player().inputHandler.onCameraChanged self.shadowManager = VehicleShadowManager(compoundModel, matrixBinding, changeCamera) if not self.damageState.isCurrentModelDamaged: self.__assembleNonDamagedOnly(resourceRefs, isPlayer, lodLink, lodStateLink) dirtEnabled = BigWorld.WG_dirtEnabled( ) and 'HD' in self.typeDescriptor.type.tags if dirtEnabled and self.fashions is not None: dirtHandlers = [ BigWorld.PyDirtHandler( True, compoundModel.node(TankPartNames.CHASSIS).position.y), BigWorld.PyDirtHandler( False, compoundModel.node(TankPartNames.HULL).position.y), BigWorld.PyDirtHandler( False, compoundModel.node(TankPartNames.TURRET).position.y), BigWorld.PyDirtHandler( False, compoundModel.node(TankPartNames.GUN).position.y) ] modelHeight, _ = self.computeVehicleHeight() self.dirtComponent = self.createComponent( Vehicular.DirtComponent, dirtHandlers, modelHeight) for fashionIdx, _ in enumerate(TankPartNames.ALL): self.fashions[fashionIdx].addMaterialHandler( dirtHandlers[fashionIdx]) self.fashions[fashionIdx].addTrackMaterialHandler( dirtHandlers[fashionIdx]) model_assembler.setupTurretRotations(self) self.waterSensor = model_assembler.assembleWaterSensor( self.typeDescriptor, self, lodStateLink, self.spaceID) if self.engineAudition is not None: self.engineAudition.setIsUnderwaterInfo( DataLinks.createBoolLink(self.waterSensor, 'isUnderWater')) self.engineAudition.setIsInWaterInfo( DataLinks.createBoolLink(self.waterSensor, 'isInWater')) self.__postSetupFilter() compoundModel.setPartBoundingBoxAttachNode( TankPartIndexes.GUN, TankNodeNames.GUN_INCLINATION) camouflages.updateFashions(self) model_assembler.assembleCustomLogicComponents(self, self.typeDescriptor, self.__attachments, self.__modelAnimators) self._createStickers() while self._loadingQueue: prefab, go, vector, callback = self._loadingQueue.pop() CGF.loadGameObjectIntoHierarchy(prefab, go, vector, callback) return def destroy(self): self._vehicleInfo = {} self.flagComponent = None self._destroySystems() fashions = VehiclePartsTuple(None, None, None, None) self._setFashions(fashions, self._isTurretDetached) self.shadowManager.unregisterCompoundModel(self.compoundModel) for go in self.filterRetrieverGameObjects: go.destroy() self.wheelsGameObject.destroy() super(CommonTankAppearance, self).destroy() self.__typeDesc = None if self.boundEffects is not None: self.boundEffects.destroy() self._vehicleStickers = None self._chassisDecal.destroy() self._chassisDecal = None self._compoundModel = None self._destroyStickers() self._loadingQueue = [] return def activate(self): typeDescr = self.typeDescriptor wheelConfig = typeDescr.chassis.generalWheelsAnimatorConfig if self.wheelsAnimator is not None and wheelConfig is not None: self.wheelsAnimator.createCollision(wheelConfig, self.collisions) super(CommonTankAppearance, self).activate() self.wheelsGameObject.activate() for go in self.filterRetrieverGameObjects: go.activate() if not self.isObserver: self._chassisDecal.attach() if not self.isObserver: self._startSystems() self.filter.enableLagDetection( not self.damageState.isCurrentModelDamaged) if self.__periodicTimerID is not None: BigWorld.cancelCallback(self.__periodicTimerID) self.__periodicTimerID = BigWorld.callback(PERIODIC_UPDATE_TIME, self.__onPeriodicTimer) self.setupGunMatrixTargets(self.filter) for lodCalculator in self.allLodCalculators: lodCalculator.setupPosition( DataLinks.linkMatrixTranslation(self.compoundModel.matrix)) for modelAnimator in self.__modelAnimators: modelAnimator.animator.setEnabled(True) modelAnimator.animator.start() if hasattr(self.filter, 'placingCompensationMatrix' ) and self.swingingAnimator is not None: self.swingingAnimator.placingCompensationMatrix = self.filter.placingCompensationMatrix self.swingingAnimator.worldMatrix = self.compoundModel.matrix if self.isObserver: self.compoundModel.visible = False self._connectCollider() self._attachStickers() return def deactivate(self): for modelAnimator in self.__modelAnimators: modelAnimator.animator.setEnabled(False) super(CommonTankAppearance, self).deactivate() self.shadowManager.unregisterCompoundModel(self.compoundModel) self._stopSystems() self.wheelsGameObject.deactivate() for go in self.filterRetrieverGameObjects: go.deactivate() self._chassisDecal.detach() self._detachStickers() def setVehicleInfo(self, vehInfo): self._vehicleInfo = vehInfo def setupGunMatrixTargets(self, target): self.turretMatrix = target.turretMatrix self.gunMatrix = target.gunMatrix def receiveShotImpulse(self, direction, impulse): if not VehicleDamageState.isDamagedModel(self.damageState.modelState): self.swingingAnimator.receiveShotImpulse(direction, impulse) if self.crashedTracksController is not None: self.crashedTracksController.receiveShotImpulse( direction, impulse) return def recoil(self): self._initiateRecoil(TankNodeNames.GUN_INCLINATION, 'HP_gunFire', self.gunRecoil) def multiGunRecoil(self, indexes): if self.gunAnimators is None: return else: for index in indexes: typeDescr = self.typeDescriptor gunNodeName = typeDescr.turret.multiGun[index].node gunFireNodeName = typeDescr.turret.multiGun[index].gunFire gunAnimator = self.gunAnimators[index].findComponentByType( Vehicular.RecoilAnimator) self._initiateRecoil(gunNodeName, gunFireNodeName, gunAnimator) return def computeFullVehicleLength(self): vehicleLength = 0.0 if self.compoundModel is not None: hullBB = Math.Matrix( self.compoundModel.getBoundsForPart(TankPartIndexes.HULL)) vehicleLength = hullBB.applyVector(Math.Vector3(0.0, 0.0, 1.0)).length return vehicleLength def _initiateRecoil(self, gunNodeName, gunFireNodeName, gunAnimator): gunNode = self.compoundModel.node(gunNodeName) impulseDir = Math.Matrix(gunNode).applyVector(Math.Vector3(0, 0, -1)) impulseValue = self.typeDescriptor.gun.impulse self.receiveShotImpulse(impulseDir, impulseValue) gunAnimator.recoil() return impulseDir def _connectCollider(self): if self.collisions is not None: chassisColisionMatrix, gunNodeName = self._vehicleColliderInfo if self.isTurretDetached: self.collisions.removeAttachment( TankPartNames.getIdx(TankPartNames.TURRET)) self.collisions.removeAttachment( TankPartNames.getIdx(TankPartNames.GUN)) collisionData = ((TankPartNames.getIdx(TankPartNames.HULL), self.compoundModel.node(TankPartNames.HULL)), (TankPartNames.getIdx(TankPartNames.CHASSIS), chassisColisionMatrix)) else: collisionData = ((TankPartNames.getIdx(TankPartNames.HULL), self.compoundModel.node(TankPartNames.HULL)), (TankPartNames.getIdx(TankPartNames.TURRET), self.compoundModel.node( TankPartNames.TURRET)), (TankPartNames.getIdx(TankPartNames.CHASSIS), chassisColisionMatrix), (TankPartNames.getIdx(TankPartNames.GUN), self.compoundModel.node(gunNodeName))) defaultPartLength = len(TankPartNames.ALL) additionalChassisParts = [] trackPairs = self.typeDescriptor.chassis.trackPairs if not trackPairs: trackPairs = [None] for x in xrange(len(trackPairs) - 1): additionalChassisParts.append( (defaultPartLength + x, chassisColisionMatrix)) if additionalChassisParts: collisionData += tuple(additionalChassisParts) self.collisions.connect(self.id, ColliderTypes.VEHICLE_COLLIDER, collisionData) return def computeVehicleHeight(self): gunLength = 0.0 height = 0.0 if self.collisions is not None: desc = self.typeDescriptor hullBB = self.collisions.getBoundingBox( TankPartNames.getIdx(TankPartNames.HULL)) turretBB = self.collisions.getBoundingBox( TankPartNames.getIdx(TankPartNames.TURRET)) gunBB = self.collisions.getBoundingBox( TankPartNames.getIdx(TankPartNames.GUN)) hullTopY = desc.chassis.hullPosition[1] + hullBB[1][1] turretTopY = desc.chassis.hullPosition[ 1] + desc.hull.turretPositions[0][1] + turretBB[1][1] gunTopY = desc.chassis.hullPosition[1] + desc.hull.turretPositions[ 0][1] + desc.turret.gunPosition[1] + gunBB[1][1] gunLength = math.fabs(gunBB[1][2] - gunBB[0][2]) height = max(hullTopY, max(turretTopY, gunTopY)) return (height, gunLength) def onWaterSplash(self, waterHitPoint, isHeavySplash): pass def onUnderWaterSwitch(self, isUnderWater): pass def getWheelsSteeringMax(self): pass def _prepareOutfit(self, outfitCD): outfitComponent = camouflages.getOutfitComponent(outfitCD) return Outfit(component=outfitComponent, vehicleCD=self.typeDescriptor.makeCompactDescr()) def _setupModels(self): self.__isAlive = not self.damageState.isCurrentModelDamaged if self.isAlive: _, gunLength = self.computeVehicleHeight() self.__weaponEnergy = gunLength * self.typeDescriptor.shot.shell.caliber if MAX_DISTANCE > 0 and not self.isObserver: transform = self.typeDescriptor.chassis.AODecals[0] splodge = BigWorld.Splodge( transform, MAX_DISTANCE, self.typeDescriptor.chassis.hullPosition.y) if splodge: self.__splodge = splodge node = self.compoundModel.node(TankPartNames.HULL) node.attach(splodge) def _createStickers(self): _logger.debug('Creating VehicleStickers for vehicleType: %s', self.typeDescriptor) isCurrentModelDamaged = self.damageState.isCurrentModelDamaged if isCurrentModelDamaged: return else: if self.vehicleStickers is not None: self._destroyStickers() self._vehicleStickers = VehicleStickers(self.spaceID, self.typeDescriptor, outfit=self.outfit) return def _destroyStickers(self): _logger.debug('Attaching VehicleStickers for vehicleType: %s', self.typeDescriptor) self._detachStickers() self._vehicleStickers = None return def _attachStickers(self): _logger.debug('Attaching VehicleStickers for vehicle: %s', self._vehicle) if self.vehicleStickers is None: _logger.error( 'Failed to attach VehicleStickers. Missing VehicleStickers. Vehicle: %s', self._vehicle) return else: isCurrentModelDamaged = self.damageState.isCurrentModelDamaged self.vehicleStickers.alpha = DEFAULT_STICKERS_ALPHA self.vehicleStickers.attach( compoundModel=self.compoundModel, isDamaged=isCurrentModelDamaged, showDamageStickers=not isCurrentModelDamaged) return def _detachStickers(self): _logger.debug('Detaching VehicleStickers for vehicle: %s', self._vehicle) if self.vehicleStickers is not None: self.vehicleStickers.detach() return @property def _vehicleColliderInfo(self): chassisColisionMatrix = self.compoundModel.matrix if self.damageState.isCurrentModelDamaged: gunNodeName = 'gun' else: gunNodeName = TankNodeNames.GUN_INCLINATION return (chassisColisionMatrix, gunNodeName) def _startSystems(self): if self.flyingInfoProvider is not None: self.flyingInfoProvider.setData(self.filter, self.suspension) if self.damageState.isCurrentModelDamaged or self.__systemStarted: return else: self.__systemStarted = True if self.trackScrollController is not None: self.trackScrollController.activate() self.trackScrollController.setData(self.filter) if self.engineAudition is not None: self.engineAudition.setWeaponEnergy(self._weaponEnergy) self.engineAudition.attachToModel(self.compoundModel) if self.hullAimingController is not None: self.hullAimingController.setData(self.filter, self.typeDescriptor) if self.detailedEngineState is not None: self.detailedEngineState.onGearUpCbk = self.__onEngineStateGearUp return def _stopSystems(self): if self.flyingInfoProvider is not None: self.flyingInfoProvider.setData(None, None) if self.__systemStarted: self.__systemStarted = False if self.trackScrollController is not None: self.trackScrollController.deactivate() self.trackScrollController.setData(None) if self.__periodicTimerID is not None: BigWorld.cancelCallback(self.__periodicTimerID) self.__periodicTimerID = None for modelAnimator in self.__modelAnimators: modelAnimator.animator.stop() self.filter.enableLagDetection(False) return def _destroySystems(self): self.__systemStarted = False if self.trackScrollController is not None: self.trackScrollController.deactivate() self.__trackScrollCtl = None for modelAnimator in self.__modelAnimators: modelAnimator.animator.stop() if self.__periodicTimerID is not None: BigWorld.cancelCallback(self.__periodicTimerID) self.__periodicTimerID = None self.__modelAnimators = [] self.filter.enableLagDetection(False) for go in self.undamagedStateChildren: CGF.removeGameObject(go) self.undamagedStateChildren = [] return def _onRequestModelsRefresh(self): self.flagComponent = None self.__updateModelStatus() return def __updateModelStatus(self): if self.damageState.isCurrentModelUndamaged: modelStatus = ModelStatus.NORMAL else: modelStatus = ModelStatus.CRASHED for htManager in self.typeDescriptor.getHitTesterManagers(): htManager.setStatus(modelStatus) def _onEngineStart(self): if self.engineAudition is not None: self.engineAudition.onEngineStart() return def __assembleNonDamagedOnly(self, resourceRefs, isPlayer, lodLink, lodStateLink): model_assembler.assembleTerrainMatKindSensor(self, lodStateLink, self.spaceID) model_assembler.assembleRecoil(self, lodLink) model_assembler.assembleMultiGunRecoil(self, lodLink) model_assembler.assembleGunLinkedNodesAnimator(self) model_assembler.assembleCollisionObstaclesCollector( self, lodStateLink, self.typeDescriptor) model_assembler.assembleTessellationCollisionSensor(self, lodStateLink) wheelsScroll = None wheelsSteering = None generalWheelsAnimatorConfig = self.typeDescriptor.chassis.generalWheelsAnimatorConfig if generalWheelsAnimatorConfig is not None: scrollableWheelsCount = generalWheelsAnimatorConfig.getNonTrackWheelsCount( ) wheelsScroll = [] for _ in xrange(scrollableWheelsCount): retrieverGameObject = ScriptGameObject(self.spaceID) retriever = retrieverGameObject.createComponent( NetworkFilters.FloatFilterRetriever) wheelsScroll.append( DataLinks.createFloatLink(retriever, 'value')) self.filterRetrievers.append(retriever) self.filterRetrieverGameObjects.append(retrieverGameObject) steerableWheelsCount = generalWheelsAnimatorConfig.getSteerableWheelsCount( ) wheelsSteering = [] for _ in xrange(steerableWheelsCount): retrieverGameObject = ScriptGameObject(self.spaceID) retriever = retrieverGameObject.createComponent( NetworkFilters.FloatFilterRetriever) wheelsSteering.append( DataLinks.createFloatLink(retriever, 'value')) self.filterRetrievers.append(retriever) self.filterRetrieverGameObjects.append(retrieverGameObject) self.wheelsAnimator = model_assembler.createWheelsAnimator( self, ColliderTypes.VEHICLE_COLLIDER, self.typeDescriptor, lambda: self.wheelsState, wheelsScroll, wheelsSteering, self.splineTracks, lodStateLink) if self.customEffectManager is not None: self.customEffectManager.setWheelsData(self) suspensionLodLink = lodStateLink if 'wheeledVehicle' in self.typeDescriptor.type.tags: wheeledLodCalculator = self.wheelsGameObject.createComponent( Vehicular.LodCalculator, DataLinks.linkMatrixTranslation(self.compoundModel.matrix), True, WHEELED_CHASSIS_PRIORITY_GROUP, isPlayer) self.allLodCalculators.append(wheeledLodCalculator) suspensionLodLink = wheeledLodCalculator.lodStateLink model_assembler.assembleSuspensionIfNeed(self, suspensionLodLink) model_assembler.assembleLeveredSuspensionIfNeed( self, suspensionLodLink) self.__assembleSwinging(lodLink) model_assembler.assembleBurnoutProcessor(self) model_assembler.assembleSuspensionSound(self, lodLink, isPlayer) model_assembler.assembleHullAimingController(self) self.trackNodesAnimator = model_assembler.createTrackNodesAnimator( self, self.typeDescriptor, lodStateLink) model_assembler.assembleTracks(resourceRefs, self.typeDescriptor, self, self.splineTracks, False, lodStateLink) model_assembler.assembleVehicleTraces(self, self.filter, lodStateLink) return def __assembleSwinging(self, lodLink): hullNode = self.compoundModel.node(TankPartNames.HULL) if hullNode is None: _logger.error( 'Could not create SwingingAnimator: failed to find hull node') return else: self.swingingAnimator = model_assembler.createSwingingAnimator( self, self.typeDescriptor, hullNode.localMatrix, self.compoundModel.matrix, lodLink) self.compoundModel.node(TankPartNames.HULL, self.swingingAnimator.animatedMProv) if hasattr(self.filter, 'placingCompensationMatrix'): self.swingingAnimator.placingCompensationMatrix = self.filter.placingCompensationMatrix return def __postSetupFilter(self): suspensionWorking = self.suspension is not None and self.suspension.hasGroundNodes placingOnGround = not (suspensionWorking or self.leveredSuspension is not None) self.filter.placingOnGround = placingOnGround return def __onPeriodicTimer(self): timeStamp = BigWorld.wg_getFrameTimestamp() if self.__frameTimestamp >= timeStamp: self.__periodicTimerID = BigWorld.callback(0.0, self.__onPeriodicTimer) else: self.__frameTimestamp = timeStamp self.__periodicTimerID = BigWorld.callback(PERIODIC_UPDATE_TIME, self.__onPeriodicTimer) self._periodicUpdate() def _periodicUpdate(self): if self._vehicle is None or not self._vehicle.isAlive(): return else: self._updateCurrTerrainMatKinds() self.__updateEffectsLOD() if self.siegeEffects: self.siegeEffects.tick() if self.customEffectManager: self.customEffectManager.update() return def __updateEffectsLOD(self): if self.customEffectManager: distanceFromPlayer = self.lodCalculator.lodDistance enableExhaust = distanceFromPlayer <= _LOD_DISTANCE_EXHAUST and not self.isUnderwater enableTrails = distanceFromPlayer <= _LOD_DISTANCE_TRAIL_PARTICLES and BigWorld.wg_isVehicleDustEnabled( ) self.customEffectManager.enable(enableTrails, EffectSettings.SETTING_DUST) self.customEffectManager.enable(enableExhaust, EffectSettings.SETTING_EXHAUST) def _stopEffects(self): self.boundEffects.stop() def playEffectWithStopCallback(self, effects): self._stopEffects() vehicle = self._vehicle return self.boundEffects.addNew( None, effects[1], effects[0], isPlayerVehicle=vehicle.isPlayerVehicle, showShockWave=vehicle.isPlayerVehicle, showFlashBang=vehicle.isPlayerVehicle, entity_id=vehicle.id, isPlayer=vehicle.isPlayerVehicle, showDecal=True, start=vehicle.position + Math.Vector3(0.0, 1.0, 0.0), end=vehicle.position + Math.Vector3(0.0, -1.0, 0.0)).stop def playEffect(self, kind, *modifs): self._stopEffects() if kind == 'empty' or self._vehicle is None: return else: enableDecal = True if kind in ('explosion', 'destruction') and self.isFlying: enableDecal = False if self.isUnderwater: if kind not in ('submersionDeath', ): return effects = self.typeDescriptor.type.effects[kind] if not effects: return vehicle = self._vehicle effects = random.choice(effects) args = dict(isPlayerVehicle=vehicle.isPlayerVehicle, showShockWave=vehicle.isPlayerVehicle, showFlashBang=vehicle.isPlayerVehicle, entity_id=vehicle.id, isPlayer=vehicle.isPlayerVehicle, showDecal=enableDecal, start=vehicle.position + Math.Vector3(0.0, 1.0, 0.0), end=vehicle.position + Math.Vector3(0.0, -1.0, 0.0)) if isSpawnedBot( self.typeDescriptor.type.tags) and kind in ('explosion', 'destruction'): if isPlayerAvatar(): if self.isFlying: instantExplosionEff = self.typeDescriptor.type.effects[ 'instantExplosion'] if instantExplosionEff: effects = random.choice(instantExplosionEff) BigWorld.player().terrainEffects.addNew( self._vehicle.position, effects[1], effects[0], None, **args) else: self.boundEffects.addNew(None, effects[1], effects[0], **args) return def _updateCurrTerrainMatKinds(self): if self.terrainMatKindSensor is None: return else: matKinds = self.terrainMatKindSensor.matKinds groundTypes = self.terrainMatKindSensor.groundTypes materialsCount = len(matKinds) for i in xrange(MATKIND_COUNT): matKind = matKinds[i] if i < materialsCount else 0 groundType = groundTypes[i] if i < materialsCount else 0 self.terrainMatKind[i] = matKind self.terrainGroundType[i] = groundType effectIndex = calcEffectMaterialIndex(matKind) effectMaterialName = '' if effectIndex is not None: effectMaterialName = material_kinds.EFFECT_MATERIALS[ effectIndex] self.terrainEffectMaterialNames[i] = effectMaterialName if self.vehicleTraces is not None: self.vehicleTraces.setCurrTerrainMatKinds( self.terrainMatKind[0], self.terrainMatKind[1]) return def onSiegeStateChanged(self, newState, timeToNextMode): if self.engineAudition is not None: self.engineAudition.onSiegeStateChanged(newState) if self.hullAimingController is not None: self.hullAimingController.onSiegeStateChanged(newState) if self.suspensionSound is not None: self.suspensionSound.vehicleState = newState if self.siegeEffects is not None: self.siegeEffects.onSiegeStateChanged(newState, timeToNextMode) enabled = newState == VEHICLE_SIEGE_STATE.ENABLED or newState == VEHICLE_SIEGE_STATE.SWITCHING_ON if self.suspension is not None: self.suspension.setLiftMode(enabled) if self.leveredSuspension is not None: self.leveredSuspension.setLiftMode(enabled) if self.vehicleTraces is not None: self.vehicleTraces.setLiftMode(enabled) return def changeEngineMode(self, mode, forceSwinging=False): if self.detailedEngineState is not None: self.detailedEngineState.mode = mode[0] if self.trackScrollController is not None: self.trackScrollController.setMode(mode) return def changeSiegeState(self, siegeState): if self.engineAudition is not None: self.engineAudition.onSiegeStateChanged(siegeState) return def turretDamaged(self): pass def maxTurretRotationSpeed(self): pass def pushToLoadingQueue(self, prefab, go, vector, callback): self._loadingQueue.append((prefab, go, vector, callback)) def _onCameraChanged(self, cameraName, currentVehicleId=None): if self.id != BigWorld.player().playerVehicleID: return isEnabled = not cameraName == 'sniper' for modelAnimator in self.__modelAnimators: modelAnimator.animator.setEnabled(isEnabled) def __onEngineStateGearUp(self): if self.customEffectManager is not None: self.customEffectManager.onGearUp() if self.engineAudition is not None: self.engineAudition.onEngineGearUp() return def __animatorCallback(self, name, time): _logger.debug('Callback aquired %s %f', name, time) if self.shellAnimator is not None: self.shellAnimator.throwShell( self.typeDescriptor.shot.shell.animation) return def __isRequireTrackDebrisGeneration(self, isLeft, pairIndex): tracks = self.typeDescriptor.chassis.tracks return tracks is not None and tracks.trackPairs[ pairIndex].tracksDebris is not None def _addCrashedTrack(self, isLeft, pairIndex, isSideFlying): if not self.__isRequireTrackDebrisGeneration(isLeft, pairIndex): if self.crashedTracksController is not None: self.crashedTracksController.addTrack(isLeft, isSideFlying) return else: track = self.tracks.getTrackGameObject(isLeft, pairIndex) debris = track.createComponent(TrackCrashWithDebrisComponent, isLeft, pairIndex, self.typeDescriptor, self.gameObject, self.boundEffects) debris.isTopPriority = self._vehicle.isPlayerVehicle debris.isPlayer = self._vehicle.isPlayerVehicle debris.isFlying = isSideFlying return def _delCrashedTrack(self, isLeft, pairIndex): if not self.__isRequireTrackDebrisGeneration(isLeft, pairIndex): if self.crashedTracksController is not None: self.crashedTracksController.delTrack(isLeft) return elif self.tracks is None: return else: track = self.tracks.getTrackGameObject(isLeft, pairIndex) debris = track.findComponentByType(TrackCrashWithDebrisComponent) if debris is not None: debris.markAsRepaired() track.removeComponent(debris) return
class CompoundAppearance(ComponentSystem, CallbackDelayer): compoundModel = property(lambda self: self.__compoundModel) boundEffects = property(lambda self: self.__boundEffects) fashion = property(lambda self: self.__fashions.chassis) typeDescriptor = property(lambda self: self.__typeDesc) id = property(lambda self: self.__vID) isAlive = property(lambda self: self.__isAlive) isObserver = property(lambda self: self.__isObserver) def __setFashions(self, fashions, isTurretDetached=False): self.__fashions = fashions self.__fashion = fashions.chassis if isTurretDetached: self.__compoundModel.setupFashions( (fashions.chassis, fashions.hull)) else: self.__compoundModel.setupFashions(fashions) fashions = property(lambda self: self.__fashions, __setFashions) terrainMatKind = property(lambda self: self.__currTerrainMatKind) terrainEffectMaterialNames = property( lambda self: self.__terrainEffectMaterialNames) isInWater = property(lambda self: self.waterSensor.isInWater) isUnderwater = property(lambda self: self.waterSensor.isUnderWater) waterHeight = property(lambda self: self.waterSensor.waterHeight) damageState = property(lambda self: self.__currentDamageState) modelsSetParams = property(lambda self: ModelsSetParams( self.__outfit.modelsSet, self.__currentDamageState.modelState)) frameTimeStamp = 0 rightTrackScroll = property(lambda self: self.__rightTrackScroll) leftTrackScroll = property(lambda self: self.__leftTrackScroll) splineTracks = property(lambda self: self.__splineTracks) activated = property(lambda self: self.__activated) isFlying = property(lambda self: self.flyingInfoProvider is not None and self.flyingInfoProvider.isFlying) isLeftSideFlying = property( lambda self: self.flyingInfoProvider is not None and self. flyingInfoProvider.isLeftSideFlying) isRightSideFlying = property( lambda self: self.flyingInfoProvider is not None and self. flyingInfoProvider.isRightSideFlying) @property def rpm(self): return self.detailedEngineState.rpm if self.detailedEngineState is not None else 0.0 @property def gear(self): return self.detailedEngineState.gearNum if self.detailedEngineState is not None else 0.0 trackScrollController = property(lambda self: self.__trackScrollCtl) filter = AutoProperty() detailedEngineState = ComponentDescriptor() engineAudition = ComponentDescriptor() trackCrashAudition = ComponentDescriptor() customEffectManager = ComponentDescriptor() highlighter = ComponentDescriptor() shadowManager = ComponentDescriptor() gunRecoil = ComponentDescriptor() gunLinkedNodesAnimator = ComponentDescriptor() swingingAnimator = ComponentDescriptor() dirtComponent = ComponentDescriptor() suspensionSound = ComponentDescriptor() siegeEffects = ComponentDescriptor() lodCalculator = ComponentDescriptor() frictionAudition = ComponentDescriptor() suspension = ComponentDescriptor() leveredSuspension = ComponentDescriptor() suspensionController = ComponentDescriptor() collisions = ComponentDescriptor() wheelsAnimator = ComponentDescriptor() trackNodesAnimator = ComponentDescriptor() vehicleTraces = ComponentDescriptor() flyingInfoProvider = ComponentDescriptor() terrainMatKindSensor = ComponentDescriptor() waterSensor = ComponentDescriptor() peripheralsController = ComponentDescriptor() tracks = ComponentDescriptor() crashedTrackController = ComponentDescriptor() collisionObstaclesCollector = ComponentDescriptor() tessellationCollisionSensor = ComponentDescriptor() def __init__(self): CallbackDelayer.__init__(self) ComponentSystem.__init__(self) self.turretMatrix = Math.WGAdaptiveMatrixProvider() self.gunMatrix = Math.WGAdaptiveMatrixProvider() self.__vehicle = None self.__filter = None self.__originalFilter = None self.__typeDesc = None self.__fashion = None self.crashedTracksController = None self.__currentDamageState = VehicleDamageState() self.__effectsPlayer = None self.__engineMode = (0, 0) self.__currTerrainMatKind = [-1] * _MATKIND_COUNT self.__terrainEffectMaterialNames = [''] * _MATKIND_COUNT self.__terrainMatKindLodDistance = _LOD_DISTANCE_TERRAIN_MATKIND_UPDATE self.__chassisDecal = VehicleDecal(self) self.__splodge = None self.__vehicleStickers = None self.onModelChanged = Event() self.__leftTrackScroll = 0.0 self.__rightTrackScroll = 0.0 self.__fashions = None self.__compoundModel = None self.__boundEffects = None self.__splineTracks = None self.flyingInfoProvider = Vehicular.FlyingInfoProvider() self.__trackScrollCtl = BigWorld.PyTrackScroll() self.__trackScrollCtl.setFlyingInfo( DataLinks.createBoolLink(self.flyingInfoProvider, 'isLeftSideFlying'), DataLinks.createBoolLink(self.flyingInfoProvider, 'isRightSideFlying')) self.__weaponEnergy = 0.0 self.__activated = False self.__systemStarted = False self.__outfit = None self.__vID = 0 self.__isAlive = True self.__isTurretDetached = False self.__periodicTimerID = None self.__wasDeactivated = False self.__dirtUpdateTime = 0.0 self.__inSpeedTreeCollision = False self.__isObserver = False self.__chassisColisionMatrix = Math.WGAdaptiveMatrixProvider() return def prerequisites(self, typeDescriptor, vID, health, isCrewActive, isTurretDetached, outfitCD): self.__currentDamageState.update(health, isCrewActive, False) self.__vID = vID self.__typeDesc = typeDescriptor self.__isTurretDetached = isTurretDetached self.__prepareOutfit(outfitCD) out = camouflages.getCamoPrereqs(self.__outfit, self.__typeDesc) splineDesc = typeDescriptor.chassis.splineDesc if splineDesc is not None: out.append(splineDesc.segmentModelLeft) out.append(splineDesc.segmentModelRight) if splineDesc.segment2ModelLeft is not None: out.append(splineDesc.segment2ModelLeft) if splineDesc.segment2ModelRight is not None: out.append(splineDesc.segment2ModelRight) self.__terrainMatKindLodDistance = typeDescriptor.chassis.traces.lodDist return out def setVehicle(self, vehicle): self.__vehicle = vehicle if self.customEffectManager is not None: self.customEffectManager.setVehicle(vehicle) if self.crashedTracksController is not None: self.crashedTracksController.setVehicle(vehicle) if self.frictionAudition is not None: self.frictionAudition.setVehicleMatrix(vehicle.matrix) self.highlighter.setVehicle(vehicle) self.__applyVehicleOutfit() return def __arenaPeriodChanged(self, period, *otherArgs): if self.detailedEngineState is None: return else: periodEndTime = BigWorld.player().arena.periodEndTime serverTime = BigWorld.serverTime() engine_state.notifyEngineOnArenaPeriodChange( self.detailedEngineState, period, periodEndTime, serverTime) return def activate(self): if self.__activated or self.__vehicle is None: return else: if self.collisions is not None and self.__vehicle.isTurretDetached: self.collisions.removeAttachment( TankPartNames.getIdx(TankPartNames.TURRET)) self.collisions.removeAttachment( TankPartNames.getIdx(TankPartNames.GUN)) super(CompoundAppearance, self).activate() isPlayerVehicle = self.__vehicle.isPlayerVehicle self.__isObserver = 'observer' in self.__typeDesc.type.tags player = BigWorld.player() self.__originalFilter = self.__vehicle.filter self.__vehicle.filter = self.__filter self.__vehicle.filter.enableStabilisedMatrix(isPlayerVehicle) self.__filter.isStrafing = self.__vehicle.isStrafing self.__filter.vehicleCollisionCallback = player.handleVehicleCollidedVehicle if isPlayerVehicle and self.collisions is not None: colliderData = (self.collisions.getColliderID(), (TankPartNames.getIdx(TankPartNames.HULL), TankPartNames.getIdx(TankPartNames.TURRET))) BigWorld.appendCameraCollider(colliderData) self.__inSpeedTreeCollision = True BigWorld.setSpeedTreeCollisionBody( self.__compoundModel.getBoundsForPart( TankPartIndexes.HULL)) self.__linkCompound() if not self.__isObserver: self.__chassisDecal.attach() self.__createAndAttachStickers() if self.__currentDamageState.isCurrentModelDamaged: self.__chassisColisionMatrix.target = self.__compoundModel.matrix gunNodeName = 'gun' else: self.__chassisColisionMatrix.target = self.__vehicle.filter.groundPlacingMatrix gunNodeName = TankNodeNames.GUN_INCLINATION if not self.__isObserver: self.__startSystems() self.setupGunMatrixTargets() if not self.__isObserver: self.__vehicle.filter.enableLagDetection( not self.__currentDamageState.isCurrentModelDamaged) self.onModelChanged() if self.lodCalculator is not None: self.lodCalculator.setupPosition( DataLinks.linkMatrixTranslation( self.__compoundModel.matrix)) if hasattr(self.filter, 'placingCompensationMatrix' ) and self.swingingAnimator is not None: self.swingingAnimator.placingCompensationMatrix = self.filter.placingCompensationMatrix self.swingingAnimator.worldMatrix = self.__compoundModel.matrix if not self.__isObserver: if self.__periodicTimerID is not None: BigWorld.cancelCallback(self.__periodicTimerID) self.__periodicTimerID = BigWorld.callback( _PERIODIC_TIME, self.__onPeriodicTimer) self.__dirtUpdateTime = BigWorld.time() if self.fashion is not None: self.fashion.activate() if self.__isObserver: self.__compoundModel.visible = False BigWorld.player().arena.onPeriodChange += self.__arenaPeriodChanged BigWorld.player( ).inputHandler.onCameraChanged += self.__onCameraChanged if self.detailedEngineState is not None: engine_state.checkEngineStart(self.detailedEngineState, BigWorld.player().arena.period) if self.collisions is not None: collisionData = ((TankPartNames.getIdx(TankPartNames.HULL), self.compoundModel.node(TankPartNames.HULL)), (TankPartNames.getIdx(TankPartNames.TURRET), self.compoundModel.node( TankPartNames.TURRET)), (TankPartNames.getIdx(TankPartNames.CHASSIS), self.__chassisColisionMatrix), (TankPartNames.getIdx(TankPartNames.GUN), self.compoundModel.node(gunNodeName))) self.collisions.connect(self.id, ColliderTypes.VEHICLE_COLLIDER, collisionData) self.__activated = True return def deactivate(self, stopEffects=True): if not self.__activated: return else: self.shadowManager.unregisterCompoundModel(self.__compoundModel) self.__activated = False self.__wasDeactivated = True if self.fashion is not None: self.fashion.deactivate() self.__stopSystems() super(CompoundAppearance, self).deactivate() self.__chassisDecal.detach() if self.__inSpeedTreeCollision: BigWorld.setSpeedTreeCollisionBody(None) if self.collisions is not None: BigWorld.removeCameraCollider(self.collisions.getColliderID()) self.__vehicle.filter.enableLagDetection(False) self.turretMatrix.target = None self.gunMatrix.target = None self.__vehicle.filter = self.__originalFilter self.__filter.reset() self.__originalFilter = None self.__vehicleStickers.detach() if stopEffects: self.__stopEffects() self.__boundEffects.stop() self.__vehicle.model = None self.__compoundModel.matrix = Math.Matrix() self.__vehicle = None BigWorld.player().arena.onPeriodChange -= self.__arenaPeriodChanged BigWorld.player( ).inputHandler.onCameraChanged -= self.__onCameraChanged return def __startSystems(self): if self.__systemStarted or self.__currentDamageState.isCurrentModelDamaged: return else: if self.flyingInfoProvider is not None: self.flyingInfoProvider.setData(self.__vehicle.filter, self.suspension) if self.__trackScrollCtl is not None: self.__trackScrollCtl.activate() self.__trackScrollCtl.setData(self.__vehicle.filter) if self.__vehicle.isPlayerVehicle: self.delayCallback(_PERIODIC_TIME_ENGINE, self.__onPeriodicTimerEngine) self.highlighter.highlight(True) if self.engineAudition is not None: self.engineAudition.setWeaponEnergy(self.__weaponEnergy) self.engineAudition.attachToModel(self.__compoundModel) if self.peripheralsController is not None: self.peripheralsController.attachToVehicle(self.__vehicle) if self.suspensionController is not None: self.suspensionController.setData( self.__vehicle.filter, self.__vehicle.typeDescriptor) if self.detailedEngineState is not None: self.detailedEngineState.onGearUpCbk = self.__onEngineStateGearUp self.delayCallback(_PERIODIC_TIME_DIRT[0][0], self.__onPeriodicTimerDirt) self.__systemStarted = True return def __stopSystems(self): if not self.__systemStarted: return else: self.__systemStarted = False if self.__periodicTimerID is not None: BigWorld.cancelCallback(self.__periodicTimerID) self.__periodicTimerID = None if self.flyingInfoProvider is not None: self.flyingInfoProvider.setData(None, None) if self.__vehicle.isPlayerVehicle: self.highlighter.highlight(False) self.stopCallback(self.__onPeriodicTimerEngine) self.stopCallback(self.__onPeriodicTimerDirt) if self.__trackScrollCtl is not None: self.__trackScrollCtl.deactivate() self.__trackScrollCtl.setData(None) if self.detailedEngineState is not None: self.detailedEngineState.onGearUpCbk = None return def __destroySystems(self): if self.__periodicTimerID is not None: BigWorld.cancelCallback(self.__periodicTimerID) self.__periodicTimerID = None if self.__trackScrollCtl is not None: self.__trackScrollCtl.deactivate() self.__trackScrollCtl = None if self.crashedTracksController is not None: self.crashedTracksController.destroy() self.crashedTracksController = None self.__systemStarted = False return def __destroyEngineAudition(self): self.engineAudition = None if self.detailedEngineState is not None: self.detailedEngineState.onEngineStart = None self.detailedEngineState.onStateChanged = None return def __prepareSystemsForDamagedVehicle(self, vehicle, isTurretDetached): if self.flyingInfoProvider is not None: self.flyingInfoProvider.setData(vehicle.filter, None) self.vehicleTraces = None self.suspensionSound = None self.swingingAnimator = None self.gunRecoil = None self.gunLinkedNodesAnimator = None self.suspension = None self.leveredSuspension = None self.trackNodesAnimator = None self.wheelsAnimator = None fashions = VehiclePartsTuple(None, None, None, None) self.__setFashions(fashions, isTurretDetached) self.customEffectManager = None self.__destroyEngineAudition() self.detailedEngineState = None self.trackCrashAudition = None self.frictionAudition = None self.terrainMatKindSensor = None self.__splineTracks = None model = self.compoundModel self.waterSensor.sensorPlaneLink = model.root self.peripheralsController = None self.dirtComponent = None self.tracks = None self.collisionObstaclesCollector = None self.tessellationCollisionSensor = None self.__destroySystems() return def destroy(self): if self.__vehicle is not None: self.deactivate() self.__destroySystems() ComponentSystem.destroy(self) self.__typeDesc = None if self.__boundEffects is not None: self.__boundEffects.destroy() self.__vehicleStickers = None self.onModelChanged = None self.__chassisDecal.destroy() self.__chassisDecal = None self.__compoundModel = None CallbackDelayer.destroy(self) return def start(self, prereqs=None): self.collisions = prereqs['collisionAssembler'] self.__typeDesc.chassis.hitTester.bbox = self.collisions.getBoundingBox( TankPartNames.getIdx(TankPartNames.CHASSIS)) self.__typeDesc.hull.hitTester.bbox = self.collisions.getBoundingBox( TankPartNames.getIdx(TankPartNames.HULL)) self.__typeDesc.turret.hitTester.bbox = self.collisions.getBoundingBox( TankPartNames.getIdx(TankPartNames.TURRET)) self.__typeDesc.gun.hitTester.bbox = self.collisions.getBoundingBox( TankPartNames.getIdx(TankPartNames.GUN)) self.__compoundModel = prereqs[self.__typeDesc.name] self.__boundEffects = bound_effects.ModelBoundEffects( self.__compoundModel) isCurrentModelDamaged = self.__currentDamageState.isCurrentModelDamaged fashions = camouflages.prepareFashions(isCurrentModelDamaged) if not isCurrentModelDamaged: model_assembler.setupTracksFashion(self.__typeDesc, fashions.chassis) self.__setFashions(fashions, self.__isTurretDetached) self.__setupModels() if not isCurrentModelDamaged: self.__splineTracks = model_assembler.setupSplineTracks( self.__fashion, self.__typeDesc, self.__compoundModel, prereqs) self.crashedTracksController = CrashedTrackController( self.__typeDesc, self.__fashion) else: self.__trackScrollCtl = None if self.__currentDamageState.effect is not None: self.__playEffect(self.__currentDamageState.effect, SpecialKeyPointNames.STATIC) self.__chassisDecal.create() return def showStickers(self, show): self.__vehicleStickers.show = show def updateTurretVisibility(self): self.__requestModelsRefresh() def changeVisibility(self, modelVisible): self.compoundModel.visible = modelVisible self.showStickers(modelVisible) if self.crashedTracksController is not None: self.crashedTracksController.setVisible(modelVisible) return def changeDrawPassVisibility(self, visibilityMask): colorPassEnabled = visibilityMask & BigWorld.ColorPassBit != 0 self.compoundModel.visible = visibilityMask self.compoundModel.skipColorPass = not colorPassEnabled self.showStickers(colorPassEnabled) if self.crashedTracksController is not None: self.crashedTracksController.setVisible(visibilityMask) return def onVehicleHealthChanged(self, showEffects=True): vehicle = self.__vehicle if not vehicle.isAlive() and vehicle.health > 0: self.changeEngineMode((0, 0)) currentState = self.__currentDamageState previousState = currentState.state isUnderWater = self.waterSensor.isUnderWater currentState.update(vehicle.health, vehicle.isCrewActive, isUnderWater) if previousState != currentState.state: if currentState.effect is not None and showEffects: self.__playEffect(currentState.effect) if vehicle.health <= 0: BigWorld.player().inputHandler.onVehicleDeath( vehicle, currentState.state == 'ammoBayExplosion') self.processVehicleDeath(currentState) self.__requestModelsRefresh() elif not vehicle.isCrewActive: self.__onCrewKilled() return @ComponentSystem.groupCall def processVehicleDeath(self, vehicleDamageState): pass def showAmmoBayEffect(self, mode, fireballVolume): if mode == constants.AMMOBAY_DESTRUCTION_MODE.POWDER_BURN_OFF: self.__playEffect('ammoBayBurnOff') return volumes = items.vehicles.g_cache.commonConfig['miscParams'][ 'explosionCandleVolumes'] candleIdx = 0 for idx, volume in enumerate(volumes): if volume >= fireballVolume: break candleIdx = idx + 1 if candleIdx > 0: self.__playEffect('explosionCandle%d' % candleIdx) else: self.__playEffect('explosion') def changeEngineMode(self, mode, forceSwinging=False): self.__engineMode = mode if self.detailedEngineState is not None: self.detailedEngineState.mode = self.__engineMode[0] if self.__trackScrollCtl is not None: self.__trackScrollCtl.setMode(self.__engineMode) return None if BattleReplay.isPlaying( ) and BattleReplay.g_replayCtrl.isTimeWarpInProgress else None def stopSwinging(self): if self.swingingAnimator is not None: self.swingingAnimator.accelSwingingPeriod = 0.0 return def removeDamageSticker(self, code): self.__vehicleStickers.delDamageSticker(code) def addDamageSticker(self, code, componentIdx, stickerID, segStart, segEnd): self.__vehicleStickers.addDamageSticker(code, componentIdx, stickerID, segStart, segEnd) def receiveShotImpulse(self, direction, impulse): if BattleReplay.isPlaying( ) and BattleReplay.g_replayCtrl.isTimeWarpInProgress: return else: if not VehicleDamageState.isDamagedModel( self.__currentDamageState.modelState): self.swingingAnimator.receiveShotImpulse(direction, impulse) if self.crashedTracksController is not None: self.crashedTracksController.receiveShotImpulse( direction, impulse) return def recoil(self): gunNode = self.compoundModel.node(TankNodeNames.GUN_INCLINATION) impulseDir = Math.Matrix(gunNode).applyVector(Math.Vector3(0, 0, -1)) impulseValue = self.__typeDesc.gun.impulse self.receiveShotImpulse(impulseDir, impulseValue) self.gunRecoil.recoil() node = self.compoundModel.node('HP_gunFire') gunPos = Math.Matrix(node).translation BigWorld.player().inputHandler.onVehicleShaken( self.__vehicle, gunPos, impulseDir, self.__typeDesc.shot.shell.caliber, ShakeReason.OWN_SHOT_DELAYED) def addCrashedTrack(self, isLeft): if not self.__vehicle.isAlive(): return else: if self.crashedTracksController is not None: self.crashedTracksController.addTrack( isLeft, self.isLeftSideFlying if isLeft else self.isRightSideFlying) if not self.__vehicle.isEnteringWorld and self.trackCrashAudition: self.trackCrashAudition.playCrashSound(isLeft) return def delCrashedTrack(self, isLeft): if self.crashedTracksController is not None: self.crashedTracksController.delTrack(isLeft) if not self.__vehicle.isEnteringWorld and self.trackCrashAudition and self.__vehicle.isPlayerVehicle: self.trackCrashAudition.playCrashSound(isLeft, True) return def __prepareOutfit(self, outfitCD): if self.__outfit: return outfit = Outfit(outfitCD) player = BigWorld.player() forceHistorical = player.isHistoricallyAccurate and player.playerVehicleID != self.__vID and not outfit.isHistorical( ) self.__outfit = Outfit() if forceHistorical else outfit def __applyVehicleOutfit(self): camouflages.updateFashions( self.__fashions, self.__typeDesc, self.__currentDamageState.isCurrentModelDamaged, self.__outfit) def getBounds(self, partIdx): return self.collisions.getBoundingBox( partIdx) if self.collisions is not None else (Math.Vector3( 0.0, 0.0, 0.0), Math.Vector3(0.0, 0.0, 0.0), 0) def __requestModelsRefresh(self): modelsSetParams = self.modelsSetParams assembler = model_assembler.prepareCompoundAssembler( self.__typeDesc, modelsSetParams, self.__vehicle.spaceID, self.__vehicle.isTurretDetached) BigWorld.loadResourceListBG((assembler, ), makeCallbackWeak(self.__onModelsRefresh, modelsSetParams.state), loadingPriority(self.__vehicle.id)) def __onModelsRefresh(self, modelState, resourceList): if BattleReplay.isFinished(): return elif self.__vehicle is None: return else: prevTurretYaw = Math.Matrix(self.turretMatrix).yaw prevGunPitch = Math.Matrix(self.gunMatrix).pitch vehicle = self.__vehicle newCompoundModel = resourceList[self.__typeDesc.name] self.deactivate(False) self.shadowManager.reattachCompoundModel(vehicle, self.__compoundModel, newCompoundModel) self.__compoundModel = newCompoundModel self.__isTurretDetached = vehicle.isTurretDetached self.__prepareSystemsForDamagedVehicle(vehicle, self.__isTurretDetached) self.__setupModels() self.setVehicle(vehicle) self.activate() self.__reattachComponents(self.__compoundModel, self.__weaponEnergy) self.__filter.syncGunAngles(prevTurretYaw, prevGunPitch) model_assembler.setupTurretRotations(self) return def __setupModels(self): self.__isAlive = not self.__currentDamageState.isCurrentModelDamaged if self.__isAlive: _, gunLength = self.computeVehicleHeight() self.__weaponEnergy = gunLength * self.__typeDesc.shot.shell.caliber if MAX_DISTANCE > 0: transform = self.__typeDesc.chassis.AODecals[0] self.__attachSplodge( BigWorld.Splodge(transform, MAX_DISTANCE, self.__typeDesc.chassis.hullPosition.y)) def __reattachComponents(self, model, weaponEnergy): self.__boundEffects.reattachTo(model) if self.__effectsPlayer is not None: self.__effectsPlayer.reattachTo(model) if self.engineAudition is not None: self.engineAudition.setWeaponEnergy(weaponEnergy) self.engineAudition.attachToModel(model) return def __playEffect(self, kind, *modifs): self.__stopEffects() if kind == 'empty' or self.__vehicle is None: return else: enableDecal = True if kind in ('explosion', 'destruction') and self.isFlying: enableDecal = False if self.isUnderwater: if kind not in ('submersionDeath', ): return effects = self.typeDescriptor.type.effects[kind] if not effects: return vehicle = self.__vehicle effects = random.choice(effects) self.__effectsPlayer = EffectsListPlayer( effects[1], effects[0], showShockWave=vehicle.isPlayerVehicle, showFlashBang=vehicle.isPlayerVehicle, isPlayer=vehicle.isPlayerVehicle, showDecal=enableDecal, start=vehicle.position + Math.Vector3(0.0, 1.0, 0.0), end=vehicle.position + Math.Vector3(0.0, -1.0, 0.0), entity_id=vehicle.id) self.__effectsPlayer.play(self.__compoundModel, *modifs) return def __stopEffects(self): if self.__effectsPlayer is not None: self.__effectsPlayer.stop() self.__effectsPlayer = None return def __onCrewKilled(self): self.__destroyEngineAudition() if self.customEffectManager is not None: self.customEffectManager = None return def onWaterSplash(self, waterHitPoint, isHeavySplash): effectName = 'waterCollisionHeavy' if isHeavySplash else 'waterCollisionLight' self.__vehicle.showCollisionEffect(waterHitPoint, effectName, Math.Vector3(0.0, 1.0, 0.0)) def onUnderWaterSwitch(self, isUnderWater): if isUnderWater and self.__effectsPlayer is not None and self.__currentDamageState.effect not in ( 'submersionDeath', ): self.__stopEffects() extra = self.__vehicle.typeDescriptor.extrasDict['fire'] if extra.isRunningFor(self.__vehicle): extra.checkUnderwater(self.__vehicle, isUnderWater) return def updateTracksScroll(self, leftScroll, rightScroll): self.__leftTrackScroll = leftScroll self.__rightTrackScroll = rightScroll if self.__trackScrollCtl is not None: self.__trackScrollCtl.setExternal(leftScroll, rightScroll) return def __onPeriodicTimerEngine(self): if self.detailedEngineState is None or self.engineAudition is None: return else: if self.siegeEffects is not None: self.siegeEffects.tick(_PERIODIC_TIME_ENGINE) return _PERIODIC_TIME_ENGINE def __onPeriodicTimer(self): timeStamp = BigWorld.wg_getFrameTimestamp() if CompoundAppearance.frameTimeStamp >= timeStamp: self.__periodicTimerID = BigWorld.callback(0.0, self.__onPeriodicTimer) return else: CompoundAppearance.frameTimeStamp = timeStamp self.__periodicTimerID = BigWorld.callback(_PERIODIC_TIME, self.__onPeriodicTimer) if self.__vehicle is None: return vehicle = self.__vehicle if self.peripheralsController is not None: self.peripheralsController.update(vehicle, self.crashedTracksController) if not vehicle.isAlive(): return distanceFromPlayer = self.lodCalculator.lodDistance self.__updateCurrTerrainMatKinds() if not self.__vehicle.isPlayerVehicle: if self.siegeEffects is not None: self.siegeEffects.tick(_PERIODIC_TIME) self.__updateEffectsLOD(distanceFromPlayer) if self.customEffectManager: self.customEffectManager.update() return def __onPeriodicTimerDirt(self): if self.__fashion is None: return else: dt = 1.0 distanceFromPlayer = self.lodCalculator.lodDistance if 0.0 <= distanceFromPlayer < _PERIODIC_TIME_DIRT[1][1]: time = BigWorld.time() simDt = time - self.__dirtUpdateTime if simDt > 0.0: if self.dirtComponent: roll = Math.Matrix(self.__compoundModel.matrix).roll hasContact = 0 waterHeight = self.waterHeight if math.fabs(roll) > math.radians(120.0): hasContact = 2 if self.waterSensor.isInWater: waterHeight = 1.0 elif self.__trackScrollCtl is not None: hasContact = 0 if self.__trackScrollCtl.hasContact( ) else 1 self.dirtComponent.update( self.filter.averageSpeed, waterHeight, self.waterSensor.waterHeightWorld, self.__currTerrainMatKind[2], hasContact, simDt) self.__dirtUpdateTime = time if distanceFromPlayer <= _PERIODIC_TIME_DIRT[1][0]: dt = _PERIODIC_TIME_DIRT[0][0] else: dt = _PERIODIC_TIME_DIRT[0][ 0] + _DIRT_ALPHA * distanceFromPlayer return dt def __updateEffectsLOD(self, distanceFromPlayer): if self.customEffectManager: enableExhaust = distanceFromPlayer <= _LOD_DISTANCE_EXHAUST and not self.isUnderwater enableTrails = distanceFromPlayer <= _LOD_DISTANCE_TRAIL_PARTICLES and BigWorld.wg_isVehicleDustEnabled( ) self.customEffectManager.enable(enableTrails, EffectSettings.SETTING_DUST) self.customEffectManager.enable(enableExhaust, EffectSettings.SETTING_EXHAUST) def __updateCurrTerrainMatKinds(self): if self.terrainMatKindSensor is None: return else: matKinds = self.terrainMatKindSensor.matKinds matKindsCount = len(matKinds) for i in xrange(_MATKIND_COUNT): matKind = matKinds[i] if i < matKindsCount else 0 self.__currTerrainMatKind[i] = matKind effectIndex = calcEffectMaterialIndex(matKind) effectMaterialName = '' if effectIndex is not None: effectMaterialName = material_kinds.EFFECT_MATERIALS[ effectIndex] self.__terrainEffectMaterialNames[i] = effectMaterialName if self.vehicleTraces is not None: self.vehicleTraces.setCurrTerrainMatKinds( self.__currTerrainMatKind[0], self.__currTerrainMatKind[1]) return def switchFireVibrations(self, bStart): if self.peripheralsController is not None: self.peripheralsController.switchFireVibrations(bStart) return def executeHitVibrations(self, hitEffectCode): if self.peripheralsController is not None: self.peripheralsController.executeHitVibrations(hitEffectCode) return def executeRammingVibrations(self, matKind=None): if self.peripheralsController is not None: self.peripheralsController.executeRammingVibrations( self.__vehicle, matKind) return def executeShootingVibrations(self, caliber): if self.peripheralsController is not None: self.peripheralsController.executeShootingVibrations(caliber) return def executeCriticalHitVibrations(self, vehicle, extrasName): if self.peripheralsController is not None: self.peripheralsController.executeCriticalHitVibrations( vehicle, extrasName) return def deviceStateChanged(self, deviceName, state): if not self.isUnderwater and self.detailedEngineState is not None and deviceName == 'engine': engineState = engine_state.getEngineStateFromName(state) self.detailedEngineState.engineState = engineState return def __linkCompound(self): vehicle = self.__vehicle vehicle.model = None vehicle.model = self.__compoundModel vehicleMatrix = vehicle.matrix self.__compoundModel.matrix = vehicleMatrix return def __createStickers(self): if self.__vehicleStickers is not None: return else: insigniaRank = self.__vehicle.publicInfo['marksOnGun'] self.__vehicleStickers = VehicleStickers(self.__typeDesc, insigniaRank, self.__outfit) clanID = BigWorld.player().arena.vehicles[ self.__vehicle.id]['clanDBID'] self.__vehicleStickers.setClanID(clanID) return def __attachStickers(self, alpha=_DEFAULT_STICKERS_ALPHA, emblemsOnly=False): self.__vehicleStickers.alpha = alpha self.__vehicleStickers.attach( self.compoundModel, self.__currentDamageState.isCurrentModelDamaged, not emblemsOnly) def __createAndAttachStickers(self): isCurrentModelDamaged = self.__currentDamageState.isCurrentModelDamaged stickersAlpha = _DEFAULT_STICKERS_ALPHA if isCurrentModelDamaged: stickersAlpha = items.vehicles.g_cache.commonConfig['miscParams'][ 'damageStickerAlpha'] self.__createStickers() self.__attachStickers(stickersAlpha, isCurrentModelDamaged) def __attachSplodge(self, splodge): node = self.__compoundModel.node(TankPartNames.HULL) if splodge: self.__splodge = splodge node.attach(splodge) def __disableStipple(self): self.compoundModel.stipple = False def computeVehicleHeight(self): gunLength = 0.0 height = 0.0 if self.collisions is not None: desc = self.__typeDesc hullBB = self.collisions.getBoundingBox( TankPartNames.getIdx(TankPartNames.HULL)) turretBB = self.collisions.getBoundingBox( TankPartNames.getIdx(TankPartNames.TURRET)) gunBB = self.collisions.getBoundingBox( TankPartNames.getIdx(TankPartNames.GUN)) hullTopY = desc.chassis.hullPosition[1] + hullBB[1][1] turretTopY = desc.chassis.hullPosition[ 1] + desc.hull.turretPositions[0][1] + turretBB[1][1] gunTopY = desc.chassis.hullPosition[1] + desc.hull.turretPositions[ 0][1] + desc.turret.gunPosition[1] + gunBB[1][1] gunLength = math.fabs(gunBB[1][2] - gunBB[0][2]) height = max(hullTopY, max(turretTopY, gunTopY)) return (height, gunLength) def setupGunMatrixTargets(self, target=None): if target is None: target = self.__filter self.turretMatrix.target = target.turretMatrix self.gunMatrix.target = target.gunMatrix return def onFriction(self, otherID, frictionPoint, state): if self.frictionAudition is not None: self.frictionAudition.processFriction(otherID, frictionPoint, state) return def assembleStipple(self): compound = self.compoundModel compound.matrix = Math.Matrix(compound.matrix) hullNode = compound.node(TankPartNames.HULL) compound.node(TankPartNames.HULL, hullNode.localMatrix) turretRotation = compound.node(TankPartNames.TURRET) if turretRotation is not None: compound.node(TankPartNames.TURRET, turretRotation.localMatrix) gunInclination = compound.node(TankNodeNames.GUN_INCLINATION) if gunInclination is not None: compound.node(TankNodeNames.GUN_INCLINATION, gunInclination.localMatrix) gunRecoil = compound.node(TankNodeNames.GUN_RECOIL) if gunRecoil is not None: compound.node(TankNodeNames.GUN_RECOIL, gunRecoil.localMatrix) self.fashions = VehiclePartsTuple(None, None, None, None) return def onSiegeStateChanged(self, newState): if self.engineAudition is not None: self.engineAudition.onSiegeStateChanged(newState) if self.suspensionController is not None: self.suspensionController.onSiegeStateChanged(newState) if self.suspensionSound is not None: self.__suspensionSound.vehicleState = newState if self.siegeEffects is not None: self.siegeEffects.onSiegeStateChanged(newState) return def __onCameraChanged(self, cameraName, currentVehicleId=None): if self.engineAudition is not None: self.engineAudition.onCameraChanged( cameraName, currentVehicleId if currentVehicleId is not None else 0) return def __onEngineStateGearUp(self): if self.customEffectManager is not None: self.customEffectManager.onGearUp() if self.engineAudition is not None: self.engineAudition.onEngineGearUp() return def addCameraCollider(self): collider = self.collisions if collider is not None: colliderData = (collider.getColliderID(), (TankPartNames.getIdx(TankPartNames.HULL), TankPartNames.getIdx(TankPartNames.TURRET))) BigWorld.appendCameraCollider(colliderData) return def removeCameraCollider(self): collider = self.collisions if collider is not None: BigWorld.removeCameraCollider(collider.getColliderID()) return
class CommonTankAppearance(ScriptGameObject): compoundModel = property(lambda self: self._compoundModel) boundEffects = property(lambda self: self.__boundEffects) fashions = property(lambda self: self.__fashions) fashion = property(lambda self: self.fashions.chassis) typeDescriptor = property(lambda self: self.__typeDesc) id = property(lambda self: self.__vID) isAlive = property(lambda self: self.__isAlive) isObserver = property(lambda self: self.__isObserver) outfit = property(lambda self: self.__outfit) renderState = property(lambda self: self.__renderState) def _setFashions(self, fashions, isTurretDetached=False): self.__fashions = fashions if isTurretDetached: self.compoundModel.setupFashions((fashions.chassis, fashions.hull)) else: self.compoundModel.setupFashions(fashions) terrainMatKind = property(lambda self: self.__currTerrainMatKind) terrainGroundType = property(lambda self: self.__currTerrainGroundType) terrainEffectMaterialNames = property(lambda self: self.__terrainEffectMaterialNames) isInWater = property(lambda self: self.waterSensor.isInWater) isUnderwater = property(lambda self: self.waterSensor.isUnderWater) waterHeight = property(lambda self: self.waterSensor.waterHeight) damageState = property(lambda self: self.__currentDamageState) modelsSetParams = property(lambda self: ModelsSetParams(self.outfit.modelsSet, self.damageState.modelState, self.__attachments)) splineTracks = property(lambda self: self._splineTracks) isFlying = property(lambda self: self.flyingInfoProvider is not None and self.flyingInfoProvider.isFlying) isLeftSideFlying = property(lambda self: self.flyingInfoProvider is not None and self.flyingInfoProvider.isLeftSideFlying) isRightSideFlying = property(lambda self: self.flyingInfoProvider is not None and self.flyingInfoProvider.isRightSideFlying) trackScrollController = property(lambda self: self.__trackScrollCtl) wheelsState = property(lambda self: 0) burnoutLevel = property(lambda self: 0.0) filterRetrievers = property(lambda self: self.__filterRetrievers) allLodCalculators = property(lambda self: self.__allLodCalculators) transmissionSlip = property(lambda self: self._commonSlip) transmissionScroll = property(lambda self: self._commonScroll) vehicleStickers = property(lambda self: self._vehicleStickers) isTurretDetached = property(lambda self: self._isTurretDetached) _weaponEnergy = property(lambda self: self.__weaponEnergy) filter = AutoProperty() areaTriggerTarget = ComponentDescriptor() burnoutProcessor = ComponentDescriptor() c11nComponent = ComponentDescriptor() collisionObstaclesCollector = ComponentDescriptor() collisions = ComponentDescriptor() crashedTracksController = ComponentDescriptor() customEffectManager = ComponentDescriptor() detailedEngineState = ComponentDescriptor() dirtComponent = ComponentDescriptor() engineAudition = ComponentDescriptor() flyingInfoProvider = ComponentDescriptor() frictionAudition = ComponentDescriptor() gearbox = ComponentDescriptor() gunLinkedNodesAnimator = ComponentDescriptor() gunRecoil = ComponentDescriptor() gunAnimators = [ComponentDescriptor()] gunRotatorAudition = ComponentDescriptor() hullAimingController = ComponentDescriptor() leveredSuspension = ComponentDescriptor() lodCalculator = ComponentDescriptor() shadowManager = ComponentDescriptor() siegeEffects = ComponentDescriptor() suspension = ComponentDescriptor() suspensionSound = ComponentDescriptor() swingingAnimator = ComponentDescriptor() terrainMatKindSensor = ComponentDescriptor() tessellationCollisionSensor = ComponentDescriptor() trackNodesAnimator = ComponentDescriptor() tracks = ComponentDescriptor() transform = ComponentDescriptor() vehicleTraces = ComponentDescriptor() waterSensor = ComponentDescriptor() wheeledLodCalculator = ComponentDescriptor() wheelsAnimator = ComponentDescriptor() flagComponent = ComponentDescriptor() def __init__(self, spaceID): ScriptGameObject.__init__(self, spaceID) self._vehicle = None self.__filter = None self.__typeDesc = None self.crashedTracksController = None self.__currentDamageState = VehicleDamageState() self.__currTerrainMatKind = [-1] * MATKIND_COUNT self.__currTerrainGroundType = [-1] * MATKIND_COUNT self.__terrainEffectMaterialNames = [''] * MATKIND_COUNT self._chassisDecal = VehicleDecal(self) self.__splodge = None self.__boundEffects = None self._splineTracks = None self.flyingInfoProvider = self.createComponent(Vehicular.FlyingInfoProvider) self.__trackScrollCtl = BigWorld.PyTrackScroll() self.__trackScrollCtl.setFlyingInfo(DataLinks.createBoolLink(self.flyingInfoProvider, 'isLeftSideFlying'), DataLinks.createBoolLink(self.flyingInfoProvider, 'isRightSideFlying')) self.__weaponEnergy = 0.0 self.__outfit = None self.__systemStarted = False self.__isAlive = True self._isTurretDetached = False self.__isObserver = False self.__attachments = [] self.__modelAnimators = [] self.turretMatrix = None self.gunMatrix = None self.__allLodCalculators = [] self._commonScroll = 0.0 self._commonSlip = 0.0 self._compoundModel = None self.__fashions = None self.__filterRetrievers = [] self._vehicleStickers = None self.__vID = 0 self.__renderState = None self.__frameTimestamp = 0 self.__periodicTimerID = None return def prerequisites(self, typeDescriptor, vID, health, isCrewActive, isTurretDetached, outfitCD, renderState=None): self.damageState.update(health, isCrewActive, False) self.__typeDesc = typeDescriptor self.__vID = vID self._isTurretDetached = isTurretDetached self.__outfit = self._prepareOutfit(outfitCD) if self.damageState.isCurrentModelUndamaged: self.__attachments = camouflages.getAttachments(self.outfit, self.typeDescriptor) self.__renderState = renderState prereqs = self.typeDescriptor.prerequisites(True) prereqs.extend(camouflages.getCamoPrereqs(self.outfit, self.typeDescriptor)) prereqs.extend(camouflages.getModelAnimatorsPrereqs(self.outfit, self.worldID)) prereqs.extend(camouflages.getAttachmentsAnimatorsPrereqs(self.__attachments, self.worldID)) splineDesc = self.typeDescriptor.chassis.splineDesc if splineDesc is not None: modelsSet = self.outfit.modelsSet prereqs.append(splineDesc.segmentModelLeft(modelsSet)) prereqs.append(splineDesc.segmentModelRight(modelsSet)) segment2ModelLeft = splineDesc.segment2ModelLeft(modelsSet) if segment2ModelLeft is not None: prereqs.append(segment2ModelLeft) segment2ModelRight = splineDesc.segment2ModelRight(modelsSet) if segment2ModelRight is not None: prereqs.append(segment2ModelRight) modelsSetParams = self.modelsSetParams compoundAssembler = model_assembler.prepareCompoundAssembler(self.typeDescriptor, modelsSetParams, self.worldID, self.isTurretDetached, renderState=self.renderState) prereqs.append(compoundAssembler) if renderState == RenderStates.OVERLAY_COLLISION: self.damageState.update(0, isCrewActive, False) if not isTurretDetached: bspModels = ((TankPartNames.getIdx(TankPartNames.CHASSIS), typeDescriptor.chassis.hitTester.bspModelName), (TankPartNames.getIdx(TankPartNames.HULL), typeDescriptor.hull.hitTester.bspModelName), (TankPartNames.getIdx(TankPartNames.TURRET), typeDescriptor.turret.hitTester.bspModelName), (TankPartNames.getIdx(TankPartNames.GUN), typeDescriptor.gun.hitTester.bspModelName)) else: bspModels = ((TankPartNames.getIdx(TankPartNames.CHASSIS), typeDescriptor.chassis.hitTester.bspModelName), (TankPartNames.getIdx(TankPartNames.HULL), typeDescriptor.hull.hitTester.bspModelName)) collisionAssembler = BigWorld.CollisionAssembler(bspModels, self.worldID) prereqs.append(collisionAssembler) physicalTracksBuilders = self.typeDescriptor.chassis.physicalTracks for name, builders in physicalTracksBuilders.iteritems(): for index, builder in enumerate(builders): prereqs.append(builder.createLoader(self.worldID, '{0}{1}PhysicalTrack'.format(name, index), modelsSetParams.skin)) return prereqs def construct(self, isPlayer, resourceRefs): self.collisions = resourceRefs['collisionAssembler'] self.typeDescriptor.chassis.hitTester.bbox = self.collisions.getBoundingBox(TankPartNames.getIdx(TankPartNames.CHASSIS)) self.typeDescriptor.hull.hitTester.bbox = self.collisions.getBoundingBox(TankPartNames.getIdx(TankPartNames.HULL)) self.typeDescriptor.turret.hitTester.bbox = self.collisions.getBoundingBox(TankPartNames.getIdx(TankPartNames.TURRET)) self.typeDescriptor.gun.hitTester.bbox = self.collisions.getBoundingBox(TankPartNames.getIdx(TankPartNames.GUN)) self.__isObserver = 'observer' in self.typeDescriptor.type.tags self._compoundModel = resourceRefs[self.typeDescriptor.name] self.__boundEffects = bound_effects.ModelBoundEffects(self.compoundModel) isCurrentModelDamaged = self.damageState.isCurrentModelDamaged fashions = camouflages.prepareFashions(isCurrentModelDamaged) if not isCurrentModelDamaged: model_assembler.setupTracksFashion(self.typeDescriptor, fashions.chassis) self._setFashions(fashions, self.isTurretDetached) self._setupModels() if not isCurrentModelDamaged: modelsSet = self.outfit.modelsSet self._splineTracks = model_assembler.setupSplineTracks(self.fashion, self.typeDescriptor, self.compoundModel, resourceRefs, modelsSet) self.crashedTracksController = CrashedTrackController(self.typeDescriptor, self.fashion, modelsSet) else: self.__trackScrollCtl = None self._chassisDecal.create() self.__modelAnimators = camouflages.getModelAnimators(self.outfit, self.typeDescriptor, self.worldID, resourceRefs, self.compoundModel) if self.modelsSetParams.state == 'undamaged': self.__modelAnimators.extend(camouflages.getAttachmentsAnimators(self.__attachments, self.worldID, resourceRefs, self.compoundModel)) self.transform = self.createComponent(GenericComponents.TransformComponent, Math.Vector3(0, 0, 0)) self.areaTriggerTarget = self.createComponent(Triggers.AreaTriggerTarget) self.__filter = model_assembler.createVehicleFilter(self.typeDescriptor) compoundModel = self.compoundModel if self.isAlive: self.detailedEngineState, self.gearbox = model_assembler.assembleDrivetrain(self, isPlayer) if not gEffectsDisabled(): self.customEffectManager = CustomEffectManager(self) if self.typeDescriptor.hasSiegeMode: self.siegeEffects = SiegeEffectsController(self, isPlayer) model_assembler.assembleVehicleAudition(isPlayer, self) self.detailedEngineState.onEngineStart = self._onEngineStart self.detailedEngineState.onStateChanged = self.engineAudition.onEngineStateChanged if isPlayer: turret = self.typeDescriptor.turret gunRotatorAudition = self.createComponent(Vehicular.GunRotatorAudition, turret.turretRotatorSoundManual, turret.weight / 1000.0, compoundModel.node(TankPartNames.TURRET)) gunRotatorAudition.vehicleMatrixLink = self.compoundModel.root gunRotatorAudition.damaged = lambda : self.turretDamaged() gunRotatorAudition.maxTurretRotationSpeed = lambda : self.maxTurretRotationSpeed() self.gunRotatorAudition = gunRotatorAudition self.frictionAudition = self.createComponent(Vehicular.FrictionAudition, TANK_FRICTION_EVENT) isLodTopPriority = isPlayer lodCalcInst = self.createComponent(Vehicular.LodCalculator, DataLinks.linkMatrixTranslation(compoundModel.matrix), True, VEHICLE_PRIORITY_GROUP, isLodTopPriority) self.lodCalculator = lodCalcInst self.allLodCalculators.append(lodCalcInst) lodLink = DataLinks.createFloatLink(lodCalcInst, 'lodDistance') lodStateLink = lodCalcInst.lodStateLink if IS_EDITOR: matrixBinding = None changeCamera = None else: matrixBinding = BigWorld.player().consistentMatrices.onVehicleMatrixBindingChanged changeCamera = BigWorld.player().inputHandler.onCameraChanged self.shadowManager = VehicleShadowManager(compoundModel, matrixBinding, changeCamera) if not self.damageState.isCurrentModelDamaged: self.__assembleNonDamagedOnly(resourceRefs, isPlayer, lodLink, lodStateLink) dirtEnabled = BigWorld.WG_dirtEnabled() and 'HD' in self.typeDescriptor.type.tags if dirtEnabled and self.fashions is not None: dirtHandlers = [BigWorld.PyDirtHandler(True, compoundModel.node(TankPartNames.CHASSIS).position.y), BigWorld.PyDirtHandler(False, compoundModel.node(TankPartNames.HULL).position.y), BigWorld.PyDirtHandler(False, compoundModel.node(TankPartNames.TURRET).position.y), BigWorld.PyDirtHandler(False, compoundModel.node(TankPartNames.GUN).position.y)] modelHeight, _ = self.computeVehicleHeight() self.dirtComponent = self.createComponent(Vehicular.DirtComponent, dirtHandlers, modelHeight) for fashionIdx, _ in enumerate(TankPartNames.ALL): self.fashions[fashionIdx].addMaterialHandler(dirtHandlers[fashionIdx]) self.fashions[fashionIdx].addTrackMaterialHandler(dirtHandlers[fashionIdx]) model_assembler.setupTurretRotations(self) self.waterSensor = model_assembler.assembleWaterSensor(self.typeDescriptor, self, lodStateLink, self.worldID) if self.engineAudition is not None: self.engineAudition.setIsUnderwaterInfo(DataLinks.createBoolLink(self.waterSensor, 'isUnderWater')) self.engineAudition.setIsInWaterInfo(DataLinks.createBoolLink(self.waterSensor, 'isInWater')) self.__postSetupFilter() compoundModel.setPartBoundingBoxAttachNode(TankPartIndexes.GUN, TankNodeNames.GUN_INCLINATION) camouflages.updateFashions(self) model_assembler.assembleCustomLogicComponents(self, self.__attachments, self.__modelAnimators) return def destroy(self): self.flagComponent = None self.__modelAnimators = [] self._destroySystems() fashions = VehiclePartsTuple(None, None, None, None) self._setFashions(fashions, self._isTurretDetached) super(CommonTankAppearance, self).destroy() self.__typeDesc = None if self.boundEffects is not None: self.boundEffects.destroy() self._vehicleStickers = None self._chassisDecal.destroy() self._chassisDecal = None self._compoundModel = None return def activate(self): if self.collisions is not None and self.isTurretDetached: self.collisions.removeAttachment(TankPartNames.getIdx(TankPartNames.TURRET)) self.collisions.removeAttachment(TankPartNames.getIdx(TankPartNames.GUN)) super(CommonTankAppearance, self).activate() if not self.isObserver: self._chassisDecal.attach() self._createAndAttachStickers() if not self.isObserver: if not self.damageState.isCurrentModelDamaged and not self.__systemStarted: self._startSystems() self.filter.enableLagDetection(not self.damageState.isCurrentModelDamaged) if self.__periodicTimerID is not None: BigWorld.cancelCallback(self.__periodicTimerID) self.__periodicTimerID = BigWorld.callback(PERIODIC_UPDATE_TIME, self.__onPeriodicTimer) self.setupGunMatrixTargets(self.filter) for lodCalculator in self.allLodCalculators: lodCalculator.setupPosition(DataLinks.linkMatrixTranslation(self.compoundModel.matrix)) for modelAnimator in self.__modelAnimators: modelAnimator.animator.start() if hasattr(self.filter, 'placingCompensationMatrix') and self.swingingAnimator is not None: self.swingingAnimator.placingCompensationMatrix = self.filter.placingCompensationMatrix self.swingingAnimator.worldMatrix = self.compoundModel.matrix if self.isObserver: self.compoundModel.visible = False if self.collisions is not None: chassisColisionMatrix, gunNodeName = self._vehicleColliderInfo collisionData = ((TankPartNames.getIdx(TankPartNames.HULL), self.compoundModel.node(TankPartNames.HULL)), (TankPartNames.getIdx(TankPartNames.TURRET), self.compoundModel.node(TankPartNames.TURRET)), (TankPartNames.getIdx(TankPartNames.CHASSIS), chassisColisionMatrix), (TankPartNames.getIdx(TankPartNames.GUN), self.compoundModel.node(gunNodeName))) self.collisions.connect(self.id, ColliderTypes.VEHICLE_COLLIDER, collisionData) return def deactivate(self): for modelAnimator in self.__modelAnimators: modelAnimator.animator.stop() if self.damageState and self.damageState.isCurrentModelDamaged: self.__modelAnimators = [] self.shadowManager.unregisterCompoundModel(self.compoundModel) if self.__systemStarted: self._stopSystems() super(CommonTankAppearance, self).deactivate() self._chassisDecal.detach() self.filter.enableLagDetection(False) if self.vehicleStickers: self.vehicleStickers.detach() def setupGunMatrixTargets(self, target): self.turretMatrix = target.turretMatrix self.gunMatrix = target.gunMatrix def receiveShotImpulse(self, direction, impulse): if not VehicleDamageState.isDamagedModel(self.damageState.modelState): self.swingingAnimator.receiveShotImpulse(direction, impulse) if self.crashedTracksController is not None: self.crashedTracksController.receiveShotImpulse(direction, impulse) return def computeVehicleHeight(self): gunLength = 0.0 height = 0.0 if self.collisions is not None: desc = self.typeDescriptor hullBB = self.collisions.getBoundingBox(TankPartNames.getIdx(TankPartNames.HULL)) turretBB = self.collisions.getBoundingBox(TankPartNames.getIdx(TankPartNames.TURRET)) gunBB = self.collisions.getBoundingBox(TankPartNames.getIdx(TankPartNames.GUN)) hullTopY = desc.chassis.hullPosition[1] + hullBB[1][1] turretTopY = desc.chassis.hullPosition[1] + desc.hull.turretPositions[0][1] + turretBB[1][1] gunTopY = desc.chassis.hullPosition[1] + desc.hull.turretPositions[0][1] + desc.turret.gunPosition[1] + gunBB[1][1] gunLength = math.fabs(gunBB[1][2] - gunBB[0][2]) height = max(hullTopY, max(turretTopY, gunTopY)) return (height, gunLength) def onWaterSplash(self, waterHitPoint, isHeavySplash): pass def onUnderWaterSwitch(self, isUnderWater): pass def getWheelsSteeringMax(self): pass def _prepareOutfit(self, outfitCD): outfitComponent = camouflages.getOutfitComponent(outfitCD) return Outfit(component=outfitComponent, vehicleCD=self.typeDescriptor.makeCompactDescr()) def _setupModels(self): self.__isAlive = not self.damageState.isCurrentModelDamaged if self.isAlive: _, gunLength = self.computeVehicleHeight() self.__weaponEnergy = gunLength * self.typeDescriptor.shot.shell.caliber if MAX_DISTANCE > 0 and not self.isObserver: transform = self.typeDescriptor.chassis.AODecals[0] splodge = BigWorld.Splodge(transform, MAX_DISTANCE, self.typeDescriptor.chassis.hullPosition.y) if splodge: self.__splodge = splodge node = self.compoundModel.node(TankPartNames.HULL) node.attach(splodge) def _createStickers(self): return VehicleStickers(self.typeDescriptor, 0, self.outfit) @property def _vehicleColliderInfo(self): chassisColisionMatrix = self.compoundModel.matrix if self.damageState.isCurrentModelDamaged: gunNodeName = 'gun' else: gunNodeName = TankNodeNames.GUN_INCLINATION return (chassisColisionMatrix, gunNodeName) def _startSystems(self): self.__systemStarted = True if self.flyingInfoProvider is not None: self.flyingInfoProvider.setData(self.filter, self.suspension) if self.trackScrollController is not None: self.trackScrollController.activate() self.trackScrollController.setData(self.filter) if self.engineAudition is not None: self.engineAudition.setWeaponEnergy(self._weaponEnergy) self.engineAudition.attachToModel(self.compoundModel) if self.hullAimingController is not None: self.hullAimingController.setData(self.filter, self.typeDescriptor) return def _stopSystems(self): self.__systemStarted = False if self.flyingInfoProvider is not None: self.flyingInfoProvider.setData(None, None) if self.trackScrollController is not None: self.trackScrollController.deactivate() self.trackScrollController.setData(None) if self.__periodicTimerID is not None: BigWorld.cancelCallback(self.__periodicTimerID) self.__periodicTimerID = None return def _destroySystems(self): self.__systemStarted = False if self.trackScrollController is not None: self.trackScrollController.deactivate() self.__trackScrollCtl = None if self.crashedTracksController is not None: self.crashedTracksController.destroy() self.crashedTracksController = None if self.__periodicTimerID is not None: BigWorld.cancelCallback(self.__periodicTimerID) self.__periodicTimerID = None return def _onRequestModelsRefresh(self): self.flagComponent = None return def _onEngineStart(self): if self.engineAudition is not None: self.engineAudition.onEngineStart() return def __assembleNonDamagedOnly(self, resourceRefs, isPlayer, lodLink, lodStateLink): model_assembler.assembleTerrainMatKindSensor(self, lodStateLink, self.worldID) model_assembler.assembleRecoil(self, lodLink) model_assembler.assembleMultiGunRecoil(self, lodLink) model_assembler.assembleGunLinkedNodesAnimator(self) model_assembler.assembleCollisionObstaclesCollector(self, lodStateLink, self.typeDescriptor, self.worldID) model_assembler.assembleTessellationCollisionSensor(self, lodStateLink) wheelsScroll = None wheelsSteering = None generalWheelsAnimatorConfig = self.typeDescriptor.chassis.generalWheelsAnimatorConfig if generalWheelsAnimatorConfig is not None: scrollableWheelsCount = generalWheelsAnimatorConfig.getNonTrackWheelsCount() wheelsScroll = [] for _ in xrange(scrollableWheelsCount): retriever = self.createComponent(NetworkFilters.FloatFilterRetriever) wheelsScroll.append(DataLinks.createFloatLink(retriever, 'value')) self.filterRetrievers.append(retriever) steerableWheelsCount = generalWheelsAnimatorConfig.getSteerableWheelsCount() wheelsSteering = [] for _ in xrange(steerableWheelsCount): retriever = self.createComponent(NetworkFilters.FloatFilterRetriever) wheelsSteering.append(DataLinks.createFloatLink(retriever, 'value')) self.filterRetrievers.append(retriever) self.wheelsAnimator = model_assembler.createWheelsAnimator(self, ColliderTypes.VEHICLE_COLLIDER, self.typeDescriptor, lambda : self.wheelsState, wheelsScroll, wheelsSteering, self.splineTracks, lodStateLink) if self.customEffectManager is not None: self.customEffectManager.setWheelsData(self) suspensionLodLink = lodStateLink if 'wheeledVehicle' in self.typeDescriptor.type.tags: wheeledLodCalculator = Vehicular.LodCalculator(self.worldID, DataLinks.linkMatrixTranslation(self.compoundModel.matrix), True, WHEELED_CHASSIS_PRIORITY_GROUP, isPlayer) self.wheeledLodCalculator = wheeledLodCalculator self.allLodCalculators.append(wheeledLodCalculator) suspensionLodLink = wheeledLodCalculator.lodStateLink model_assembler.assembleSuspensionIfNeed(self, suspensionLodLink) model_assembler.assembleLeveredSuspensionIfNeed(self, suspensionLodLink) self.__assembleSwinging(lodLink) model_assembler.assembleBurnoutProcessor(self) model_assembler.assembleSuspensionSound(self, lodLink, isPlayer) model_assembler.assembleHullAimingController(self) self.trackNodesAnimator = model_assembler.createTrackNodesAnimator(self, self.typeDescriptor, lodStateLink) model_assembler.assembleTracks(resourceRefs, self.typeDescriptor, self, self.splineTracks, False, lodStateLink) model_assembler.assembleVehicleTraces(self, self.filter, lodStateLink) return def __assembleSwinging(self, lodLink): self.swingingAnimator = model_assembler.createSwingingAnimator(self, self.typeDescriptor, self.compoundModel.node(TankPartNames.HULL).localMatrix, self.compoundModel.matrix, lodLink) self.compoundModel.node(TankPartNames.HULL, self.swingingAnimator.animatedMProv) if hasattr(self.filter, 'placingCompensationMatrix'): self.swingingAnimator.placingCompensationMatrix = self.filter.placingCompensationMatrix def __postSetupFilter(self): suspensionWorking = self.suspension is not None and self.suspension.hasGroundNodes placingOnGround = not (suspensionWorking or self.leveredSuspension is not None) self.filter.placingOnGround = placingOnGround return def _createAndAttachStickers(self): isCurrentModelDamaged = self.damageState.isCurrentModelDamaged stickersAlpha = DEFAULT_STICKERS_ALPHA if isCurrentModelDamaged: stickersAlpha = items.vehicles.g_cache.commonConfig['miscParams']['damageStickerAlpha'] if self.vehicleStickers is None: self._vehicleStickers = self._createStickers() self.vehicleStickers.alpha = stickersAlpha self.vehicleStickers.attach(compoundModel=self.compoundModel, isDamaged=self.damageState.isCurrentModelDamaged, showDamageStickers=not isCurrentModelDamaged) return def __onPeriodicTimer(self): timeStamp = BigWorld.wg_getFrameTimestamp() if self.__frameTimestamp >= timeStamp: self.__periodicTimerID = BigWorld.callback(0.0, self.__onPeriodicTimer) else: self.__frameTimestamp = timeStamp self.__periodicTimerID = BigWorld.callback(PERIODIC_UPDATE_TIME, self.__onPeriodicTimer) self._periodicUpdate() def _periodicUpdate(self): if self._vehicle is None or not self._vehicle.isAlive(): return else: self._updateCurrTerrainMatKinds() self.__updateEffectsLOD() if self.customEffectManager: self.customEffectManager.update() return def __updateEffectsLOD(self): if self.customEffectManager: distanceFromPlayer = self.lodCalculator.lodDistance enableExhaust = distanceFromPlayer <= _LOD_DISTANCE_EXHAUST and not self.isUnderwater enableTrails = distanceFromPlayer <= _LOD_DISTANCE_TRAIL_PARTICLES and BigWorld.wg_isVehicleDustEnabled() self.customEffectManager.enable(enableTrails, EffectSettings.SETTING_DUST) self.customEffectManager.enable(enableExhaust, EffectSettings.SETTING_EXHAUST) def _stopEffects(self): self.boundEffects.stop() def playEffect(self, kind, *modifs): self._stopEffects() if kind == 'empty' or self._vehicle is None: return else: enableDecal = True if kind in ('explosion', 'destruction') and self.isFlying: enableDecal = False if self.isUnderwater: if kind not in ('submersionDeath',): return effects = self.typeDescriptor.type.effects[kind] if not effects: return vehicle = self._vehicle effects = random.choice(effects) args = dict(isPlayerVehicle=vehicle.isPlayerVehicle, showShockWave=vehicle.isPlayerVehicle, showFlashBang=vehicle.isPlayerVehicle, entity_id=vehicle.id, isPlayer=vehicle.isPlayerVehicle, showDecal=enableDecal, start=vehicle.position + Math.Vector3(0.0, 1.0, 0.0), end=vehicle.position + Math.Vector3(0.0, -1.0, 0.0)) if isSpawnedBot(self.typeDescriptor.type.tags) and kind in ('explosion', 'destruction'): player = BigWorld.player() if player is not None and isPlayerAvatar(): player.terrainEffects.addNew(self._vehicle.position, effects[1], effects[0], None, **args) else: self.boundEffects.addNew(None, effects[1], effects[0], **args) return def _updateCurrTerrainMatKinds(self): if self.terrainMatKindSensor is None: return else: matKinds = self.terrainMatKindSensor.matKinds groundTypes = self.terrainMatKindSensor.groundTypes materialsCount = len(matKinds) for i in xrange(MATKIND_COUNT): matKind = matKinds[i] if i < materialsCount else 0 groundType = groundTypes[i] if i < materialsCount else 0 self.terrainMatKind[i] = matKind self.terrainGroundType[i] = groundType effectIndex = calcEffectMaterialIndex(matKind) effectMaterialName = '' if effectIndex is not None: effectMaterialName = material_kinds.EFFECT_MATERIALS[effectIndex] self.terrainEffectMaterialNames[i] = effectMaterialName if self.vehicleTraces is not None: self.vehicleTraces.setCurrTerrainMatKinds(self.terrainMatKind[0], self.terrainMatKind[1]) return def changeEngineMode(self, mode, forceSwinging=False): if self.detailedEngineState is not None: self.detailedEngineState.mode = mode[0] if self.trackScrollController is not None: self.trackScrollController.setMode(mode) return def changeSiegeState(self, siegeState): if self.engineAudition is not None: self.engineAudition.onSiegeStateChanged(siegeState) return def turretDamaged(self): pass def maxTurretRotationSpeed(self): pass
def __startBuild(self, vDesc, vState): self.__curBuildInd += 1 self.__vState = vState self.__resources = {} self.__vehicleStickers = None cfg = hangarCFG() if vState == 'undamaged': self.__currentEmblemsAlpha = cfg['emblems_alpha_undamaged'] self.__isVehicleDestroyed = False else: self.__currentEmblemsAlpha = cfg['emblems_alpha_damaged'] self.__isVehicleDestroyed = True self.__vDesc = vDesc resources = camouflages.getCamoPrereqs(self.__outfit, vDesc) if not self.__isVehicleDestroyed: self.__attachments = camouflages.getAttachments(self.__outfit, vDesc) modelsSet = self.__outfit.modelsSet splineDesc = vDesc.chassis.splineDesc if splineDesc is not None: for _, trackDesc in splineDesc.trackPairs.iteritems(): resources += trackDesc.prerequisites(modelsSet) from vehicle_systems import model_assembler resources.append(model_assembler.prepareCompoundAssembler(self.__vDesc, ModelsSetParams(modelsSet, self.__vState, self.__attachments), self.__spaceId)) g_eventBus.handleEvent(CameraRelatedEvents(CameraRelatedEvents.VEHICLE_LOADING, ctx={'started': True, 'vEntityId': self.__vEntity.id, 'intCD': self.__vDesc.type.compactDescr}), scope=EVENT_BUS_SCOPE.DEFAULT) cfg = hangarCFG() gunScale = Math.Vector3(1.0, 1.0, 1.1) capsuleScale = Math.Vector3(1.5, 1.5, 1.5) loadedGunScale = cfg.get('cam_capsule_gun_scale', gunScale) if loadedGunScale is not None: gunScale = loadedGunScale loadedCapsuleScale = cfg.get('cam_capsule_scale', capsuleScale) if loadedCapsuleScale is not None: capsuleScale = loadedCapsuleScale hitTesterManagers = {TankPartNames.CHASSIS: vDesc.chassis.hitTesterManager, TankPartNames.HULL: vDesc.hull.hitTesterManager, TankPartNames.TURRET: vDesc.turret.hitTesterManager, TankPartNames.GUN: vDesc.gun.hitTesterManager} bspModels = () crashedBspModels = () for partName, htManager in hitTesterManagers.iteritems(): partId = TankPartNames.getIdx(partName) bspModel = (partId, htManager.modelHitTester.bspModelName) bspModels = bspModels + (bspModel,) if htManager.crashedModelHitTester: crashedBspModel = (partId, htManager.crashedModelHitTester.bspModelName) crashedBspModels = crashedBspModels + (crashedBspModel,) bspModels = bspModels + ((TankPartNames.getIdx(TankPartNames.GUN) + 1, vDesc.hull.hitTesterManager.modelHitTester.bspModelName, capsuleScale), (TankPartNames.getIdx(TankPartNames.GUN) + 2, vDesc.turret.hitTesterManager.modelHitTester.bspModelName, capsuleScale), (TankPartNames.getIdx(TankPartNames.GUN) + 3, vDesc.gun.hitTesterManager.modelHitTester.bspModelName, gunScale)) if vDesc.hull.hitTesterManager.crashedModelHitTester: crashedBspModels = crashedBspModels + ((TankPartNames.getIdx(TankPartNames.GUN) + 1, vDesc.hull.hitTesterManager.crashedModelHitTester.bspModelName, capsuleScale),) if vDesc.turret.hitTesterManager.crashedModelHitTester: crashedBspModels = crashedBspModels + ((TankPartNames.getIdx(TankPartNames.GUN) + 2, vDesc.turret.hitTesterManager.crashedModelHitTester.bspModelName, capsuleScale),) if vDesc.gun.hitTesterManager.crashedModelHitTester: crashedBspModels = crashedBspModels + ((TankPartNames.getIdx(TankPartNames.GUN) + 3, vDesc.gun.hitTesterManager.crashedModelHitTester.bspModelName, gunScale),) modelCA = BigWorld.CollisionAssembler(bspModels, self.__spaceId) modelCA.name = 'ModelCollisions' resources.append(modelCA) if crashedBspModels: crashedModelCA = BigWorld.CollisionAssembler(crashedBspModels, self.__spaceId) crashedModelCA.name = 'CrashedModelCollisions' resources.append(crashedModelCA) physicalTracksBuilders = vDesc.chassis.physicalTracks for name, builders in physicalTracksBuilders.iteritems(): for index, builder in enumerate(builders): resources.append(builder.createLoader(self.__spaceId, '{0}{1}PhysicalTrack'.format(name, index), modelsSet)) BigWorld.loadResourceListBG(tuple(resources), makeCallbackWeak(self.__onResourcesLoaded, self.__curBuildInd)) return