From dd42f84140d5f181c19c464bb9ccf93af1ef3f46 Mon Sep 17 00:00:00 2001 From: GenZmeY Date: Sun, 13 Dec 2020 18:01:13 +0300 Subject: [PATCH] upload --- AkAudio/Classes/ActorFactoryAKAmbientSound.uc | 21 + AkAudio/Classes/AkAmbientSound.uc | 51 + AkAudio/Classes/AkComponent.uc | 96 + AkAudio/Classes/InterpTrackAkEvent.uc | 44 + AkAudio/Classes/InterpTrackAkRTPC.uc | 26 + AkAudio/Classes/InterpTrackInstAkEvent.uc | 14 + AkAudio/Classes/InterpTrackInstAkRTPC.uc | 12 + AkAudio/Classes/SeqAct_AkClearBanks.uc | 17 + AkAudio/Classes/SeqAct_AkLoadBank.uc | 33 + AkAudio/Classes/SeqAct_AkPostEvent.uc | 32 + AkAudio/Classes/SeqAct_AkPostTrigger.uc | 17 + AkAudio/Classes/SeqAct_AkSetRTPCValue.uc | 33 + AkAudio/Classes/SeqAct_AkSetState.uc | 20 + AkAudio/Classes/SeqAct_AkSetSwitch.uc | 18 + AkAudio/Classes/SeqAct_AkStartAmbientSound.uc | 18 + AkAudio/Classes/SeqAct_AkStopAll.uc | 17 + BaseAI/Classes/AIDebugTool.uc | 244 + BaseAI/Classes/AIPlugin.uc | 90 + BaseAI/Classes/AIPluginLeap.uc | 413 + BaseAI/Classes/AIPluginMovement.uc | 367 + BaseAI/Classes/AIPluginStuckFix.uc | 190 + BaseAI/Classes/AITickablePlugin.uc | 57 + BaseAI/Classes/BaseAIController.uc | 318 + BaseAI/Classes/BaseAIPawn.uc | 229 + BaseAI/Classes/BaseAISquad.uc | 79 + BaseAI/Classes/BaseAISubsystem.uc | 114 + BaseAI/Classes/BaseAITypes.uc | 105 + BaseAI/Classes/BaseAiPlugInHistory.uc | 111 + BaseAI/Classes/CodeSpeedTestCommandlet.uc | 25 + BaseAI/Classes/LatentActionObserver.uc | 13 + BaseAI/Classes/NavigationPath.uc | 64 + BaseAI/Classes/PlayerInputRecorder.uc | 52 + BaseAI/Classes/PlugInOwnerInterface.uc | 14 + BaseAI/Classes/PluginBase.uc | 122 + BaseAI/Classes/PluginSquad.uc | 26 + BaseAI/Globals.uci | 66 + Core/Classes/Commandlet.uc | 120 + Core/Classes/Component.uc | 89 + Core/Classes/DistributionFloat.uc | 131 + Core/Classes/DistributionVector.uc | 133 + Core/Classes/Factory.uc | 28 + Core/Classes/HelpCommandlet.uc | 20 + Core/Classes/Interface.uc | 9 + Core/Classes/Object.uc | 2232 +++ Core/Classes/Subsystem.uc | 33 + Core/Globals.uci | 144 + Core/nFringeGlobals.uci | 49 + Engine/Classes/AICommandBase.uc | 48 + Engine/Classes/AIController.uc | 358 + Engine/Classes/AISubsystem.uc | 51 + Engine/Classes/AISwitchablePylon.uc | 56 + Engine/Classes/AccessControl.uc | 1687 +++ Engine/Classes/Actor.uc | 4269 ++++++ Engine/Classes/ActorComponent.uc | 46 + Engine/Classes/ActorFactory.uc | 91 + Engine/Classes/ActorFactoryAI.uc | 42 + Engine/Classes/ActorFactoryActor.uc | 31 + Engine/Classes/ActorFactoryAmbientSound.uc | 39 + .../ActorFactoryAmbientSoundMovable.uc | 19 + .../ActorFactoryAmbientSoundNonLoop.uc | 19 + ...FactoryAmbientSoundNonLoopingToggleable.uc | 19 + .../Classes/ActorFactoryAmbientSoundSimple.uc | 36 + ...ctorFactoryAmbientSoundSimpleToggleable.uc | 19 + Engine/Classes/ActorFactoryApexClothing.uc | 66 + .../Classes/ActorFactoryApexDestructible.uc | 41 + Engine/Classes/ActorFactoryArchetype.uc | 32 + Engine/Classes/ActorFactoryCoverLink.uc | 15 + Engine/Classes/ActorFactoryDecal.uc | 59 + Engine/Classes/ActorFactoryDecalMovable.uc | 12 + .../ActorFactoryDominantDirectionalLight.uc | 28 + ...rFactoryDominantDirectionalLightMovable.uc | 27 + Engine/Classes/ActorFactoryDynamicSM.uc | 54 + Engine/Classes/ActorFactoryEmitter.uc | 36 + Engine/Classes/ActorFactoryFlex.uc | 35 + Engine/Classes/ActorFactoryFlexForceField.uc | 51 + ...ctorFactoryFogVolumeConstantDensityInfo.uc | 29 + ...toryFogVolumeLinearHalfspaceDensityInfo.uc | 12 + ...torFactoryFogVolumeSphericalDensityInfo.uc | 17 + .../ActorFactoryFracturedStaticMesh.uc | 35 + .../Classes/ActorFactoryInteractiveFoliage.uc | 12 + Engine/Classes/ActorFactoryLensFlare.uc | 35 + Engine/Classes/ActorFactoryLight.uc | 15 + Engine/Classes/ActorFactoryMover.uc | 14 + Engine/Classes/ActorFactoryPathNode.uc | 15 + Engine/Classes/ActorFactoryPhysicsAsset.uc | 55 + Engine/Classes/ActorFactoryPlayerStart.uc | 15 + Engine/Classes/ActorFactoryPylon.uc | 15 + Engine/Classes/ActorFactoryRigidBody.uc | 80 + Engine/Classes/ActorFactorySkeletalMesh.uc | 35 + .../ActorFactorySkeletalMeshCinematic.uc | 12 + Engine/Classes/ActorFactorySkeletalMeshMAT.uc | 12 + Engine/Classes/ActorFactoryStaticMesh.uc | 35 + Engine/Classes/ActorFactoryTrigger.uc | 15 + Engine/Classes/ActorFactoryVehicle.uc | 31 + Engine/Classes/Admin.uc | 79 + Engine/Classes/AdvancedReachSpec.uc | 24 + Engine/Classes/AkBank.uc | 25 + Engine/Classes/AkBaseSoundObject.uc | 13 + Engine/Classes/AkEvent.uc | 108 + Engine/Classes/AlienFXLEDInterface.uc | 25 + Engine/Classes/AmbientOcclusionEffect.uc | 206 + Engine/Classes/AmbientSound.uc | 46 + Engine/Classes/AmbientSoundMovable.uc | 25 + Engine/Classes/AmbientSoundNonLoop.uc | 30 + .../AmbientSoundNonLoopingToggleable.uc | 30 + Engine/Classes/AmbientSoundSimple.uc | 38 + Engine/Classes/AmbientSoundSimpleSpline.uc | 42 + .../AmbientSoundSimpleSplineNonLoop.uc | 29 + .../Classes/AmbientSoundSimpleToggleable.uc | 146 + Engine/Classes/AmbientSoundSpline.uc | 61 + Engine/Classes/AmbientSoundSplineMultiCue.uc | 36 + Engine/Classes/AnalyticEventsBase.uc | 225 + Engine/Classes/AnimMetaData.uc | 22 + Engine/Classes/AnimMetaData_SkelControl.uc | 36 + .../AnimMetaData_SkelControlKeyFrame.uc | 20 + Engine/Classes/AnimNode.uc | 284 + Engine/Classes/AnimNodeAdditiveBlending.uc | 37 + Engine/Classes/AnimNodeAimOffset.uc | 255 + Engine/Classes/AnimNodeBlend.uc | 48 + Engine/Classes/AnimNodeBlendBase.uc | 124 + Engine/Classes/AnimNodeBlendByBase.uc | 40 + Engine/Classes/AnimNodeBlendByPhysics.uc | 34 + Engine/Classes/AnimNodeBlendByPosture.uc | 24 + Engine/Classes/AnimNodeBlendByProperty.uc | 66 + Engine/Classes/AnimNodeBlendBySpeed.uc | 65 + Engine/Classes/AnimNodeBlendDirectional.uc | 52 + Engine/Classes/AnimNodeBlendList.uc | 79 + Engine/Classes/AnimNodeBlendMultiBone.uc | 77 + Engine/Classes/AnimNodeBlendPerBone.uc | 45 + Engine/Classes/AnimNodeCrossfader.uc | 95 + Engine/Classes/AnimNodeFrame.uc | 84 + Engine/Classes/AnimNodeMirror.uc | 23 + Engine/Classes/AnimNodePlayCustomAnim.uc | 152 + Engine/Classes/AnimNodeRandom.uc | 72 + Engine/Classes/AnimNodeScalePlayRate.uc | 22 + Engine/Classes/AnimNodeScaleRateBySpeed.uc | 19 + Engine/Classes/AnimNodeSequence.uc | 338 + Engine/Classes/AnimNodeSequenceBlendBase.uc | 95 + Engine/Classes/AnimNodeSequenceBlendByAim.uc | 74 + Engine/Classes/AnimNodeSlot.uc | 267 + Engine/Classes/AnimNodeSynch.uc | 72 + Engine/Classes/AnimNode_MultiBlendPerBone.uc | 184 + Engine/Classes/AnimNotify.uc | 78 + Engine/Classes/AnimNotify_AkEvent.uc | 40 + Engine/Classes/AnimNotify_CameraEffect.uc | 20 + .../AnimNotify_ClothingMaxDistanceScale.uc | 39 + Engine/Classes/AnimNotify_Footstep.uc | 28 + Engine/Classes/AnimNotify_Forcefield.uc | 29 + Engine/Classes/AnimNotify_Kismet.uc | 14 + .../Classes/AnimNotify_PawnMaterialParam.uc | 36 + Engine/Classes/AnimNotify_PlayFaceFxAnim.uc | 70 + .../Classes/AnimNotify_PlayParticleEffect.uc | 56 + Engine/Classes/AnimNotify_Rumble.uc | 30 + Engine/Classes/AnimNotify_Script.uc | 25 + Engine/Classes/AnimNotify_Scripted.uc | 16 + Engine/Classes/AnimNotify_Sound.uc | 33 + Engine/Classes/AnimNotify_Trails.uc | 178 + Engine/Classes/AnimNotify_ViewShake.uc | 102 + Engine/Classes/AnimObject.uc | 63 + Engine/Classes/AnimSequence.uc | 484 + Engine/Classes/AnimSet.uc | 144 + Engine/Classes/AnimTree.uc | 275 + .../Classes/AnimationCompressionAlgorithm.uc | 236 + ...AnimationCompressionAlgorithm_Automatic.uc | 51 + ...ompressionAlgorithm_BitwiseCompressOnly.uc | 22 + ...onCompressionAlgorithm_LeastDestructive.uc | 24 + ...ompressionAlgorithm_PerTrackCompression.uc | 177 + ...mpressionAlgorithm_RemoveEverySecondKey.uc | 34 + ...onCompressionAlgorithm_RemoveLinearKeys.uc | 183 + ...nCompressionAlgorithm_RemoveTrivialKeys.uc | 34 + ...imationCompressionAlgorithm_RevertToRaw.uc | 25 + Engine/Classes/ApexAsset.uc | 61 + Engine/Classes/ApexClothingAsset.uc | 171 + Engine/Classes/ApexComponentBase.uc | 98 + Engine/Classes/ApexDestructibleActor.uc | 199 + .../Classes/ApexDestructibleActorSpawnable.uc | 11 + Engine/Classes/ApexDestructibleAsset.uc | 632 + .../ApexDestructibleDamageParameters.uc | 29 + Engine/Classes/ApexDynamicComponent.uc | 24 + Engine/Classes/ApexGenericAsset.uc | 99 + Engine/Classes/ApexStaticComponent.uc | 42 + .../ApexStaticDestructibleComponent.uc | 119 + Engine/Classes/AppNotificationsBase.uc | 102 + Engine/Classes/ArrowComponent.uc | 28 + Engine/Classes/AudioComponent.uc | 263 + Engine/Classes/AudioDevice.uc | 181 + Engine/Classes/AutoLadder.uc | 13 + .../AutoNavMeshPathObstacleUnregister.uc | 23 + Engine/Classes/AutoTestManager.uc | 887 ++ Engine/Classes/BlockingVolume.uc | 59 + Engine/Classes/BlurEffect.uc | 39 + Engine/Classes/BookMark.uc | 24 + Engine/Classes/BookMark2D.uc | 22 + Engine/Classes/BroadcastHandler.uc | 119 + Engine/Classes/Brush.uc | 125 + Engine/Classes/BrushComponent.uc | 149 + Engine/Classes/BrushShape.uc | 27 + Engine/Classes/Camera.uc | 1000 ++ Engine/Classes/CameraActor.uc | 119 + Engine/Classes/CameraAnim.uc | 91 + Engine/Classes/CameraAnimInst.uc | 119 + Engine/Classes/CameraConeComponent.uc | 11 + Engine/Classes/CameraModifier.uc | 250 + Engine/Classes/CameraModifier_CameraShake.uc | 291 + Engine/Classes/CameraShake.uc | 120 + Engine/Classes/Canvas.uc | 764 + Engine/Classes/CeilingReachSpec.uc | 26 + Engine/Classes/CheatManager.uc | 1429 ++ Engine/Classes/ClipPadEntry.uc | 24 + Engine/Classes/CloudSaveSystem.uc | 654 + .../CloudSaveSystemDataBlobStoreInterface.uc | 37 + Engine/Classes/CloudSaveSystemKVSInterface.uc | 12 + Engine/Classes/CloudStorageBase.uc | 244 + .../CloudStorageBaseCloudSaveSystemKVS.uc | 61 + Engine/Classes/CloudStorageUpgradeHelper.uc | 26 + Engine/Classes/CodecMovie.uc | 113 + Engine/Classes/CodecMovieFallback.uc | 72 + Engine/Classes/ColorScaleVolume.uc | 81 + Engine/Classes/Console.uc | 1295 ++ Engine/Classes/Controller.uc | 1972 +++ Engine/Classes/CoverGroup.uc | 84 + .../Classes/CoverGroupRenderingComponent.uc | 17 + Engine/Classes/CoverLink.uc | 1417 ++ Engine/Classes/CoverMeshComponent.uc | 86 + Engine/Classes/CoverReplicator.uc | 794 ++ Engine/Classes/CoverSlipReachSpec.uc | 19 + Engine/Classes/CrowdAgentBase.uc | 41 + Engine/Classes/CrowdPopulationManagerBase.uc | 13 + Engine/Classes/CullDistanceVolume.uc | 77 + Engine/Classes/CurveEdPresetCurve.uc | 36 + Engine/Classes/CustomPropertyItemHandler.uc | 41 + Engine/Classes/CylinderComponent.uc | 43 + Engine/Classes/DOFAndBloomEffect.uc | 134 + Engine/Classes/DOFBloomMotionBlurEffect.uc | 56 + Engine/Classes/DOFEffect.uc | 71 + Engine/Classes/DamageType.uc | 62 + Engine/Classes/DataStoreClient.uc | 231 + Engine/Classes/DecalActor.uc | 13 + Engine/Classes/DecalActorBase.uc | 65 + Engine/Classes/DecalActorMovable.uc | 19 + Engine/Classes/DecalComponent.uc | 423 + Engine/Classes/DecalManager.uc | 293 + Engine/Classes/DecalMaterial.uc | 27 + Engine/Classes/DefaultPhysicsVolume.uc | 24 + Engine/Classes/DirectionalLight.uc | 60 + Engine/Classes/DirectionalLightComponent.uc | 86 + Engine/Classes/DirectionalLightToggleable.uc | 70 + Engine/Classes/DiscordRPCIntegration.uc | 42 + Engine/Classes/DistributionFloatConstant.uc | 46 + .../Classes/DistributionFloatConstantCurve.uc | 53 + .../Classes/DistributionFloatParameterBase.uc | 44 + .../DistributionFloatParticleParameter.uc | 13 + .../DistributionFloatSoundParameter.uc | 13 + Engine/Classes/DistributionFloatUniform.uc | 78 + .../Classes/DistributionFloatUniformCurve.uc | 83 + .../Classes/DistributionFloatUniformRange.uc | 105 + Engine/Classes/DistributionVectorConstant.uc | 66 + .../DistributionVectorConstantCurve.uc | 72 + .../DistributionVectorParameterBase.uc | 36 + .../DistributionVectorParticleParameter.uc | 13 + Engine/Classes/DistributionVectorUniform.uc | 121 + .../Classes/DistributionVectorUniformCurve.uc | 135 + .../Classes/DistributionVectorUniformRange.uc | 108 + Engine/Classes/DmgType_Crushed.uc | 4 + Engine/Classes/DmgType_Fell.uc | 13 + Engine/Classes/DmgType_Suicided.uc | 10 + Engine/Classes/DmgType_Telefragged.uc | 9 + Engine/Classes/DominantDirectionalLight.uc | 54 + .../DominantDirectionalLightComponent.uc | 43 + .../DominantDirectionalLightMovable.uc | 24 + Engine/Classes/DominantPointLight.uc | 52 + Engine/Classes/DominantPointLightComponent.uc | 25 + Engine/Classes/DominantSpotLight.uc | 54 + Engine/Classes/DominantSpotLightComponent.uc | 37 + Engine/Classes/DoorMarker.uc | 187 + .../Classes/DownloadableContentEnumerator.uc | 96 + Engine/Classes/DownloadableContentManager.uc | 243 + Engine/Classes/DrawBoxComponent.uc | 25 + Engine/Classes/DrawCapsuleComponent.uc | 27 + Engine/Classes/DrawConeComponent.uc | 34 + Engine/Classes/DrawCylinderComponent.uc | 34 + Engine/Classes/DrawFrustumComponent.uc | 44 + Engine/Classes/DrawLightConeComponent.uc | 22 + Engine/Classes/DrawLightRadiusComponent.uc | 18 + Engine/Classes/DrawPylonRadiusComponent.uc | 24 + Engine/Classes/DrawQuadComponent.uc | 30 + Engine/Classes/DrawSoundRadiusComponent.uc | 18 + Engine/Classes/DrawSphereComponent.uc | 27 + Engine/Classes/DrawTaperedCapsuleComponent.uc | 29 + Engine/Classes/DroppedPickup.uc | 270 + Engine/Classes/DynamicAnchor.uc | 43 + Engine/Classes/DynamicBlockingVolume.uc | 100 + Engine/Classes/DynamicCameraActor.uc | 15 + .../DynamicLightEnvironmentComponent.uc | 241 + Engine/Classes/DynamicPhysicsVolume.uc | 40 + Engine/Classes/DynamicPylon.uc | 81 + Engine/Classes/DynamicSMActor.uc | 297 + Engine/Classes/DynamicSMActor_Spawnable.uc | 11 + Engine/Classes/DynamicTriggerVolume.uc | 39 + Engine/Classes/EdCoordSystem.uc | 23 + .../Classes/EditorLinkSelectionInterface.uc | 17 + Engine/Classes/Emitter.uc | 351 + Engine/Classes/EmitterCameraLensEffectBase.uc | 120 + Engine/Classes/EmitterPool.uc | 213 + Engine/Classes/EmitterSpawnable.uc | 52 + Engine/Classes/Engine.uc | 1205 ++ Engine/Classes/EngineBaseTypes.uc | 46 + Engine/Classes/EngineTypes.uc | 602 + Engine/Classes/EnvironmentVolume.uc | 128 + Engine/Classes/ExponentialHeightFog.uc | 89 + .../Classes/ExponentialHeightFogComponent.uc | 87 + Engine/Classes/FaceFXAnimSet.uc | 84 + Engine/Classes/FaceFXAsset.uc | 109 + Engine/Classes/FacebookIntegration.uc | 85 + Engine/Classes/FailedConnect.uc | 41 + Engine/Classes/FileLog.uc | 40 + Engine/Classes/FileWriter.uc | 80 + Engine/Classes/FlexActor.uc | 18 + Engine/Classes/FlexAsset.uc | 121 + Engine/Classes/FlexComponent.uc | 61 + Engine/Classes/FlexContainer.uc | 222 + Engine/Classes/FlexForceFieldActor.uc | 50 + Engine/Classes/FlexForceFieldComponent.uc | 97 + Engine/Classes/FloorToCeilingReachSpec.uc | 25 + Engine/Classes/FluidInfluenceActor.uc | 106 + Engine/Classes/FluidInfluenceComponent.uc | 158 + Engine/Classes/FluidSurfaceActor.uc | 65 + Engine/Classes/FluidSurfaceActorMovable.uc | 18 + Engine/Classes/FluidSurfaceComponent.uc | 299 + .../Classes/FogVolumeConeDensityComponent.uc | 47 + Engine/Classes/FogVolumeConeDensityInfo.uc | 29 + .../FogVolumeConstantDensityComponent.uc | 23 + .../Classes/FogVolumeConstantDensityInfo.uc | 15 + Engine/Classes/FogVolumeDensityComponent.uc | 110 + Engine/Classes/FogVolumeDensityInfo.uc | 145 + ...ogVolumeLinearHalfspaceDensityComponent.uc | 31 + .../FogVolumeLinearHalfspaceDensityInfo.uc | 15 + .../FogVolumeSphericalDensityComponent.uc | 39 + .../Classes/FogVolumeSphericalDensityInfo.uc | 37 + Engine/Classes/Font.uc | 282 + Engine/Classes/FontImportOptions.uc | 88 + Engine/Classes/ForceFeedbackManager.uc | 134 + Engine/Classes/ForceFeedbackWaveform.uc | 97 + Engine/Classes/ForceFieldShape.uc | 26 + Engine/Classes/ForceFieldShapeBox.uc | 61 + Engine/Classes/ForceFieldShapeCapsule.uc | 67 + Engine/Classes/ForceFieldShapeSphere.uc | 59 + Engine/Classes/ForcedLoopSoundNode.uc | 21 + Engine/Classes/ForcedReachSpec.uc | 27 + Engine/Classes/FractureManager.uc | 172 + Engine/Classes/FractureMaterial.uc | 16 + Engine/Classes/FracturedBaseComponent.uc | 144 + Engine/Classes/FracturedSMActorSpawnable.uc | 20 + .../Classes/FracturedSkinnedMeshComponent.uc | 80 + Engine/Classes/FracturedStaticMeshActor.uc | 753 + .../FracturedStaticMeshActor_Spawnable.uc | 12 + .../Classes/FracturedStaticMeshComponent.uc | 168 + Engine/Classes/FracturedStaticMeshPart.uc | 167 + Engine/Classes/GameEngine.uc | 643 + Engine/Classes/GameInfo.uc | 4099 ++++++ Engine/Classes/GameMessage.uc | 119 + Engine/Classes/GamePadLightbarSubsystem.uc | 305 + Engine/Classes/GameReplicationInfo.uc | 345 + Engine/Classes/GameStats.uci | 202 + Engine/Classes/GameUISceneClient.uc | 328 + Engine/Classes/GameViewportClient.uc | 1669 +++ Engine/Classes/GameplayEvents.uc | 403 + Engine/Classes/GameplayEventsHandler.uc | 181 + Engine/Classes/GameplayEventsReader.uc | 86 + .../Classes/GameplayEventsUploadAnalytics.uc | 196 + Engine/Classes/GameplayEventsWriter.uc | 339 + Engine/Classes/GameplayEventsWriterBase.uc | 280 + Engine/Classes/GeneratedMeshAreaLight.uc | 19 + Engine/Classes/GenericParamListStatEntry.uc | 30 + Engine/Classes/Goal_AtActor.uc | 96 + Engine/Classes/Goal_Null.uc | 47 + Engine/Classes/GravityVolume.uc | 23 + Engine/Classes/HUD.uc | 994 ++ Engine/Classes/HeadTrackingComponent.uc | 128 + Engine/Classes/HeightFog.uc | 89 + Engine/Classes/HeightFogComponent.uc | 52 + Engine/Classes/HttpBaseInterface.uc | 68 + Engine/Classes/HttpFactory.uc | 27 + Engine/Classes/HttpRequestInterface.uc | 98 + Engine/Classes/HttpResponseInterface.uc | 27 + Engine/Classes/HttpStatusCodes.uci | 84 + .../Classes/ImageBasedReflectionComponent.uc | 74 + Engine/Classes/ImageReflection.uc | 102 + Engine/Classes/ImageReflectionComponent.uc | 14 + Engine/Classes/ImageReflectionSceneCapture.uc | 33 + Engine/Classes/ImageReflectionShadowPlane.uc | 102 + .../ImageReflectionShadowPlaneComponent.uc | 46 + Engine/Classes/InAppMessageBase.uc | 37 + Engine/Classes/InGameAdManager.uc | 74 + Engine/Classes/Info.uc | 68 + Engine/Classes/IniLocPatcher.uc | 559 + Engine/Classes/Input.uc | 153 + Engine/Classes/InstancedFoliageActor.uc | 55 + Engine/Classes/InstancedFoliageSettings.uc | 123 + .../Classes/InstancedStaticMeshComponent.uc | 175 + Engine/Classes/Interaction.uc | 214 + Engine/Classes/InteractiveFoliageActor.uc | 125 + Engine/Classes/InteractiveFoliageComponent.uc | 24 + Engine/Classes/Interface_NavMeshPathObject.uc | 357 + .../Classes/Interface_NavMeshPathObstacle.uc | 133 + Engine/Classes/Interface_NavMeshPathSwitch.uc | 71 + Engine/Classes/Interface_NavigationHandle.uc | 62 + .../Interface_PylonGeometryProvider.uc | 17 + Engine/Classes/Interface_RVO.uc | 28 + Engine/Classes/Interface_Speaker.uc | 10 + Engine/Classes/InterpActor.uc | 516 + Engine/Classes/InterpActor_ForCinematic.uc | 14 + Engine/Classes/InterpCurveEdSetup.uc | 67 + Engine/Classes/InterpData.uc | 138 + Engine/Classes/InterpFilter.uc | 22 + Engine/Classes/InterpFilter_Classes.uc | 26 + Engine/Classes/InterpFilter_Custom.uc | 22 + Engine/Classes/InterpGroup.uc | 96 + Engine/Classes/InterpGroupAI.uc | 49 + Engine/Classes/InterpGroupCamera.uc | 49 + Engine/Classes/InterpGroupDirector.uc | 29 + Engine/Classes/InterpGroupInst.uc | 72 + Engine/Classes/InterpGroupInstAI.uc | 84 + Engine/Classes/InterpGroupInstCamera.uc | 6 + Engine/Classes/InterpGroupInstDirector.uc | 6 + Engine/Classes/InterpTrack.uc | 114 + Engine/Classes/InterpTrackAnimControl.uc | 145 + Engine/Classes/InterpTrackAudioMaster.uc | 31 + Engine/Classes/InterpTrackBoolProp.uc | 146 + Engine/Classes/InterpTrackColorProp.uc | 32 + Engine/Classes/InterpTrackColorScale.uc | 31 + Engine/Classes/InterpTrackDirector.uc | 75 + Engine/Classes/InterpTrackEvent.uc | 65 + Engine/Classes/InterpTrackFaceFX.uc | 98 + Engine/Classes/InterpTrackFade.uc | 35 + Engine/Classes/InterpTrackFloatBase.uc | 63 + .../Classes/InterpTrackFloatMaterialParam.uc | 41 + .../Classes/InterpTrackFloatParticleParam.uc | 25 + Engine/Classes/InterpTrackFloatProp.uc | 42 + Engine/Classes/InterpTrackHeadTracking.uc | 110 + Engine/Classes/InterpTrackInst.uc | 31 + Engine/Classes/InterpTrackInstAnimControl.uc | 21 + Engine/Classes/InterpTrackInstAudioMaster.uc | 13 + Engine/Classes/InterpTrackInstBoolProp.uc | 38 + Engine/Classes/InterpTrackInstColorProp.uc | 20 + Engine/Classes/InterpTrackInstColorScale.uc | 12 + Engine/Classes/InterpTrackInstDirector.uc | 23 + Engine/Classes/InterpTrackInstEvent.uc | 25 + Engine/Classes/InterpTrackInstFaceFX.uc | 19 + Engine/Classes/InterpTrackInstFade.uc | 12 + .../InterpTrackInstFloatMaterialParam.uc | 28 + .../InterpTrackInstFloatParticleParam.uc | 14 + Engine/Classes/InterpTrackInstFloatProp.uc | 23 + Engine/Classes/InterpTrackInstHeadTracking.uc | 49 + .../Classes/InterpTrackInstLinearColorProp.uc | 20 + Engine/Classes/InterpTrackInstMorphWeight.uc | 10 + Engine/Classes/InterpTrackInstMove.uc | 27 + Engine/Classes/InterpTrackInstNotify.uc | 13 + .../Classes/InterpTrackInstParticleReplay.uc | 24 + Engine/Classes/InterpTrackInstProperty.uc | 33 + .../InterpTrackInstSkelControlScale.uc | 11 + .../InterpTrackInstSkelControlStrength.uc | 20 + Engine/Classes/InterpTrackInstSlomo.uc | 24 + Engine/Classes/InterpTrackInstSound.uc | 18 + Engine/Classes/InterpTrackInstToggle.uc | 33 + .../InterpTrackInstVectorMaterialParam.uc | 28 + Engine/Classes/InterpTrackInstVectorProp.uc | 20 + Engine/Classes/InterpTrackInstVisibility.uc | 23 + Engine/Classes/InterpTrackLinearColorBase.uc | 87 + Engine/Classes/InterpTrackLinearColorProp.uc | 34 + Engine/Classes/InterpTrackMorphWeight.uc | 24 + Engine/Classes/InterpTrackMove.uc | 359 + Engine/Classes/InterpTrackMoveAxis.uc | 77 + Engine/Classes/InterpTrackNotify.uc | 64 + Engine/Classes/InterpTrackParticleReplay.uc | 87 + Engine/Classes/InterpTrackSkelControlScale.uc | 23 + .../Classes/InterpTrackSkelControlStrength.uc | 23 + Engine/Classes/InterpTrackSlomo.uc | 28 + Engine/Classes/InterpTrackSound.uc | 80 + Engine/Classes/InterpTrackToggle.uc | 88 + Engine/Classes/InterpTrackVectorBase.uc | 82 + .../Classes/InterpTrackVectorMaterialParam.uc | 41 + Engine/Classes/InterpTrackVectorProp.uc | 32 + Engine/Classes/InterpTrackVisibility.uc | 99 + Engine/Classes/Inventory.uc | 261 + Engine/Classes/InventoryManager.uc | 800 ++ Engine/Classes/JsonObject.uc | 117 + Engine/Classes/KActor.uc | 434 + Engine/Classes/KActorFromStatic.uc | 221 + Engine/Classes/KActorSpawnable.uc | 68 + Engine/Classes/KAsset.uc | 240 + Engine/Classes/KAssetSpawnable.uc | 12 + Engine/Classes/KMeshProps.uc | 140 + Engine/Classes/Keypoint.uc | 28 + Engine/Classes/KillZDamageType.uc | 11 + Engine/Classes/KismetBookMark.uc | 19 + Engine/Classes/Ladder.uc | 58 + Engine/Classes/LadderReachSpec.uc | 25 + Engine/Classes/LadderVolume.uc | 150 + Engine/Classes/Landscape.uc | 140 + Engine/Classes/LandscapeComponent.uc | 341 + Engine/Classes/LandscapeGizmoActiveActor.uc | 122 + Engine/Classes/LandscapeGizmoActor.uc | 50 + .../Classes/LandscapeGizmoRenderComponent.uc | 23 + .../LandscapeHeightfieldCollisionComponent.uc | 122 + Engine/Classes/LandscapeInfo.uc | 103 + Engine/Classes/LandscapeLayerInfoObject.uc | 26 + .../LandscapeMaterialInstanceConstant.uc | 24 + Engine/Classes/LandscapeProxy.uc | 227 + Engine/Classes/LensFlare.uc | 310 + Engine/Classes/LensFlareComponent.uc | 182 + Engine/Classes/LensFlareSource.uc | 257 + Engine/Classes/LevelGridVolume.uc | 299 + .../LevelGridVolumeRenderingComponent.uc | 27 + Engine/Classes/LevelStreaming.uc | 125 + Engine/Classes/LevelStreamingAlwaysLoaded.uc | 27 + Engine/Classes/LevelStreamingDistance.uc | 30 + Engine/Classes/LevelStreamingKismet.uc | 33 + Engine/Classes/LevelStreamingPersistent.uc | 40 + Engine/Classes/LevelStreamingVolume.uc | 133 + Engine/Classes/LiftCenter.uc | 127 + Engine/Classes/LiftExit.uc | 80 + Engine/Classes/Light.uc | 375 + Engine/Classes/LightComponent.uc | 564 + Engine/Classes/LightEnvironmentComponent.uc | 83 + Engine/Classes/LightFunction.uc | 24 + .../Classes/LightmappedSurfaceCollection.uc | 19 + .../LightmassCharacterIndirectDetailVolume.uc | 27 + Engine/Classes/LightmassImportanceVolume.uc | 28 + Engine/Classes/LightmassLevelSettings.uc | 61 + .../LightmassPrimitiveSettingsObject.uc | 17 + Engine/Classes/LineBatchComponent.uc | 18 + Engine/Classes/LocalMessage.uc | 126 + Engine/Classes/LocalPlayer.uc | 760 + Engine/Classes/LogitechLEDInterface.uc | 22 + Engine/Classes/MantleReachSpec.uc | 21 + Engine/Classes/MapInfo.uc | 40 + Engine/Classes/MassiveLODOverrideVolume.uc | 42 + Engine/Classes/Material.uc | 891 ++ Engine/Classes/MaterialEffect.uc | 25 + Engine/Classes/MaterialExpression.uc | 195 + Engine/Classes/MaterialExpressionAbs.uc | 42 + .../MaterialExpressionActorWorldPosition.uc | 19 + Engine/Classes/MaterialExpressionAdd.uc | 26 + ...aterialExpressionAntialiasedTextureMask.uc | 40 + .../Classes/MaterialExpressionAppendVector.uc | 29 + .../Classes/MaterialExpressionBumpOffset.uc | 36 + .../Classes/MaterialExpressionCameraVector.uc | 18 + .../MaterialExpressionCameraWorldPosition.uc | 20 + Engine/Classes/MaterialExpressionCeil.uc | 27 + Engine/Classes/MaterialExpressionClamp.uc | 27 + Engine/Classes/MaterialExpressionComment.uc | 31 + .../MaterialExpressionComponentMask.uc | 32 + Engine/Classes/MaterialExpressionConstant.uc | 20 + .../MaterialExpressionConstant2Vector.uc | 22 + .../MaterialExpressionConstant3Vector.uc | 23 + .../MaterialExpressionConstant4Vector.uc | 24 + .../MaterialExpressionConstantBiasScale.uc | 30 + .../MaterialExpressionConstantClamp.uc | 31 + Engine/Classes/MaterialExpressionCosine.uc | 30 + .../Classes/MaterialExpressionCrossProduct.uc | 27 + Engine/Classes/MaterialExpressionCustom.uc | 48 + .../MaterialExpressionCustomTexture.uc | 24 + .../MaterialExpressionDepthBiasBlend.uc | 75 + .../MaterialExpressionDepthBiasedAlpha.uc | 72 + .../MaterialExpressionDepthBiasedBlend.uc | 85 + .../MaterialExpressionDepthOfFieldFunction.uc | 48 + .../MaterialExpressionDeriveNormalZ.uc | 27 + .../Classes/MaterialExpressionDesaturation.uc | 36 + Engine/Classes/MaterialExpressionDestColor.uc | 30 + Engine/Classes/MaterialExpressionDestDepth.uc | 29 + Engine/Classes/MaterialExpressionDistance.uc | 26 + Engine/Classes/MaterialExpressionDivide.uc | 26 + .../Classes/MaterialExpressionDotProduct.uc | 27 + .../MaterialExpressionDynamicParameter.uc | 95 + .../MaterialExpressionFlipBookSample.uc | 16 + Engine/Classes/MaterialExpressionFloor.uc | 27 + .../Classes/MaterialExpressionFluidNormal.uc | 28 + Engine/Classes/MaterialExpressionFmod.uc | 28 + ...terialExpressionFoliageImpulseDirection.uc | 20 + ...onFoliageNormalizedRotationAxisAndAngle.uc | 20 + .../Classes/MaterialExpressionFontSample.uc | 58 + .../MaterialExpressionFontSampleParameter.uc | 72 + Engine/Classes/MaterialExpressionFrac.uc | 27 + Engine/Classes/MaterialExpressionFresnel.uc | 41 + .../MaterialExpressionFunctionInput.uc | 102 + .../MaterialExpressionFunctionOutput.uc | 63 + Engine/Classes/MaterialExpressionIf.uc | 32 + .../MaterialExpressionLandscapeLayerBlend.uc | 82 + .../MaterialExpressionLensFlareIntensity.uc | 42 + .../MaterialExpressionLensFlareOcclusion.uc | 42 + ...terialExpressionLensFlareRadialDistance.uc | 42 + .../MaterialExpressionLensFlareRayDistance.uc | 42 + ...terialExpressionLensFlareSourceDistance.uc | 42 + .../Classes/MaterialExpressionLightVector.uc | 18 + .../Classes/MaterialExpressionLightmapUVs.uc | 37 + .../MaterialExpressionLightmassReplace.uc | 26 + .../MaterialExpressionLinearInterpolate.uc | 28 + .../MaterialExpressionMaterialFunctionCall.uc | 94 + ...alExpressionMeshEmitterDynamicParameter.uc | 18 + ...aterialExpressionMeshEmitterVertexColor.uc | 25 + Engine/Classes/MaterialExpressionMeshSubUV.uc | 24 + .../MaterialExpressionMeshSubUVBlend.uc | 17 + Engine/Classes/MaterialExpressionMultiply.uc | 26 + Engine/Classes/MaterialExpressionNormalize.uc | 26 + .../MaterialExpressionObjectOrientation.uc | 20 + .../Classes/MaterialExpressionObjectRadius.uc | 19 + .../MaterialExpressionObjectWorldPosition.uc | 20 + .../MaterialExpressionOcclusionPercentage.uc | 36 + Engine/Classes/MaterialExpressionOneMinus.uc | 27 + Engine/Classes/MaterialExpressionPanner.uc | 37 + Engine/Classes/MaterialExpressionParameter.uc | 53 + .../MaterialExpressionParticleMacroUV.uc | 21 + .../MaterialExpressionParticleSubUV.uc | 24 + .../MaterialExpressionPerInstanceRandom.uc | 19 + .../Classes/MaterialExpressionPixelDepth.uc | 28 + Engine/Classes/MaterialExpressionPower.uc | 28 + .../MaterialExpressionQualitySwitch.uc | 28 + .../MaterialExpressionReflectionVector.uc | 18 + .../MaterialExpressionRotateAboutAxis.uc | 28 + Engine/Classes/MaterialExpressionRotator.uc | 41 + .../MaterialExpressionSPHFluidNormal.uc | 29 + .../MaterialExpressionSPHFluidThickness.uc | 28 + .../MaterialExpressionSPHFluidVertexColor.uc | 33 + .../MaterialExpressionScalarParameter.uc | 21 + .../Classes/MaterialExpressionSceneDepth.uc | 33 + .../Classes/MaterialExpressionSceneTexture.uc | 44 + .../MaterialExpressionScreenPosition.uc | 21 + .../Classes/MaterialExpressionScreenSize.uc | 19 + Engine/Classes/MaterialExpressionSine.uc | 30 + .../Classes/MaterialExpressionSphereMask.uc | 39 + .../Classes/MaterialExpressionSquareRoot.uc | 27 + .../Classes/MaterialExpressionStaticBool.uc | 21 + .../MaterialExpressionStaticBoolParameter.uc | 29 + ...lExpressionStaticComponentMaskParameter.uc | 47 + .../Classes/MaterialExpressionStaticSwitch.uc | 35 + ...MaterialExpressionStaticSwitchParameter.uc | 37 + Engine/Classes/MaterialExpressionSubtract.uc | 26 + .../MaterialExpressionTerrainLayerCoords.uc | 39 + .../MaterialExpressionTerrainLayerSwitch.uc | 83 + .../MaterialExpressionTerrainLayerWeight.uc | 83 + Engine/Classes/MaterialExpressionTexelSize.uc | 19 + .../MaterialExpressionTextureCoordinate.uc | 35 + .../MaterialExpressionTextureObject.uc | 29 + ...aterialExpressionTextureObjectParameter.uc | 29 + .../MaterialExpressionTextureSample.uc | 59 + ...aterialExpressionTextureSampleParameter.uc | 64 + ...erialExpressionTextureSampleParameter2D.uc | 26 + ...ialExpressionTextureSampleParameterCube.uc | 27 + ...xpressionTextureSampleParameterFlipbook.uc | 21 + ...pressionTextureSampleParameterMeshSubUV.uc | 22 + ...ionTextureSampleParameterMeshSubUVBlend.uc | 20 + ...alExpressionTextureSampleParameterMovie.uc | 40 + ...lExpressionTextureSampleParameterNormal.uc | 38 + ...alExpressionTextureSampleParameterSubUV.uc | 22 + Engine/Classes/MaterialExpressionTime.uc | 27 + Engine/Classes/MaterialExpressionTransform.uc | 47 + .../MaterialExpressionTransformPosition.uc | 43 + .../Classes/MaterialExpressionTwoSidedSign.uc | 18 + .../MaterialExpressionVectorParameter.uc | 26 + .../Classes/MaterialExpressionVertexColor.uc | 25 + ...MaterialExpressionWindDirectionAndSpeed.uc | 20 + .../Classes/MaterialExpressionWorldNormal.uc | 20 + .../MaterialExpressionWorldPosition.uc | 26 + Engine/Classes/MaterialFunction.uc | 60 + Engine/Classes/MaterialInstance.uc | 378 + Engine/Classes/MaterialInstanceActor.uc | 34 + Engine/Classes/MaterialInstanceConstant.uc | 199 + Engine/Classes/MaterialInstanceTimeVarying.uc | 236 + .../MaterialInstanceTimeVaryingActor.uc | 32 + Engine/Classes/MaterialInterface.uc | 947 ++ Engine/Classes/MatineeActor.uc | 154 + Engine/Classes/MatineePawn.uc | 35 + Engine/Classes/MeshComponent.uc | 79 + Engine/Classes/MeshComponentFactory.uc | 18 + Engine/Classes/MicroTransactionBase.uc | 112 + Engine/Classes/MixerIntegration.uc | 92 + Engine/Classes/ModelComponent.uc | 30 + Engine/Classes/MorphNodeBase.uc | 66 + Engine/Classes/MorphNodeMultiPose.uc | 82 + Engine/Classes/MorphNodePose.uc | 47 + Engine/Classes/MorphNodeWeight.uc | 29 + Engine/Classes/MorphNodeWeightBase.uc | 42 + Engine/Classes/MorphNodeWeightByBoneAngle.uc | 72 + .../Classes/MorphNodeWeightByBoneRotation.uc | 53 + Engine/Classes/MorphTarget.uc | 14 + Engine/Classes/MorphTargetSet.uc | 58 + Engine/Classes/MorphWeightSequence.uc | 13 + Engine/Classes/MotionBlurEffect.uc | 64 + .../Classes/MultiCueSplineAudioComponent.uc | 101 + Engine/Classes/MultiFont.uc | 66 + Engine/Classes/MultiProviderAnalytics.uc | 181 + Engine/Classes/MusicTrackDataStructures.uc | 41 + Engine/Classes/Mutator.uc | 304 + Engine/Classes/NavMeshBoundsVolume.uc | 17 + .../NavMeshGoalFilter_MinPathDistance.uc | 47 + .../NavMeshGoalFilter_NotNearOtherAI.uc | 49 + .../NavMeshGoalFilter_OutOfViewFrom.uc | 49 + ...MeshGoalFilter_OutsideOfDotProductWedge.uc | 54 + .../NavMeshGoalFilter_PolyEncompassesAI.uc | 53 + Engine/Classes/NavMeshGoal_At.uc | 109 + .../Classes/NavMeshGoal_ClosestActorInList.uc | 69 + Engine/Classes/NavMeshGoal_Filter.uc | 52 + .../NavMeshGoal_GenericFilterContainer.uc | 146 + Engine/Classes/NavMeshGoal_Null.uc | 53 + .../Classes/NavMeshGoal_PolyEncompassesAI.uc | 50 + Engine/Classes/NavMeshGoal_Random.uc | 61 + .../NavMeshGoal_WithinDistanceEnvelope.uc | 53 + Engine/Classes/NavMeshObstacle.uc | 154 + Engine/Classes/NavMeshPathConstraint.uc | 65 + Engine/Classes/NavMeshPathGoalEvaluator.uc | 139 + Engine/Classes/NavMeshPath_AlongLine.uc | 42 + .../Classes/NavMeshPath_EnforceTwoWayEdges.uc | 33 + .../NavMeshPath_MinDistBetweenSpecsOfType.uc | 63 + Engine/Classes/NavMeshPath_SameCoverLink.uc | 41 + Engine/Classes/NavMeshPath_Toward.uc | 70 + .../NavMeshPath_WithinDistanceEnvelope.uc | 72 + .../NavMeshPath_WithinTraversalDist.uc | 52 + Engine/Classes/NavMeshRenderingComponent.uc | 26 + Engine/Classes/NavigationHandle.uc | 954 ++ Engine/Classes/NavigationPoint.uc | 591 + Engine/Classes/Note.uc | 47 + Engine/Classes/NxCylindricalForceField.uc | 54 + .../Classes/NxCylindricalForceFieldCapsule.uc | 65 + Engine/Classes/NxForceField.uc | 123 + Engine/Classes/NxForceFieldComponent.uc | 102 + .../NxForceFieldCylindricalComponent.uc | 67 + Engine/Classes/NxForceFieldGeneric.uc | 140 + .../Classes/NxForceFieldGenericComponent.uc | 93 + Engine/Classes/NxForceFieldRadial.uc | 67 + Engine/Classes/NxForceFieldRadialComponent.uc | 53 + Engine/Classes/NxForceFieldSpawnable.uc | 45 + Engine/Classes/NxForceFieldTornado.uc | 85 + .../Classes/NxForceFieldTornadoComponent.uc | 71 + Engine/Classes/NxGenericForceField.uc | 108 + Engine/Classes/NxGenericForceFieldBox.uc | 60 + Engine/Classes/NxGenericForceFieldBrush.uc | 170 + Engine/Classes/NxGenericForceFieldCapsule.uc | 56 + Engine/Classes/NxRadialCustomForceField.uc | 26 + Engine/Classes/NxRadialForceField.uc | 68 + Engine/Classes/NxTornadoAngularForceField.uc | 57 + .../NxTornadoAngularForceFieldCapsule.uc | 56 + Engine/Classes/NxTornadoForceField.uc | 54 + Engine/Classes/NxTornadoForceFieldCapsule.uc | 56 + Engine/Classes/ObjectReferencer.uc | 10 + Engine/Classes/OnlineAccountInterface.uc | 81 + Engine/Classes/OnlineAuthInterface.uc | 614 + .../OnlineCommunityContentInterface.uc | 218 + Engine/Classes/OnlineContentInterface.uc | 405 + Engine/Classes/OnlineEventsInterface.uc | 40 + Engine/Classes/OnlineGameDVRInterface.uc | 60 + Engine/Classes/OnlineGameDownloadInterface.uc | 33 + Engine/Classes/OnlineGameInterface.uc | 1079 ++ Engine/Classes/OnlineGameSearch.uc | 300 + Engine/Classes/OnlineGameSettings.uc | 179 + Engine/Classes/OnlineMarketplaceInterface.uc | 147 + Engine/Classes/OnlineMatchmakingStats.uc | 25 + Engine/Classes/OnlineNewsInterface.uc | 50 + Engine/Classes/OnlinePartyChatInterface.uc | 191 + Engine/Classes/OnlinePartyInterface.uc | 33 + Engine/Classes/OnlinePlayerInterface.uc | 1248 ++ Engine/Classes/OnlinePlayerInterfaceEx.uc | 628 + Engine/Classes/OnlinePlayerStorage.uc | 553 + .../Classes/OnlinePlaylistGameTypeProvider.uc | 20 + Engine/Classes/OnlineProfileSettings.uc | 315 + Engine/Classes/OnlineRecentPlayersList.uc | 372 + Engine/Classes/OnlineSocialInterface.uc | 107 + Engine/Classes/OnlineStats.uc | 33 + Engine/Classes/OnlineStatsInterface.uc | 241 + Engine/Classes/OnlineStatsRead.uc | 155 + Engine/Classes/OnlineStatsWrite.uc | 128 + Engine/Classes/OnlineSubsystem.uc | 2517 ++++ Engine/Classes/OnlineSuppliedUIInterface.uc | 52 + Engine/Classes/OnlineSystemInterface.uc | 162 + .../Classes/OnlineTitleFileCacheInterface.uc | 143 + Engine/Classes/OnlineTitleFileInterface.uc | 106 + Engine/Classes/OnlineVoiceInterface.uc | 279 + Engine/Classes/PBRuleNodeAlternate.uc | 39 + Engine/Classes/PBRuleNodeBase.uc | 78 + Engine/Classes/PBRuleNodeComment.uc | 48 + Engine/Classes/PBRuleNodeCorner.uc | 90 + Engine/Classes/PBRuleNodeCycle.uc | 50 + Engine/Classes/PBRuleNodeEdgeAngle.uc | 63 + Engine/Classes/PBRuleNodeEdgeMesh.uc | 29 + Engine/Classes/PBRuleNodeExtractTopBottom.uc | 42 + Engine/Classes/PBRuleNodeLODQuad.uc | 26 + Engine/Classes/PBRuleNodeMesh.uc | 127 + Engine/Classes/PBRuleNodeOcclusion.uc | 27 + Engine/Classes/PBRuleNodeQuad.uc | 41 + Engine/Classes/PBRuleNodeRandom.uc | 40 + Engine/Classes/PBRuleNodeRepeat.uc | 29 + Engine/Classes/PBRuleNodeSize.uc | 35 + Engine/Classes/PBRuleNodeSplit.uc | 62 + Engine/Classes/PBRuleNodeSubRuleset.uc | 28 + Engine/Classes/PBRuleNodeTransform.uc | 28 + Engine/Classes/PBRuleNodeVariation.uc | 32 + Engine/Classes/PBRuleNodeWindowWall.uc | 50 + Engine/Classes/ParticleEmitter.uc | 229 + Engine/Classes/ParticleEventManager.uc | 16 + Engine/Classes/ParticleLODLevel.uc | 109 + .../ParticleLightEnvironmentComponent.uc | 79 + Engine/Classes/ParticleModule.uc | 498 + Engine/Classes/ParticleModuleAcceleration.uc | 40 + .../Classes/ParticleModuleAccelerationBase.uc | 24 + .../ParticleModuleAccelerationOverLifetime.uc | 32 + Engine/Classes/ParticleModuleAttractorBase.uc | 8 + .../ParticleModuleAttractorBoneSocket.uc | 267 + Engine/Classes/ParticleModuleAttractorLine.uc | 37 + .../ParticleModuleAttractorParticle.uc | 86 + .../Classes/ParticleModuleAttractorPoint.uc | 57 + .../ParticleModuleAttractorSkelVertSurface.uc | 261 + Engine/Classes/ParticleModuleBeamBase.uc | 68 + Engine/Classes/ParticleModuleBeamModifier.uc | 115 + Engine/Classes/ParticleModuleBeamNoise.uc | 139 + Engine/Classes/ParticleModuleBeamSource.uc | 100 + Engine/Classes/ParticleModuleBeamTarget.uc | 102 + Engine/Classes/ParticleModuleCameraBase.uc | 8 + Engine/Classes/ParticleModuleCameraOffset.uc | 77 + Engine/Classes/ParticleModuleCollision.uc | 268 + .../Classes/ParticleModuleCollisionActor.uc | 68 + Engine/Classes/ParticleModuleCollisionBase.uc | 28 + Engine/Classes/ParticleModuleColor.uc | 56 + Engine/Classes/ParticleModuleColorBase.uc | 8 + .../Classes/ParticleModuleColorByParameter.uc | 33 + .../Classes/ParticleModuleColorOverDensity.uc | 40 + Engine/Classes/ParticleModuleColorOverLife.uc | 48 + .../ParticleModuleColorScaleOverDensity.uc | 39 + .../ParticleModuleColorScaleOverLife.uc | 79 + Engine/Classes/ParticleModuleColor_Seeded.uc | 61 + Engine/Classes/ParticleModuleEventBase.uc | 18 + .../Classes/ParticleModuleEventGenerator.uc | 149 + .../ParticleModuleEventReceiverBase.uc | 48 + ...articleModuleEventReceiverKillParticles.uc | 31 + .../ParticleModuleEventReceiverSpawn.uc | 69 + .../Classes/ParticleModuleEventSendToGame.uc | 18 + .../Classes/ParticleModuleFlexForceField.uc | 28 + Engine/Classes/ParticleModuleFlexSpawn.uc | 48 + .../Classes/ParticleModuleForceFieldBase.uc | 49 + .../ParticleModuleForceFieldCylindrical.uc | 14 + .../ParticleModuleForceFieldGeneric.uc | 15 + .../Classes/ParticleModuleForceFieldRadial.uc | 15 + .../ParticleModuleForceFieldTornado.uc | 15 + Engine/Classes/ParticleModuleKillBase.uc | 8 + Engine/Classes/ParticleModuleKillBox.uc | 48 + Engine/Classes/ParticleModuleKillHeight.uc | 39 + Engine/Classes/ParticleModuleLifetime.uc | 55 + Engine/Classes/ParticleModuleLifetimeBase.uc | 29 + .../Classes/ParticleModuleLifetime_Seeded.uc | 72 + Engine/Classes/ParticleModuleLocation.uc | 59 + Engine/Classes/ParticleModuleLocationBase.uc | 8 + .../ParticleModuleLocationBoneSocket.uc | 203 + .../Classes/ParticleModuleLocationDirect.uc | 62 + .../Classes/ParticleModuleLocationEmitter.uc | 70 + .../ParticleModuleLocationEmitterDirect.uc | 40 + .../ParticleModuleLocationPrimitiveBase.uc | 60 + ...ParticleModuleLocationPrimitiveCylinder.uc | 78 + ...eModuleLocationPrimitiveCylinder_Seeded.uc | 61 + .../ParticleModuleLocationPrimitiveSphere.uc | 37 + ...cleModuleLocationPrimitiveSphere_Seeded.uc | 61 + .../ParticleModuleLocationSkelVertSurface.uc | 191 + ...ParticleModuleLocationStaticVertSurface.uc | 151 + .../ParticleModuleLocationWorldOffset.uc | 12 + ...articleModuleLocationWorldOffset_Seeded.uc | 60 + .../Classes/ParticleModuleLocation_Seeded.uc | 61 + Engine/Classes/ParticleModuleMaterialBase.uc | 8 + .../ParticleModuleMaterialByParameter.uc | 51 + Engine/Classes/ParticleModuleMeshMaterial.uc | 46 + Engine/Classes/ParticleModuleMeshRotation.uc | 49 + .../Classes/ParticleModuleMeshRotationRate.uc | 53 + ...ticleModuleMeshRotationRateMultiplyLife.uc | 37 + .../ParticleModuleMeshRotationRateOverLife.uc | 63 + .../ParticleModuleMeshRotationRate_Seeded.uc | 61 + .../ParticleModuleMeshRotation_Seeded.uc | 61 + Engine/Classes/ParticleModuleOrbit.uc | 140 + Engine/Classes/ParticleModuleOrbitBase.uc | 14 + .../ParticleModuleOrientationAxisLock.uc | 63 + .../Classes/ParticleModuleOrientationBase.uc | 8 + Engine/Classes/ParticleModuleParameterBase.uc | 8 + .../Classes/ParticleModuleParameterDynamic.uc | 258 + .../ParticleModuleParameterDynamic_Seeded.uc | 62 + .../Classes/ParticleModulePhysicsVolumes.uc | 44 + Engine/Classes/ParticleModuleRequired.uc | 338 + Engine/Classes/ParticleModuleRotation.uc | 39 + Engine/Classes/ParticleModuleRotationBase.uc | 8 + .../ParticleModuleRotationOverLifetime.uc | 37 + Engine/Classes/ParticleModuleRotationRate.uc | 45 + .../Classes/ParticleModuleRotationRateBase.uc | 8 + .../ParticleModuleRotationRateMultiplyLife.uc | 37 + .../ParticleModuleRotationRate_Seeded.uc | 61 + .../Classes/ParticleModuleRotation_Seeded.uc | 61 + Engine/Classes/ParticleModuleSize.uc | 40 + Engine/Classes/ParticleModuleSizeBase.uc | 8 + .../Classes/ParticleModuleSizeMultiplyLife.uc | 62 + .../ParticleModuleSizeMultiplyVelocity.uc | 78 + Engine/Classes/ParticleModuleSizeScale.uc | 46 + .../Classes/ParticleModuleSizeScaleByTime.uc | 71 + .../ParticleModuleSizeScaleOverDensity.uc | 34 + Engine/Classes/ParticleModuleSize_Seeded.uc | 61 + .../Classes/ParticleModuleSourceMovement.uc | 36 + Engine/Classes/ParticleModuleSpawn.uc | 86 + Engine/Classes/ParticleModuleSpawnBase.uc | 104 + Engine/Classes/ParticleModuleSpawnPerUnit.uc | 112 + .../Classes/ParticleModuleStoreSpawnTime.uc | 33 + .../ParticleModuleStoreSpawnTimeBase.uc | 15 + Engine/Classes/ParticleModuleSubUV.uc | 61 + Engine/Classes/ParticleModuleSubUVBase.uc | 8 + Engine/Classes/ParticleModuleSubUVDirect.uc | 39 + Engine/Classes/ParticleModuleSubUVMovie.uc | 84 + Engine/Classes/ParticleModuleSubUVSelect.uc | 28 + Engine/Classes/ParticleModuleTrailBase.uc | 28 + Engine/Classes/ParticleModuleTrailSource.uc | 121 + Engine/Classes/ParticleModuleTrailSpawn.uc | 73 + Engine/Classes/ParticleModuleTrailTaper.uc | 60 + .../ParticleModuleTypeDataAnimTrail.uc | 102 + Engine/Classes/ParticleModuleTypeDataApex.uc | 37 + Engine/Classes/ParticleModuleTypeDataBase.uc | 27 + Engine/Classes/ParticleModuleTypeDataBeam.uc | 100 + Engine/Classes/ParticleModuleTypeDataBeam2.uc | 202 + Engine/Classes/ParticleModuleTypeDataMesh.uc | 162 + .../ParticleModuleTypeDataMeshPhysX.uc | 55 + Engine/Classes/ParticleModuleTypeDataPhysX.uc | 91 + .../Classes/ParticleModuleTypeDataRibbon.uc | 160 + Engine/Classes/ParticleModuleTypeDataTrail.uc | 47 + .../Classes/ParticleModuleTypeDataTrail2.uc | 91 + Engine/Classes/ParticleModuleUberBase.uc | 44 + Engine/Classes/ParticleModuleUberLTISIVCL.uc | 100 + .../Classes/ParticleModuleUberLTISIVCLIL.uc | 110 + .../ParticleModuleUberLTISIVCLILIRSSBLIRR.uc | 153 + Engine/Classes/ParticleModuleUberRainDrops.uc | 151 + .../Classes/ParticleModuleUberRainImpacts.uc | 195 + .../Classes/ParticleModuleUberRainSplashA.uc | 129 + .../Classes/ParticleModuleUberRainSplashB.uc | 121 + Engine/Classes/ParticleModuleVelocity.uc | 46 + Engine/Classes/ParticleModuleVelocityBase.uc | 17 + Engine/Classes/ParticleModuleVelocityCone.uc | 63 + .../ParticleModuleVelocityInheritParent.uc | 28 + .../ParticleModuleVelocityOverLifetime.uc | 36 + .../Classes/ParticleModuleVelocity_Seeded.uc | 61 + .../Classes/ParticleModuleWorldAttractor.uc | 39 + .../Classes/ParticleModuleWorldForcesBase.uc | 8 + Engine/Classes/ParticleSpriteEmitter.uc | 24 + Engine/Classes/ParticleSystem.uc | 412 + Engine/Classes/ParticleSystemComponent.uc | 962 ++ Engine/Classes/ParticleSystemReplay.uc | 96 + Engine/Classes/PathBlockingVolume.uc | 32 + Engine/Classes/PathConstraint.uc | 34 + Engine/Classes/PathGoalEvaluator.uc | 48 + Engine/Classes/PathNode.uc | 26 + Engine/Classes/PathNode_Dynamic.uc | 20 + Engine/Classes/PathRenderingComponent.uc | 25 + Engine/Classes/PathTargetPoint.uc | 46 + Engine/Classes/Path_AlongLine.uc | 43 + Engine/Classes/Path_AvoidInEscapableNodes.uc | 54 + .../Classes/Path_MinDistBetweenSpecsOfType.uc | 59 + Engine/Classes/Path_TowardGoal.uc | 43 + Engine/Classes/Path_TowardPoint.uc | 43 + Engine/Classes/Path_WithinDistanceEnvelope.uc | 72 + Engine/Classes/Path_WithinTraversalDist.uc | 53 + Engine/Classes/Pawn.uc | 3834 +++++ Engine/Classes/PhysXParticleSystem.uc | 208 + Engine/Classes/PhysicalMaterial.uc | 182 + .../Classes/PhysicalMaterialPropertyBase.uc | 82 + Engine/Classes/PhysicsAsset.uc | 106 + Engine/Classes/PhysicsAssetInstance.uc | 145 + Engine/Classes/PhysicsLODVerticalEmitter.uc | 14 + Engine/Classes/PhysicsVolume.uc | 274 + Engine/Classes/PickupFactory.uc | 476 + Engine/Classes/PixelFormatEnum.uci | 42 + Engine/Classes/PlatformInterfaceBase.uc | 204 + .../Classes/PlatformInterfaceWebResponse.uc | 41 + Engine/Classes/Player.uc | 38 + Engine/Classes/PlayerController.uc | 9697 +++++++++++++ Engine/Classes/PlayerInput.uc | 583 + Engine/Classes/PlayerManagerInteraction.uc | 76 + Engine/Classes/PlayerReplicationInfo.uc | 636 + Engine/Classes/PlayerStart.uc | 149 + Engine/Classes/PlayfabInterface.uc | 457 + Engine/Classes/PointLight.uc | 79 + Engine/Classes/PointLightComponent.uc | 108 + Engine/Classes/PointLightMovable.uc | 61 + Engine/Classes/PointLightToggleable.uc | 89 + Engine/Classes/PortalMarker.uc | 29 + Engine/Classes/PortalTeleporter.uc | 75 + Engine/Classes/PortalVolume.uc | 44 + Engine/Classes/PostProcessChain.uc | 26 + Engine/Classes/PostProcessEffect.uc | 85 + Engine/Classes/PostProcessVolume.uc | 1313 ++ Engine/Classes/PotentialClimbWatcher.uc | 36 + .../PrecomputedVisibilityOverrideVolume.uc | 33 + Engine/Classes/PrecomputedVisibilityVolume.uc | 27 + Engine/Classes/Prefab.uc | 49 + Engine/Classes/PrefabInstance.uc | 150 + Engine/Classes/PrefabSequence.uc | 64 + Engine/Classes/PrefabSequenceContainer.uc | 51 + Engine/Classes/PrimitiveComponent.uc | 879 ++ Engine/Classes/PrimitiveComponentFactory.uc | 30 + Engine/Classes/ProcBuilding.uc | 446 + Engine/Classes/ProcBuildingRuleset.uc | 119 + Engine/Classes/ProcBuilding_SimpleLODActor.uc | 21 + Engine/Classes/Projectile.uc | 367 + Engine/Classes/ProscribedReachSpec.uc | 27 + Engine/Classes/Pylon.uc | 964 ++ Engine/Classes/PylonSeed.uc | 54 + Engine/Classes/RB_BSJointActor.uc | 18 + Engine/Classes/RB_BSJointSetup.uc | 10 + Engine/Classes/RB_BodyInstance.uc | 250 + Engine/Classes/RB_BodySetup.uc | 124 + Engine/Classes/RB_ConstraintActor.uc | 170 + Engine/Classes/RB_ConstraintActorSpawnable.uc | 18 + Engine/Classes/RB_ConstraintDrawComponent.uc | 29 + Engine/Classes/RB_ConstraintInstance.uc | 138 + Engine/Classes/RB_ConstraintSetup.uc | 160 + Engine/Classes/RB_CylindricalForceActor.uc | 146 + Engine/Classes/RB_DistanceJointSetup.uc | 20 + Engine/Classes/RB_ForceFieldExcludeVolume.uc | 35 + Engine/Classes/RB_Handle.uc | 85 + Engine/Classes/RB_HingeActor.uc | 27 + Engine/Classes/RB_HingeSetup.uc | 16 + Engine/Classes/RB_LineImpulseActor.uc | 100 + Engine/Classes/RB_PrismaticActor.uc | 28 + Engine/Classes/RB_PrismaticSetup.uc | 14 + Engine/Classes/RB_PulleyJointActor.uc | 18 + Engine/Classes/RB_PulleyJointSetup.uc | 10 + Engine/Classes/RB_RadialForceActor.uc | 151 + Engine/Classes/RB_RadialImpulseActor.uc | 79 + Engine/Classes/RB_RadialImpulseComponent.uc | 38 + Engine/Classes/RB_SkelJointSetup.uc | 16 + Engine/Classes/RB_Spring.uc | 77 + Engine/Classes/RB_StayUprightSetup.uc | 15 + Engine/Classes/RB_Thruster.uc | 69 + Engine/Classes/RadialBlurActor.uc | 29 + Engine/Classes/RadialBlurComponent.uc | 85 + Engine/Classes/RazerLEDInterface.uc | 22 + Engine/Classes/ReachSpec.uc | 188 + Engine/Classes/ReplicationInfo.uc | 22 + Engine/Classes/ReverbVolume.uc | 180 + Engine/Classes/ReverbVolumeToggleable.uc | 35 + Engine/Classes/RigidBodyBase.uc | 9 + Engine/Classes/Route.uc | 82 + Engine/Classes/RouteRenderingComponent.uc | 13 + Engine/Classes/SVehicle.uc | 869 ++ Engine/Classes/SVehicleSimBase.uc | 84 + Engine/Classes/SVehicleSimCar.uc | 36 + Engine/Classes/SVehicleSimTank.uc | 73 + Engine/Classes/SVehicleWheel.uc | 117 + Engine/Classes/SaveGameSummary.uc | 18 + Engine/Classes/SavedMove.uc | 321 + Engine/Classes/Scene.uc | 35 + Engine/Classes/SceneCapture2DActor.uc | 55 + Engine/Classes/SceneCapture2DComponent.uc | 84 + .../Classes/SceneCapture2DHitMaskComponent.uc | 103 + Engine/Classes/SceneCaptureActor.uc | 91 + Engine/Classes/SceneCaptureComponent.uc | 140 + Engine/Classes/SceneCaptureCubeMapActor.uc | 67 + .../Classes/SceneCaptureCubeMapComponent.uc | 52 + Engine/Classes/SceneCapturePortalActor.uc | 64 + Engine/Classes/SceneCapturePortalComponent.uc | 48 + Engine/Classes/SceneCaptureReflectActor.uc | 71 + .../Classes/SceneCaptureReflectComponent.uc | 40 + Engine/Classes/Scout.uc | 341 + Engine/Classes/ScriptViewportClient.uc | 9 + Engine/Classes/ScriptedTexture.uc | 48 + Engine/Classes/SeqAct_AIAbortMoveToActor.uc | 10 + Engine/Classes/SeqAct_AIMoveToActor.uc | 84 + Engine/Classes/SeqAct_AccessObjectList.uc | 52 + Engine/Classes/SeqAct_ActivateRemoteEvent.uc | 56 + Engine/Classes/SeqAct_ActorFactory.uc | 127 + Engine/Classes/SeqAct_ActorFactoryEx.uc | 25 + Engine/Classes/SeqAct_AddFloat.uc | 37 + Engine/Classes/SeqAct_AddInt.uc | 38 + .../Classes/SeqAct_AddRemoveFaceFXAnimSet.uc | 21 + Engine/Classes/SeqAct_AndGate.uc | 35 + Engine/Classes/SeqAct_ApplySoundNode.uc | 19 + Engine/Classes/SeqAct_AssignController.uc | 12 + Engine/Classes/SeqAct_AttachToActor.uc | 48 + Engine/Classes/SeqAct_AttachToEvent.uc | 24 + Engine/Classes/SeqAct_CameraFade.uc | 56 + Engine/Classes/SeqAct_CameraLookAt.uc | 90 + Engine/Classes/SeqAct_CameraShake.uc | 69 + Engine/Classes/SeqAct_CastToFloat.uc | 31 + Engine/Classes/SeqAct_CastToInt.uc | 43 + Engine/Classes/SeqAct_ChangeCollision.uc | 54 + Engine/Classes/SeqAct_CommitMapChange.uc | 23 + Engine/Classes/SeqAct_ConsoleCommand.uc | 43 + Engine/Classes/SeqAct_ControlMovieTexture.uc | 57 + Engine/Classes/SeqAct_ConvertToString.uc | 35 + Engine/Classes/SeqAct_Delay.uc | 60 + Engine/Classes/SeqAct_DelaySwitch.uc | 103 + Engine/Classes/SeqAct_Destroy.uc | 13 + Engine/Classes/SeqAct_DivideFloat.uc | 42 + Engine/Classes/SeqAct_DivideInt.uc | 42 + Engine/Classes/SeqAct_DrawText.uc | 50 + Engine/Classes/SeqAct_FeatureTest.uc | 35 + Engine/Classes/SeqAct_FinishSequence.uc | 31 + Engine/Classes/SeqAct_FlyThroughHasEnded.uc | 13 + Engine/Classes/SeqAct_ForceFeedback.uc | 21 + .../Classes/SeqAct_ForceGarbageCollection.uc | 22 + Engine/Classes/SeqAct_Gate.uc | 100 + Engine/Classes/SeqAct_GetDistance.uc | 23 + .../Classes/SeqAct_GetLocationAndRotation.uc | 47 + Engine/Classes/SeqAct_GetProperty.uc | 25 + Engine/Classes/SeqAct_GetVectorComponents.uc | 31 + Engine/Classes/SeqAct_GetVelocity.uc | 35 + Engine/Classes/SeqAct_GiveInventory.uc | 14 + Engine/Classes/SeqAct_HeadTrackingControl.uc | 172 + Engine/Classes/SeqAct_Interp.uc | 356 + Engine/Classes/SeqAct_IsInObjectList.uc | 68 + Engine/Classes/SeqAct_Latent.uc | 52 + Engine/Classes/SeqAct_LevelStreaming.uc | 36 + Engine/Classes/SeqAct_LevelStreamingBase.uc | 47 + Engine/Classes/SeqAct_LevelVisibility.uc | 40 + Engine/Classes/SeqAct_Log.uc | 58 + Engine/Classes/SeqAct_MITV_Activate.uc | 52 + Engine/Classes/SeqAct_ModifyCover.uc | 34 + Engine/Classes/SeqAct_ModifyHealth.uc | 64 + Engine/Classes/SeqAct_ModifyObjectList.uc | 76 + Engine/Classes/SeqAct_MultiLevelStreaming.uc | 42 + Engine/Classes/SeqAct_MultiplyFloat.uc | 37 + Engine/Classes/SeqAct_MultiplyInt.uc | 37 + .../Classes/SeqAct_ParticleEventGenerator.uc | 89 + Engine/Classes/SeqAct_PhysXSwitch.uc | 43 + Engine/Classes/SeqAct_PlayCameraAnim.uc | 71 + Engine/Classes/SeqAct_PlayFaceFXAnim.uc | 33 + Engine/Classes/SeqAct_PlayMusicTrack.uc | 24 + Engine/Classes/SeqAct_PlaySound.uc | 83 + Engine/Classes/SeqAct_Possess.uc | 27 + Engine/Classes/SeqAct_PrepareMapChange.uc | 59 + Engine/Classes/SeqAct_ProjectileFactory.uc | 69 + Engine/Classes/SeqAct_RandomSwitch.uc | 28 + Engine/Classes/SeqAct_RangeSwitch.uc | 85 + Engine/Classes/SeqAct_SetActiveAnimChild.uc | 27 + Engine/Classes/SeqAct_SetApexClothingParam.uc | 16 + Engine/Classes/SeqAct_SetBlockRigidBody.uc | 14 + Engine/Classes/SeqAct_SetBool.uc | 21 + Engine/Classes/SeqAct_SetCameraTarget.uc | 37 + Engine/Classes/SeqAct_SetDOFParams.uc | 68 + Engine/Classes/SeqAct_SetDamageInstigator.uc | 14 + Engine/Classes/SeqAct_SetFloat.uc | 46 + Engine/Classes/SeqAct_SetInt.uc | 46 + Engine/Classes/SeqAct_SetLocation.uc | 49 + .../Classes/SeqAct_SetMatInstScalarParam.uc | 23 + Engine/Classes/SeqAct_SetMatInstTexParam.uc | 16 + .../Classes/SeqAct_SetMatInstVectorParam.uc | 32 + Engine/Classes/SeqAct_SetMaterial.uc | 24 + Engine/Classes/SeqAct_SetMesh.uc | 28 + Engine/Classes/SeqAct_SetMotionBlurParams.uc | 40 + Engine/Classes/SeqAct_SetObject.uc | 36 + Engine/Classes/SeqAct_SetParticleSysParam.uc | 25 + Engine/Classes/SeqAct_SetPhysics.uc | 20 + .../SeqAct_SetRigidBodyIgnoreVehicles.uc | 14 + Engine/Classes/SeqAct_SetSequenceVariable.uc | 15 + Engine/Classes/SeqAct_SetSkelControlTarget.uc | 18 + Engine/Classes/SeqAct_SetSoundMode.uc | 52 + Engine/Classes/SeqAct_SetString.uc | 42 + Engine/Classes/SeqAct_SetVector.uc | 41 + Engine/Classes/SeqAct_SetVectorComponents.uc | 31 + Engine/Classes/SeqAct_SetVelocity.uc | 31 + .../Classes/SeqAct_SetWorldAttractorParam.uc | 70 + Engine/Classes/SeqAct_StreamInTextures.uc | 96 + Engine/Classes/SeqAct_SubtractFloat.uc | 37 + Engine/Classes/SeqAct_SubtractInt.uc | 37 + Engine/Classes/SeqAct_Switch.uc | 115 + Engine/Classes/SeqAct_Teleport.uc | 61 + Engine/Classes/SeqAct_Timer.uc | 59 + Engine/Classes/SeqAct_Toggle.uc | 26 + .../SeqAct_ToggleAffectedByHitEffects.uc | 16 + Engine/Classes/SeqAct_ToggleCinematicMode.uc | 58 + .../Classes/SeqAct_ToggleConstraintDrive.uc | 23 + Engine/Classes/SeqAct_ToggleGodMode.uc | 15 + Engine/Classes/SeqAct_ToggleHUD.uc | 31 + Engine/Classes/SeqAct_ToggleHidden.uc | 17 + Engine/Classes/SeqAct_ToggleInput.uc | 17 + Engine/Classes/SeqAct_Trace.uc | 59 + .../Classes/SeqAct_UpdatePhysBonesFromAnim.uc | 20 + Engine/Classes/SeqAct_WaitForLevelsVisible.uc | 48 + Engine/Classes/SeqCond_CompareBool.uc | 31 + Engine/Classes/SeqCond_CompareFloat.uc | 53 + Engine/Classes/SeqCond_CompareInt.uc | 53 + Engine/Classes/SeqCond_CompareObject.uc | 23 + Engine/Classes/SeqCond_GetServerType.uc | 25 + Engine/Classes/SeqCond_Increment.uc | 58 + Engine/Classes/SeqCond_IncrementFloat.uc | 60 + Engine/Classes/SeqCond_IsAlive.uc | 22 + Engine/Classes/SeqCond_IsBenchmarking.uc | 31 + Engine/Classes/SeqCond_IsConsole.uc | 34 + Engine/Classes/SeqCond_IsInCombat.uc | 22 + Engine/Classes/SeqCond_IsLoggedIn.uc | 67 + Engine/Classes/SeqCond_IsPIE.uc | 31 + Engine/Classes/SeqCond_IsSameTeam.uc | 19 + Engine/Classes/SeqCond_MatureLanguage.uc | 31 + Engine/Classes/SeqCond_ShowGore.uc | 32 + Engine/Classes/SeqCond_SwitchBase.uc | 104 + Engine/Classes/SeqCond_SwitchClass.uc | 100 + Engine/Classes/SeqCond_SwitchObject.uc | 118 + Engine/Classes/SeqCond_SwitchPlatform.uc | 40 + .../Classes/SeqEvent_AIReachedRouteActor.uc | 14 + Engine/Classes/SeqEvent_AISeeEnemy.uc | 36 + Engine/Classes/SeqEvent_AnalogInput.uc | 55 + Engine/Classes/SeqEvent_AnimNotify.uc | 22 + Engine/Classes/SeqEvent_Console.uc | 32 + Engine/Classes/SeqEvent_ConstraintBroken.uc | 15 + Engine/Classes/SeqEvent_Death.uc | 14 + Engine/Classes/SeqEvent_Destroyed.uc | 14 + Engine/Classes/SeqEvent_GetInventory.uc | 22 + Engine/Classes/SeqEvent_HitWall.uc | 19 + Engine/Classes/SeqEvent_Input.uc | 49 + Engine/Classes/SeqEvent_LOS.uc | 34 + Engine/Classes/SeqEvent_LevelBeginning.uc | 22 + Engine/Classes/SeqEvent_LevelLoaded.uc | 29 + Engine/Classes/SeqEvent_LevelStartup.uc | 21 + Engine/Classes/SeqEvent_MobileTouch.uc | 21 + Engine/Classes/SeqEvent_Mover.uc | 115 + Engine/Classes/SeqEvent_ParticleEvent.uc | 75 + Engine/Classes/SeqEvent_PickupStatusChange.uc | 17 + Engine/Classes/SeqEvent_PlayerSpawned.uc | 17 + Engine/Classes/SeqEvent_ProjectileLanded.uc | 26 + Engine/Classes/SeqEvent_RemoteEvent.uc | 44 + Engine/Classes/SeqEvent_RigidBodyCollision.uc | 26 + Engine/Classes/SeqEvent_SeeDeath.uc | 24 + Engine/Classes/SeqEvent_SequenceActivated.uc | 30 + Engine/Classes/SeqEvent_TakeDamage.uc | 170 + Engine/Classes/SeqEvent_Touch.uc | 116 + Engine/Classes/SeqEvent_TouchInput.uc | 52 + Engine/Classes/SeqEvent_Used.uc | 47 + Engine/Classes/SeqVar_Bool.uc | 35 + Engine/Classes/SeqVar_Byte.uc | 13 + Engine/Classes/SeqVar_Character.uc | 37 + Engine/Classes/SeqVar_External.uc | 36 + Engine/Classes/SeqVar_Float.uc | 36 + Engine/Classes/SeqVar_Group.uc | 27 + Engine/Classes/SeqVar_Int.uc | 36 + Engine/Classes/SeqVar_Name.uc | 13 + Engine/Classes/SeqVar_Named.uc | 53 + Engine/Classes/SeqVar_Object.uc | 72 + Engine/Classes/SeqVar_ObjectList.uc | 62 + Engine/Classes/SeqVar_ObjectVolume.uc | 43 + Engine/Classes/SeqVar_Player.uc | 69 + Engine/Classes/SeqVar_RandomFloat.uc | 39 + Engine/Classes/SeqVar_RandomInt.uc | 46 + Engine/Classes/SeqVar_String.uc | 48 + Engine/Classes/SeqVar_Union.uc | 14 + Engine/Classes/SeqVar_Vector.uc | 59 + Engine/Classes/Sequence.uc | 370 + Engine/Classes/SequenceAction.uc | 33 + Engine/Classes/SequenceCondition.uc | 18 + Engine/Classes/SequenceEvent.uc | 165 + Engine/Classes/SequenceFrame.uc | 74 + Engine/Classes/SequenceFrameWrapped.uc | 20 + Engine/Classes/SequenceObject.uc | 300 + Engine/Classes/SequenceOp.uc | 727 + Engine/Classes/SequenceVariable.uc | 91 + Engine/Classes/Settings.uc | 1095 ++ Engine/Classes/ShadowMap2D.uc | 32 + Engine/Classes/ShadowMapTexture2D.uc | 10 + Engine/Classes/SharedCloudFileInterface.uc | 98 + Engine/Classes/SimpleSplineAudioComponent.uc | 160 + .../SimpleSplineNonLoopAudioComponent.uc | 60 + Engine/Classes/SkelControlBase.uc | 267 + Engine/Classes/SkelControlFootPlacement.uc | 55 + Engine/Classes/SkelControlHandlebars.uc | 51 + Engine/Classes/SkelControlLimb.uc | 95 + Engine/Classes/SkelControlLookAt.uc | 168 + Engine/Classes/SkelControlSingleBone.uc | 50 + Engine/Classes/SkelControlSpline.uc | 54 + Engine/Classes/SkelControlTrail.uc | 58 + Engine/Classes/SkelControlWheel.uc | 57 + Engine/Classes/SkelControl_CCD_IK.uc | 55 + Engine/Classes/SkelControl_Multiply.uc | 28 + Engine/Classes/SkelControl_TwistBone.uc | 30 + Engine/Classes/SkeletalMesh.uc | 740 + Engine/Classes/SkeletalMeshActor.uc | 735 + .../SkeletalMeshActorBasedOnExtremeContent.uc | 61 + Engine/Classes/SkeletalMeshActorMAT.uc | 105 + .../Classes/SkeletalMeshActorMATSpawnable.uc | 11 + .../Classes/SkeletalMeshActorMATWalkable.uc | 26 + Engine/Classes/SkeletalMeshActorSpawnable.uc | 13 + Engine/Classes/SkeletalMeshCinematicActor.uc | 31 + Engine/Classes/SkeletalMeshComponent.uc | 1863 +++ Engine/Classes/SkeletalMeshSocket.uc | 58 + Engine/Classes/SkyLight.uc | 21 + Engine/Classes/SkyLightComponent.uc | 38 + Engine/Classes/SkyLightToggleable.uc | 33 + Engine/Classes/SlotToSlotReachSpec.uc | 23 + Engine/Classes/SoundClass.uc | 83 + Engine/Classes/SoundCue.uc | 62 + Engine/Classes/SoundMode.uc | 101 + Engine/Classes/SoundNode.uc | 13 + Engine/Classes/SoundNodeAmbient.uc | 83 + Engine/Classes/SoundNodeAmbientNonLoop.uc | 29 + .../Classes/SoundNodeAmbientNonLoopToggle.uc | 17 + Engine/Classes/SoundNodeAttenuation.uc | 63 + Engine/Classes/SoundNodeAttenuationAndGain.uc | 62 + Engine/Classes/SoundNodeConcatenator.uc | 20 + Engine/Classes/SoundNodeConcatenatorRadio.uc | 17 + Engine/Classes/SoundNodeDelay.uc | 30 + Engine/Classes/SoundNodeDistanceCrossFade.uc | 72 + Engine/Classes/SoundNodeDoppler.uc | 33 + Engine/Classes/SoundNodeEnveloper.uc | 28 + Engine/Classes/SoundNodeLooping.uc | 32 + Engine/Classes/SoundNodeMature.uc | 17 + Engine/Classes/SoundNodeMixer.uc | 19 + Engine/Classes/SoundNodeModulator.uc | 42 + .../Classes/SoundNodeModulatorContinuous.uc | 38 + Engine/Classes/SoundNodeOscillator.uc | 68 + Engine/Classes/SoundNodeRandom.uc | 48 + Engine/Classes/SoundNodeWave.uc | 166 + Engine/Classes/SoundNodeWaveParam.uc | 16 + Engine/Classes/SoundNodeWaveStreaming.uc | 41 + Engine/Classes/SpeechRecognition.uc | 205 + Engine/Classes/SpeedTree.uc | 84 + Engine/Classes/SpeedTreeActor.uc | 43 + Engine/Classes/SpeedTreeActorFactory.uc | 31 + Engine/Classes/SpeedTreeComponent.uc | 209 + Engine/Classes/SpeedTreeComponentFactory.uc | 33 + .../SphericalHarmonicLightComponent.uc | 30 + Engine/Classes/SplineActor.uc | 149 + Engine/Classes/SplineAudioComponent.uc | 68 + Engine/Classes/SplineComponent.uc | 58 + Engine/Classes/SplineComponentSimplified.uc | 13 + Engine/Classes/SplineLoftActor.uc | 89 + Engine/Classes/SplineLoftActorMovable.uc | 28 + Engine/Classes/SplineMeshComponent.uc | 75 + Engine/Classes/SpotLight.uc | 98 + Engine/Classes/SpotLightComponent.uc | 43 + Engine/Classes/SpotLightMovable.uc | 63 + Engine/Classes/SpotLightToggleable.uc | 89 + Engine/Classes/SpriteComponent.uc | 43 + Engine/Classes/StaticLightCollectionActor.uc | 45 + Engine/Classes/StaticMeshActor.uc | 163 + Engine/Classes/StaticMeshActorBase.uc | 31 + .../StaticMeshActorBasedOnExtremeContent.uc | 89 + Engine/Classes/StaticMeshCollectionActor.uc | 47 + Engine/Classes/StaticMeshComponent.uc | 187 + Engine/Classes/StaticMeshComponentFactory.uc | 25 + Engine/Classes/StringsTag.uc | 22 + Engine/Classes/Surface.uc | 21 + Engine/Classes/SwatTurnReachSpec.uc | 24 + Engine/Classes/TWDeferredWorkManager.uc | 95 + .../Classes/TWFixupSplattermapUVCommandlet.uc | 29 + .../Classes/TWGenerateLightmapUVCommandlet.uc | 35 + Engine/Classes/TWIndoorLightingVolume.uc | 81 + ...rialExpressionLightBrightnessMultiplier.uc | 27 + Engine/Classes/TWOnlineLobby.uc | 116 + Engine/Classes/TWOnlineUGCInterface.uc | 23 + Engine/Classes/TWOutdoorLightingVolume.uc | 84 + .../TWParticleModuleEventReceiverBlood.uc | 40 + .../TWParticleModuleEventReceiverSFX.uc | 41 + Engine/Classes/TWPostProcessEffect.uc | 257 + .../Classes/TWSceneCapture2DDPGComponent.uc | 33 + Engine/Classes/TWSeqEvent_LightFlicker.uc | 20 + Engine/Classes/TWSplatterMap2D.uc | 25 + Engine/Classes/TWSplatterMapTexture2D.uc | 24 + Engine/Classes/TargetPoint.uc | 51 + Engine/Classes/TeamInfo.uc | 112 + Engine/Classes/TeleportReachSpec.uc | 21 + Engine/Classes/Teleporter.uc | 263 + Engine/Classes/Terrain.uc | 1007 ++ Engine/Classes/TerrainComponent.uc | 270 + Engine/Classes/TerrainLayerSetup.uc | 63 + Engine/Classes/TerrainMaterial.uc | 54 + Engine/Classes/TerrainWeightMapTexture.uc | 40 + Engine/Classes/TestSplittingVolume.uc | 24 + Engine/Classes/Texture.uc | 484 + Engine/Classes/Texture2D.uc | 544 + Engine/Classes/Texture2DComposite.uc | 87 + Engine/Classes/Texture2DDynamic.uc | 90 + Engine/Classes/TextureCube.uc | 96 + Engine/Classes/TextureFlipBook.uc | 229 + Engine/Classes/TextureMovie.uc | 195 + Engine/Classes/TextureRenderTarget.uc | 74 + Engine/Classes/TextureRenderTarget2D.uc | 134 + Engine/Classes/TextureRenderTargetCube.uc | 109 + Engine/Classes/TranslationContext.uc | 43 + Engine/Classes/TranslatorTag.uc | 33 + Engine/Classes/Trigger.uc | 120 + Engine/Classes/TriggerStreamingLevel.uc | 57 + Engine/Classes/TriggerVolume.uc | 41 + Engine/Classes/Trigger_Dynamic.uc | 16 + Engine/Classes/Trigger_LOS.uc | 70 + Engine/Classes/Trigger_PawnsOnly.uc | 14 + Engine/Classes/TriggeredPath.uc | 90 + Engine/Classes/TwitterIntegrationBase.uc | 82 + Engine/Classes/UICharacterSummary.uc | 19 + Engine/Classes/UIDataProvider.uc | 13 + Engine/Classes/UIDataProvider_MenuItem.uc | 87 + .../UIDataProvider_OnlineFriendMessages.uc | 169 + .../Classes/UIDataProvider_OnlineFriends.uc | 215 + .../UIDataProvider_OnlinePartyChatList.uc | 145 + .../UIDataProvider_OnlinePlayerDataBase.uc | 62 + .../UIDataProvider_OnlinePlayerStorage.uc | 398 + ...UIDataProvider_OnlinePlayerStorageArray.uc | 52 + .../UIDataProvider_OnlineProfileSettings.uc | 127 + .../UIDataProvider_PlayerAchievements.uc | 189 + Engine/Classes/UIDataProvider_Settings.uc | 21 + .../Classes/UIDataProvider_SettingsArray.uc | 57 + Engine/Classes/UIDataStore.uc | 182 + Engine/Classes/UIDataStorePublisher.uc | 27 + Engine/Classes/UIDataStoreSubscriber.uc | 75 + Engine/Classes/UIDataStore_DynamicResource.uc | 209 + Engine/Classes/UIDataStore_Fonts.uc | 12 + Engine/Classes/UIDataStore_GameResource.uc | 105 + Engine/Classes/UIDataStore_GameState.uc | 35 + Engine/Classes/UIDataStore_InputAlias.uc | 176 + Engine/Classes/UIDataStore_MenuItems.uc | 81 + .../Classes/UIDataStore_OnlineGameSearch.uc | 434 + .../Classes/UIDataStore_OnlineGameSettings.uc | 193 + .../Classes/UIDataStore_OnlinePlayerData.uc | 325 + Engine/Classes/UIDataStore_OnlineStats.uc | 253 + Engine/Classes/UIDataStore_Registry.uc | 82 + Engine/Classes/UIDataStore_Remote.uc | 14 + Engine/Classes/UIDataStore_Settings.uc | 18 + Engine/Classes/UIDataStore_StringAliasMap.uc | 76 + Engine/Classes/UIDataStore_StringBase.uc | 14 + Engine/Classes/UIDev.uci | 4 + Engine/Classes/UIGameInfoSummary.uc | 28 + Engine/Classes/UIInteraction.uc | 665 + Engine/Classes/UIManager.uc | 102 + Engine/Classes/UIMapSummary.uc | 19 + Engine/Classes/UIPropertyDataProvider.uc | 31 + .../Classes/UIResourceCombinationProvider.uc | 51 + Engine/Classes/UIResourceDataProvider.uc | 26 + Engine/Classes/UIRoot.uc | 628 + Engine/Classes/UISceneClient.uc | 187 + Engine/Classes/UISoundTheme.uc | 70 + Engine/Classes/UIWeaponSummary.uc | 21 + Engine/Classes/UberPostProcessEffect.uc | 223 + ...erCloudFileCloudSaveSystemDataBlobStore.uc | 182 + Engine/Classes/UserCloudFileInterface.uc | 185 + Engine/Classes/Vehicle.uc | 953 ++ Engine/Classes/Volume.uc | 156 + Engine/Classes/VolumePathNode.uc | 49 + Engine/Classes/VolumeTimer.uc | 26 + Engine/Classes/WallTransReachSpec.uc | 18 + Engine/Classes/WaterVolume.uc | 71 + Engine/Classes/WaveFormBase.uc | 19 + Engine/Classes/Weapon.uc | 1957 +++ Engine/Classes/WindDirectionalSource.uc | 29 + .../Classes/WindDirectionalSourceComponent.uc | 38 + Engine/Classes/WindPointSource.uc | 42 + Engine/Classes/WindPointSourceComponent.uc | 32 + Engine/Classes/WorldAttractor.uc | 198 + Engine/Classes/WorldInfo.uc | 2051 +++ Engine/Classes/ZoneInfo.uc | 20 + GFxUI/Classes/FlashMovie.uc | 25 + GFxUI/Classes/GFxAction_CloseMovie.uc | 37 + GFxUI/Classes/GFxAction_GetVariable.uc | 37 + GFxUI/Classes/GFxAction_Invoke.uc | 38 + GFxUI/Classes/GFxAction_OpenMovie.uc | 75 + GFxUI/Classes/GFxAction_SetCaptureKeys.uc | 39 + GFxUI/Classes/GFxAction_SetVariable.uc | 37 + GFxUI/Classes/GFxClikWidget.uc | 128 + GFxUI/Classes/GFxEngine.uc | 68 + GFxUI/Classes/GFxEvent_FsCommand.uc | 51 + GFxUI/Classes/GFxFSCmdHandler.uc | 33 + GFxUI/Classes/GFxFSCmdHandler_Kismet.uc | 21 + GFxUI/Classes/GFxInteraction.uc | 88 + GFxUI/Classes/GFxMoviePlayer.uc | 734 + GFxUI/Classes/GFxObject.uc | 261 + GFxUI/Classes/GFxRawData.uc | 42 + GFxUI/Classes/SwfMovie.uc | 72 + GFxUIEditor/Classes/GFxImportCommandlet.uc | 19 + GFxUIEditor/Classes/GFxMovieFactory.uc | 167 + GFxUIEditor/Classes/GFxReimportCommandlet.uc | 30 + .../Classes/GenericBrowserType_GFxMovie.uc | 41 + .../Classes/DebugCameraController.uc | 278 + GameFramework/Classes/DebugCameraHUD.uc | 140 + GameFramework/Classes/DebugCameraInput.uc | 44 + .../Classes/DynamicGameCrowdDestination.uc | 13 + .../Classes/DynamicSpriteComponent.uc | 34 + GameFramework/Classes/FrameworkGame.uc | 18 + .../Classes/GameAICmd_Hover_MoveToGoal.uc | 252 + .../GameAICmd_Hover_MoveToGoal_Mesh.uc | 636 + GameFramework/Classes/GameAICommand.uc | 261 + GameFramework/Classes/GameAIController.uc | 341 + GameFramework/Classes/GameCameraBase.uc | 41 + .../Classes/GameCameraBlockingVolume.uc | 24 + GameFramework/Classes/GameCheatManager.uc | 285 + GameFramework/Classes/GameCrowdAgent.uc | 1556 ++ .../Classes/GameCrowdAgentBehavior.uc | 215 + GameFramework/Classes/GameCrowdAgentSM.uc | 73 + .../Classes/GameCrowdAgentSkeletal.uc | 353 + .../Classes/GameCrowdBehaviorPoint.uc | 91 + .../GameCrowdBehavior_PlayAnimation.uc | 223 + .../Classes/GameCrowdBehavior_RunFromPanic.uc | 87 + .../Classes/GameCrowdBehavior_WaitForGroup.uc | 54 + .../Classes/GameCrowdBehavior_WaitInQueue.uc | 72 + GameFramework/Classes/GameCrowdDestination.uc | 762 + .../Classes/GameCrowdDestinationQueuePoint.uc | 214 + GameFramework/Classes/GameCrowdGroup.uc | 37 + GameFramework/Classes/GameCrowdInfoVolume.uc | 49 + .../GameCrowdInteractionDestination.uc | 20 + .../Classes/GameCrowdInteractionPoint.uc | 91 + .../Classes/GameCrowdPopulationManager.uc | 717 + .../Classes/GameCrowdReplicationActor.uc | 85 + .../Classes/GameCrowdSpawnInterface.uc | 9 + .../Classes/GameCrowdSpawnRelativeActor.uc | 17 + .../Classes/GameCrowdSpawnerInterface.uc | 11 + .../Classes/GameCrowd_ListOfAgents.uc | 18 + .../GameDestinationConnRenderingComponent.uc | 25 + GameFramework/Classes/GameExplosion.uc | 198 + GameFramework/Classes/GameExplosionActor.uc | 787 ++ GameFramework/Classes/GameExplosionContent.uc | 81 + GameFramework/Classes/GameFixedCamera.uc | 56 + .../Classes/GameKActorSpawnableEffect.uc | 77 + GameFramework/Classes/GamePawn.uc | 92 + GameFramework/Classes/GamePlayerCamera.uc | 371 + GameFramework/Classes/GamePlayerController.uc | 275 + GameFramework/Classes/GameSkelCtrl_Recoil.uc | 94 + GameFramework/Classes/GameSpecialMove.uc | 200 + GameFramework/Classes/GameStateObject.uc | 185 + GameFramework/Classes/GameStatsAggregator.uc | 614 + .../Classes/GameThirdPersonCamera.uc | 660 + .../Classes/GameThirdPersonCameraMode.uc | 476 + .../GameThirdPersonCameraMode_Default.uc | 74 + GameFramework/Classes/GameTypes.uc | 289 + GameFramework/Classes/GameWaveForms.uc | 48 + .../Classes/MobileDebugCameraController.uc | 184 + GameFramework/Classes/MobileDebugCameraHUD.uc | 151 + .../Classes/MobileDebugCameraInput.uc | 44 + GameFramework/Classes/MobileHUD.uc | 597 + GameFramework/Classes/MobileInputZone.uc | 427 + GameFramework/Classes/MobileMenuBar.uc | 200 + GameFramework/Classes/MobileMenuBarItem.uc | 29 + GameFramework/Classes/MobileMenuButton.uc | 96 + GameFramework/Classes/MobileMenuElement.uc | 45 + GameFramework/Classes/MobileMenuGame.uc | 63 + GameFramework/Classes/MobileMenuImage.uc | 100 + GameFramework/Classes/MobileMenuInventory.uc | 378 + GameFramework/Classes/MobileMenuLabel.uc | 72 + GameFramework/Classes/MobileMenuList.uc | 786 ++ GameFramework/Classes/MobileMenuListItem.uc | 28 + GameFramework/Classes/MobileMenuObject.uc | 286 + .../Classes/MobileMenuObjectProxy.uc | 43 + .../Classes/MobileMenuPlayerController.uc | 10 + GameFramework/Classes/MobileMenuScene.uc | 282 + GameFramework/Classes/MobilePlayerInput.uc | 1035 ++ .../Classes/MobileSecondaryViewportClient.uc | 54 + .../Classes/MobileTouchInputVolume.uc | 67 + .../Classes/NavMeshGoal_OutOfViewFrom.uc | 60 + ...asAgainstPolysWithinDistanceOfLocations.uc | 61 + .../Classes/PMESTG_LeaveADecalBase.uc | 21 + GameFramework/Classes/PlayerCollectorGame.uc | 51 + .../Classes/SecondaryViewportClient.uc | 32 + .../Classes/SeqAct_ControlGameMovie.uc | 47 + GameFramework/Classes/SeqAct_Deproject.uc | 44 + ...SeqAct_GameCrowdPopulationManagerToggle.uc | 161 + .../Classes/SeqAct_GameCrowdSpawner.uc | 22 + .../Classes/SeqAct_MobileAddInputZones.uc | 26 + .../Classes/SeqAct_MobileClearInputZones.uc | 20 + .../Classes/SeqAct_MobileRemoveInputZone.uc | 22 + .../Classes/SeqAct_MobileSaveLoadValue.uc | 40 + .../Classes/SeqAct_ModifyProperty.uc | 40 + .../Classes/SeqAct_PlayAgentAnimation.uc | 95 + .../Classes/SeqAct_ToggleMouseCursor.uc | 15 + .../SeqEvent_CrowdAgentReachedDestination.uc | 25 + GameFramework/Classes/SeqEvent_HudRender.uc | 56 + .../Classes/SeqEvent_HudRenderImage.uc | 58 + .../Classes/SeqEvent_HudRenderText.uc | 100 + GameFramework/Classes/SeqEvent_MobileBase.uc | 58 + .../Classes/SeqEvent_MobileButton.uc | 34 + GameFramework/Classes/SeqEvent_MobileInput.uc | 43 + GameFramework/Classes/SeqEvent_MobileLook.uc | 34 + .../Classes/SeqEvent_MobileMotion.uc | 52 + .../Classes/SeqEvent_MobileObjectPicker.uc | 46 + .../Classes/SeqEvent_MobileRawInput.uc | 71 + GameFramework/Classes/SeqEvent_MobileSwipe.uc | 56 + .../SeqEvent_MobileTouchInputVolume.uc | 17 + .../Classes/SeqEvent_MobileZoneBase.uc | 40 + GameFramework/Classes/TouchableElement3D.uc | 20 + GameFramework/Globals.uci | 23 + IpDrv/Classes/ClientBeaconAddressResolver.uc | 53 + IpDrv/Classes/HelloWeb.uc | 73 + IpDrv/Classes/ImageServer.uc | 48 + IpDrv/Classes/InternetLink.uc | 113 + IpDrv/Classes/MCPBase.uc | 49 + IpDrv/Classes/McpClashMobBase.uc | 295 + IpDrv/Classes/McpClashMobFileDownload.uc | 25 + IpDrv/Classes/McpClashMobManager.uc | 1279 ++ IpDrv/Classes/McpGroupsBase.uc | 298 + IpDrv/Classes/McpGroupsManager.uc | 943 ++ IpDrv/Classes/McpIdMappingBase.uc | 89 + IpDrv/Classes/McpIdMappingManager.uc | 301 + IpDrv/Classes/McpManagedValueManager.uc | 524 + IpDrv/Classes/McpManagedValueManagerBase.uc | 142 + IpDrv/Classes/McpMessageBase.uc | 223 + IpDrv/Classes/McpMessageManager.uc | 691 + IpDrv/Classes/McpServerTimeBase.uc | 51 + IpDrv/Classes/McpServerTimeManager.uc | 115 + IpDrv/Classes/McpServiceBase.uc | 62 + IpDrv/Classes/McpServiceConfig.uc | 28 + IpDrv/Classes/McpUserCloudFileDownload.uc | 946 ++ IpDrv/Classes/McpUserInventoryBase.uc | 327 + IpDrv/Classes/McpUserInventoryManager.uc | 1523 ++ IpDrv/Classes/McpUserManager.uc | 692 + IpDrv/Classes/McpUserManagerBase.uc | 160 + IpDrv/Classes/MeshBeacon.uc | 258 + IpDrv/Classes/MeshBeaconClient.uc | 373 + IpDrv/Classes/MeshBeaconHost.uc | 461 + IpDrv/Classes/OnlineAuthInterfaceImpl.uc | 798 ++ IpDrv/Classes/OnlineEventsInterfaceMcp.uc | 219 + IpDrv/Classes/OnlineGameInterfaceImpl.uc | 1340 ++ IpDrv/Classes/OnlineImageDownloaderWeb.uc | 290 + IpDrv/Classes/OnlineNewsInterfaceMcp.uc | 143 + IpDrv/Classes/OnlinePlaylistManager.uc | 761 + IpDrv/Classes/OnlinePlaylistProvider.uc | 21 + IpDrv/Classes/OnlineSubsystemCommonImpl.uc | 76 + IpDrv/Classes/OnlineTitleFileDownloadBase.uc | 194 + IpDrv/Classes/OnlineTitleFileDownloadMcp.uc | 134 + IpDrv/Classes/OnlineTitleFileDownloadWeb.uc | 337 + IpDrv/Classes/PartyBeacon.uc | 214 + IpDrv/Classes/PartyBeaconClient.uc | 247 + IpDrv/Classes/PartyBeaconHost.uc | 515 + IpDrv/Classes/TcpLink.uc | 108 + IpDrv/Classes/TitleFileDownloadCache.uc | 237 + IpDrv/Classes/UIDataStore_OnlinePlaylists.uc | 179 + IpDrv/Classes/WebApplication.uc | 30 + IpDrv/Classes/WebConnection.uc | 297 + IpDrv/Classes/WebRequest.uc | 170 + IpDrv/Classes/WebResponse.uc | 255 + IpDrv/Classes/WebServer.uc | 206 + KFGame/Classes/AICommand.uc | 564 + KFGame/Classes/AICommand_Attack_Grab.uc | 178 + KFGame/Classes/AICommand_Attack_Kick.uc | 145 + KFGame/Classes/AICommand_Attack_Melee.uc | 513 + KFGame/Classes/AICommand_Base_Boss.uc | 14 + KFGame/Classes/AICommand_Base_Combat.uc | 88 + KFGame/Classes/AICommand_Base_Crawler.uc | 543 + KFGame/Classes/AICommand_Base_Fleshpound.uc | 111 + KFGame/Classes/AICommand_Base_Hans.uc | 120 + KFGame/Classes/AICommand_Base_Zed.uc | 215 + KFGame/Classes/AICommand_BossTheatrics.uc | 116 + KFGame/Classes/AICommand_CrawlerEmerge.uc | 94 + .../Classes/AICommand_Crawler_LeapToWall.uc | 223 + .../Classes/AICommand_Crawler_MoveToGoal.uc | 221 + KFGame/Classes/AICommand_Debug.uc | 967 ++ KFGame/Classes/AICommand_DebugTurn.uc | 127 + KFGame/Classes/AICommand_Evade.uc | 233 + KFGame/Classes/AICommand_Flee.uc | 284 + KFGame/Classes/AICommand_Hans_GunStance.uc | 96 + KFGame/Classes/AICommand_HeadlessWander.uc | 270 + KFGame/Classes/AICommand_MoveToEnemy.uc | 473 + KFGame/Classes/AICommand_MoveToGoal.uc | 1791 +++ KFGame/Classes/AICommand_PanicWander.uc | 74 + KFGame/Classes/AICommand_Pause.uc | 124 + KFGame/Classes/AICommand_PushedBySM.uc | 109 + KFGame/Classes/AICommand_SM_Attack.uc | 213 + .../AICommand_ScriptedPawn_TraverseSpline.uc | 138 + KFGame/Classes/AICommand_SpecialMove.uc | 370 + KFGame/Classes/AICommand_StepAside.uc | 349 + KFGame/Classes/AICommand_Stumble.uc | 83 + KFGame/Classes/AICommand_SummonZeds.uc | 74 + KFGame/Classes/AICommand_TauntEnemy.uc | 130 + KFGame/Classes/AICommand_ThrowGrenade.uc | 124 + KFGame/Classes/AICommand_Wander.uc | 230 + KFGame/Classes/AIDebugGoal.uc | 29 + KFGame/Classes/ActorFactoryKFPathnode.uc | 21 + .../ActorFactoryKFScriptedPlayerPathGoal.uc | 21 + KFGame/Classes/ActorFactoryKFWallPathNode.uc | 21 + KFGame/Classes/EphemeralMatchStats.uc | 1391 ++ KFGame/Classes/FloorToWallReachSpec.uc | 36 + KFGame/Classes/Goal_AwayFromPosition.uc | 56 + KFGame/Classes/Goal_Random.uc | 63 + KFGame/Classes/Goal_WallToEnemy.uc | 52 + KFGame/Classes/GroundFireEmitterPool.uc | 16 + KFGame/Classes/KFAIController.uc | 7770 ++++++++++ KFGame/Classes/KFAIController_Hans.uc | 2372 ++++ KFGame/Classes/KFAIController_Monster.uc | 519 + KFGame/Classes/KFAIController_ScriptedPawn.uc | 18 + KFGame/Classes/KFAIController_ZedBoss.uc | 133 + KFGame/Classes/KFAIController_ZedClot.uc | 94 + KFGame/Classes/KFAIController_ZedCrawler.uc | 617 + .../Classes/KFAIController_ZedFleshpound.uc | 385 + KFGame/Classes/KFAIDirector.uc | 424 + KFGame/Classes/KFAIPluginRage_Fleshpound.uc | 201 + KFGame/Classes/KFAISpawnManager.uc | 1384 ++ KFGame/Classes/KFAISpawnManager_Long.uc | 119 + KFGame/Classes/KFAISpawnManager_Normal.uc | 95 + KFGame/Classes/KFAISpawnManager_Short.uc | 77 + KFGame/Classes/KFAISpawnSquad.uc | 36 + KFGame/Classes/KFAISteering.uc | 119 + KFGame/Classes/KFAISubsystem.uc | 31 + KFGame/Classes/KFAIWaveInfo.uc | 74 + KFGame/Classes/KFAccessControl.uc | 162 + KFGame/Classes/KFActor_DoshPile.uc | 175 + KFGame/Classes/KFAfflictionAdvanced.uc | 60 + KFGame/Classes/KFAfflictionBase.uc | 166 + KFGame/Classes/KFAfflictionManager.uc | 744 + KFGame/Classes/KFAffliction_Bleed.uc | 244 + KFGame/Classes/KFAffliction_EMP.uc | 129 + KFGame/Classes/KFAffliction_EMPDisrupt.uc | 75 + KFGame/Classes/KFAffliction_EvilDAR_EMP.uc | 14 + KFGame/Classes/KFAffliction_Fire.uc | 220 + KFGame/Classes/KFAffliction_Freeze.uc | 14 + KFGame/Classes/KFAffliction_HeavyRecovery.uc | 31 + KFGame/Classes/KFAffliction_Knockdown.uc | 54 + KFGame/Classes/KFAffliction_MediumRecovery.uc | 31 + KFGame/Classes/KFAffliction_Microwave.uc | 290 + KFGame/Classes/KFAffliction_Poison.uc | 55 + KFGame/Classes/KFAffliction_Snare.uc | 53 + KFGame/Classes/KFAffliction_Stumble.uc | 37 + KFGame/Classes/KFAffliction_Stun.uc | 14 + KFGame/Classes/KFAiBaseRangedBehavior.uc | 354 + KFGame/Classes/KFAiBehaviorTypes.uc | 226 + .../KFAiDirectProjectileFireBehavior.uc | 108 + KFGame/Classes/KFAiLeapBehavior.uc | 134 + .../KFAnimNotify_AkEvent_IfActiveMGTarget.uc | 30 + .../KFAnimNotify_AkEvent_NotEmpty_1P.uc | 29 + KFGame/Classes/KFAnimNotify_CameraAnim.uc | 43 + KFGame/Classes/KFAnimNotify_Decal.uc | 112 + KFGame/Classes/KFAnimNotify_HideBone.uc | 31 + KFGame/Classes/KFAnimNotify_Interrupt.uc | 18 + KFGame/Classes/KFAnimNotify_MeleeImpact.uc | 70 + KFGame/Classes/KFAnimNotify_MeleeImpact_1P.uc | 41 + KFGame/Classes/KFAnimNotify_MeleeTrails.uc | 22 + KFGame/Classes/KFAnimNotify_PlayDialog.uc | 26 + KFGame/Classes/KFAnimNotify_ReloadAmmo.uc | 18 + KFGame/Classes/KFAnimNotify_SpawnKActor.uc | 129 + .../Classes/KFAnimNotify_ZedVoiceAkEvent.uc | 34 + KFGame/Classes/KFAnimSeq_ByWeaponClass.uc | 75 + KFGame/Classes/KFAnimSeq_Directional.uc | 71 + KFGame/Classes/KFAnimSeq_TurnInPlace.uc | 59 + KFGame/Classes/KFAnimSeq_Tween.uc | 63 + KFGame/Classes/KFAnim_AimOffset.uc | 67 + KFGame/Classes/KFAnim_BlendByTargetingMode.uc | 65 + .../Classes/KFAnim_BlendFacialExpression.uc | 41 + KFGame/Classes/KFAnim_BlendList.uc | 30 + KFGame/Classes/KFAnim_Health.uc | 49 + KFGame/Classes/KFAnim_Movement.uc | 70 + KFGame/Classes/KFAnim_PhysFalling.uc | 61 + KFGame/Classes/KFAnim_Random.uc | 25 + KFGame/Classes/KFAnim_RandomScripted.uc | 43 + KFGame/Classes/KFAnim_ScaleRateBySpeed.uc | 41 + KFGame/Classes/KFAnim_Slot.uc | 30 + KFGame/Classes/KFAnim_TurnInPlace.uc | 93 + KFGame/Classes/KFAnim_TurnInPlace_Rotator.uc | 36 + KFGame/Classes/KFAutoPurchaseHelper.uc | 1432 ++ KFGame/Classes/KFBossCamera.uc | 149 + .../Classes/KFBulletSkeletalMeshComponent.uc | 56 + KFGame/Classes/KFCameraLensEmit_BloodBase.uc | 19 + KFGame/Classes/KFCameraLensEmit_BloodGorge.uc | 18 + KFGame/Classes/KFCameraLensEmit_EMP.uc | 18 + KFGame/Classes/KFCameraLensEmit_Fire.uc | 26 + .../KFCameraLensEmit_PowerUp_HellishRage.uc | 17 + KFGame/Classes/KFCameraLensEmit_Puke.uc | 17 + KFGame/Classes/KFCameraLensEmit_Puke_Light.uc | 18 + KFGame/Classes/KFCameraShake.uc | 12 + KFGame/Classes/KFCarryableObject.uc | 28 + KFGame/Classes/KFCharacterAttachment.uc | 68 + KFGame/Classes/KFCharacterInfoBase.uc | 131 + KFGame/Classes/KFCharacterInfo_Human.uc | 1168 ++ KFGame/Classes/KFCharacterInfo_Monster.uc | 289 + .../Classes/KFCharacterInfo_ScriptedPawn.uc | 162 + KFGame/Classes/KFCheatManager.uc | 7557 ++++++++++ KFGame/Classes/KFCommon_LocalizedStrings.uc | 218 + KFGame/Classes/KFCostTimerNode.uc | 56 + KFGame/Classes/KFCustomizationCamera.uc | 187 + KFGame/Classes/KFCustomizationPoint.uc | 37 + KFGame/Classes/KFDT_Ballistic.uc | 58 + KFGame/Classes/KFDT_Ballistic_Shell.uc | 43 + KFGame/Classes/KFDT_Bleeding.uc | 23 + KFGame/Classes/KFDT_Bludgeon.uc | 30 + .../Classes/KFDT_DemoNuke_Toxic_Lingering.uc | 35 + KFGame/Classes/KFDT_DrainHealth.uc | 18 + KFGame/Classes/KFDT_EMP.uc | 38 + .../Classes/KFDT_Environment_KActorImpulse.uc | 18 + KFGame/Classes/KFDT_Explosive.uc | 124 + .../Classes/KFDT_ExplosiveSubmunition_HX25.uc | 31 + KFGame/Classes/KFDT_Explosive_DoorTrap.uc | 30 + KFGame/Classes/KFDT_Explosive_Sacrifice.uc | 32 + KFGame/Classes/KFDT_Explosive_Shrapnel.uc | 28 + KFGame/Classes/KFDT_Falling.uc | 17 + KFGame/Classes/KFDT_Fire.uc | 50 + KFGame/Classes/KFDT_Fire_Ground.uc | 32 + KFGame/Classes/KFDT_Fire_HellishRage.uc | 24 + KFGame/Classes/KFDT_Fire_Mac10DoT.uc | 27 + KFGame/Classes/KFDT_Fire_MicrowaveRifleDoT.uc | 27 + KFGame/Classes/KFDT_Fire_Napalm.uc | 22 + KFGame/Classes/KFDT_Freeze.uc | 141 + KFGame/Classes/KFDT_Freeze_Ground.uc | 18 + KFGame/Classes/KFDT_Healing.uc | 33 + KFGame/Classes/KFDT_HellishRageCost.uc | 22 + KFGame/Classes/KFDT_HuskCannonDot.uc | 44 + KFGame/Classes/KFDT_Knockdown.uc | 21 + KFGame/Classes/KFDT_Microwave.uc | 16 + KFGame/Classes/KFDT_NPCBump.uc | 19 + KFGame/Classes/KFDT_NPCBump_Large.uc | 20 + KFGame/Classes/KFDT_NoGoVolume.uc | 19 + KFGame/Classes/KFDT_Piercing.uc | 40 + KFGame/Classes/KFDT_SWATBatteringRam.uc | 20 + KFGame/Classes/KFDT_Slashing.uc | 158 + KFGame/Classes/KFDT_Sonic.uc | 35 + KFGame/Classes/KFDT_Toxic.uc | 49 + KFGame/Classes/KFDT_Toxic_AcidicRounds.uc | 30 + KFGame/Classes/KFDT_Toxic_DemoNuke.uc | 44 + KFGame/Classes/KFDT_Toxic_HRGHealthrower.uc | 31 + KFGame/Classes/KFDT_Toxic_MedicGrenade.uc | 20 + .../KFDT_Toxic_MedicGrenadeLauncher.uc | 20 + KFGame/Classes/KFDT_Toxic_ZedativeCloud.uc | 24 + KFGame/Classes/KFDamageType.uc | 446 + .../Classes/KFDataStore_OnlineGameSearch.uc | 34 + KFGame/Classes/KFDebugCameraController.uc | 447 + KFGame/Classes/KFDebugCameraHUD.uc | 156 + KFGame/Classes/KFDebugCameraInput.uc | 48 + KFGame/Classes/KFDebugFlare.uc | 45 + KFGame/Classes/KFDebugLines.uc | 303 + KFGame/Classes/KFDemoRecSpectator.uc | 328 + KFGame/Classes/KFDestructibleActor.uc | 1170 ++ KFGame/Classes/KFDialogEnvironmentVolume.uc | 72 + KFGame/Classes/KFDialogManager.uc | 2998 ++++ .../Classes/KFDominantDirectionalLightning.uc | 102 + KFGame/Classes/KFDoorActor.uc | 2039 +++ KFGame/Classes/KFDoorMarker.uc | 199 + KFGame/Classes/KFDoorReachSpec.uc | 20 + KFGame/Classes/KFDoorTrigger.uc | 164 + KFGame/Classes/KFDroppedPickup.uc | 655 + KFGame/Classes/KFDroppedPickup_Cash.uc | 130 + KFGame/Classes/KFDummyReplicationInfo.uc | 25 + .../KFDynamicFogAndDamageVolumeInfo.uc | 370 + KFGame/Classes/KFEmit_CameraEffect.uc | 18 + KFGame/Classes/KFEmit_Path.uc | 283 + KFGame/Classes/KFEmit_ScriptedPath.uc | 6 + KFGame/Classes/KFEmit_TraderPath.uc | 55 + KFGame/Classes/KFEmitter.uc | 58 + KFGame/Classes/KFEmoteCamera.uc | 17 + KFGame/Classes/KFEmoteCameraMode.uc | 25 + KFGame/Classes/KFEmoteList.uc | 119 + KFGame/Classes/KFExplosionActor.uc | 447 + KFGame/Classes/KFExplosionActorLingering.uc | 206 + KFGame/Classes/KFExplosionActorPlaceable.uc | 34 + KFGame/Classes/KFExplosionActorReplicated.uc | 136 + KFGame/Classes/KFExplosionLight.uc | 51 + KFGame/Classes/KFExplosionLightComponent.uc | 48 + KFGame/Classes/KFExplosion_AirborneAgent.uc | 316 + KFGame/Classes/KFExplosion_Nuke.uc | 108 + KFGame/Classes/KFExplosion_ReplicatedNuke.uc | 47 + KFGame/Classes/KFExplosion_ZedativeCloud.uc | 142 + .../Classes/KFExportSteamItemsCommandlet.uc | 14 + KFGame/Classes/KFFirstPersonCamera.uc | 55 + .../KFFixupCosmeticReferencesCommandlet.uc | 11 + .../KFFixupCosmeticUITexturesCommandlet.uc | 11 + KFGame/Classes/KFFlashlightAttachment.uc | 498 + KFGame/Classes/KFForcedReachSpec.uc | 46 + KFGame/Classes/KFFracturedMeshActor.uc | 351 + KFGame/Classes/KFFracturedMeshGlass.uc | 164 + ...pecialEventObjectivesContainer_Fall2020.uc | 27 + ...cialEventObjectivesContainer_Spring2020.uc | 27 + .../KFGFxChristmasObjectivesContainer.uc | 26 + .../KFGFxCollapsedObjectivesContainer.uc | 123 + ...FGFxControlsContainer_ControllerPresets.uc | 199 + .../Classes/KFGFxControlsContainer_Input.uc | 155 + .../KFGFxControlsContainer_Keybinding.uc | 307 + .../Classes/KFGFxDailyObjectivesContainer.uc | 424 + .../KFGFxEndlessDARObjectivesContainer.uc | 100 + .../KFGFxExpandedObjectivesContainer.uc | 72 + .../KFGFxFall2019ObjectivesContainer.uc | 27 + .../Classes/KFGFxFallObjectivesContainer.uc | 28 + .../KFGFxGearContainer_PerksSelection.uc | 80 + KFGame/Classes/KFGFxHUD_ChatBoxWidget.uc | 84 + KFGame/Classes/KFGFxHUD_ObjectiveConatiner.uc | 198 + KFGame/Classes/KFGFxHUD_PlayerBackpack.uc | 252 + KFGame/Classes/KFGFxHUD_PlayerMoveList.uc | 303 + KFGame/Classes/KFGFxHUD_PlayerStatus.uc | 219 + KFGame/Classes/KFGFxHUD_PostRoundMenu.uc | 147 + .../KFGFxHUD_ScoreboardMapInfoContainer.uc | 116 + .../KFGFxHUD_ScoreboardVersusWidget.uc | 115 + KFGame/Classes/KFGFxHUD_ScoreboardWidget.uc | 244 + KFGame/Classes/KFGFxHUD_SpectatorInfo.uc | 140 + .../Classes/KFGFxHUD_SpectatorInfo_Versus.uc | 43 + KFGame/Classes/KFGFxHUD_TraderCompass.uc | 194 + KFGame/Classes/KFGFxHUD_WaveInfo.uc | 164 + KFGame/Classes/KFGFxHUD_WeaponSelectWidget.uc | 256 + KFGame/Classes/KFGFxHudWrapper.uc | 256 + KFGame/Classes/KFGFxHud_PlayerRosterWidget.uc | 119 + KFGame/Classes/KFGFxMenu_DoshVault.uc | 311 + KFGame/Classes/KFGFxMenu_Exit.uc | 166 + KFGame/Classes/KFGFxMenu_Gear.uc | 733 + KFGame/Classes/KFGFxMenu_IIS.uc | 424 + KFGame/Classes/KFGFxMenu_Inventory.uc | 1292 ++ KFGame/Classes/KFGFxMenu_Perks.uc | 453 + KFGame/Classes/KFGFxMenu_PostGameReport.uc | 530 + KFGame/Classes/KFGFxMenu_ServerBrowser.uc | 449 + KFGame/Classes/KFGFxMenu_Store.uc | 292 + .../KFGFxMissionObjectivesContainer.uc | 146 + KFGame/Classes/KFGFxMoviePlayer_HUD.uc | 1378 ++ .../KFGFxMoviePlayer_Manager_Versus.uc | 52 + .../Classes/KFGFxMoviePlayer_NaughtyList.uc | 92 + KFGame/Classes/KFGFxMoviePlayer_PlayerInfo.uc | 205 + .../Classes/KFGFxMoviePlayer_PostRoundMenu.uc | 71 + KFGame/Classes/KFGFxMoviePlayer_ScoreBoard.uc | 138 + KFGame/Classes/KFGFxMoviePlayer_ScreenSize.uc | 188 + KFGame/Classes/KFGFxNaughtyList.uc | 11 + KFGame/Classes/KFGFxObject_Container.uc | 53 + KFGame/Classes/KFGFxObject_Popup.uc | 60 + KFGame/Classes/KFGFxOptionsMenu_Audio.uc | 375 + KFGame/Classes/KFGFxOptionsMenu_Controls.uc | 322 + .../Classes/KFGFxOptionsMenu_GameSettings.uc | 611 + KFGame/Classes/KFGFxOptionsMenu_Graphics.uc | 3529 +++++ .../Classes/KFGFxOptionsMenu_Graphics_DX10.uc | 27 + KFGame/Classes/KFGFxOptionsMenu_Selection.uc | 102 + KFGame/Classes/KFGFxPerksContainer.uc | 13 + KFGame/Classes/KFGFxPerksContainer_Details.uc | 111 + KFGame/Classes/KFGFxPerksContainer_Header.uc | 59 + .../Classes/KFGFxPerksContainer_Prestige.uc | 107 + .../Classes/KFGFxPerksContainer_Selection.uc | 159 + KFGame/Classes/KFGFxPerksContainer_Skills.uc | 127 + .../KFGFxPerksContainer_SkillsSummary.uc | 100 + KFGame/Classes/KFGFxPopup_Confirmation.uc | 68 + KFGame/Classes/KFGFxPopup_ConnectionError.uc | 16 + KFGame/Classes/KFGFxPopup_FriendsConfirm.uc | 58 + KFGame/Classes/KFGFxPopup_FriendsList.uc | 257 + KFGame/Classes/KFGFxPopup_InputPrompt.uc | 56 + KFGame/Classes/KFGFxPopup_OptionMic.uc | 156 + .../Classes/KFGFxPostGameContainer_MapVote.uc | 132 + .../KFGFxPostGameContainer_PlayerStats.uc | 174 + .../KFGFxPostGameContainer_PlayerXP.uc | 93 + .../KFGFxPostGameContainer_TeamAwards.uc | 135 + .../Classes/KFGFxPostRoundContainer_Team.uc | 100 + KFGame/Classes/KFGFxScreenSizeContainer.uc | 79 + KFGame/Classes/KFGFxServerBrowser_Filters.uc | 483 + .../KFGFxServerBrowser_ServerDetails.uc | 148 + .../Classes/KFGFxServerBrowser_ServerList.uc | 1057 ++ ...cialEventObjectivesContainer_Summer2020.uc | 29 + ...pecialEventObjectivesContainer_Xmas2019.uc | 27 + .../KFGFxSpecialeventObjectivesContainer.uc | 213 + .../KFGFxSpring2019ObjectivesContainer.uc | 27 + .../KFGFxStartContainer_InGameOverview.uc | 422 + .../KFGFxStartContainer_NewsImageHolder.uc | 46 + ...GFxStartContainer_ServerBrowserOverview.uc | 30 + .../KFGFxStartGameContainer_FindGame.uc | 202 + .../KFGFxStartGameContainer_Options.uc | 581 + KFGame/Classes/KFGFxStoreContainer_Cart.uc | 37 + KFGame/Classes/KFGFxStoreContainer_Details.uc | 35 + KFGame/Classes/KFGFxStoreContainer_Main.uc | 458 + .../KFGFxSummer2019ObjectivesContainer.uc | 27 + .../KFGFxSummerSideShowObjectivesContainer.uc | 21 + .../KFGFxTraderContainer_ErrorMessage.uc | 19 + KFGame/Classes/KFGFxTraderContainer_Filter.uc | 137 + .../Classes/KFGFxTraderContainer_GameInfo.uc | 77 + .../KFGFxTraderContainer_ItemDetails.uc | 378 + .../KFGFxTraderContainer_PlayerInfo.uc | 117 + .../KFGFxTraderContainer_PlayerInventory.uc | 282 + KFGame/Classes/KFGFxTraderContainer_Store.uc | 335 + .../Classes/KFGFxWeeklyObjectivesContainer.uc | 182 + ...FGFxWidget_BackendStatusIndicatorWidget.uc | 65 + KFGame/Classes/KFGFxWidget_BaseParty.uc | 496 + KFGame/Classes/KFGFxWidget_BossHealthBar.uc | 243 + KFGame/Classes/KFGFxWidget_ButtonPrompt.uc | 41 + KFGame/Classes/KFGFxWidget_KickVote.uc | 176 + .../KFGFxWidget_LevelUpNotification.uc | 86 + KFGame/Classes/KFGFxWidget_MenuBar.uc | 346 + KFGame/Classes/KFGFxWidget_MenuBarVersus.uc | 6 + .../Classes/KFGFxWidget_MusicNotification.uc | 33 + .../KFGFxWidget_NonCriticalGameMessage.uc | 16 + KFGame/Classes/KFGFxWidget_PartyInGame.uc | 414 + .../Classes/KFGFxWidget_PartyInGame_Versus.uc | 180 + KFGame/Classes/KFGFxWidget_PartyMainMenu.uc | 547 + KFGame/Classes/KFGFxWidget_RhythmCounter.uc | 24 + KFGame/Classes/KFGFxWidget_VoiceComms.uc | 233 + KFGame/Classes/KFGFxWorld_C4Screen.uc | 63 + KFGame/Classes/KFGFxWorld_MedicOptics.uc | 99 + KFGame/Classes/KFGameConductor.uc | 888 ++ KFGame/Classes/KFGameDifficultyInfo.uc | 555 + KFGame/Classes/KFGameEngine.uc | 662 + KFGame/Classes/KFGameExplosion.uc | 52 + KFGame/Classes/KFGameInfo.uc | 3830 +++++ KFGame/Classes/KFGameInfoSummary.uc | 10 + KFGame/Classes/KFGameInfo_Entry.uc | 528 + KFGame/Classes/KFGameReplicationInfo.uc | 2129 +++ KFGame/Classes/KFGameViewportClient.uc | 225 + KFGame/Classes/KFGameWaveforms.uc | 23 + KFGame/Classes/KFGamepadLayoutManager.uc | 135 + KFGame/Classes/KFGameplayEventsWriter.uc | 703 + KFGame/Classes/KFGameplayPoolManager.uc | 103 + KFGame/Classes/KFGfxMenu_StartGame.uc | 1925 +++ KFGame/Classes/KFGfxMenu_Trader.uc | 810 ++ KFGame/Classes/KFGfxMoviePlayer_Manager.uc | 2323 +++ KFGame/Classes/KFGfxMoviePlayer_World.uc | 13 + KFGame/Classes/KFGfxObject_Menu.uc | 507 + KFGame/Classes/KFGfxObject_TraderItems.uc | 162 + KFGame/Classes/KFGfxPopup_Gamma.uc | 114 + KFGame/Classes/KFGfxWorld_HealerScreen.uc | 45 + KFGame/Classes/KFGfxWorld_WelderScreen.uc | 56 + KFGame/Classes/KFGibSkeletalMeshComponent.uc | 33 + KFGame/Classes/KFGibStaticMeshComponent.uc | 27 + KFGame/Classes/KFGiblet.uc | 140 + KFGame/Classes/KFGibletInfo.uc | 34 + KFGame/Classes/KFGoreChunkAttachmentInfo.uc | 33 + KFGame/Classes/KFGoreChunkAttachment_Skull.uc | 27 + KFGame/Classes/KFGoreJointInfo.uc | 166 + KFGame/Classes/KFGoreManager.uc | 1179 ++ KFGame/Classes/KFHTTPImageDownloader.uc | 90 + KFGame/Classes/KFHUDBase.uc | 1383 ++ KFGame/Classes/KFHeadShotEffectList.uc | 64 + KFGame/Classes/KFImpactEffectInfo.uc | 64 + KFGame/Classes/KFImpactEffectManager.uc | 359 + KFGame/Classes/KFImpactFXEmitterPool.uc | 16 + KFGame/Classes/KFInterface_DamageCauser.uc | 14 + KFGame/Classes/KFInterface_MapObjective.uc | 59 + KFGame/Classes/KFInterface_MinigameActor.uc | 16 + KFGame/Classes/KFInterface_MinigameTarget.uc | 15 + KFGame/Classes/KFInterface_MonsterBoss.uc | 51 + KFGame/Classes/KFInterface_TriggerOwner.uc | 13 + KFGame/Classes/KFInterface_Usable.uc | 11 + .../KFInterface_UsableTriggerTarget.uc | 11 + KFGame/Classes/KFInventoryCatalog.uc | 240 + KFGame/Classes/KFInventoryManager.uc | 2620 ++++ KFGame/Classes/KFKActor.uc | 70 + KFGame/Classes/KFKActorSpawnable.uc | 60 + KFGame/Classes/KFKActorSpawnable_Door.uc | 50 + KFGame/Classes/KFKAsset.uc | 19 + KFGame/Classes/KFLEDEffectsManager.uc | 656 + KFGame/Classes/KFLaserSightAttachment.uc | 412 + KFGame/Classes/KFLeapReachSpec.uc | 27 + KFGame/Classes/KFLightPool.uc | 145 + KFGame/Classes/KFLocalMessage.uc | 354 + KFGame/Classes/KFLocalMessage_Game.uc | 311 + KFGame/Classes/KFLocalMessage_Interaction.uc | 261 + KFGame/Classes/KFLocalMessage_PlayerKills.uc | 67 + KFGame/Classes/KFLocalMessage_Priority.uc | 410 + .../KFLocalMessage_ServerNotification.uc | 29 + KFGame/Classes/KFLocalMessage_VoiceComms.uc | 66 + KFGame/Classes/KFMapInfo.uc | 454 + KFGame/Classes/KFMapMutator.uc | 14 + KFGame/Classes/KFMapObjective_ActorBase.uc | 383 + KFGame/Classes/KFMapObjective_CommonVars.uci | 45 + KFGame/Classes/KFMapObjective_VolumeBase.uc | 512 + KFGame/Classes/KFMapSummary.uc | 30 + KFGame/Classes/KFMapTravelData.uc | 107 + KFGame/Classes/KFMedicWeaponComponent.uc | 424 + KFGame/Classes/KFMeleeHelperAI.uc | 606 + KFGame/Classes/KFMeleeHelperBase.uc | 452 + KFGame/Classes/KFMeleeHelperWeapon.uc | 824 ++ KFGame/Classes/KFMission_LocalizedStrings.uc | 64 + KFGame/Classes/KFMonsterDifficultyInfo.uc | 275 + KFGame/Classes/KFMusicStingerHelper.uc | 342 + KFGame/Classes/KFMusicTrackInfo.uc | 37 + KFGame/Classes/KFMutator.uc | 108 + KFGame/Classes/KFMutatorSummary.uc | 44 + KFGame/Classes/KFMuzzleFlash.uc | 288 + KFGame/Classes/KFNaughtyListActor.uc | 66 + KFGame/Classes/KFOnlineGameSearch.uc | 54 + KFGame/Classes/KFOnlineGameSettings.uc | 74 + KFGame/Classes/KFOnlineGameSettingsVersus.uc | 20 + KFGame/Classes/KFOnlineStatsRead.uc | 235 + KFGame/Classes/KFOnlineStatsReadDingo.uc | 121 + KFGame/Classes/KFOnlineStatsWrite.uc | 2224 +++ KFGame/Classes/KFOnlineStatsWriteDingo.uc | 70 + KFGame/Classes/KFOutbreakEvent.uc | 769 + KFGame/Classes/KFParticleSystemComponent.uc | 44 + KFGame/Classes/KFPathnode.uc | 190 + KFGame/Classes/KFPawn.uc | 5626 ++++++++ KFGame/Classes/KFPawnAnimInfo.uc | 867 ++ KFGame/Classes/KFPawnBlockingVolume.uc | 34 + KFGame/Classes/KFPawnSoundGroup.uc | 392 + KFGame/Classes/KFPawnVoiceGroup.uc | 62 + KFGame/Classes/KFPawnVoiceGroupEventData.uc | 78 + KFGame/Classes/KFPawn_Customization.uc | 349 + KFGame/Classes/KFPawn_Human.uc | 2083 +++ KFGame/Classes/KFPawn_Monster.uc | 4855 +++++++ KFGame/Classes/KFPawn_MonsterBoss.uc | 446 + KFGame/Classes/KFPawn_Scripted.uc | 1143 ++ KFGame/Classes/KFPawn_ZedHansBase.uc | 717 + KFGame/Classes/KFPerk.uc | 1488 ++ KFGame/Classes/KFPerkFXEmitterPool.uc | 16 + KFGame/Classes/KFPerk_Berserker.uc | 953 ++ KFGame/Classes/KFPerk_Commando.uc | 737 + KFGame/Classes/KFPerk_Demolitionist.uc | 1169 ++ KFGame/Classes/KFPerk_FieldMedic.uc | 761 + KFGame/Classes/KFPerk_Firebug.uc | 710 + KFGame/Classes/KFPerk_Gunslinger.uc | 891 ++ KFGame/Classes/KFPerk_Monster.uc | 41 + KFGame/Classes/KFPerk_Sharpshooter.uc | 720 + KFGame/Classes/KFPerk_Support.uc | 868 ++ KFGame/Classes/KFPerk_Survivalist.uc | 853 ++ KFGame/Classes/KFPerk_Swat.uc | 678 + KFGame/Classes/KFPersistentBloodActor.uc | 151 + KFGame/Classes/KFPhysicalMaterialProperty.uc | 14 + KFGame/Classes/KFPickupFactory.uc | 221 + KFGame/Classes/KFPickupFactory_Item.uc | 324 + KFGame/Classes/KFPlayerCamera.uc | 297 + KFGame/Classes/KFPlayerController.uc | 11690 ++++++++++++++++ .../KFPlayerController_WeeklySurvival.uc | 84 + KFGame/Classes/KFPlayerInput.uc | 2960 ++++ KFGame/Classes/KFPlayerReplicationInfo.uc | 1458 ++ .../Classes/KFPlayerReplicationInfoVersus.uc | 263 + KFGame/Classes/KFPlayerStart.uc | 36 + KFGame/Classes/KFPowerUp.uc | 183 + KFGame/Classes/KFPowerUp_HellishRage.uc | 104 + KFGame/Classes/KFProfileSettings.uc | 367 + KFGame/Classes/KFProj_BallisticExplosive.uc | 478 + KFGame/Classes/KFProj_Bullet.uc | 191 + .../KFProj_ExplosiveSubmunition_HX25.uc | 166 + KFGame/Classes/KFProj_Grenade.uc | 357 + KFGame/Classes/KFProj_HealingDart.uc | 115 + KFGame/Classes/KFProj_PinningBullet.uc | 87 + KFGame/Classes/KFProj_RicochetBullet.uc | 50 + KFGame/Classes/KFProj_RicochetStickBullet.uc | 497 + KFGame/Classes/KFProjectile.uc | 1481 ++ KFGame/Classes/KFProjectileStickHelper.uc | 505 + .../KFProjectileStickHelper_HRGScorcher.uc | 124 + .../Classes/KFPruneSkeletalMeshCommandlet.uc | 33 + KFGame/Classes/KFReachSpec.uc | 31 + KFGame/Classes/KFRealtimeTimerHelper.uc | 54 + KFGame/Classes/KFRepairableActor.uc | 421 + KFGame/Classes/KFRepairableActorTrigger.uc | 91 + KFGame/Classes/KFReplicatedShowPathActor.uc | 175 + KFGame/Classes/KFReverbVolume.uc | 168 + KFGame/Classes/KFSFXVolume.uc | 87 + KFGame/Classes/KFSM_BloatKingGorgeVictim.uc | 14 + KFGame/Classes/KFSM_Block.uc | 269 + KFGame/Classes/KFSM_DeathAnim.uc | 277 + KFGame/Classes/KFSM_DisabledGrappleVictim.uc | 25 + KFGame/Classes/KFSM_DoorMeleeAttack.uc | 59 + KFGame/Classes/KFSM_Emerge.uc | 279 + KFGame/Classes/KFSM_Evade.uc | 58 + KFGame/Classes/KFSM_EvilDAR_EMPGrapple.uc | 25 + KFGame/Classes/KFSM_Frozen.uc | 289 + KFGame/Classes/KFSM_GrappleCombined.uc | 488 + KFGame/Classes/KFSM_GrappleVictim.uc | 122 + KFGame/Classes/KFSM_HansGrappleVictim.uc | 49 + .../Classes/KFSM_InteractionPawnFollower.uc | 81 + KFGame/Classes/KFSM_InteractionPawnLeader.uc | 491 + KFGame/Classes/KFSM_MeleeAttack.uc | 221 + KFGame/Classes/KFSM_Patriarch_Grapple.uc | 39 + KFGame/Classes/KFSM_PlaySingleAnim.uc | 91 + .../KFSM_PlaySingleAnim_ScriptedPawn.uc | 28 + KFGame/Classes/KFSM_PlayerMeleeBase.uc | 246 + KFGame/Classes/KFSM_Player_Emote.uc | 300 + KFGame/Classes/KFSM_RagdollKnockdown.uc | 377 + KFGame/Classes/KFSM_RangedAttack.uc | 92 + KFGame/Classes/KFSM_RecoverFromRagdoll.uc | 295 + KFGame/Classes/KFSM_StartSprintAnim.uc | 17 + KFGame/Classes/KFSM_Stumble.uc | 210 + KFGame/Classes/KFSM_Stunned.uc | 155 + KFGame/Classes/KFSM_TentacleGrappleBase.uc | 370 + KFGame/Classes/KFSM_Zed_Boss_Theatrics.uc | 356 + KFGame/Classes/KFSM_Zed_Taunt.uc | 113 + KFGame/Classes/KFSM_Zed_WalkingTaunt.uc | 40 + KFGame/Classes/KFSceneCaptureDebugCam.uc | 405 + KFGame/Classes/KFScout.uc | 104 + KFGame/Classes/KFScriptedPawnSpawner.uc | 197 + KFGame/Classes/KFScriptedPlayerPathGoal.uc | 27 + KFGame/Classes/KFSeasonalEventStats.uc | 72 + KFGame/Classes/KFSeqAct_DisableDoor.uc | 37 + KFGame/Classes/KFSeqAct_FlickerLightning.uc | 43 + .../Classes/KFSeqAct_MovePawnsNotInVolume.uc | 66 + .../Classes/KFSeqAct_RestartScriptedPawn.uc | 126 + .../Classes/KFSeqAct_SetMonsterProperties.uc | 84 + .../Classes/KFSeqAct_SetPathnodeExtraCost.uc | 34 + .../Classes/KFSeqAct_SetPawnIconVisibility.uc | 46 + .../Classes/KFSeqAct_SetTeleporterURLNum.uc | 18 + KFGame/Classes/KFSeqAct_SetTrader.uc | 68 + KFGame/Classes/KFSeqAct_SetTraderEnabled.uc | 63 + .../Classes/KFSeqAct_SetTraderVolumeIgnore.uc | 89 + KFGame/Classes/KFSeqAct_ShowPath.uc | 111 + KFGame/Classes/KFSeqAct_StartScriptedPawn.uc | 179 + KFGame/Classes/KFSeqAct_ToggleEx.uc | 31 + KFGame/Classes/KFSeqAct_UnlockAchievement.uc | 20 + KFGame/Classes/KFSeqAction_DoshVault.uc | 35 + .../KFSeqEvent_ActivateTriggerProgress.uc | 34 + KFGame/Classes/KFSeqEvent_CollectTrigger.uc | 32 + KFGame/Classes/KFSeqEvent_DoshVault.uc | 82 + KFGame/Classes/KFSeqEvent_LevelLoaded.uc | 82 + .../KFSeqEvent_MapObjectiveActivated.uc | 37 + .../Classes/KFSeqEvent_MinigameActivated.uc | 61 + .../KFSeqEvent_MinigameStateChanged.uc | 37 + .../Classes/KFSeqEvent_ObjectiveProgress.uc | 123 + KFGame/Classes/KFSeqEvent_PawnTeleported.uc | 17 + KFGame/Classes/KFSeqEvent_PlayerDied.uc | 22 + KFGame/Classes/KFSeqEvent_PowerUpActivated.uc | 38 + KFGame/Classes/KFSeqEvent_RepairableActor.uc | 27 + KFGame/Classes/KFSeqEvent_TraderClosed.uc | 40 + KFGame/Classes/KFSeqEvent_TraderOpened.uc | 43 + KFGame/Classes/KFSeqEvent_WaveEnd.uc | 44 + KFGame/Classes/KFSeqEvent_WaveProgress.uc | 58 + KFGame/Classes/KFSeqEvent_WaveStart.uc | 43 + KFGame/Classes/KFSkelControl_AmmoSlider.uc | 44 + KFGame/Classes/KFSkelControl_FootPlacement.uc | 79 + KFGame/Classes/KFSkelControl_SpinBone.uc | 32 + KFGame/Classes/KFSkelControl_SprayScaling.uc | 82 + KFGame/Classes/KFSkelControl_SprayWhipDir.uc | 21 + KFGame/Classes/KFSkelControl_WeaponTilt.uc | 45 + KFGame/Classes/KFSkeletalMeshActor.uc | 29 + KFGame/Classes/KFSkeletalMeshComponent.uc | 186 + KFGame/Classes/KFSkinTypeEffects.uc | 277 + KFGame/Classes/KFSpawnRenderingComponent.uc | 27 + KFGame/Classes/KFSpawnVolume.uc | 509 + KFGame/Classes/KFSpawner.uc | 446 + KFGame/Classes/KFSpecialMove.uc | 648 + KFGame/Classes/KFSpecialMoveHandler.uc | 402 + KFGame/Classes/KFSprayActor.uc | 1089 ++ KFGame/Classes/KFSteamWebAPICall.uc | 102 + KFGame/Classes/KFSteamWebUpToDateCheck.uc | 54 + KFGame/Classes/KFTargetingWeaponComponent.uc | 681 + KFGame/Classes/KFTeamInfo_Human.uc | 131 + KFGame/Classes/KFTeleporter.uc | 119 + KFGame/Classes/KFThirdPersonCamera.uc | 52 + KFGame/Classes/KFThirdPersonCameraMode.uc | 45 + KFGame/Classes/KFTraderDialogManager.uc | 782 ++ KFGame/Classes/KFTraderTrigger.uc | 284 + KFGame/Classes/KFTraderVoiceGroupBase.uc | 125 + KFGame/Classes/KFTrigger_ChokePoint.uc | 96 + KFGame/Classes/KFTrigger_DoshActivated.uc | 65 + KFGame/Classes/KFTrigger_MinigameButton.uc | 311 + KFGame/Classes/KFTrigger_MinigameCash.uc | 38 + KFGame/Classes/KFTrigger_NotifyOwner.uc | 50 + KFGame/Classes/KFTrigger_PowerUp.uc | 350 + .../Classes/KFUIDataProvider_SearchResult.uc | 2 + KFGame/Classes/KFUIDataStore_GameResource.uc | 94 + KFGame/Classes/KFUnlockManager.uc | 323 + KFGame/Classes/KFUnlockableAsset.uc | 12 + KFGame/Classes/KFUsablePerkTrigger.uc | 105 + KFGame/Classes/KFUsableTrigger.uc | 99 + KFGame/Classes/KFVehicleMovementEffect.uc | 56 + KFGame/Classes/KFVersusNoGoVolume.uc | 163 + KFGame/Classes/KFVersusNoTakeoverVolume.uc | 15 + KFGame/Classes/KFVoiceInfo.uc | 91 + KFGame/Classes/KFVoteCollector.uc | 887 ++ KFGame/Classes/KFWallPathNode.uc | 137 + KFGame/Classes/KFWaterMeshActor.uc | 25 + KFGame/Classes/KFWeapAttach_DualBase.uc | 374 + KFGame/Classes/KFWeapAttach_Minigun.uc | 78 + KFGame/Classes/KFWeapAttach_SprayBase.uc | 512 + KFGame/Classes/KFWeapDef_9mm.uc | 35 + KFGame/Classes/KFWeapDef_9mmDual.uc | 35 + KFGame/Classes/KFWeapDef_AA12.uc | 26 + KFGame/Classes/KFWeapDef_AF2011.uc | 26 + KFGame/Classes/KFWeapDef_AF2011Dual.uc | 26 + KFGame/Classes/KFWeapDef_AR15.uc | 32 + KFGame/Classes/KFWeapDef_AbominationAxe.uc | 21 + KFGame/Classes/KFWeapDef_Ak12.uc | 28 + KFGame/Classes/KFWeapDef_Armor.uc | 24 + KFGame/Classes/KFWeapDef_Blunderbuss.uc | 33 + KFGame/Classes/KFWeapDef_Bullpup.uc | 30 + KFGame/Classes/KFWeapDef_C4.uc | 30 + KFGame/Classes/KFWeapDef_CaulkBurn.uc | 32 + KFGame/Classes/KFWeapDef_CenterfireMB464.uc | 30 + KFGame/Classes/KFWeapDef_ChainBat.uc | 30 + KFGame/Classes/KFWeapDef_ChiappaRhino.uc | 30 + KFGame/Classes/KFWeapDef_ChiappaRhinoDual.uc | 30 + KFGame/Classes/KFWeapDef_Colt1911.uc | 30 + KFGame/Classes/KFWeapDef_Colt1911Dual.uc | 30 + KFGame/Classes/KFWeapDef_CompoundBow.uc | 29 + KFGame/Classes/KFWeapDef_Crossbow.uc | 30 + KFGame/Classes/KFWeapDef_Crovel.uc | 31 + KFGame/Classes/KFWeapDef_Deagle.uc | 28 + KFGame/Classes/KFWeapDef_DeagleDual.uc | 28 + KFGame/Classes/KFWeapDef_DoubleBarrel.uc | 30 + KFGame/Classes/KFWeapDef_DragonsBreath.uc | 30 + KFGame/Classes/KFWeapDef_ElephantGun.uc | 24 + KFGame/Classes/KFWeapDef_Eviscerator.uc | 29 + KFGame/Classes/KFWeapDef_FNFal.uc | 26 + KFGame/Classes/KFWeapDef_FireAxe.uc | 30 + KFGame/Classes/KFWeapDef_FlameThrower.uc | 28 + KFGame/Classes/KFWeapDef_FlareGun.uc | 27 + KFGame/Classes/KFWeapDef_FlareGunDual.uc | 27 + KFGame/Classes/KFWeapDef_FreezeThrower.uc | 28 + KFGame/Classes/KFWeapDef_G18.uc | 27 + KFGame/Classes/KFWeapDef_Grenade_Berserker.uc | 21 + KFGame/Classes/KFWeapDef_Grenade_Commando.uc | 22 + KFGame/Classes/KFWeapDef_Grenade_Demo.uc | 22 + KFGame/Classes/KFWeapDef_Grenade_Firebug.uc | 21 + .../Classes/KFWeapDef_Grenade_Gunslinger.uc | 22 + KFGame/Classes/KFWeapDef_Grenade_Medic.uc | 22 + KFGame/Classes/KFWeapDef_Grenade_SWAT.uc | 23 + .../Classes/KFWeapDef_Grenade_Sharpshooter.uc | 18 + KFGame/Classes/KFWeapDef_Grenade_Support.uc | 21 + KFGame/Classes/KFWeapDef_HK_UMP.uc | 25 + .../Classes/KFWeapDef_HRGIncendiaryRifle.uc | 33 + KFGame/Classes/KFWeapDef_HRGIncision.uc | 24 + KFGame/Classes/KFWeapDef_HRGScorcher.uc | 29 + KFGame/Classes/KFWeapDef_HRGWinterbite.uc | 27 + KFGame/Classes/KFWeapDef_HRGWinterbiteDual.uc | 27 + .../Classes/KFWeapDef_HRG_EMP_ArcGenerator.uc | 22 + KFGame/Classes/KFWeapDef_HRG_Kaboomstick.uc | 30 + KFGame/Classes/KFWeapDef_HX25.uc | 32 + KFGame/Classes/KFWeapDef_HZ12.uc | 30 + KFGame/Classes/KFWeapDef_Healer.uc | 20 + KFGame/Classes/KFWeapDef_Healthrower_HRG.uc | 28 + KFGame/Classes/KFWeapDef_Hemogoblin.uc | 28 + KFGame/Classes/KFWeapDef_HuskCannon.uc | 27 + KFGame/Classes/KFWeapDef_IonThruster.uc | 20 + KFGame/Classes/KFWeapDef_Katana.uc | 29 + KFGame/Classes/KFWeapDef_Knife_Berserker.uc | 18 + KFGame/Classes/KFWeapDef_Knife_Commando.uc | 18 + KFGame/Classes/KFWeapDef_Knife_Demo.uc | 18 + KFGame/Classes/KFWeapDef_Knife_Firebug.uc | 18 + KFGame/Classes/KFWeapDef_Knife_Gunslinger.uc | 18 + KFGame/Classes/KFWeapDef_Knife_Medic.uc | 18 + KFGame/Classes/KFWeapDef_Knife_SWAT.uc | 18 + .../Classes/KFWeapDef_Knife_Sharpshooter.uc | 18 + KFGame/Classes/KFWeapDef_Knife_Support.uc | 18 + KFGame/Classes/KFWeapDef_Knife_Survivalist.uc | 18 + KFGame/Classes/KFWeapDef_Kriss.uc | 26 + KFGame/Classes/KFWeapDef_LazerCutter.uc | 19 + KFGame/Classes/KFWeapDef_M14EBR.uc | 28 + KFGame/Classes/KFWeapDef_M16M203.uc | 32 + KFGame/Classes/KFWeapDef_M32.uc | 22 + KFGame/Classes/KFWeapDef_M4.uc | 28 + KFGame/Classes/KFWeapDef_M79.uc | 30 + KFGame/Classes/KFWeapDef_M99.uc | 23 + KFGame/Classes/KFWeapDef_MB500.uc | 32 + KFGame/Classes/KFWeapDef_MKB42.uc | 25 + KFGame/Classes/KFWeapDef_MP5RAS.uc | 30 + KFGame/Classes/KFWeapDef_MP7.uc | 32 + KFGame/Classes/KFWeapDef_Mac10.uc | 27 + KFGame/Classes/KFWeapDef_MaceAndShield.uc | 24 + KFGame/Classes/KFWeapDef_MedicBat.uc | 28 + KFGame/Classes/KFWeapDef_MedicPistol.uc | 32 + KFGame/Classes/KFWeapDef_MedicRifle.uc | 26 + .../KFWeapDef_MedicRifleGrenadeLauncher.uc | 26 + KFGame/Classes/KFWeapDef_MedicSMG.uc | 30 + KFGame/Classes/KFWeapDef_MedicShotgun.uc | 29 + KFGame/Classes/KFWeapDef_MicrowaveGun.uc | 26 + KFGame/Classes/KFWeapDef_MicrowaveRifle.uc | 19 + .../Classes/KFWeapDef_Mine_Reconstructor.uc | 29 + KFGame/Classes/KFWeapDef_Minigun.uc | 23 + KFGame/Classes/KFWeapDef_MosinNagant.uc | 30 + KFGame/Classes/KFWeapDef_NailGun.uc | 31 + KFGame/Classes/KFWeapDef_NailGun_HRG.uc | 29 + KFGame/Classes/KFWeapDef_P90.uc | 28 + KFGame/Classes/KFWeapDef_Pistol_DualG18.uc | 28 + KFGame/Classes/KFWeapDef_Pistol_G18C.uc | 28 + KFGame/Classes/KFWeapDef_PowerGloves.uc | 25 + KFGame/Classes/KFWeapDef_Pulverizer.uc | 28 + KFGame/Classes/KFWeapDef_RPG7.uc | 26 + KFGame/Classes/KFWeapDef_RailGun.uc | 26 + KFGame/Classes/KFWeapDef_Random.uc | 17 + KFGame/Classes/KFWeapDef_Remington1858.uc | 32 + KFGame/Classes/KFWeapDef_Remington1858Dual.uc | 32 + KFGame/Classes/KFWeapDef_SCAR.uc | 26 + KFGame/Classes/KFWeapDef_SW500.uc | 26 + KFGame/Classes/KFWeapDef_SW500Dual.uc | 26 + KFGame/Classes/KFWeapDef_SW500Dual_HRG.uc | 28 + KFGame/Classes/KFWeapDef_SW500_HRG.uc | 28 + KFGame/Classes/KFWeapDef_SealSqueal.uc | 25 + KFGame/Classes/KFWeapDef_Seeker6.uc | 26 + KFGame/Classes/KFWeapDef_Stoner63A.uc | 26 + KFGame/Classes/KFWeapDef_Thompson.uc | 30 + KFGame/Classes/KFWeapDef_Welder.uc | 20 + KFGame/Classes/KFWeapDef_Winchester1894.uc | 32 + KFGame/Classes/KFWeapDef_Zweihander.uc | 29 + KFGame/Classes/KFWeap_DualBase.uc | 995 ++ KFGame/Classes/KFWeap_FlameBase.uc | 809 ++ KFGame/Classes/KFWeap_GrenadeLauncher_Base.uc | 104 + .../KFWeap_GrenadeLauncher_CylinderBase.uc | 507 + KFGame/Classes/KFWeap_HealerBase.uc | 819 ++ KFGame/Classes/KFWeap_MedicBase.uc | 944 ++ KFGame/Classes/KFWeap_MeleeBase.uc | 1385 ++ KFGame/Classes/KFWeap_MinigunBase.uc | 606 + KFGame/Classes/KFWeap_PistolBase.uc | 360 + KFGame/Classes/KFWeap_RifleBase.uc | 53 + KFGame/Classes/KFWeap_SMGBase.uc | 29 + KFGame/Classes/KFWeap_ScopedBase.uc | 354 + KFGame/Classes/KFWeap_ShotgunBase.uc | 59 + KFGame/Classes/KFWeap_ThrownBase.uc | 384 + KFGame/Classes/KFWeapon.uc | 7972 +++++++++++ KFGame/Classes/KFWeaponAmbientEchoHandler.uc | 271 + KFGame/Classes/KFWeaponAttachment.uc | 1273 ++ KFGame/Classes/KFWeaponDefinition.uc | 135 + KFGame/Classes/KFWeaponSkinList.uc | 3300 +++++ KFGame/Classes/KFWeeklyOutbreakInformation.uc | 32 + KFGame/Classes/KFWeldableActor.uc | 187 + KFGame/Classes/KFWeldableComponent.uc | 231 + KFGame/Classes/KFWeldableTrigger.uc | 59 + KFGame/Classes/KFWireConnector.uc | 73 + KFGame/Classes/KFWireStart.uc | 24 + KFGame/Classes/KFZedArmorInfo.uc | 351 + KFGame/Classes/KFweapDef_Knife_Base.uc | 19 + KFGame/Classes/Path_AroundDestructibles.uc | 84 + KFGame/Classes/Path_AvoidChokePoints.uc | 48 + KFGame/Classes/Path_AvoidClosedDoors.uc | 51 + KFGame/Classes/Path_PreferDarkness.uc | 48 + KFGame/Classes/Path_PreferWalls.uc | 49 + KFGame/Classes/Path_ToTrader.uc | 38 + KFGame/Classes/WallReachSpec.uc | 86 + KFGame/Classes/WallToFloorReachSpec.uc | 38 + KFGame/Globals.uci | 81 + KFGame/KFGameAnalytics.uci | 53 + KFGame/KFGameDialog.uci | 647 + KFGame/KFMatchStats.uci | 53 + KFGame/KFOnlineStats.uci | 154 + KFGame/KFProfileSettings.uci | 73 + .../Classes/AICommand_Base_Matriarch.uc | 120 + .../Classes/AICommand_Base_Patriarch.uc | 120 + .../AICommand_BloatKingSubspawn_Explode.uc | 101 + .../Classes/AICommand_BloatKing_Gorge.uc | 93 + .../Classes/AICommand_DAR_EMPAttack.uc | 57 + .../Classes/AICommand_DAR_LaserAttack.uc | 49 + .../Classes/AICommand_DAR_RocketAttack.uc | 49 + ...ICommand_FleshpoundKing_ChestBeamAttack.uc | 76 + .../Classes/AICommand_HuskFireBallAttack.uc | 53 + .../AICommand_HuskFlameThrowerAttack.uc | 101 + .../Classes/AICommand_Husk_Suicide.uc | 115 + .../AICommand_MatriarchPlasmaCannon.uc | 102 + .../AICommand_Matriarch_LightningStorm.uc | 89 + .../AICommand_Matriarch_ScorpionWhip.uc | 102 + .../AICommand_Matriarch_SweepingClaw.uc | 89 + .../Classes/AICommand_Matriarch_TeslaBlast.uc | 54 + .../AICommand_Matriarch_WarningSiren.uc | 93 + .../Classes/AICommand_Patriarch_Grab.uc | 99 + .../AICommand_Patriarch_MinigunBarrage.uc | 144 + .../AICommand_Patriarch_MissileAttack.uc | 93 + .../AICommand_Patriarch_MortarAttack.uc | 102 + .../Classes/AICommand_RangedAttack.uc | 99 + .../Classes/AICommand_Siren_Scream.uc | 134 + .../KFAIController_HansFriendlyTest.uc | 187 + .../KFAIController_HuskFriendlyTest.uc | 43 + .../Classes/KFAIController_Ranged.uc | 42 + .../Classes/KFAIController_ZedBloat.uc | 75 + .../Classes/KFAIController_ZedBloatKing.uc | 423 + .../KFAIController_ZedBloatKingSubspawn.uc | 177 + .../Classes/KFAIController_ZedClot_Alpha.uc | 126 + .../KFAIController_ZedClot_AlphaKing.uc | 143 + .../Classes/KFAIController_ZedClot_Cyst.uc | 124 + .../Classes/KFAIController_ZedClot_Slasher.uc | 163 + .../Classes/KFAIController_ZedCrawlerKing.uc | 14 + .../Classes/KFAIController_ZedDAR.uc | 439 + .../Classes/KFAIController_ZedDAR_EMP.uc | 31 + .../Classes/KFAIController_ZedDAR_Laser.uc | 31 + .../Classes/KFAIController_ZedDAR_Rocket.uc | 33 + .../KFAIController_ZedFleshpoundKing.uc | 293 + .../Classes/KFAIController_ZedGorefast.uc | 137 + .../KFAIController_ZedGorefastDualBlade.uc | 14 + .../Classes/KFAIController_ZedHusk.uc | 436 + .../Classes/KFAIController_ZedMatriarch.uc | 690 + .../Classes/KFAIController_ZedPatriarch.uc | 1999 +++ .../Classes/KFAIController_ZedScrake.uc | 92 + .../Classes/KFAIController_ZedSiren.uc | 224 + .../Classes/KFAIController_ZedStalker.uc | 167 + .../Classes/KFAISpawnManager_Endless.uc | 242 + .../Classes/KFAISpawnManager_Tutorial.uc | 27 + .../Classes/KFAISpawnManager_Versus.uc | 1548 ++ .../Classes/KFActor_DestructibleTracker.uc | 77 + .../Classes/KFAffliction_Fire_Patriarch.uc | 21 + KFGameContent/Classes/KFBloodRainVolume.uc | 111 + .../Classes/KFCarryableObject_Collectible.uc | 186 + KFGameContent/Classes/KFCarryable_Datapad.uc | 69 + KFGameContent/Classes/KFCarryable_Gear.uc | 23 + KFGameContent/Classes/KFCollectibleActor.uc | 74 + KFGameContent/Classes/KFDT_Ballistic_9mm.uc | 26 + .../Classes/KFDT_Ballistic_AA12Shotgun.uc | 52 + .../Classes/KFDT_Ballistic_AF2011.uc | 47 + KFGameContent/Classes/KFDT_Ballistic_AK12.uc | 46 + KFGameContent/Classes/KFDT_Ballistic_AR15.uc | 28 + .../Classes/KFDT_Ballistic_AssaultRifle.uc | 23 + .../Classes/KFDT_Ballistic_Assault_Medic.uc | 77 + .../KFDT_Ballistic_BlunderbussImpact.uc | 27 + .../KFDT_Ballistic_BlunderbussShards.uc | 38 + .../Classes/KFDT_Ballistic_Bullpup.uc | 28 + .../Classes/KFDT_Ballistic_CenterfireMB464.uc | 46 + .../Classes/KFDT_Ballistic_ChiappaRhino.uc | 47 + .../Classes/KFDT_Ballistic_Colt1911.uc | 28 + .../Classes/KFDT_Ballistic_DBShotgun.uc | 52 + .../Classes/KFDT_Ballistic_Deagle.uc | 48 + .../Classes/KFDT_Ballistic_DragonsBreath.uc | 84 + .../Classes/KFDT_Ballistic_ElephantGun.uc | 46 + KFGameContent/Classes/KFDT_Ballistic_FNFal.uc | 49 + KFGameContent/Classes/KFDT_Ballistic_G18.uc | 25 + KFGameContent/Classes/KFDT_Ballistic_G18C.uc | 25 + .../Classes/KFDT_Ballistic_HK_UMP.uc | 23 + .../Classes/KFDT_Ballistic_HRGBuckshot.uc | 48 + .../KFDT_Ballistic_HRGIncendiaryRifle.uc | 57 + ...llistic_HRGIncendiaryRifleGrenadeImpact.uc | 26 + .../Classes/KFDT_Ballistic_HRGIncisionHeal.uc | 62 + .../Classes/KFDT_Ballistic_HRGIncisionHurt.uc | 72 + .../Classes/KFDT_Ballistic_HRGNailgun.uc | 38 + .../KFDT_Ballistic_HRGScorcherBrokenImpact.uc | 28 + ...FDT_Ballistic_HRGScorcherLightingImpact.uc | 45 + .../Classes/KFDT_Ballistic_HRGTeslauncher.uc | 79 + ...T_Ballistic_HRGTeslauncherGrenadeImpact.uc | 27 + .../Classes/KFDT_Ballistic_HRG_Kaboomstick.uc | 28 + .../Classes/KFDT_Ballistic_HX25Impact.uc | 29 + .../KFDT_Ballistic_HX25SubmunitionImpact.uc | 53 + KFGameContent/Classes/KFDT_Ballistic_HZ12.uc | 50 + .../Classes/KFDT_Ballistic_Handgun.uc | 22 + .../Classes/KFDT_Ballistic_HansAK12.uc | 30 + .../Classes/KFDT_Ballistic_Hemogoblin.uc | 124 + KFGameContent/Classes/KFDT_Ballistic_Kriss.uc | 26 + .../Classes/KFDT_Ballistic_LazerCutter.uc | 28 + .../Classes/KFDT_Ballistic_M14EBR.uc | 47 + .../Classes/KFDT_Ballistic_M16M203.uc | 29 + .../Classes/KFDT_Ballistic_M203Impact.uc | 28 + .../Classes/KFDT_Ballistic_M32Impact.uc | 27 + .../Classes/KFDT_Ballistic_M4Shotgun.uc | 52 + .../Classes/KFDT_Ballistic_M79Impact.uc | 28 + KFGameContent/Classes/KFDT_Ballistic_M99.uc | 47 + KFGameContent/Classes/KFDT_Ballistic_MB500.uc | 51 + KFGameContent/Classes/KFDT_Ballistic_MKB42.uc | 43 + .../Classes/KFDT_Ballistic_MP5RAS.uc | 26 + KFGameContent/Classes/KFDT_Ballistic_MP7.uc | 26 + ...FDT_Ballistic_MedicRifleGrenadeLauncher.uc | 41 + ...llistic_MedicRifleGrenadeLauncherImpact.uc | 29 + .../Classes/KFDT_Ballistic_MicrowaveRifle.uc | 78 + .../Classes/KFDT_Ballistic_Minigun.uc | 27 + .../Classes/KFDT_Ballistic_MosinNagant.uc | 48 + .../KFDT_Ballistic_MosinNagantSpecial.uc | 31 + .../Classes/KFDT_Ballistic_NailShotgun.uc | 41 + KFGameContent/Classes/KFDT_Ballistic_P90.uc | 28 + .../Classes/KFDT_Ballistic_PatMinigun.uc | 28 + .../Classes/KFDT_Ballistic_Pistol_Medic.uc | 41 + .../Classes/KFDT_Ballistic_RPG7Impact.uc | 28 + .../Classes/KFDT_Ballistic_RailGun.uc | 60 + .../Classes/KFDT_Ballistic_Rem1858.uc | 29 + .../Classes/KFDT_Ballistic_Rem1858_Dual.uc | 17 + KFGameContent/Classes/KFDT_Ballistic_Rifle.uc | 21 + KFGameContent/Classes/KFDT_Ballistic_SCAR.uc | 47 + .../Classes/KFDT_Ballistic_SMG_Medic.uc | 40 + KFGameContent/Classes/KFDT_Ballistic_SW500.uc | 49 + .../Classes/KFDT_Ballistic_SW500_Dual.uc | 17 + .../KFDT_Ballistic_SealSquealImpact.uc | 35 + .../Classes/KFDT_Ballistic_Seeker6Impact.uc | 26 + .../Classes/KFDT_Ballistic_Shotgun.uc | 25 + .../Classes/KFDT_Ballistic_Shotgun_Medic.uc | 66 + .../Classes/KFDT_Ballistic_Stoner63A.uc | 26 + .../Classes/KFDT_Ballistic_Submachinegun.uc | 18 + .../Classes/KFDT_Ballistic_Thompson.uc | 28 + .../Classes/KFDT_Ballistic_Winchester.uc | 46 + KFGameContent/Classes/KFDT_BellTrap.uc | 14 + .../Classes/KFDT_Bleeding_Hemogoblin.uc | 30 + .../Classes/KFDT_BloatKingSubspawn_Death.uc | 19 + KFGameContent/Classes/KFDT_BloatPuke.uc | 23 + KFGameContent/Classes/KFDT_Bludgeon_9mm.uc | 16 + .../Classes/KFDT_Bludgeon_AA12Shotgun.uc | 16 + KFGameContent/Classes/KFDT_Bludgeon_AF2011.uc | 16 + KFGameContent/Classes/KFDT_Bludgeon_AK12.uc | 16 + KFGameContent/Classes/KFDT_Bludgeon_AR15.uc | 16 + .../Classes/KFDT_Bludgeon_ArcGenerator.uc | 16 + .../Classes/KFDT_Bludgeon_Assault_Medic.uc | 16 + .../Classes/KFDT_Bludgeon_BloatKing.uc | 30 + .../Classes/KFDT_Bludgeon_BloatKingGorge.uc | 32 + .../Classes/KFDT_Bludgeon_Blunderbuss.uc | 16 + .../Classes/KFDT_Bludgeon_Bullpup.uc | 16 + KFGameContent/Classes/KFDT_Bludgeon_C4.uc | 16 + .../Classes/KFDT_Bludgeon_Carryable.uc | 20 + .../Classes/KFDT_Bludgeon_CaulkBurn.uc | 17 + .../Classes/KFDT_Bludgeon_CenterfireMB464.uc | 15 + .../Classes/KFDT_Bludgeon_ChainBat.uc | 27 + .../Classes/KFDT_Bludgeon_ChainBatBash.uc | 22 + .../Classes/KFDT_Bludgeon_ChainBatHeavy.uc | 22 + .../Classes/KFDT_Bludgeon_ChiappaRhino.uc | 16 + .../Classes/KFDT_Bludgeon_Colt1911.uc | 17 + .../Classes/KFDT_Bludgeon_Crossbow.uc | 16 + KFGameContent/Classes/KFDT_Bludgeon_Crovel.uc | 25 + .../Classes/KFDT_Bludgeon_CrovelBash.uc | 21 + .../Classes/KFDT_Bludgeon_DBShotgun.uc | 16 + KFGameContent/Classes/KFDT_Bludgeon_Deagle.uc | 16 + .../Classes/KFDT_Bludgeon_DragonsBreath.uc | 16 + .../Classes/KFDT_Bludgeon_ElephantGun.uc | 16 + KFGameContent/Classes/KFDT_Bludgeon_FNFal.uc | 16 + .../Classes/KFDT_Bludgeon_FireAxeBash.uc | 24 + .../Classes/KFDT_Bludgeon_Flamethrower.uc | 16 + .../Classes/KFDT_Bludgeon_FlareGun.uc | 17 + .../Classes/KFDT_Bludgeon_Fleshpound.uc | 18 + .../Classes/KFDT_Bludgeon_Fleshpound_AOE.uc | 15 + .../Classes/KFDT_Bludgeon_FreezeThrower.uc | 15 + KFGameContent/Classes/KFDT_Bludgeon_G18C.uc | 16 + .../Classes/KFDT_Bludgeon_G18Shield.uc | 25 + .../KFDT_Bludgeon_G18Shield_Impulse.uc | 26 + KFGameContent/Classes/KFDT_Bludgeon_HK_UMP.uc | 16 + .../Classes/KFDT_Bludgeon_HRGBuckshot.uc | 16 + .../Classes/KFDT_Bludgeon_HRGHealthrower.uc | 16 + .../KFDT_Bludgeon_HRGIncendiaryRifle.uc | 17 + .../Classes/KFDT_Bludgeon_HRGIncision.uc | 14 + .../Classes/KFDT_Bludgeon_HRGNailgun.uc | 16 + .../Classes/KFDT_Bludgeon_HRGScorcher.uc | 19 + .../Classes/KFDT_Bludgeon_HRGTeslauncher.uc | 17 + .../Classes/KFDT_Bludgeon_HRGWinterbite.uc | 17 + .../Classes/KFDT_Bludgeon_HRG_Kaboomstick.uc | 18 + KFGameContent/Classes/KFDT_Bludgeon_HX25.uc | 16 + KFGameContent/Classes/KFDT_Bludgeon_HZ12.uc | 15 + KFGameContent/Classes/KFDT_Bludgeon_Healer.uc | 16 + .../Classes/KFDT_Bludgeon_Hemogoblin.uc | 16 + .../Classes/KFDT_Bludgeon_HuskCannon.uc | 15 + KFGameContent/Classes/KFDT_Bludgeon_Kriss.uc | 17 + .../Classes/KFDT_Bludgeon_LazerCutter.uc | 16 + KFGameContent/Classes/KFDT_Bludgeon_M14EBR.uc | 16 + .../Classes/KFDT_Bludgeon_M16M203.uc | 16 + KFGameContent/Classes/KFDT_Bludgeon_M32.uc | 16 + .../Classes/KFDT_Bludgeon_M4Shotgun.uc | 16 + KFGameContent/Classes/KFDT_Bludgeon_M79.uc | 16 + KFGameContent/Classes/KFDT_Bludgeon_M99.uc | 15 + KFGameContent/Classes/KFDT_Bludgeon_MB500.uc | 16 + KFGameContent/Classes/KFDT_Bludgeon_MKB42.uc | 16 + KFGameContent/Classes/KFDT_Bludgeon_MP5RAS.uc | 17 + KFGameContent/Classes/KFDT_Bludgeon_MP7.uc | 17 + KFGameContent/Classes/KFDT_Bludgeon_Mac10.uc | 15 + .../Classes/KFDT_Bludgeon_MaceAndShield.uc | 28 + .../KFDT_Bludgeon_MaceAndShield_Bash.uc | 41 + .../KFDT_Bludgeon_MaceAndShield_MaceHeavy.uc | 26 + ...KFDT_Bludgeon_MaceAndShield_ShieldHeavy.uc | 38 + ...KFDT_Bludgeon_MaceAndShield_ShieldLight.uc | 38 + .../Classes/KFDT_Bludgeon_Matriarch.uc | 30 + .../Classes/KFDT_Bludgeon_MedicBatBash.uc | 46 + .../Classes/KFDT_Bludgeon_MedicBatHeavy.uc | 46 + .../Classes/KFDT_Bludgeon_MedicBatLight.uc | 47 + ...KFDT_Bludgeon_MedicRifleGrenadeLauncher.uc | 15 + .../Classes/KFDT_Bludgeon_MicrowaveGun.uc | 16 + .../Classes/KFDT_Bludgeon_MicrowaveRifle.uc | 16 + .../KFDT_Bludgeon_Mine_Reconstructor.uc | 15 + .../Classes/KFDT_Bludgeon_Minigun.uc | 16 + .../Classes/KFDT_Bludgeon_NailShotgun.uc | 16 + KFGameContent/Classes/KFDT_Bludgeon_P90.uc | 16 + .../Classes/KFDT_Bludgeon_Patriarch.uc | 30 + .../Classes/KFDT_Bludgeon_PatriarchKick.uc | 28 + .../Classes/KFDT_Bludgeon_PatriarchMetal.uc | 26 + .../Classes/KFDT_Bludgeon_Pistol_Medic.uc | 16 + .../Classes/KFDT_Bludgeon_PowerGloves.uc | 24 + .../Classes/KFDT_Bludgeon_PowerGlovesBash.uc | 25 + .../Classes/KFDT_Bludgeon_PowerGlovesHeavy.uc | 28 + .../Classes/KFDT_Bludgeon_Pulverizer.uc | 27 + .../Classes/KFDT_Bludgeon_PulverizerBash.uc | 27 + .../Classes/KFDT_Bludgeon_PulverizerHeavy.uc | 27 + KFGameContent/Classes/KFDT_Bludgeon_RPG7.uc | 16 + .../Classes/KFDT_Bludgeon_RailGun.uc | 15 + .../Classes/KFDT_Bludgeon_Rem1858.uc | 16 + .../Classes/KFDT_Bludgeon_RifleButt.uc | 23 + KFGameContent/Classes/KFDT_Bludgeon_SCAR.uc | 16 + .../Classes/KFDT_Bludgeon_SMG_Medic.uc | 16 + KFGameContent/Classes/KFDT_Bludgeon_SW500.uc | 16 + .../Classes/KFDT_Bludgeon_SealSqueal.uc | 15 + .../Classes/KFDT_Bludgeon_Seeker6.uc | 15 + .../Classes/KFDT_Bludgeon_Shotgun_Medic.uc | 16 + .../Classes/KFDT_Bludgeon_Stoner63A.uc | 15 + .../Classes/KFDT_Bludgeon_Thompson.uc | 15 + KFGameContent/Classes/KFDT_Bludgeon_Welder.uc | 16 + .../Classes/KFDT_Bludgeon_Winchester.uc | 16 + .../Classes/KFDT_Bludgeon_ZedJump.uc | 22 + KFGameContent/Classes/KFDT_DAR_EMPBlast.uc | 16 + KFGameContent/Classes/KFDT_Dart_Healing.uc | 19 + KFGameContent/Classes/KFDT_Dart_Toxic.uc | 18 + KFGameContent/Classes/KFDT_EMPTrap.uc | 24 + .../KFDT_EMP_ArcGeneratorSphereImpact.uc | 34 + ...T_EMP_ArcGenerator_AltFiremodeZapDamage.uc | 33 + .../Classes/KFDT_EMP_ArcGenerator_Beam.uc | 35 + ...P_ArcGenerator_DefaultFiremodeZapDamage.uc | 33 + KFGameContent/Classes/KFDT_EMP_EMPGrenade.uc | 28 + .../KFDT_EMP_MatriarchLightningStorm.uc | 26 + .../Classes/KFDT_EMP_MatriarchPlasmaCannon.uc | 33 + .../Classes/KFDT_EMP_MatriarchTeslaBlast.uc | 26 + .../Classes/KFDT_EMP_TeslauncherEMPGrenade.uc | 27 + KFGameContent/Classes/KFDT_EvilDAR_Laser.uc | 19 + KFGameContent/Classes/KFDT_EvilDAR_Rocket.uc | 25 + .../Classes/KFDT_Explosive_Blunderbuss.uc | 32 + KFGameContent/Classes/KFDT_Explosive_C4.uc | 41 + .../Classes/KFDT_Explosive_CrawlerSuicide.uc | 33 + .../Classes/KFDT_Explosive_DynamiteGrenade.uc | 35 + .../KFDT_Explosive_FlashBangGrenade.uc | 38 + ...KFDT_Explosive_FleshpoundKingRage_Heavy.uc | 33 + ...KFDT_Explosive_FleshpoundKingRage_Light.uc | 33 + .../Classes/KFDT_Explosive_FragGrenade.uc | 30 + .../Classes/KFDT_Explosive_HEGrenade.uc | 33 + .../KFDT_Explosive_HRGIncendiaryRifle.uc | 68 + .../Classes/KFDT_Explosive_HRGWinterbite.uc | 31 + .../Classes/KFDT_Explosive_HRG_Kaboomstick.uc | 34 + KFGameContent/Classes/KFDT_Explosive_HX25.uc | 34 + .../Classes/KFDT_Explosive_HansHEGrenade.uc | 26 + .../Classes/KFDT_Explosive_HuskCannon.uc | 59 + .../KFDT_Explosive_HuskCannonImpact.uc | 32 + .../Classes/KFDT_Explosive_HuskSuicide.uc | 32 + .../Classes/KFDT_Explosive_M16M203.uc | 33 + KFGameContent/Classes/KFDT_Explosive_M32.uc | 31 + KFGameContent/Classes/KFDT_Explosive_M79.uc | 33 + .../Classes/KFDT_Explosive_NailBombGrenade.uc | 28 + .../Classes/KFDT_Explosive_PatMissile.uc | 30 + .../Classes/KFDT_Explosive_PatMortar.uc | 30 + .../KFDT_Explosive_PlayerZedTakeover.uc | 27 + .../Classes/KFDT_Explosive_Pulverizer.uc | 34 + KFGameContent/Classes/KFDT_Explosive_RPG7.uc | 34 + .../Classes/KFDT_Explosive_RPG7BackBlast.uc | 31 + .../Classes/KFDT_Explosive_SealSqueal.uc | 31 + .../Classes/KFDT_Explosive_Seeker6.uc | 32 + KFGameContent/Classes/KFDT_FireTrap.uc | 28 + KFGameContent/Classes/KFDT_Fire_CaulkBurn.uc | 41 + .../Classes/KFDT_Fire_DragonsBreathDoT.uc | 41 + .../Classes/KFDT_Fire_Environment.uc | 16 + .../Classes/KFDT_Fire_EnvironmentTrap.uc | 17 + .../Classes/KFDT_Fire_FlameThrower.uc | 40 + KFGameContent/Classes/KFDT_Fire_FlareGun.uc | 46 + .../Classes/KFDT_Fire_FlareGunDoT.uc | 43 + .../Classes/KFDT_Fire_FlareGun_Dual.uc | 18 + .../Classes/KFDT_Fire_Ground_CaulkNBurn.uc | 19 + .../Classes/KFDT_Fire_Ground_DragonsBreath.uc | 41 + .../Classes/KFDT_Fire_Ground_FlameThrower.uc | 19 + .../Classes/KFDT_Fire_Ground_FlareGun.uc | 43 + .../KFDT_Fire_Ground_HRGIncendiaryRifle.uc | 27 + .../Classes/KFDT_Fire_Ground_HRGScorcher.uc | 41 + .../Classes/KFDT_Fire_Ground_HuskCannon.uc | 19 + .../Classes/KFDT_Fire_Ground_MicrowaveGun.uc | 17 + .../KFDT_Fire_Ground_MolotovGrenade.uc | 35 + .../KFDT_Fire_HRGIncendiaryRifleBulletDoT.uc | 38 + .../KFDT_Fire_HRGIncendiaryRifleGrenadeDoT.uc | 23 + .../Classes/KFDT_Fire_HRGScorcherDoT.uc | 41 + .../Classes/KFDT_Fire_HRGTeslauncherDoT.uc | 29 + .../Classes/KFDT_Fire_HuskFireball.uc | 38 + .../Classes/KFDT_Fire_HuskFlamethrower.uc | 20 + .../Classes/KFDT_Fire_IonThrusterDoT.uc | 42 + KFGameContent/Classes/KFDT_Fire_Mac10.uc | 81 + .../Classes/KFDT_Fire_MolotovGrenade.uc | 35 + KFGameContent/Classes/KFDT_Fire_ZedGround.uc | 17 + .../Classes/KFDT_FleshpoundKing_ChestBeam.uc | 24 + .../KFDT_Freeze_CompoundBowCryExplosion.uc | 24 + .../KFDT_Freeze_DualHRGWinterbiteImpact.uc | 17 + .../Classes/KFDT_Freeze_FreezeGrenade.uc | 49 + .../Classes/KFDT_Freeze_FreezeThrower.uc | 46 + .../KFDT_Freeze_FreezeThrower_IceShards.uc | 17 + .../KFDT_Freeze_Ground_FreezeThrower.uc | 17 + .../KFDT_Freeze_HRGWinterbiteImpact.uc | 25 + .../Classes/KFDT_Healing_MedicGrenade.uc | 18 + KFGameContent/Classes/KFDT_HeavyZedBump.uc | 40 + .../Classes/KFDT_Krampus_ChipperPit.uc | 43 + .../Classes/KFDT_LazerCutter_Beam.uc | 34 + KFGameContent/Classes/KFDT_MediumZedBump.uc | 40 + KFGameContent/Classes/KFDT_Microwave_Beam.uc | 46 + KFGameContent/Classes/KFDT_Microwave_Blast.uc | 41 + ...FDT_Mine_Reconstructor_BileExplosionDoT.uc | 33 + KFGameContent/Classes/KFDT_PiercingTrap.uc | 18 + .../KFDT_Piercing_AbominationAxeStab.uc | 24 + .../Classes/KFDT_Piercing_ChiappaShrapnel.uc | 25 + .../KFDT_Piercing_CompoundBowCryoImpact.uc | 26 + .../KFDT_Piercing_CompoundBowSharpImpact.uc | 27 + .../Classes/KFDT_Piercing_Crossbow.uc | 30 + .../Classes/KFDT_Piercing_IonThrusterStab.uc | 57 + .../Classes/KFDT_Piercing_KatanaStab.uc | 23 + .../Classes/KFDT_Piercing_KnifeStab.uc | 23 + .../KFDT_Piercing_KnifeStab_Berserker.uc | 17 + .../KFDT_Piercing_KnifeStab_FieldMedic.uc | 29 + .../Classes/KFDT_Piercing_KnifeStab_SWAT.uc | 18 + .../KFDT_Piercing_KnifeStab_Survivalist.uc | 17 + .../Classes/KFDT_Piercing_MosinNagant.uc | 25 + .../Classes/KFDT_Piercing_NadeFragment.uc | 59 + .../Classes/KFDT_Piercing_NailFragment.uc | 60 + .../Classes/KFDT_Piercing_ZweihanderStab.uc | 24 + .../Classes/KFDT_Pirecing_CompoundBow.uc | 21 + .../Classes/KFDT_Slashing_AbominationAxe.uc | 140 + .../KFDT_Slashing_AbominationAxeHeavy.uc | 38 + KFGameContent/Classes/KFDT_Slashing_Crovel.uc | 24 + .../Classes/KFDT_Slashing_Eviscerator.uc | 140 + .../Classes/KFDT_Slashing_EvisceratorProj.uc | 189 + .../Classes/KFDT_Slashing_FireAxe.uc | 138 + .../Classes/KFDT_Slashing_FireAxeHeavy.uc | 42 + .../Classes/KFDT_Slashing_Gorefast.uc | 20 + .../Classes/KFDT_Slashing_Gorefast_AOE.uc | 16 + KFGameContent/Classes/KFDT_Slashing_Hans.uc | 23 + .../Classes/KFDT_Slashing_IonThruster.uc | 175 + .../Classes/KFDT_Slashing_IonThrusterHeavy.uc | 51 + .../KFDT_Slashing_IonThrusterSpecial.uc | 50 + KFGameContent/Classes/KFDT_Slashing_Katana.uc | 138 + .../Classes/KFDT_Slashing_KatanaHeavy.uc | 41 + KFGameContent/Classes/KFDT_Slashing_Knife.uc | 140 + .../Classes/KFDT_Slashing_KnifeHeavy.uc | 43 + .../KFDT_Slashing_KnifeHeavy_Berserker.uc | 17 + .../Classes/KFDT_Slashing_KnifeHeavy_Medic.uc | 30 + .../Classes/KFDT_Slashing_KnifeHeavy_SWAT.uc | 18 + .../KFDT_Slashing_KnifeHeavy_Survivalist.uc | 17 + .../Classes/KFDT_Slashing_Knife_Berserker.uc | 17 + .../Classes/KFDT_Slashing_Knife_Medic.uc | 30 + .../Classes/KFDT_Slashing_Knife_SWAT.uc | 18 + .../KFDT_Slashing_Knife_Survivalist.uc | 17 + .../KFDT_Slashing_MatriarchTentacle.uc | 28 + .../Classes/KFDT_Slashing_PatTentacle.uc | 28 + .../Classes/KFDT_Slashing_Patriarch.uc | 29 + .../Classes/KFDT_Slashing_PowerGloves.uc | 24 + KFGameContent/Classes/KFDT_Slashing_Scrake.uc | 18 + .../Classes/KFDT_Slashing_Scrake_AOE.uc | 15 + .../Classes/KFDT_Slashing_ZedWeak.uc | 20 + .../Classes/KFDT_Slashing_Zweihander.uc | 140 + .../Classes/KFDT_Slashing_ZweihanderHeavy.uc | 43 + .../KFDT_Sonic_MatriarchWarningSiren.uc | 14 + .../Classes/KFDT_Sonic_VortexScream.uc | 18 + KFGameContent/Classes/KFDT_SwingMinigame.uc | 35 + .../Classes/KFDT_Toxic_BloatKingFart.uc | 25 + .../Classes/KFDT_Toxic_BloatKingPukeMine.uc | 23 + .../KFDT_Toxic_BloatKingSubspawnExplosion.uc | 16 + .../Classes/KFDT_Toxic_BloatPukeMine.uc | 21 + .../Classes/KFDT_Toxic_EnvironmentGas.uc | 24 + .../Classes/KFDT_Toxic_HansGrenade.uc | 29 + .../Classes/KFDT_Toxic_MedicBatDoT.uc | 27 + .../Classes/KFDT_Toxic_MedicBatGas.uc | 33 + .../KFDT_Toxic_MineReconstructorExplosion.uc | 42 + .../KFDT_Toxic_MineReconstructorImpact.uc | 55 + ...KFDT_Toxic_MineReconstructorImpactHeavy.uc | 56 + .../KFDT_Toxic_PlayerCrawlerSuicide.uc | 26 + .../Classes/KFDT_Trap_BiolapseBloodBlender.uc | 15 + .../Classes/KFDT_Trap_BiolapseTrapDoor.uc | 15 + .../Classes/KFDT_Trap_SanitariumSuction.uc | 15 + .../Classes/KFDT_Trap_SanitariumTentacle.uc | 15 + KFGameContent/Classes/KFDifficulty_Bloat.uc | 93 + .../Classes/KFDifficulty_BloatKing.uc | 65 + .../Classes/KFDifficulty_BloatKingSubspawn.uc | 51 + .../Classes/KFDifficulty_ClotAlpha.uc | 46 + .../Classes/KFDifficulty_ClotAlphaKing.uc | 58 + .../Classes/KFDifficulty_ClotCyst.uc | 40 + .../Classes/KFDifficulty_ClotSlasher.uc | 55 + KFGameContent/Classes/KFDifficulty_Crawler.uc | 53 + .../Classes/KFDifficulty_CrawlerKing.uc | 15 + KFGameContent/Classes/KFDifficulty_DAR.uc | 47 + KFGameContent/Classes/KFDifficulty_DAR_EMP.uc | 50 + .../Classes/KFDifficulty_DAR_Laser.uc | 50 + .../Classes/KFDifficulty_DAR_Rocket.uc | 50 + .../Classes/KFDifficulty_Fleshpound.uc | 72 + .../Classes/KFDifficulty_FleshpoundKing.uc | 86 + .../Classes/KFDifficulty_FleshpoundMini.uc | 73 + .../Classes/KFDifficulty_Gorefast.uc | 67 + .../Classes/KFDifficulty_GorefastDualBlade.uc | 54 + KFGameContent/Classes/KFDifficulty_Hans.uc | 63 + KFGameContent/Classes/KFDifficulty_Husk.uc | 87 + .../Classes/KFDifficulty_Matriarch.uc | 55 + .../Classes/KFDifficulty_Patriarch.uc | 66 + KFGameContent/Classes/KFDifficulty_Scrake.uc | 70 + KFGameContent/Classes/KFDifficulty_Siren.uc | 51 + KFGameContent/Classes/KFDifficulty_Stalker.uc | 55 + .../Classes/KFDroppedPickup_Carryable.uc | 36 + .../Classes/KFDynamicPhysicsVolume.uc | 41 + KFGameContent/Classes/KFExplosionActorC4.uc | 22 + .../Classes/KFExplosionActor_HuskCannon.uc | 22 + .../Classes/KFExplosion_BloatKingFart.uc | 22 + .../Classes/KFExplosion_BloatKingSubspawn.uc | 12 + .../KFExplosion_BlunderbussCannonball.uc | 14 + .../Classes/KFExplosion_GroundFire.uc | 34 + .../Classes/KFExplosion_GroundIce.uc | 31 + ...FExplosion_HRGIncendiaryRifleGroundFire.uc | 33 + .../KFExplosion_HRGScorcherGroundFire.uc | 36 + .../KFExplosion_HansNerveGasGrenade.uc | 24 + .../Classes/KFExplosion_HansSmokeGrenade.uc | 72 + ...FExplosion_HuskCannonFireballGroundFire.uc | 47 + .../KFExplosion_HuskFireballGroundFire.uc | 26 + .../Classes/KFExplosion_MedicGrenade.uc | 130 + .../Classes/KFExplosion_MedicGrenadeMini.uc | 25 + .../Classes/KFExplosion_MineReconstructor.uc | 285 + KFGameContent/Classes/KFExplosion_Molotov.uc | 31 + .../KFExplosion_PlayerBloatPukeMine.uc | 41 + .../KFExplosion_PlayerCrawlerSuicide.uc | 22 + .../KFExplosion_ReplicatedMedicGrenade.uc | 141 + .../Classes/KFExplosion_SirenScream.uc | 39 + .../Classes/KFGFXHudWrapper_Versus.uc | 418 + .../Classes/KFGFxHUD_PlayerStatusVersus.uc | 80 + .../Classes/KFGFxMoviePlayer_HUD_Versus.uc | 200 + .../KFGFxMoviePlayer_Manager_Tutorial.uc | 27 + .../Classes/KFGFxMoviePlayer_Tutorial.uc | 150 + .../Classes/KFGFxTutorialContainer.uc | 129 + .../Classes/KFGameConductorVersus.uc | 94 + KFGameContent/Classes/KFGameContentRoot.uc | 18 + .../Classes/KFGameDifficulty_Endless.uc | 1996 +++ .../KFGameDifficulty_Endless_Console.uc | 14 + .../Classes/KFGameDifficulty_Objective.uc | 53 + .../KFGameDifficulty_Objective_Console.uc | 53 + .../Classes/KFGameDifficulty_Survival.uc | 53 + .../KFGameDifficulty_Survival_Console.uc | 14 + .../Classes/KFGameDifficulty_Versus.uc | 20 + .../KFGameDifficulty_Versus_Console.uc | 13 + KFGameContent/Classes/KFGameInfo_Endless.uc | 696 + KFGameContent/Classes/KFGameInfo_Objective.uc | 307 + KFGameContent/Classes/KFGameInfo_Survival.uc | 1905 +++ KFGameContent/Classes/KFGameInfo_Tutorial.uc | 491 + .../Classes/KFGameInfo_VersusSurvival.uc | 1547 ++ .../Classes/KFGameInfo_WeeklySurvival.uc | 618 + .../Classes/KFGameReplicationInfoVersus.uc | 258 + .../Classes/KFGameReplicationInfo_Endless.uc | 107 + .../KFGameReplicationInfo_Objective.uc | 146 + .../KFGameReplicationInfo_WeeklySurvival.uc | 19 + KFGameContent/Classes/KFGoreJoint_Arm.uc | 22 + KFGameContent/Classes/KFGoreJoint_Chest.uc | 31 + KFGameContent/Classes/KFGoreJoint_Foot.uc | 22 + KFGameContent/Classes/KFGoreJoint_ForeArm.uc | 21 + KFGameContent/Classes/KFGoreJoint_Hand.uc | 24 + KFGameContent/Classes/KFGoreJoint_Head.uc | 79 + KFGameContent/Classes/KFGoreJoint_Hips.uc | 22 + KFGameContent/Classes/KFGoreJoint_Leg.uc | 22 + KFGameContent/Classes/KFGoreJoint_Neck.uc | 25 + KFGameContent/Classes/KFGoreJoint_Shoulder.uc | 51 + KFGameContent/Classes/KFGoreJoint_Spine1.uc | 45 + KFGameContent/Classes/KFGoreJoint_Thigh.uc | 25 + KFGameContent/Classes/KFInventory_Armor.uc | 19 + KFGameContent/Classes/KFInventory_Money.uc | 99 + KFGameContent/Classes/KFMGA_AnimatedTrap.uc | 286 + KFGameContent/Classes/KFMGA_DoshTossPit.uc | 218 + KFGameContent/Classes/KFMGA_Rollercoaster.uc | 210 + KFGameContent/Classes/KFMGA_Target.uc | 247 + KFGameContent/Classes/KFMGA_TargetGame.uc | 81 + .../Classes/KFMGA_Target_BloatDunk.uc | 93 + KFGameContent/Classes/KFMGVolume_DoshToss.uc | 24 + KFGameContent/Classes/KFMGVolume_SwingHit.uc | 21 + KFGameContent/Classes/KFMG_BloatDunk.uc | 466 + .../Classes/KFMG_MultilevelTargetGame.uc | 140 + .../Classes/KFMG_RiggedTargetGame.uc | 386 + KFGameContent/Classes/KFMG_SwingRide.uc | 222 + KFGameContent/Classes/KFMG_TargetGame.uc | 171 + .../Classes/KFMapMutator_SantasWorkshop.uc | 47 + .../Classes/KFMapObjective_ActivateTrigger.uc | 546 + .../Classes/KFMapObjective_AreaDefense.uc | 340 + .../Classes/KFMapObjective_CollectActors.uc | 1147 ++ .../Classes/KFMapObjective_DoshHold.uc | 575 + .../Classes/KFMapObjective_EscortPawns.uc | 658 + .../Classes/KFMapObjective_ExterminateWave.uc | 351 + .../Classes/KFMapObjective_HoldZone.uc | 359 + .../Classes/KFMapObjective_RepairActors.uc | 564 + .../KFMedicWeaponComponent_HRGIncision.uc | 35 + .../Classes/KFObjectiveCollectActor.uc | 288 + .../Classes/KFOutbreakEvent_Endless.uc | 274 + .../Classes/KFOutbreakEvent_Weekly.uc | 386 + .../Classes/KFPawnVoiceGroupEventData_Hans.uc | 64 + .../KFPawnVoiceGroupEventData_Matriarch.uc | 272 + .../KFPawnVoiceGroupEventData_Patriarch.uc | 74 + .../KFPawnVoiceGroupEventData_Player.uc | 269 + .../Classes/KFPawnVoiceGroup_Alberts.uc | 490 + KFGameContent/Classes/KFPawnVoiceGroup_Ana.uc | 490 + .../Classes/KFPawnVoiceGroup_BadAssSanta.uc | 489 + .../Classes/KFPawnVoiceGroup_Banner.uc | 490 + .../Classes/KFPawnVoiceGroup_Briar.uc | 489 + .../Classes/KFPawnVoiceGroup_Briar_Classic.uc | 489 + .../Classes/KFPawnVoiceGroup_Coleman.uc | 489 + KFGameContent/Classes/KFPawnVoiceGroup_DAR.uc | 488 + .../Classes/KFPawnVoiceGroup_DJSkully.uc | 489 + .../Classes/KFPawnVoiceGroup_Hans.uc | 85 + .../Classes/KFPawnVoiceGroup_Jaeger.uc | 489 + .../Classes/KFPawnVoiceGroup_Masterson.uc | 489 + .../KFPawnVoiceGroup_Masterson_Classic.uc | 489 + .../Classes/KFPawnVoiceGroup_Matriarch.uc | 98 + .../Classes/KFPawnVoiceGroup_MrFoster.uc | 488 + .../Classes/KFPawnVoiceGroup_Mrs_Foster.uc | 488 + .../Classes/KFPawnVoiceGroup_Patriarch.uc | 103 + KFGameContent/Classes/KFPawnVoiceGroup_Rae.uc | 489 + .../Classes/KFPawnVoiceGroup_Strasser.uc | 490 + .../Classes/KFPawnVoiceGroup_Tanaka.uc | 489 + KFGameContent/Classes/KFPawn_Human_Versus.uc | 54 + KFGameContent/Classes/KFPawn_ZedBloat.uc | 407 + KFGameContent/Classes/KFPawn_ZedBloatKing.uc | 777 + .../Classes/KFPawn_ZedBloatKingSubspawn.uc | 260 + .../KFPawn_ZedBloatKing_SantasWorkshop.uc | 17 + .../Classes/KFPawn_ZedBloat_Versus.uc | 119 + KFGameContent/Classes/KFPawn_ZedClot.uc | 105 + KFGameContent/Classes/KFPawn_ZedClot_Alpha.uc | 101 + .../Classes/KFPawn_ZedClot_AlphaKing.uc | 230 + .../KFPawn_ZedClot_AlphaKing_Versus.uc | 106 + .../Classes/KFPawn_ZedClot_Alpha_Versus.uc | 105 + KFGameContent/Classes/KFPawn_ZedClot_Cyst.uc | 93 + .../Classes/KFPawn_ZedClot_Slasher.uc | 91 + .../Classes/KFPawn_ZedClot_Slasher_Versus.uc | 132 + KFGameContent/Classes/KFPawn_ZedCrawler.uc | 467 + .../Classes/KFPawn_ZedCrawlerKing.uc | 123 + .../Classes/KFPawn_ZedCrawler_Versus.uc | 136 + KFGameContent/Classes/KFPawn_ZedDAR.uc | 434 + KFGameContent/Classes/KFPawn_ZedDAR_EMP.uc | 94 + KFGameContent/Classes/KFPawn_ZedDAR_Laser.uc | 42 + KFGameContent/Classes/KFPawn_ZedDAR_Rocket.uc | 42 + .../Classes/KFPawn_ZedFleshPound_Versus.uc | 184 + KFGameContent/Classes/KFPawn_ZedFleshpound.uc | 606 + .../Classes/KFPawn_ZedFleshpoundKing.uc | 973 ++ .../Classes/KFPawn_ZedFleshpoundMini.uc | 75 + .../Classes/KFPawn_ZedFleshpoundMini_Mixer.uc | 19 + .../Classes/KFPawn_ZedFleshpound_Mixer.uc | 19 + KFGameContent/Classes/KFPawn_ZedGorefast.uc | 131 + .../Classes/KFPawn_ZedGorefastDualBlade.uc | 108 + .../Classes/KFPawn_ZedGorefast_Versus.uc | 126 + KFGameContent/Classes/KFPawn_ZedHans.uc | 1663 +++ .../Classes/KFPawn_ZedHansFriendlyTest.uc | 33 + .../Classes/KFPawn_ZedHans_Versus.uc | 138 + KFGameContent/Classes/KFPawn_ZedHusk.uc | 660 + .../Classes/KFPawn_ZedHuskFriendlyTest.uc | 45 + .../Classes/KFPawn_ZedHusk_Versus.uc | 316 + KFGameContent/Classes/KFPawn_ZedMatriarch.uc | 2002 +++ KFGameContent/Classes/KFPawn_ZedPatriarch.uc | 2330 +++ .../Classes/KFPawn_ZedPatriarch_Versus.uc | 551 + KFGameContent/Classes/KFPawn_ZedScrake.uc | 394 + .../Classes/KFPawn_ZedScrake_Mixer.uc | 19 + .../Classes/KFPawn_ZedScrake_Versus.uc | 162 + KFGameContent/Classes/KFPawn_ZedSiren.uc | 253 + .../Classes/KFPawn_ZedSiren_Versus.uc | 117 + KFGameContent/Classes/KFPawn_ZedStalker.uc | 552 + .../Classes/KFPawn_ZedStalker_Versus.uc | 147 + KFGameContent/Classes/KFPhysicsVolume.uc | 76 + KFGameContent/Classes/KFPickupFactory_Ammo.uc | 103 + .../Classes/KFPickupFactory_ItemDefault.uc | 26 + .../Classes/KFPlayerCamera_Patriarch.uc | 6 + .../Classes/KFPlayerCamera_Versus.uc | 83 + .../Classes/KFPlayerControllerVersus.uc | 371 + .../Classes/KFPlayerZedSuicideCamera.uc | 137 + .../Classes/KFPlayerZedWaitingCamera.uc | 309 + .../Classes/KFProj_ArcGeneratorSphereBlast.uc | 585 + .../Classes/KFProj_Blade_Eviscerator.uc | 75 + .../Classes/KFProj_BloatKingPukeMine.uc | 65 + KFGameContent/Classes/KFProj_BloatPukeMine.uc | 635 + .../Classes/KFProj_Bolt_CompoundBowCryo.uc | 264 + .../Classes/KFProj_Bolt_CompoundBowSharp.uc | 144 + KFGameContent/Classes/KFProj_Bolt_Crossbow.uc | 57 + .../Classes/KFProj_BrokenFlare_HRGScorcher.uc | 263 + .../KFProj_BrokenFlare_HRGScorcherSplash.uc | 126 + .../Classes/KFProj_Bullet_AssaultRifle.uc | 23 + .../Classes/KFProj_Bullet_DragonsBreath.uc | 86 + KFGameContent/Classes/KFProj_Bullet_G18.uc | 22 + KFGameContent/Classes/KFProj_Bullet_G18c.uc | 22 + .../KFProj_Bullet_HRGIncendiaryRifle.uc | 14 + .../Classes/KFProj_Bullet_HRGIncisionHeal.uc | 13 + .../Classes/KFProj_Bullet_HRGIncisionHurt.uc | 13 + .../Classes/KFProj_Bullet_HRGTeslauncher.uc | 20 + .../Classes/KFProj_Bullet_Hemogoblin.uc | 23 + .../Classes/KFProj_Bullet_IncendiaryBullet.uc | 23 + .../Classes/KFProj_Bullet_LazerCutter.uc | 20 + KFGameContent/Classes/KFProj_Bullet_M14EBR.uc | 22 + KFGameContent/Classes/KFProj_Bullet_M99.uc | 21 + KFGameContent/Classes/KFProj_Bullet_Mac10.uc | 21 + .../KFProj_Bullet_MatriarchTeslaBlast.uc | 117 + .../Classes/KFProj_Bullet_MicrowaveRifle.uc | 23 + .../Classes/KFProj_Bullet_Minigun.uc | 37 + .../Classes/KFProj_Bullet_MosinNagant.uc | 22 + KFGameContent/Classes/KFProj_Bullet_Pellet.uc | 48 + .../Classes/KFProj_Bullet_Pistol50AE.uc | 23 + .../Classes/KFProj_Bullet_Pistol9mm.uc | 23 + .../Classes/KFProj_Bullet_PistolAF2011.uc | 22 + .../Classes/KFProj_Bullet_PistolColt1911.uc | 23 + .../Classes/KFProj_Bullet_PistolDeagle.uc | 23 + .../KFProj_Bullet_Pistol_ChiappaRhino.uc | 33 + ...Proj_Bullet_Pistol_ChiappaRhinoShrapnel.uc | 30 + .../Classes/KFProj_Bullet_RailGun.uc | 22 + .../Classes/KFProj_Bullet_RevolverRem1858.uc | 23 + .../Classes/KFProj_Bullet_RevolverSW500.uc | 23 + .../Classes/KFProj_Bullet_Winchester1894.uc | 22 + .../Classes/KFProj_Cannonball_Blunderbuss.uc | 465 + .../Classes/KFProj_CaulkNBurn_GroundFire.uc | 48 + .../Classes/KFProj_DragonsBreathSplash.uc | 25 + .../Classes/KFProj_DynamiteGrenade.uc | 176 + .../Classes/KFProj_DynamiteGrenade_Mini.uc | 78 + KFGameContent/Classes/KFProj_EMPGrenade.uc | 90 + .../Classes/KFProj_EMPGrenade_Mini.uc | 99 + KFGameContent/Classes/KFProj_EvilDAR_Laser.uc | 77 + .../Classes/KFProj_EvilDAR_Rocket.uc | 75 + .../Classes/KFProj_Explosive_HRGWinterbite.uc | 98 + .../KFProj_Explosive_HRG_Kaboomstick.uc | 167 + .../Classes/KFProj_Explosive_HX25.uc | 79 + .../Classes/KFProj_FlameThrower_GroundFire.uc | 48 + .../KFProj_Flame_HRGIncendiaryRifle.uc | 56 + KFGameContent/Classes/KFProj_FlareGun.uc | 122 + .../Classes/KFProj_FlareGunSplash.uc | 19 + .../Classes/KFProj_FlashBangGrenade.uc | 76 + .../Classes/KFProj_FlashBangGrenade_Mini.uc | 86 + KFGameContent/Classes/KFProj_FragGrenade.uc | 63 + .../Classes/KFProj_FragGrenade_Mini.uc | 91 + KFGameContent/Classes/KFProj_FreezeGrenade.uc | 91 + .../Classes/KFProj_FreezeGrenade_Mini.uc | 101 + .../Classes/KFProj_FreezeThrower_GroundIce.uc | 40 + .../Classes/KFProj_FreezeThrower_IceShards.uc | 29 + KFGameContent/Classes/KFProj_GrenadeShard.uc | 90 + .../KFProj_Grenade_HRGIncendiaryRifle.uc | 254 + .../Classes/KFProj_Grenade_HRGTeslauncher.uc | 212 + KFGameContent/Classes/KFProj_GroundFire.uc | 187 + KFGameContent/Classes/KFProj_GroundIce.uc | 155 + KFGameContent/Classes/KFProj_HEGrenade.uc | 61 + .../Classes/KFProj_HEGrenade_Mini.uc | 89 + KFGameContent/Classes/KFProj_HansHEGrenade.uc | 75 + .../Classes/KFProj_HansHEGrenade_Halloween.uc | 19 + .../Classes/KFProj_HansNerveGasGrenade.uc | 111 + .../KFProj_HansNerveGasGrenade_Halloween.uc | 14 + .../Classes/KFProj_HansSmokeGrenade.uc | 82 + .../KFProj_HansSmokeGrenade_Halloween.uc | 14 + .../Classes/KFProj_HealingDart_MedicBase.uc | 18 + .../Classes/KFProj_HighExplosive_M16M203.uc | 81 + .../Classes/KFProj_HighExplosive_M32.uc | 79 + .../Classes/KFProj_HighExplosive_M79.uc | 81 + .../Classes/KFProj_HuskCannon_Fireball.uc | 431 + .../Classes/KFProj_HuskGroundFire.uc | 23 + KFGameContent/Classes/KFProj_Husk_Fireball.uc | 223 + .../Classes/KFProj_Husk_Fireball_Versus.uc | 92 + .../KFProj_LightingFlare_HRGScorcher.uc | 282 + KFGameContent/Classes/KFProj_Mac10Splash.uc | 19 + KFGameContent/Classes/KFProj_MedicGrenade.uc | 108 + .../Classes/KFProj_MedicGrenade_Mini.uc | 114 + .../Classes/KFProj_MicrowaveGun_GroundFire.uc | 46 + .../Classes/KFProj_MicrowaveImpact.uc | 74 + .../Classes/KFProj_Mine_Reconstructor.uc | 947 ++ .../Classes/KFProj_Missile_Patriarch.uc | 368 + .../KFProj_Missile_Patriarch_Versus.uc | 19 + KFGameContent/Classes/KFProj_MolotovFlare.uc | 120 + .../Classes/KFProj_MolotovGrenade.uc | 206 + .../Classes/KFProj_MolotovGrenade_Mini.uc | 84 + KFGameContent/Classes/KFProj_MolotovSplash.uc | 199 + .../Classes/KFProj_Mortar_Patriarch.uc | 44 + .../Classes/KFProj_NailBombGrenade.uc | 69 + .../Classes/KFProj_NailBombGrenade_Mini.uc | 96 + KFGameContent/Classes/KFProj_NailShard.uc | 35 + .../Classes/KFProj_Nail_Blunderbuss.uc | 31 + .../Classes/KFProj_Nail_HRGNailgun.uc | 32 + KFGameContent/Classes/KFProj_Nail_Nailgun.uc | 142 + KFGameContent/Classes/KFProj_Rocket_RPG7.uc | 79 + .../Classes/KFProj_Rocket_SealSqueal.uc | 296 + .../Classes/KFProj_Rocket_Seeker6.uc | 124 + KFGameContent/Classes/KFProj_Thrown_C4.uc | 433 + KFGameContent/Classes/KFSM_AlphaRally.uc | 112 + .../Classes/KFSM_BloatKingSubspawn_Explode.uc | 63 + .../Classes/KFSM_BloatKing_Enrage.uc | 21 + KFGameContent/Classes/KFSM_BloatKing_Gorge.uc | 436 + KFGameContent/Classes/KFSM_DAR_EMPAttack.uc | 368 + KFGameContent/Classes/KFSM_DAR_LaserAttack.uc | 20 + .../Classes/KFSM_DAR_RocketAttack.uc | 20 + KFGameContent/Classes/KFSM_Emerge_Crawler.uc | 85 + KFGameContent/Classes/KFSM_Evade_Fear.uc | 26 + .../Classes/KFSM_FleshpoundKing_ChestBeam.uc | 361 + KFGameContent/Classes/KFSM_GorgeVictim.uc | 18 + .../Classes/KFSM_GrappleAttack_Hans.uc | 428 + .../Classes/KFSM_Hans_GrenadeBarrage.uc | 28 + .../Classes/KFSM_Hans_GrenadeHalfBarrage.uc | 28 + .../Classes/KFSM_Hans_ThrowGrenade.uc | 84 + .../Classes/KFSM_Hans_WeaponSwitch.uc | 66 + .../Classes/KFSM_Husk_FireBallAttack.uc | 96 + .../Classes/KFSM_Husk_FlameThrowerAttack.uc | 206 + KFGameContent/Classes/KFSM_Husk_Suicide.uc | 106 + .../Classes/KFSM_Matriarch_LightningStorm.uc | 143 + .../Classes/KFSM_Matriarch_MeleeAttack.uc | 40 + .../Classes/KFSM_Matriarch_PlasmaCannon.uc | 529 + .../Classes/KFSM_Matriarch_ScorpionWhip.uc | 56 + .../Classes/KFSM_Matriarch_SweepingClaw.uc | 35 + KFGameContent/Classes/KFSM_Matriarch_Taunt.uc | 61 + .../Classes/KFSM_Matriarch_TeslaBlast.uc | 165 + .../Classes/KFSM_Matriarch_WarningSiren.uc | 106 + KFGameContent/Classes/KFSM_Patriarch_Heal.uc | 111 + .../Classes/KFSM_Patriarch_MinigunBarrage.uc | 449 + .../Classes/KFSM_Patriarch_MissileAttack.uc | 318 + .../Classes/KFSM_Patriarch_MortarAttack.uc | 194 + KFGameContent/Classes/KFSM_Patriarch_Taunt.uc | 58 + .../Classes/KFSM_PlayerAlpha_Grab.uc | 63 + .../Classes/KFSM_PlayerAlpha_Melee.uc | 17 + .../Classes/KFSM_PlayerAlpha_Rally.uc | 26 + .../Classes/KFSM_PlayerBloat_Block.uc | 26 + .../Classes/KFSM_PlayerBloat_Melee.uc | 17 + .../Classes/KFSM_PlayerBloat_Melee2.uc | 18 + .../KFSM_PlayerBloat_PukeMineAttack.uc | 24 + .../Classes/KFSM_PlayerCrawler_Melee.uc | 17 + .../Classes/KFSM_PlayerCrawler_Melee2.uc | 16 + .../Classes/KFSM_PlayerCrawler_Suicide.uc | 169 + .../Classes/KFSM_PlayerFleshpound_Block.uc | 26 + .../Classes/KFSM_PlayerFleshpound_Melee.uc | 39 + .../Classes/KFSM_PlayerFleshpound_Melee2.uc | 23 + .../Classes/KFSM_PlayerFleshpound_Rage.uc | 61 + .../Classes/KFSM_PlayerGorefast_Block.uc | 26 + .../Classes/KFSM_PlayerGorefast_Melee.uc | 17 + .../Classes/KFSM_PlayerGorefast_Melee2.uc | 16 + .../Classes/KFSM_PlayerGorefast_Melee3.uc | 15 + .../Classes/KFSM_PlayerHusk_FireBallAttack.uc | 198 + .../KFSM_PlayerHusk_FlameThrowerAttack.uc | 90 + .../Classes/KFSM_PlayerHusk_Melee.uc | 17 + .../Classes/KFSM_PlayerHusk_Suicide.uc | 65 + .../Classes/KFSM_PlayerPatriarch_Heal.uc | 76 + .../Classes/KFSM_PlayerPatriarch_Melee.uc | 21 + .../KFSM_PlayerPatriarch_MinigunBarrage.uc | 124 + .../KFSM_PlayerPatriarch_MissileAttack.uc | 27 + .../KFSM_PlayerPatriarch_MortarAttack.uc | 36 + .../KFSM_PlayerPatriarch_TentacleGrab.uc | 131 + .../Classes/KFSM_PlayerScrake_Block.uc | 26 + .../Classes/KFSM_PlayerScrake_Melee.uc | 37 + .../Classes/KFSM_PlayerScrake_Melee2.uc | 24 + .../Classes/KFSM_PlayerScrake_Melee3.uc | 21 + .../Classes/KFSM_PlayerSiren_Melee.uc | 17 + .../Classes/KFSM_PlayerSiren_NormalScream.uc | 36 + .../Classes/KFSM_PlayerSiren_VortexScream.uc | 529 + .../Classes/KFSM_PlayerSiren_VortexVictim.uc | 69 + .../Classes/KFSM_PlayerSlasher_Melee.uc | 17 + .../Classes/KFSM_PlayerSlasher_Melee2.uc | 16 + .../Classes/KFSM_PlayerSlasher_Roll.uc | 67 + .../Classes/KFSM_PlayerStalker_Melee.uc | 19 + .../Classes/KFSM_PlayerStalker_Melee2.uc | 19 + .../Classes/KFSM_PlayerStalker_Roll.uc | 49 + .../Classes/KFSM_PlayerZedBlockBase.uc | 99 + KFGameContent/Classes/KFSM_ScreamBase.uc | 270 + KFGameContent/Classes/KFSM_Siren_Scream.uc | 128 + .../Classes/KFSeasonalEventStats_Fall2019.uc | 110 + .../Classes/KFSeasonalEventStats_Fall2020.uc | 132 + .../KFSeasonalEventStats_Spring2019.uc | 105 + .../KFSeasonalEventStats_Spring2020.uc | 118 + .../KFSeasonalEventStats_Summer2019.uc | 106 + .../KFSeasonalEventStats_Summer2020.uc | 147 + .../Classes/KFSeasonalEventStats_Xmas2018.uc | 126 + .../Classes/KFSeasonalEventStats_Xmas2019.uc | 113 + KFGameContent/Classes/KFSeqAct_BloodRain.uc | 72 + .../KFSeqAct_DamageDestructibleActor.uc | 48 + .../KFSeqAct_MinigameActivateGenerator.uc | 42 + .../Classes/KFSeqAct_SetScriptedPawnSpeed.uc | 40 + .../Classes/KFSeqAct_StartObjectiveWave.uc | 27 + .../Classes/KFSeqAct_TriggerMapObjective.uc | 46 + .../KFSeqEvent_CollectActorsProgress.uc | 16 + .../KFSeqEvent_EscortPawnsCompletionPct.uc | 16 + .../KFSeqEvent_EscortPawnsHealthPct.uc | 17 + .../KFSeqEvent_ExterminateBossHealthPct.uc | 17 + .../Classes/KFSeqEvent_ExterminateWavePct.uc | 16 + .../Classes/KFSeqEvent_HoldZoneProgress.uc | 26 + .../KFSeqEvent_MinigameEndCondition.uc | 54 + ...FSeqEvent_MinigameGeneratorStateChanged.uc | 49 + .../KFSeqEvent_RepairActorsProgress.uc | 16 + ...KFSkinTypeEffects_InvulnerabilityShield.uc | 42 + .../Classes/KFSprayActor_ArcGenerator.uc | 746 + .../Classes/KFStaticMeshActor_TrackLocalPC.uc | 33 + .../KFTargetingWeaponComponent_HRGIncision.uc | 101 + .../KFTargetingWeaponComponent_RailGun.uc | 35 + KFGameContent/Classes/KFTeamInfo_Zeds.uc | 22 + .../Classes/KFThirdPersonCamera_Versus.uc | 7 + .../Classes/KFTraderVoiceGroup_Default.uc | 165 + .../Classes/KFTraderVoiceGroup_Hans.uc | 294 + .../Classes/KFTraderVoiceGroup_Lockheart.uc | 286 + .../Classes/KFTraderVoiceGroup_Objective.uc | 165 + .../Classes/KFTraderVoiceGroup_Patriarch.uc | 286 + .../Classes/KFTraderVoiceGroup_Santa.uc | 285 + .../Classes/KFTrigger_BloatKingGorge.uc | 36 + .../Classes/KFTrigger_MinigameGenerator.uc | 517 + .../Classes/KFTrigger_ObjectiveLever.uc | 82 + .../KFTrigger_SirenProjectileShield.uc | 48 + .../Classes/KFTutorialSectionInfo.uc | 134 + KFGameContent/Classes/KFVolume_CameraFade.uc | 50 + .../Classes/KFVolume_DamageAdjust.uc | 47 + .../Classes/KFVolume_DisableZedJump.uc | 34 + .../Classes/KFVolume_RagdollThrow.uc | 140 + .../Classes/KFWeapActor_Hemogoblin_Tube.uc | 98 + .../Classes/KFWeapAttach_ArcGenerator.uc | 23 + .../Classes/KFWeapAttach_CompoundBow.uc | 402 + KFGameContent/Classes/KFWeapAttach_Dual_C4.uc | 88 + .../Classes/KFWeapAttach_Eviscerator.uc | 53 + .../Classes/KFWeapAttach_Flamethrower.uc | 171 + KFGameContent/Classes/KFWeapAttach_G18.uc | 15 + .../Classes/KFWeapAttach_HuskCannon.uc | 156 + .../Classes/KFWeapAttach_IonThruster.uc | 44 + .../Classes/KFWeapAttach_LazerCutter.uc | 409 + KFGameContent/Classes/KFWeapAttach_M99.uc | 49 + .../Classes/KFWeapAttach_MaceAndShield.uc | 18 + .../KFWeapAttach_Mine_Reconstructor.uc | 126 + .../Classes/KFWeapAttach_MultiAmmo.uc | 71 + .../Classes/KFWeapAttach_PowerGloves.uc | 17 + .../Classes/KFWeapAttach_Pulverizer.uc | 84 + KFGameContent/Classes/KFWeapAttach_Railgun.uc | 111 + .../Classes/KFWeapDef_HRGTeslauncher.uc | 30 + KFGameContent/Classes/KFWeapDef_Medic32.uc | 21 + .../Classes/KFWeap_AssaultRifle_AK12.uc | 293 + .../Classes/KFWeap_AssaultRifle_AR15.uc | 119 + .../Classes/KFWeap_AssaultRifle_Bullpup.uc | 122 + .../KFWeap_AssaultRifle_DualMKb42_Hans.uc | 137 + ...AssaultRifle_DualMKb42_HansFriendlyTest.uc | 26 + .../Classes/KFWeap_AssaultRifle_FNFal.uc | 151 + .../KFWeap_AssaultRifle_HRGIncendiaryRifle.uc | 133 + .../KFWeap_AssaultRifle_HRGTeslauncher.uc | 294 + .../KFWeap_AssaultRifle_LazerCutter.uc | 1198 ++ .../Classes/KFWeap_AssaultRifle_M16M203.uc | 660 + .../Classes/KFWeap_AssaultRifle_MKB42.uc | 297 + .../Classes/KFWeap_AssaultRifle_Medic.uc | 139 + ..._AssaultRifle_MedicRifleGrenadeLauncher.uc | 620 + .../Classes/KFWeap_AssaultRifle_Microwave.uc | 165 + .../Classes/KFWeap_AssaultRifle_SCAR.uc | 115 + .../Classes/KFWeap_AssaultRifle_Thompson.uc | 126 + KFGameContent/Classes/KFWeap_AssetDummy.uc | 37 + .../Classes/KFWeap_Beam_Microwave.uc | 296 + .../Classes/KFWeap_Blunt_ChainBat.uc | 80 + KFGameContent/Classes/KFWeap_Blunt_Crovel.uc | 80 + .../Classes/KFWeap_Blunt_MaceAndShield.uc | 222 + .../Classes/KFWeap_Blunt_MedicBat.uc | 797 ++ .../Classes/KFWeap_Blunt_PowerGloves.uc | 82 + .../Classes/KFWeap_Blunt_Pulverizer.uc | 508 + .../Classes/KFWeap_Bow_CompoundBow.uc | 818 ++ KFGameContent/Classes/KFWeap_Bow_Crossbow.uc | 154 + .../Classes/KFWeap_Edged_AbominationAxe.uc | 77 + KFGameContent/Classes/KFWeap_Edged_FireAxe.uc | 78 + .../Classes/KFWeap_Edged_IonThruster.uc | 635 + KFGameContent/Classes/KFWeap_Edged_Katana.uc | 80 + KFGameContent/Classes/KFWeap_Edged_Knife.uc | 73 + .../Classes/KFWeap_Edged_Zweihander.uc | 82 + KFGameContent/Classes/KFWeap_Eviscerator.uc | 490 + .../Classes/KFWeap_Flame_CaulkBurn.uc | 233 + .../Classes/KFWeap_Flame_Flamethrower.uc | 310 + .../Classes/KFWeap_GrenadeLauncher_HX25.uc | 203 + .../Classes/KFWeap_GrenadeLauncher_M32.uc | 244 + .../Classes/KFWeap_GrenadeLauncher_M79.uc | 113 + .../Classes/KFWeap_HRG_EMP_ArcGenerator.uc | 864 ++ .../Classes/KFWeap_HRG_Healthrower.uc | 1104 ++ KFGameContent/Classes/KFWeap_HRG_Nailgun.uc | 206 + .../Classes/KFWeap_HRG_Revolver_Buckshot.uc | 116 + .../KFWeap_HRG_Revolver_DualBuckshot.uc | 161 + .../Classes/KFWeap_Healer_Syringe.uc | 54 + KFGameContent/Classes/KFWeap_HuskCannon.uc | 530 + .../Classes/KFWeap_Ice_FreezeThrower.uc | 291 + .../Classes/KFWeap_Knife_Berserker.uc | 31 + .../Classes/KFWeap_Knife_Commando.uc | 32 + .../Classes/KFWeap_Knife_Demolitionist.uc | 30 + .../Classes/KFWeap_Knife_FieldMedic.uc | 34 + KFGameContent/Classes/KFWeap_Knife_Firebug.uc | 30 + .../Classes/KFWeap_Knife_Gunslinger.uc | 30 + KFGameContent/Classes/KFWeap_Knife_SWAT.uc | 34 + .../Classes/KFWeap_Knife_Sharpshooter.uc | 30 + KFGameContent/Classes/KFWeap_Knife_Support.uc | 30 + .../Classes/KFWeap_Knife_Survivalist.uc | 31 + KFGameContent/Classes/KFWeap_LMG_Stoner63A.uc | 287 + .../Classes/KFWeap_Mine_Reconstructor.uc | 929 ++ KFGameContent/Classes/KFWeap_Minigun.uc | 313 + .../Classes/KFWeap_Minigun_Patriarch.uc | 159 + .../KFWeap_Minigun_Patriarch_Versus.uc | 23 + KFGameContent/Classes/KFWeap_Pistol_9mm.uc | 119 + KFGameContent/Classes/KFWeap_Pistol_AF2011.uc | 129 + .../Classes/KFWeap_Pistol_Blunderbuss.uc | 583 + .../Classes/KFWeap_Pistol_ChiappaRhino.uc | 110 + .../Classes/KFWeap_Pistol_ChiappaRhinoDual.uc | 120 + .../Classes/KFWeap_Pistol_Colt1911.uc | 116 + KFGameContent/Classes/KFWeap_Pistol_Deagle.uc | 115 + .../Classes/KFWeap_Pistol_Dual9mm.uc | 132 + .../Classes/KFWeap_Pistol_DualAF2011.uc | 204 + .../Classes/KFWeap_Pistol_DualColt1911.uc | 129 + .../Classes/KFWeap_Pistol_DualDeagle.uc | 125 + .../Classes/KFWeap_Pistol_DualFlare.uc | 136 + .../Classes/KFWeap_Pistol_DualG18.uc | 321 + .../KFWeap_Pistol_DualHRGWinterbite.uc | 131 + KFGameContent/Classes/KFWeap_Pistol_Dummy.uc | 26 + KFGameContent/Classes/KFWeap_Pistol_Flare.uc | 122 + KFGameContent/Classes/KFWeap_Pistol_G18C.uc | 252 + .../Classes/KFWeap_Pistol_HRGScorcher.uc | 147 + .../Classes/KFWeap_Pistol_HRGWinterbite.uc | 116 + KFGameContent/Classes/KFWeap_Pistol_Medic.uc | 138 + .../Classes/KFWeap_PowerClaw_Matriarch.uc | 215 + KFGameContent/Classes/KFWeap_Random.uc | 17 + .../Classes/KFWeap_Revolver_DualRem1858.uc | 339 + .../Classes/KFWeap_Revolver_DualSW500.uc | 299 + .../Classes/KFWeap_Revolver_Rem1858.uc | 231 + .../Classes/KFWeap_Revolver_SW500.uc | 209 + .../Classes/KFWeap_Rifle_CenterfireMB464.uc | 114 + .../Classes/KFWeap_Rifle_HRGIncision.uc | 216 + .../Classes/KFWeap_Rifle_Hemogoblin.uc | 157 + KFGameContent/Classes/KFWeap_Rifle_M14EBR.uc | 124 + KFGameContent/Classes/KFWeap_Rifle_M99.uc | 121 + .../Classes/KFWeap_Rifle_MosinNagant.uc | 300 + KFGameContent/Classes/KFWeap_Rifle_RailGun.uc | 604 + .../Classes/KFWeap_Rifle_Winchester1894.uc | 117 + .../Classes/KFWeap_RocketLauncher_RPG7.uc | 213 + .../KFWeap_RocketLauncher_SealSqueal.uc | 336 + .../Classes/KFWeap_RocketLauncher_Seeker6.uc | 661 + KFGameContent/Classes/KFWeap_SMG_G18.uc | 424 + KFGameContent/Classes/KFWeap_SMG_HK_UMP.uc | 305 + KFGameContent/Classes/KFWeap_SMG_Kriss.uc | 109 + KFGameContent/Classes/KFWeap_SMG_MP5RAS.uc | 114 + KFGameContent/Classes/KFWeap_SMG_MP7.uc | 115 + KFGameContent/Classes/KFWeap_SMG_Mac10.uc | 124 + KFGameContent/Classes/KFWeap_SMG_Medic.uc | 133 + KFGameContent/Classes/KFWeap_SMG_P90.uc | 111 + KFGameContent/Classes/KFWeap_Shotgun_AA12.uc | 124 + .../Classes/KFWeap_Shotgun_DoubleBarrel.uc | 267 + .../Classes/KFWeap_Shotgun_DragonsBreath.uc | 121 + .../Classes/KFWeap_Shotgun_ElephantGun.uc | 260 + .../Classes/KFWeap_Shotgun_HRG_Kaboomstick.uc | 129 + KFGameContent/Classes/KFWeap_Shotgun_HZ12.uc | 215 + KFGameContent/Classes/KFWeap_Shotgun_M4.uc | 110 + KFGameContent/Classes/KFWeap_Shotgun_MB500.uc | 112 + KFGameContent/Classes/KFWeap_Shotgun_Medic.uc | 169 + .../Classes/KFWeap_Shotgun_Nailgun.uc | 212 + KFGameContent/Classes/KFWeap_Thrown_C4.uc | 493 + KFGameContent/Classes/KFWeap_Welder.uc | 788 ++ .../Classes/KFZedArmorInfo_BloatKing.uc | 91 + .../Classes/KFZedArmorInfo_ClotKing.uc | 70 + .../Classes/KFZedArmorInfo_EvilDAR.uc | 85 + .../Classes/KFZedArmorInfo_Matriarch.uc | 74 + KFGameContent/Classes/SprayActor_Flame.uc | 676 + KFGameContent/Classes/SprayActor_Heal.uc | 105 + .../DownloadableContentEnumeratorDingo.uc | 52 + .../Classes/KFOnlineLobbyDingo.uc | 71 + .../OnlineCommunityContentInterfaceDingo.uc | 286 + .../Classes/OnlineContentInterfaceDingo.uc | 769 + .../Classes/OnlineGameDVRInterfaceDingo.uc | 184 + .../Classes/OnlineGameInterfaceDingo.uc | 1321 ++ .../OnlineMarketplaceInterfaceDingo.uc | 354 + .../Classes/OnlineStatsInterfaceDingo.uc | 382 + .../Classes/OnlineSubsystemDingo.uc | 3255 +++++ .../Classes/OnlineTitleFileInterfaceDingo.uc | 147 + .../Classes/KFOnlineLobbySteamworks.uc | 711 + .../Classes/KFWorkshopSteamworks.uc | 101 + .../Classes/OnlineAuthInterfaceSteamworks.uc | 118 + .../Classes/OnlineGameInterfaceSteamworks.uc | 462 + .../Classes/OnlineLobbyInterfaceSteamworks.uc | 901 ++ .../Classes/OnlineSubsystemSteamworks.uc | 4610 ++++++ OnlineSubsystemSteamworks/Globals.uci | 10 + .../Classes/InterpTrackInstSubstanceInput.uc | 18 + .../Classes/InterpTrackSubstanceInput.uc | 29 + .../Classes/SeqAct_SubstanceRender.uc | 22 + .../Classes/SeqAct_SubstanceSetInputFloat.uc | 24 + .../Classes/SeqAct_SubstanceSetInputImg.uc | 24 + .../Classes/SeqAct_SubstanceSetInputInt.uc | 24 + .../Classes/SubstanceAirGraphActor.uc | 33 + .../Classes/SubstanceAirGraphInstance.uc | 61 + .../Classes/SubstanceAirImageInput.uc | 42 + .../Classes/SubstanceAirInstanceFactory.uc | 26 + SubstanceAir/Classes/SubstanceAirTexture2D.uc | 38 + ...icBrowserType_SubstanceAirGraphInstance.uc | 24 + ...nericBrowserType_SubstanceAirImageInput.uc | 22 + ...BrowserType_SubstanceAirInstanceFactory.uc | 27 + ...enericBrowserType_SubstanceAirTexture2D.uc | 23 + .../Classes/ImageInputThumbnailRenderer.uc | 18 + UDKBase/classes/CastleGame.uc | 42 + UDKBase/classes/CastlePC.uc | 989 ++ UDKBase/classes/CloudGame.uc | 10 + UDKBase/classes/CloudHUD.uc | 62 + UDKBase/classes/CloudMenuMicroTrans.uc | 175 + UDKBase/classes/CloudPC.uc | 524 + UDKBase/classes/CloudSaveData.uc | 9 + UDKBase/classes/MobileGameCrowdAgent.uc | 52 + UDKBase/classes/MobileHUDExt.uc | 381 + UDKBase/classes/MobileMenuBase.uc | 62 + UDKBase/classes/MobileMenuControls.uc | 158 + UDKBase/classes/MobileMenuDebug.uc | 92 + UDKBase/classes/MobileMenuPause.uc | 335 + UDKBase/classes/MobileMenuSplash.uc | 103 + UDKBase/classes/MobilePlaceablePawn.uc | 124 + UDKBase/classes/MobileProjectile.uc | 310 + UDKBase/classes/ParticleModuleTypeDataSnow.uc | 60 + UDKBase/classes/SeqAct_MobileCrowdSpawner.uc | 11 + UDKBase/classes/SimpleGame.uc | 96 + UDKBase/classes/SimplePC.uc | 647 + UDKBase/classes/SimplePawn.uc | 205 + UDKBase/classes/UDKAIDecisionComponent.uc | 23 + UDKBase/classes/UDKAnimBlendBase.uc | 35 + UDKBase/classes/UDKAnimBlendByDriving.uc | 21 + UDKBase/classes/UDKAnimBlendByFall.uc | 80 + UDKBase/classes/UDKAnimBlendByFlying.uc | 58 + UDKBase/classes/UDKAnimBlendByHoverJump.uc | 20 + .../classes/UDKAnimBlendByHoverboardTilt.uc | 39 + .../classes/UDKAnimBlendByHoverboardTurn.uc | 26 + .../classes/UDKAnimBlendByHoverboarding.uc | 44 + UDKBase/classes/UDKAnimBlendByIdle.uc | 18 + UDKBase/classes/UDKAnimBlendByPhysics.uc | 45 + .../classes/UDKAnimBlendByPhysicsVolume.uc | 64 + UDKBase/classes/UDKAnimBlendByPosture.uc | 18 + UDKBase/classes/UDKAnimBlendBySlotActive.uc | 22 + UDKBase/classes/UDKAnimBlendBySpeed.uc | 26 + UDKBase/classes/UDKAnimBlendByTurnInPlace.uc | 23 + UDKBase/classes/UDKAnimBlendByVehicle.uc | 25 + UDKBase/classes/UDKAnimBlendByWeapType.uc | 18 + UDKBase/classes/UDKAnimBlendByWeapon.uc | 81 + .../classes/UDKAnimNodeCopyBoneTranslation.uc | 52 + UDKBase/classes/UDKAnimNodeFramePlayer.uc | 13 + UDKBase/classes/UDKAnimNodeJumpLeanOffset.uc | 52 + UDKBase/classes/UDKAnimNodeSeqWeap.uc | 21 + UDKBase/classes/UDKAnimNodeSequence.uc | 37 + .../UDKAnimNodeSequenceByBoneRotation.uc | 67 + UDKBase/classes/UDKBot.uc | 322 + UDKBase/classes/UDKCarriedObject.uc | 82 + .../classes/UDKDataStore_GameSearchBase.uc | 120 + UDKBase/classes/UDKEmitCameraEffect.uc | 62 + UDKBase/classes/UDKEmitterPool.uc | 121 + UDKBase/classes/UDKExplosionLight.uc | 58 + UDKBase/classes/UDKForcedDirectionVolume.uc | 138 + UDKBase/classes/UDKGame.uc | 16 + UDKBase/classes/UDKGameInteraction.uc | 95 + UDKBase/classes/UDKGameObjective.uc | 87 + UDKBase/classes/UDKGameSettingsCommon.uc | 26 + UDKBase/classes/UDKGameViewportClient.uc | 24 + UDKBase/classes/UDKHUD.uc | 65 + UDKBase/classes/UDKJumpPad.uc | 143 + UDKBase/classes/UDKJumpPadReachspec.uc | 12 + UDKBase/classes/UDKKActorBreakable.uc | 121 + UDKBase/classes/UDKMapInfo.uc | 14 + UDKBase/classes/UDKMapMusicInfo.uc | 89 + UDKBase/classes/UDKMobileInputZone.uc | 186 + UDKBase/classes/UDKParticleSystemComponent.uc | 34 + UDKBase/classes/UDKPawn.uc | 542 + UDKBase/classes/UDKPickupFactory.uc | 119 + UDKBase/classes/UDKPlayerController.uc | 141 + UDKBase/classes/UDKPlayerInput.uc | 11 + UDKBase/classes/UDKProfileSettings.uc | 26 + UDKBase/classes/UDKProjectile.uc | 87 + UDKBase/classes/UDKScout.uc | 52 + UDKBase/classes/UDKScriptedNavigationPoint.uc | 42 + .../classes/UDKSkelControl_CantileverBeam.uc | 40 + UDKBase/classes/UDKSkelControl_Damage.uc | 155 + UDKBase/classes/UDKSkelControl_DamageHinge.uc | 40 + .../classes/UDKSkelControl_DamageSpring.uc | 54 + .../UDKSkelControl_HoverboardSuspension.uc | 39 + .../classes/UDKSkelControl_HoverboardSwing.uc | 32 + .../UDKSkelControl_HoverboardVibration.uc | 30 + UDKBase/classes/UDKSkelControl_HugGround.uc | 43 + .../classes/UDKSkelControl_LockRotation.uc | 34 + UDKBase/classes/UDKSkelControl_LookAt.uc | 36 + .../classes/UDKSkelControl_MassBoneScaling.uc | 29 + .../classes/UDKSkelControl_PropellerBlade.uc | 28 + UDKBase/classes/UDKSkelControl_Rotate.uc | 26 + UDKBase/classes/UDKSkelControl_SpinControl.uc | 27 + .../UDKSkelControl_TurretConstrained.uc | 89 + UDKBase/classes/UDKSkelControl_VehicleFlap.uc | 39 + UDKBase/classes/UDKSkeletalMeshComponent.uc | 49 + UDKBase/classes/UDKSquadAI.uc | 41 + UDKBase/classes/UDKTeamOwnedInfo.uc | 10 + UDKBase/classes/UDKTeamPlayerStart.uc | 20 + UDKBase/classes/UDKTeleporterBase.uc | 123 + UDKBase/classes/UDKTrajectoryReachspec.uc | 18 + UDKBase/classes/UDKUIDataProvider_MapInfo.uc | 28 + .../classes/UDKUIDataProvider_MenuOption.uc | 58 + .../classes/UDKUIDataProvider_SearchResult.uc | 37 + .../UDKUIDataProvider_ServerDetails.uc | 23 + ...UDKUIDataProvider_SimpleElementProvider.uc | 7 + .../classes/UDKUIDataProvider_StringArray.uc | 10 + UDKBase/classes/UDKUIDataStore_MenuItems.uc | 93 + UDKBase/classes/UDKUIDataStore_Options.uc | 33 + .../UDKUIDataStore_StringAliasBindingMap.uc | 69 + .../classes/UDKUIDataStore_StringAliasMap.uc | 19 + UDKBase/classes/UDKUIDataStore_StringList.uc | 203 + UDKBase/classes/UDKUIResourceDataProvider.uc | 55 + UDKBase/classes/UDKVehicle.uc | 748 + UDKBase/classes/UDKVehicleBase.uc | 310 + UDKBase/classes/UDKVehicleFactory.uc | 61 + UDKBase/classes/UDKVehicleMovementEffect.uc | 52 + UDKBase/classes/UDKVehicleSimCar.uc | 109 + UDKBase/classes/UDKVehicleSimChopper.uc | 96 + UDKBase/classes/UDKVehicleSimHover.uc | 30 + UDKBase/classes/UDKVehicleSimHoverboard.uc | 74 + UDKBase/classes/UDKVehicleWheel.uc | 75 + UDKBase/classes/UDKWeapon.uc | 75 + UDKBase/classes/UDKWeaponPawn.uc | 37 + UDKBase/classes/UDKWeaponShield.uc | 26 + UnrealEd/Classes/ASVSkelComponent.uc | 62 + UnrealEd/Classes/AnimNodeEditInfo.uc | 24 + .../Classes/AnimNodeEditInfo_AimOffset.uc | 28 + UnrealEd/Classes/AnimSetLabelRenderer.uc | 19 + UnrealEd/Classes/AnimTreeEdSkelComponent.uc | 16 + UnrealEd/Classes/AnimTreeLabelRenderer.uc | 19 + .../Classes/ApexClothingAssetLabelRenderer.uc | 19 + .../ApexDestructibleAssetLabelRenderer.uc | 19 + .../ApexDestructibleAssetThumbnailRenderer.uc | 31 + .../Classes/ApexGenericAssetLabelRenderer.uc | 19 + .../Classes/ArchetypeThumbnailRenderer.uc | 25 + UnrealEd/Classes/BasicStatsVisualizer.uc | 146 + UnrealEd/Classes/BrowserManager.uc | 104 + UnrealEd/Classes/BrushBuilder.uc | 69 + UnrealEd/Classes/CascadeConfiguration.uc | 33 + UnrealEd/Classes/CascadeOptions.uc | 86 + .../Classes/CascadeParticleSystemComponent.uc | 22 + UnrealEd/Classes/CascadePreviewComponent.uc | 16 + UnrealEd/Classes/ConeBuilder.uc | 82 + UnrealEd/Classes/ConvertMapToNavMesh.uc | 16 + UnrealEd/Classes/CubeBuilder.uc | 86 + UnrealEd/Classes/CurveEdOptions.uc | 27 + UnrealEd/Classes/CurveEdPresetBase.uc | 72 + UnrealEd/Classes/CurveEdPreset_CosWave.uc | 127 + UnrealEd/Classes/CurveEdPreset_LinearDecay.uc | 141 + UnrealEd/Classes/CurveEdPreset_Nothing.uc | 27 + UnrealEd/Classes/CurveEdPreset_SineWave.uc | 127 + UnrealEd/Classes/CurveEdPreset_UserSet.uc | 145 + UnrealEd/Classes/CurvedStairBuilder.uc | 127 + .../Classes/CustomPropertyItemBindings.uc | 233 + UnrealEd/Classes/CylinderBuilder.uc | 84 + UnrealEd/Classes/DEditorFontParameterValue.uc | 13 + UnrealEd/Classes/DEditorParameterValue.uc | 14 + .../Classes/DEditorScalarParameterValue.uc | 17 + ...EditorStaticComponentMaskParameterValue.uc | 46 + .../DEditorStaticSwitchParameterValue.uc | 23 + .../Classes/DEditorTextureParameterValue.uc | 11 + .../Classes/DEditorVectorParameterValue.uc | 12 + .../Classes/DefaultSizedThumbnailRenderer.uc | 34 + UnrealEd/Classes/EdModeComponent.uc | 14 + UnrealEd/Classes/EditorComponent.uc | 49 + UnrealEd/Classes/EditorEngine.uc | 284 + UnrealEd/Classes/EditorUserSettings.uc | 105 + UnrealEd/Classes/EditorViewportInput.uc | 17 + UnrealEd/Classes/FaceFXStudioSkelComponent.uc | 13 + UnrealEd/Classes/FbxImportUI.uc | 89 + .../FindUnreferencedFunctionsCommandlet.uc | 40 + .../Classes/FontThumbnailLabelRenderer.uc | 20 + UnrealEd/Classes/FontThumbnailRenderer.uc | 43 + .../FracturedStaticMeshLabelRenderer.uc | 19 + UnrealEd/Classes/GameStatsDatabase.uc | 411 + UnrealEd/Classes/GameStatsDatabaseVisitor.uc | 62 + UnrealEd/Classes/GameStatsFileReader.uc | 56 + UnrealEd/Classes/GameStatsReport.uc | 271 + UnrealEd/Classes/GameStatsVisitorImpl.uc | 61 + UnrealEd/Classes/GameStatsVisualizer.uc | 97 + UnrealEd/Classes/GenericBrowserType.uc | 316 + UnrealEd/Classes/GenericBrowserType_AkBank.uc | 22 + .../Classes/GenericBrowserType_AkEvent.uc | 22 + UnrealEd/Classes/GenericBrowserType_All.uc | 20 + .../Classes/GenericBrowserType_AnimTree.uc | 29 + .../Classes/GenericBrowserType_Animation.uc | 29 + .../GenericBrowserType_ApexClothingAsset.uc | 20 + ...enericBrowserType_ApexDestructibleAsset.uc | 20 + ...erType_ApexDestructibleDamageParameters.uc | 14 + .../GenericBrowserType_ApexGenericAsset.uc | 26 + .../Classes/GenericBrowserType_Archetype.uc | 45 + .../Classes/GenericBrowserType_CameraAnim.uc | 29 + .../GenericBrowserType_CurveEdPresetCurve.uc | 20 + UnrealEd/Classes/GenericBrowserType_Custom.uc | 71 + .../GenericBrowserType_DecalMaterial.uc | 28 + .../GenericBrowserType_FaceFXAnimSet.uc | 31 + .../Classes/GenericBrowserType_FaceFXAsset.uc | 33 + .../GenericBrowserType_FlexContainer.uc | 20 + UnrealEd/Classes/GenericBrowserType_Font.uc | 45 + .../GenericBrowserType_FractureMaterial.uc | 17 + .../GenericBrowserType_FracturedStaticMesh.uc | 30 + ...ricBrowserType_InstancedFoliageSettings.uc | 20 + .../GenericBrowserType_LandscapeLayer.uc | 20 + .../Classes/GenericBrowserType_LensFlare.uc | 29 + .../Classes/GenericBrowserType_Material.uc | 38 + .../GenericBrowserType_MaterialFunction.uc | 38 + ...ricBrowserType_MaterialInstanceConstant.uc | 31 + ...BrowserType_MaterialInstanceTimeVarying.uc | 31 + .../GenericBrowserType_MorphTargetSet.uc | 27 + .../GenericBrowserType_MorphWeightSequence.uc | 19 + .../GenericBrowserType_ParticleSystem.uc | 31 + .../GenericBrowserType_PhysXParticleSystem.uc | 19 + .../GenericBrowserType_PhysicalMaterial.uc | 21 + .../GenericBrowserType_PhysicsAsset.uc | 29 + .../Classes/GenericBrowserType_PostProcess.uc | 29 + UnrealEd/Classes/GenericBrowserType_Prefab.uc | 19 + .../GenericBrowserType_ProcBuildingRuleset.uc | 22 + .../GenericBrowserType_RenderTexture.uc | 30 + .../Classes/GenericBrowserType_Sequence.uc | 29 + .../GenericBrowserType_SkeletalMesh.uc | 31 + .../Classes/GenericBrowserType_SoundClass.uc | 22 + .../Classes/GenericBrowserType_SoundCue.uc | 29 + .../Classes/GenericBrowserType_SoundMode.uc | 22 + .../Classes/GenericBrowserType_SoundWave.uc | 29 + UnrealEd/Classes/GenericBrowserType_Sounds.uc | 40 + .../GenericBrowserType_SpeechRecognition.uc | 20 + .../Classes/GenericBrowserType_SpeedTree.uc | 24 + .../Classes/GenericBrowserType_StaticMesh.uc | 31 + .../GenericBrowserType_TemplateMapMetadata.uc | 20 + .../GenericBrowserType_TerrainLayer.uc | 20 + .../GenericBrowserType_TerrainMaterial.uc | 20 + .../Classes/GenericBrowserType_Texture.uc | 38 + .../Classes/GenericBrowserType_TextureCube.uc | 21 + .../GenericBrowserType_TextureMovie.uc | 19 + .../Classes/GenericParamListVisualizer.uc | 94 + .../Classes/GenericThumbnailLabelRenderer.uc | 24 + UnrealEd/Classes/GeomModifier.uc | 137 + UnrealEd/Classes/GeomModifier_Clip.uc | 58 + UnrealEd/Classes/GeomModifier_Create.uc | 30 + UnrealEd/Classes/GeomModifier_Delete.uc | 30 + UnrealEd/Classes/GeomModifier_Edit.uc | 26 + UnrealEd/Classes/GeomModifier_Extrude.uc | 49 + UnrealEd/Classes/GeomModifier_Flip.uc | 30 + UnrealEd/Classes/GeomModifier_Lathe.uc | 48 + UnrealEd/Classes/GeomModifier_Optimize.uc | 30 + UnrealEd/Classes/GeomModifier_Pen.uc | 66 + UnrealEd/Classes/GeomModifier_Split.uc | 30 + UnrealEd/Classes/GeomModifier_Triangulate.uc | 30 + UnrealEd/Classes/GeomModifier_Turn.uc | 30 + UnrealEd/Classes/GeomModifier_Weld.uc | 30 + UnrealEd/Classes/GroupActor.uc | 277 + UnrealEd/Classes/HeatmapVisualizer.uc | 168 + UnrealEd/Classes/IconThumbnailRenderer.uc | 81 + UnrealEd/Classes/InterpEdOptions.uc | 15 + UnrealEd/Classes/InterpTrackAkEventHelper.uc | 22 + UnrealEd/Classes/InterpTrackAkRTPCHelper.uc | 22 + .../Classes/InterpTrackAnimControlHelper.uc | 48 + UnrealEd/Classes/InterpTrackBoolPropHelper.uc | 31 + .../Classes/InterpTrackColorPropHelper.uc | 30 + UnrealEd/Classes/InterpTrackDirectorHelper.uc | 28 + UnrealEd/Classes/InterpTrackEventHelper.uc | 28 + UnrealEd/Classes/InterpTrackFaceFXHelper.uc | 14 + .../Classes/InterpTrackFloatPropHelper.uc | 30 + .../Classes/InterpTrackHeadTrackingHelper.uc | 29 + UnrealEd/Classes/InterpTrackHelper.uc | 53 + .../InterpTrackLinearColorPropHelper.uc | 30 + UnrealEd/Classes/InterpTrackNotifyHelper.uc | 47 + .../InterpTrackParticleReplayHelper.uc | 29 + UnrealEd/Classes/InterpTrackSoundHelper.uc | 28 + UnrealEd/Classes/InterpTrackToggleHelper.uc | 29 + .../Classes/InterpTrackVectorPropHelper.uc | 39 + .../Classes/InterpTrackVisibilityHelper.uc | 29 + UnrealEd/Classes/KismetBindings.uc | 29 + .../Classes/LandscapeLayerLabelRenderer.uc | 19 + UnrealEd/Classes/LensFlareEditorOptions.uc | 35 + .../Classes/LensFlareEditorPropertyWrapper.uc | 28 + UnrealEd/Classes/LensFlarePreviewComponent.uc | 16 + .../Classes/LensFlareThumbnailRenderer.uc | 53 + UnrealEd/Classes/LightingChannelsObject.uc | 19 + UnrealEd/Classes/LightmassOptionsObject.uc | 18 + UnrealEd/Classes/LinearStairBuilder.uc | 133 + .../Classes/MaterialEditorInstanceConstant.uc | 194 + .../MaterialEditorInstanceTimeVarying.uc | 154 + .../Classes/MaterialEditorMeshComponent.uc | 15 + UnrealEd/Classes/MaterialEditorOptions.uc | 41 + .../MaterialEditorSkeletalMeshComponent.uc | 7 + .../Classes/MaterialFunctionLabelRenderer.uc | 19 + .../Classes/MaterialInstanceLabelRenderer.uc | 19 + .../MaterialInstanceThumbnailRenderer.uc | 32 + .../Classes/MemCountThumbnailLabelRenderer.uc | 42 + .../Classes/ParticleSystemLabelRenderer.uc | 20 + .../ParticleSystemThumbnailRenderer.uc | 53 + UnrealEd/Classes/PerformanceVisualizer.uc | 61 + UnrealEd/Classes/PhATSimOptions.uc | 60 + UnrealEd/Classes/PhATSkeletalMeshComponent.uc | 43 + UnrealEd/Classes/PhysicsAssetLabelRenderer.uc | 19 + UnrealEd/Classes/PlayerMovementVisualizer.uc | 106 + UnrealEd/Classes/PostProcessLabelRenderer.uc | 19 + UnrealEd/Classes/PrefabThumbnailRenderer.uc | 32 + UnrealEd/Classes/PreviewMaterial.uc | 15 + UnrealEd/Classes/SequenceObjectHelper.uc | 40 + UnrealEd/Classes/SheetBuilder.uc | 78 + UnrealEd/Classes/SkeletalMeshLabelRenderer.uc | 19 + .../Classes/SkeletalMeshThumbnailRenderer.uc | 32 + UnrealEd/Classes/SoundLabelRenderer.uc | 19 + UnrealEd/Classes/SoundNodeHelper.uc | 7 + UnrealEd/Classes/SpiralStairBuilder.uc | 128 + UnrealEd/Classes/StaticMeshLabelRenderer.uc | 19 + UnrealEd/Classes/StaticMeshMode_Options.uc | 38 + .../Classes/StaticMeshThumbnailRenderer.uc | 32 + .../TagSuboptimalTexturesCommandlet.uc | 23 + UnrealEd/Classes/TemplateMapMetadata.uc | 26 + UnrealEd/Classes/TerrainEditOptions.uc | 77 + UnrealEd/Classes/TetrahedronBuilder.uc | 69 + .../Classes/TextureCubeThumbnailRenderer.uc | 45 + UnrealEd/Classes/TextureThumbnailRenderer.uc | 69 + UnrealEd/Classes/ThumbnailLabelRenderer.uc | 97 + UnrealEd/Classes/ThumbnailManager.uc | 297 + UnrealEd/Classes/ThumbnailRenderer.uc | 86 + UnrealEd/Classes/UnrealEdEngine.uc | 134 + UnrealEd/Classes/UnrealEdKeyBindings.uc | 34 + UnrealEd/Classes/UnrealEdOptions.uc | 119 + UnrealEd/Classes/UnrealEdTypes.uc | 76 + UnrealEd/Classes/VolumetricBuilder.uc | 63 + WebAdmin/Classes/AbstractSettingsModifier.uc | 105 + WebAdmin/Classes/AdminCommandHandler.uc | 230 + WebAdmin/Classes/BanImporter.uc | 181 + WebAdmin/Classes/BasicWebAdminAuth.uc | 114 + WebAdmin/Classes/BasicWebAdminUser.uc | 175 + WebAdmin/Classes/ChatLog.uc | 158 + WebAdmin/Classes/DCEGameInfo.uc | 25 + WebAdmin/Classes/DCEMapInfo.uc | 25 + WebAdmin/Classes/DCEMutator.uc | 25 + WebAdmin/Classes/DataStoreCache.uc | 757 + WebAdmin/Classes/DataStoreCacheEntry.uc | 81 + WebAdmin/Classes/DataStoreCacheKF.uc | 41 + WebAdmin/Classes/GeneralSettings.uc | 266 + WebAdmin/Classes/HashLib.uc | 10 + WebAdmin/Classes/IAdvWebAdminSettings.uc | 44 + WebAdmin/Classes/IQueryHandler.uc | 96 + WebAdmin/Classes/ISession.uc | 48 + WebAdmin/Classes/ISessionHandler.uc | 28 + WebAdmin/Classes/ISettingsModifier.uc | 44 + WebAdmin/Classes/ISettingsPrivileges.uc | 19 + WebAdmin/Classes/IWebAdminAuth.uc | 63 + WebAdmin/Classes/IWebAdminUser.uc | 81 + WebAdmin/Classes/KF2ImageServer.uc | 97 + WebAdmin/Classes/KF2ServerAdmin.uc | 6 + WebAdmin/Classes/KFGameInfoSettings.uc | 101 + .../Classes/KFGameInfo_SurvivalSettings.uc | 8 + WebAdmin/Classes/MessagingSpectator.uc | 149 + WebAdmin/Classes/MultiAdminData.uc | 165 + WebAdmin/Classes/MultiWebAdminAuth.uc | 275 + WebAdmin/Classes/MultiWebAdminUser.uc | 62 + WebAdmin/Classes/NewsDesk.uc | 113 + WebAdmin/Classes/PCCleanUp.uc | 44 + WebAdmin/Classes/QHCurrent.uc | 1739 +++ WebAdmin/Classes/QHCurrentKF.uc | 180 + WebAdmin/Classes/QHDefaults.uc | 1610 +++ WebAdmin/Classes/QHDefaultsKF.uc | 18 + WebAdmin/Classes/QHMultiAdmin.uc | 374 + WebAdmin/Classes/Session.uc | 115 + WebAdmin/Classes/SessionHandler.uc | 78 + WebAdmin/Classes/SettingRendererState.uc | 134 + WebAdmin/Classes/SettingsMagic.uc | 76 + WebAdmin/Classes/SettingsRenderer.uc | 738 + WebAdmin/Classes/Sha1HashLib.uc | 202 + WebAdmin/Classes/TeamChatProxy.uc | 30 + WebAdmin/Classes/WebAdmin.uc | 1313 ++ WebAdmin/Classes/WebAdminMenu.uc | 333 + WebAdmin/Classes/WebAdminMessages.uc | 45 + WebAdmin/Classes/WebAdminSettings.uc | 246 + WebAdmin/Classes/WebAdminSkin.uc | 17 + WebAdmin/Classes/WebAdminSystemSettings.uc | 340 + WebAdmin/Classes/WebAdminUtils.uc | 487 + WebAdmin/Classes/WebConnectionEx.uc | 31 + WebAdmin/Classes/WelcomeSettings.uc | 87 + WebAdmin/SettingsMacros.uci | 154 + WebAdmin/WebAdmin.uci | 159 + WinDrv/Classes/FacebookWindows.uc | 179 + WinDrv/Classes/HttpRequestWindows.uc | 28 + WinDrv/Classes/HttpRequestWindowsMcp.uc | 41 + WinDrv/Classes/HttpResponseWindows.uc | 21 + 3764 files changed, 596895 insertions(+) create mode 100644 AkAudio/Classes/ActorFactoryAKAmbientSound.uc create mode 100644 AkAudio/Classes/AkAmbientSound.uc create mode 100644 AkAudio/Classes/AkComponent.uc create mode 100644 AkAudio/Classes/InterpTrackAkEvent.uc create mode 100644 AkAudio/Classes/InterpTrackAkRTPC.uc create mode 100644 AkAudio/Classes/InterpTrackInstAkEvent.uc create mode 100644 AkAudio/Classes/InterpTrackInstAkRTPC.uc create mode 100644 AkAudio/Classes/SeqAct_AkClearBanks.uc create mode 100644 AkAudio/Classes/SeqAct_AkLoadBank.uc create mode 100644 AkAudio/Classes/SeqAct_AkPostEvent.uc create mode 100644 AkAudio/Classes/SeqAct_AkPostTrigger.uc create mode 100644 AkAudio/Classes/SeqAct_AkSetRTPCValue.uc create mode 100644 AkAudio/Classes/SeqAct_AkSetState.uc create mode 100644 AkAudio/Classes/SeqAct_AkSetSwitch.uc create mode 100644 AkAudio/Classes/SeqAct_AkStartAmbientSound.uc create mode 100644 AkAudio/Classes/SeqAct_AkStopAll.uc create mode 100644 BaseAI/Classes/AIDebugTool.uc create mode 100644 BaseAI/Classes/AIPlugin.uc create mode 100644 BaseAI/Classes/AIPluginLeap.uc create mode 100644 BaseAI/Classes/AIPluginMovement.uc create mode 100644 BaseAI/Classes/AIPluginStuckFix.uc create mode 100644 BaseAI/Classes/AITickablePlugin.uc create mode 100644 BaseAI/Classes/BaseAIController.uc create mode 100644 BaseAI/Classes/BaseAIPawn.uc create mode 100644 BaseAI/Classes/BaseAISquad.uc create mode 100644 BaseAI/Classes/BaseAISubsystem.uc create mode 100644 BaseAI/Classes/BaseAITypes.uc create mode 100644 BaseAI/Classes/BaseAiPlugInHistory.uc create mode 100644 BaseAI/Classes/CodeSpeedTestCommandlet.uc create mode 100644 BaseAI/Classes/LatentActionObserver.uc create mode 100644 BaseAI/Classes/NavigationPath.uc create mode 100644 BaseAI/Classes/PlayerInputRecorder.uc create mode 100644 BaseAI/Classes/PlugInOwnerInterface.uc create mode 100644 BaseAI/Classes/PluginBase.uc create mode 100644 BaseAI/Classes/PluginSquad.uc create mode 100644 BaseAI/Globals.uci create mode 100644 Core/Classes/Commandlet.uc create mode 100644 Core/Classes/Component.uc create mode 100644 Core/Classes/DistributionFloat.uc create mode 100644 Core/Classes/DistributionVector.uc create mode 100644 Core/Classes/Factory.uc create mode 100644 Core/Classes/HelpCommandlet.uc create mode 100644 Core/Classes/Interface.uc create mode 100644 Core/Classes/Object.uc create mode 100644 Core/Classes/Subsystem.uc create mode 100644 Core/Globals.uci create mode 100644 Core/nFringeGlobals.uci create mode 100644 Engine/Classes/AICommandBase.uc create mode 100644 Engine/Classes/AIController.uc create mode 100644 Engine/Classes/AISubsystem.uc create mode 100644 Engine/Classes/AISwitchablePylon.uc create mode 100644 Engine/Classes/AccessControl.uc create mode 100644 Engine/Classes/Actor.uc create mode 100644 Engine/Classes/ActorComponent.uc create mode 100644 Engine/Classes/ActorFactory.uc create mode 100644 Engine/Classes/ActorFactoryAI.uc create mode 100644 Engine/Classes/ActorFactoryActor.uc create mode 100644 Engine/Classes/ActorFactoryAmbientSound.uc create mode 100644 Engine/Classes/ActorFactoryAmbientSoundMovable.uc create mode 100644 Engine/Classes/ActorFactoryAmbientSoundNonLoop.uc create mode 100644 Engine/Classes/ActorFactoryAmbientSoundNonLoopingToggleable.uc create mode 100644 Engine/Classes/ActorFactoryAmbientSoundSimple.uc create mode 100644 Engine/Classes/ActorFactoryAmbientSoundSimpleToggleable.uc create mode 100644 Engine/Classes/ActorFactoryApexClothing.uc create mode 100644 Engine/Classes/ActorFactoryApexDestructible.uc create mode 100644 Engine/Classes/ActorFactoryArchetype.uc create mode 100644 Engine/Classes/ActorFactoryCoverLink.uc create mode 100644 Engine/Classes/ActorFactoryDecal.uc create mode 100644 Engine/Classes/ActorFactoryDecalMovable.uc create mode 100644 Engine/Classes/ActorFactoryDominantDirectionalLight.uc create mode 100644 Engine/Classes/ActorFactoryDominantDirectionalLightMovable.uc create mode 100644 Engine/Classes/ActorFactoryDynamicSM.uc create mode 100644 Engine/Classes/ActorFactoryEmitter.uc create mode 100644 Engine/Classes/ActorFactoryFlex.uc create mode 100644 Engine/Classes/ActorFactoryFlexForceField.uc create mode 100644 Engine/Classes/ActorFactoryFogVolumeConstantDensityInfo.uc create mode 100644 Engine/Classes/ActorFactoryFogVolumeLinearHalfspaceDensityInfo.uc create mode 100644 Engine/Classes/ActorFactoryFogVolumeSphericalDensityInfo.uc create mode 100644 Engine/Classes/ActorFactoryFracturedStaticMesh.uc create mode 100644 Engine/Classes/ActorFactoryInteractiveFoliage.uc create mode 100644 Engine/Classes/ActorFactoryLensFlare.uc create mode 100644 Engine/Classes/ActorFactoryLight.uc create mode 100644 Engine/Classes/ActorFactoryMover.uc create mode 100644 Engine/Classes/ActorFactoryPathNode.uc create mode 100644 Engine/Classes/ActorFactoryPhysicsAsset.uc create mode 100644 Engine/Classes/ActorFactoryPlayerStart.uc create mode 100644 Engine/Classes/ActorFactoryPylon.uc create mode 100644 Engine/Classes/ActorFactoryRigidBody.uc create mode 100644 Engine/Classes/ActorFactorySkeletalMesh.uc create mode 100644 Engine/Classes/ActorFactorySkeletalMeshCinematic.uc create mode 100644 Engine/Classes/ActorFactorySkeletalMeshMAT.uc create mode 100644 Engine/Classes/ActorFactoryStaticMesh.uc create mode 100644 Engine/Classes/ActorFactoryTrigger.uc create mode 100644 Engine/Classes/ActorFactoryVehicle.uc create mode 100644 Engine/Classes/Admin.uc create mode 100644 Engine/Classes/AdvancedReachSpec.uc create mode 100644 Engine/Classes/AkBank.uc create mode 100644 Engine/Classes/AkBaseSoundObject.uc create mode 100644 Engine/Classes/AkEvent.uc create mode 100644 Engine/Classes/AlienFXLEDInterface.uc create mode 100644 Engine/Classes/AmbientOcclusionEffect.uc create mode 100644 Engine/Classes/AmbientSound.uc create mode 100644 Engine/Classes/AmbientSoundMovable.uc create mode 100644 Engine/Classes/AmbientSoundNonLoop.uc create mode 100644 Engine/Classes/AmbientSoundNonLoopingToggleable.uc create mode 100644 Engine/Classes/AmbientSoundSimple.uc create mode 100644 Engine/Classes/AmbientSoundSimpleSpline.uc create mode 100644 Engine/Classes/AmbientSoundSimpleSplineNonLoop.uc create mode 100644 Engine/Classes/AmbientSoundSimpleToggleable.uc create mode 100644 Engine/Classes/AmbientSoundSpline.uc create mode 100644 Engine/Classes/AmbientSoundSplineMultiCue.uc create mode 100644 Engine/Classes/AnalyticEventsBase.uc create mode 100644 Engine/Classes/AnimMetaData.uc create mode 100644 Engine/Classes/AnimMetaData_SkelControl.uc create mode 100644 Engine/Classes/AnimMetaData_SkelControlKeyFrame.uc create mode 100644 Engine/Classes/AnimNode.uc create mode 100644 Engine/Classes/AnimNodeAdditiveBlending.uc create mode 100644 Engine/Classes/AnimNodeAimOffset.uc create mode 100644 Engine/Classes/AnimNodeBlend.uc create mode 100644 Engine/Classes/AnimNodeBlendBase.uc create mode 100644 Engine/Classes/AnimNodeBlendByBase.uc create mode 100644 Engine/Classes/AnimNodeBlendByPhysics.uc create mode 100644 Engine/Classes/AnimNodeBlendByPosture.uc create mode 100644 Engine/Classes/AnimNodeBlendByProperty.uc create mode 100644 Engine/Classes/AnimNodeBlendBySpeed.uc create mode 100644 Engine/Classes/AnimNodeBlendDirectional.uc create mode 100644 Engine/Classes/AnimNodeBlendList.uc create mode 100644 Engine/Classes/AnimNodeBlendMultiBone.uc create mode 100644 Engine/Classes/AnimNodeBlendPerBone.uc create mode 100644 Engine/Classes/AnimNodeCrossfader.uc create mode 100644 Engine/Classes/AnimNodeFrame.uc create mode 100644 Engine/Classes/AnimNodeMirror.uc create mode 100644 Engine/Classes/AnimNodePlayCustomAnim.uc create mode 100644 Engine/Classes/AnimNodeRandom.uc create mode 100644 Engine/Classes/AnimNodeScalePlayRate.uc create mode 100644 Engine/Classes/AnimNodeScaleRateBySpeed.uc create mode 100644 Engine/Classes/AnimNodeSequence.uc create mode 100644 Engine/Classes/AnimNodeSequenceBlendBase.uc create mode 100644 Engine/Classes/AnimNodeSequenceBlendByAim.uc create mode 100644 Engine/Classes/AnimNodeSlot.uc create mode 100644 Engine/Classes/AnimNodeSynch.uc create mode 100644 Engine/Classes/AnimNode_MultiBlendPerBone.uc create mode 100644 Engine/Classes/AnimNotify.uc create mode 100644 Engine/Classes/AnimNotify_AkEvent.uc create mode 100644 Engine/Classes/AnimNotify_CameraEffect.uc create mode 100644 Engine/Classes/AnimNotify_ClothingMaxDistanceScale.uc create mode 100644 Engine/Classes/AnimNotify_Footstep.uc create mode 100644 Engine/Classes/AnimNotify_Forcefield.uc create mode 100644 Engine/Classes/AnimNotify_Kismet.uc create mode 100644 Engine/Classes/AnimNotify_PawnMaterialParam.uc create mode 100644 Engine/Classes/AnimNotify_PlayFaceFxAnim.uc create mode 100644 Engine/Classes/AnimNotify_PlayParticleEffect.uc create mode 100644 Engine/Classes/AnimNotify_Rumble.uc create mode 100644 Engine/Classes/AnimNotify_Script.uc create mode 100644 Engine/Classes/AnimNotify_Scripted.uc create mode 100644 Engine/Classes/AnimNotify_Sound.uc create mode 100644 Engine/Classes/AnimNotify_Trails.uc create mode 100644 Engine/Classes/AnimNotify_ViewShake.uc create mode 100644 Engine/Classes/AnimObject.uc create mode 100644 Engine/Classes/AnimSequence.uc create mode 100644 Engine/Classes/AnimSet.uc create mode 100644 Engine/Classes/AnimTree.uc create mode 100644 Engine/Classes/AnimationCompressionAlgorithm.uc create mode 100644 Engine/Classes/AnimationCompressionAlgorithm_Automatic.uc create mode 100644 Engine/Classes/AnimationCompressionAlgorithm_BitwiseCompressOnly.uc create mode 100644 Engine/Classes/AnimationCompressionAlgorithm_LeastDestructive.uc create mode 100644 Engine/Classes/AnimationCompressionAlgorithm_PerTrackCompression.uc create mode 100644 Engine/Classes/AnimationCompressionAlgorithm_RemoveEverySecondKey.uc create mode 100644 Engine/Classes/AnimationCompressionAlgorithm_RemoveLinearKeys.uc create mode 100644 Engine/Classes/AnimationCompressionAlgorithm_RemoveTrivialKeys.uc create mode 100644 Engine/Classes/AnimationCompressionAlgorithm_RevertToRaw.uc create mode 100644 Engine/Classes/ApexAsset.uc create mode 100644 Engine/Classes/ApexClothingAsset.uc create mode 100644 Engine/Classes/ApexComponentBase.uc create mode 100644 Engine/Classes/ApexDestructibleActor.uc create mode 100644 Engine/Classes/ApexDestructibleActorSpawnable.uc create mode 100644 Engine/Classes/ApexDestructibleAsset.uc create mode 100644 Engine/Classes/ApexDestructibleDamageParameters.uc create mode 100644 Engine/Classes/ApexDynamicComponent.uc create mode 100644 Engine/Classes/ApexGenericAsset.uc create mode 100644 Engine/Classes/ApexStaticComponent.uc create mode 100644 Engine/Classes/ApexStaticDestructibleComponent.uc create mode 100644 Engine/Classes/AppNotificationsBase.uc create mode 100644 Engine/Classes/ArrowComponent.uc create mode 100644 Engine/Classes/AudioComponent.uc create mode 100644 Engine/Classes/AudioDevice.uc create mode 100644 Engine/Classes/AutoLadder.uc create mode 100644 Engine/Classes/AutoNavMeshPathObstacleUnregister.uc create mode 100644 Engine/Classes/AutoTestManager.uc create mode 100644 Engine/Classes/BlockingVolume.uc create mode 100644 Engine/Classes/BlurEffect.uc create mode 100644 Engine/Classes/BookMark.uc create mode 100644 Engine/Classes/BookMark2D.uc create mode 100644 Engine/Classes/BroadcastHandler.uc create mode 100644 Engine/Classes/Brush.uc create mode 100644 Engine/Classes/BrushComponent.uc create mode 100644 Engine/Classes/BrushShape.uc create mode 100644 Engine/Classes/Camera.uc create mode 100644 Engine/Classes/CameraActor.uc create mode 100644 Engine/Classes/CameraAnim.uc create mode 100644 Engine/Classes/CameraAnimInst.uc create mode 100644 Engine/Classes/CameraConeComponent.uc create mode 100644 Engine/Classes/CameraModifier.uc create mode 100644 Engine/Classes/CameraModifier_CameraShake.uc create mode 100644 Engine/Classes/CameraShake.uc create mode 100644 Engine/Classes/Canvas.uc create mode 100644 Engine/Classes/CeilingReachSpec.uc create mode 100644 Engine/Classes/CheatManager.uc create mode 100644 Engine/Classes/ClipPadEntry.uc create mode 100644 Engine/Classes/CloudSaveSystem.uc create mode 100644 Engine/Classes/CloudSaveSystemDataBlobStoreInterface.uc create mode 100644 Engine/Classes/CloudSaveSystemKVSInterface.uc create mode 100644 Engine/Classes/CloudStorageBase.uc create mode 100644 Engine/Classes/CloudStorageBaseCloudSaveSystemKVS.uc create mode 100644 Engine/Classes/CloudStorageUpgradeHelper.uc create mode 100644 Engine/Classes/CodecMovie.uc create mode 100644 Engine/Classes/CodecMovieFallback.uc create mode 100644 Engine/Classes/ColorScaleVolume.uc create mode 100644 Engine/Classes/Console.uc create mode 100644 Engine/Classes/Controller.uc create mode 100644 Engine/Classes/CoverGroup.uc create mode 100644 Engine/Classes/CoverGroupRenderingComponent.uc create mode 100644 Engine/Classes/CoverLink.uc create mode 100644 Engine/Classes/CoverMeshComponent.uc create mode 100644 Engine/Classes/CoverReplicator.uc create mode 100644 Engine/Classes/CoverSlipReachSpec.uc create mode 100644 Engine/Classes/CrowdAgentBase.uc create mode 100644 Engine/Classes/CrowdPopulationManagerBase.uc create mode 100644 Engine/Classes/CullDistanceVolume.uc create mode 100644 Engine/Classes/CurveEdPresetCurve.uc create mode 100644 Engine/Classes/CustomPropertyItemHandler.uc create mode 100644 Engine/Classes/CylinderComponent.uc create mode 100644 Engine/Classes/DOFAndBloomEffect.uc create mode 100644 Engine/Classes/DOFBloomMotionBlurEffect.uc create mode 100644 Engine/Classes/DOFEffect.uc create mode 100644 Engine/Classes/DamageType.uc create mode 100644 Engine/Classes/DataStoreClient.uc create mode 100644 Engine/Classes/DecalActor.uc create mode 100644 Engine/Classes/DecalActorBase.uc create mode 100644 Engine/Classes/DecalActorMovable.uc create mode 100644 Engine/Classes/DecalComponent.uc create mode 100644 Engine/Classes/DecalManager.uc create mode 100644 Engine/Classes/DecalMaterial.uc create mode 100644 Engine/Classes/DefaultPhysicsVolume.uc create mode 100644 Engine/Classes/DirectionalLight.uc create mode 100644 Engine/Classes/DirectionalLightComponent.uc create mode 100644 Engine/Classes/DirectionalLightToggleable.uc create mode 100644 Engine/Classes/DiscordRPCIntegration.uc create mode 100644 Engine/Classes/DistributionFloatConstant.uc create mode 100644 Engine/Classes/DistributionFloatConstantCurve.uc create mode 100644 Engine/Classes/DistributionFloatParameterBase.uc create mode 100644 Engine/Classes/DistributionFloatParticleParameter.uc create mode 100644 Engine/Classes/DistributionFloatSoundParameter.uc create mode 100644 Engine/Classes/DistributionFloatUniform.uc create mode 100644 Engine/Classes/DistributionFloatUniformCurve.uc create mode 100644 Engine/Classes/DistributionFloatUniformRange.uc create mode 100644 Engine/Classes/DistributionVectorConstant.uc create mode 100644 Engine/Classes/DistributionVectorConstantCurve.uc create mode 100644 Engine/Classes/DistributionVectorParameterBase.uc create mode 100644 Engine/Classes/DistributionVectorParticleParameter.uc create mode 100644 Engine/Classes/DistributionVectorUniform.uc create mode 100644 Engine/Classes/DistributionVectorUniformCurve.uc create mode 100644 Engine/Classes/DistributionVectorUniformRange.uc create mode 100644 Engine/Classes/DmgType_Crushed.uc create mode 100644 Engine/Classes/DmgType_Fell.uc create mode 100644 Engine/Classes/DmgType_Suicided.uc create mode 100644 Engine/Classes/DmgType_Telefragged.uc create mode 100644 Engine/Classes/DominantDirectionalLight.uc create mode 100644 Engine/Classes/DominantDirectionalLightComponent.uc create mode 100644 Engine/Classes/DominantDirectionalLightMovable.uc create mode 100644 Engine/Classes/DominantPointLight.uc create mode 100644 Engine/Classes/DominantPointLightComponent.uc create mode 100644 Engine/Classes/DominantSpotLight.uc create mode 100644 Engine/Classes/DominantSpotLightComponent.uc create mode 100644 Engine/Classes/DoorMarker.uc create mode 100644 Engine/Classes/DownloadableContentEnumerator.uc create mode 100644 Engine/Classes/DownloadableContentManager.uc create mode 100644 Engine/Classes/DrawBoxComponent.uc create mode 100644 Engine/Classes/DrawCapsuleComponent.uc create mode 100644 Engine/Classes/DrawConeComponent.uc create mode 100644 Engine/Classes/DrawCylinderComponent.uc create mode 100644 Engine/Classes/DrawFrustumComponent.uc create mode 100644 Engine/Classes/DrawLightConeComponent.uc create mode 100644 Engine/Classes/DrawLightRadiusComponent.uc create mode 100644 Engine/Classes/DrawPylonRadiusComponent.uc create mode 100644 Engine/Classes/DrawQuadComponent.uc create mode 100644 Engine/Classes/DrawSoundRadiusComponent.uc create mode 100644 Engine/Classes/DrawSphereComponent.uc create mode 100644 Engine/Classes/DrawTaperedCapsuleComponent.uc create mode 100644 Engine/Classes/DroppedPickup.uc create mode 100644 Engine/Classes/DynamicAnchor.uc create mode 100644 Engine/Classes/DynamicBlockingVolume.uc create mode 100644 Engine/Classes/DynamicCameraActor.uc create mode 100644 Engine/Classes/DynamicLightEnvironmentComponent.uc create mode 100644 Engine/Classes/DynamicPhysicsVolume.uc create mode 100644 Engine/Classes/DynamicPylon.uc create mode 100644 Engine/Classes/DynamicSMActor.uc create mode 100644 Engine/Classes/DynamicSMActor_Spawnable.uc create mode 100644 Engine/Classes/DynamicTriggerVolume.uc create mode 100644 Engine/Classes/EdCoordSystem.uc create mode 100644 Engine/Classes/EditorLinkSelectionInterface.uc create mode 100644 Engine/Classes/Emitter.uc create mode 100644 Engine/Classes/EmitterCameraLensEffectBase.uc create mode 100644 Engine/Classes/EmitterPool.uc create mode 100644 Engine/Classes/EmitterSpawnable.uc create mode 100644 Engine/Classes/Engine.uc create mode 100644 Engine/Classes/EngineBaseTypes.uc create mode 100644 Engine/Classes/EngineTypes.uc create mode 100644 Engine/Classes/EnvironmentVolume.uc create mode 100644 Engine/Classes/ExponentialHeightFog.uc create mode 100644 Engine/Classes/ExponentialHeightFogComponent.uc create mode 100644 Engine/Classes/FaceFXAnimSet.uc create mode 100644 Engine/Classes/FaceFXAsset.uc create mode 100644 Engine/Classes/FacebookIntegration.uc create mode 100644 Engine/Classes/FailedConnect.uc create mode 100644 Engine/Classes/FileLog.uc create mode 100644 Engine/Classes/FileWriter.uc create mode 100644 Engine/Classes/FlexActor.uc create mode 100644 Engine/Classes/FlexAsset.uc create mode 100644 Engine/Classes/FlexComponent.uc create mode 100644 Engine/Classes/FlexContainer.uc create mode 100644 Engine/Classes/FlexForceFieldActor.uc create mode 100644 Engine/Classes/FlexForceFieldComponent.uc create mode 100644 Engine/Classes/FloorToCeilingReachSpec.uc create mode 100644 Engine/Classes/FluidInfluenceActor.uc create mode 100644 Engine/Classes/FluidInfluenceComponent.uc create mode 100644 Engine/Classes/FluidSurfaceActor.uc create mode 100644 Engine/Classes/FluidSurfaceActorMovable.uc create mode 100644 Engine/Classes/FluidSurfaceComponent.uc create mode 100644 Engine/Classes/FogVolumeConeDensityComponent.uc create mode 100644 Engine/Classes/FogVolumeConeDensityInfo.uc create mode 100644 Engine/Classes/FogVolumeConstantDensityComponent.uc create mode 100644 Engine/Classes/FogVolumeConstantDensityInfo.uc create mode 100644 Engine/Classes/FogVolumeDensityComponent.uc create mode 100644 Engine/Classes/FogVolumeDensityInfo.uc create mode 100644 Engine/Classes/FogVolumeLinearHalfspaceDensityComponent.uc create mode 100644 Engine/Classes/FogVolumeLinearHalfspaceDensityInfo.uc create mode 100644 Engine/Classes/FogVolumeSphericalDensityComponent.uc create mode 100644 Engine/Classes/FogVolumeSphericalDensityInfo.uc create mode 100644 Engine/Classes/Font.uc create mode 100644 Engine/Classes/FontImportOptions.uc create mode 100644 Engine/Classes/ForceFeedbackManager.uc create mode 100644 Engine/Classes/ForceFeedbackWaveform.uc create mode 100644 Engine/Classes/ForceFieldShape.uc create mode 100644 Engine/Classes/ForceFieldShapeBox.uc create mode 100644 Engine/Classes/ForceFieldShapeCapsule.uc create mode 100644 Engine/Classes/ForceFieldShapeSphere.uc create mode 100644 Engine/Classes/ForcedLoopSoundNode.uc create mode 100644 Engine/Classes/ForcedReachSpec.uc create mode 100644 Engine/Classes/FractureManager.uc create mode 100644 Engine/Classes/FractureMaterial.uc create mode 100644 Engine/Classes/FracturedBaseComponent.uc create mode 100644 Engine/Classes/FracturedSMActorSpawnable.uc create mode 100644 Engine/Classes/FracturedSkinnedMeshComponent.uc create mode 100644 Engine/Classes/FracturedStaticMeshActor.uc create mode 100644 Engine/Classes/FracturedStaticMeshActor_Spawnable.uc create mode 100644 Engine/Classes/FracturedStaticMeshComponent.uc create mode 100644 Engine/Classes/FracturedStaticMeshPart.uc create mode 100644 Engine/Classes/GameEngine.uc create mode 100644 Engine/Classes/GameInfo.uc create mode 100644 Engine/Classes/GameMessage.uc create mode 100644 Engine/Classes/GamePadLightbarSubsystem.uc create mode 100644 Engine/Classes/GameReplicationInfo.uc create mode 100644 Engine/Classes/GameStats.uci create mode 100644 Engine/Classes/GameUISceneClient.uc create mode 100644 Engine/Classes/GameViewportClient.uc create mode 100644 Engine/Classes/GameplayEvents.uc create mode 100644 Engine/Classes/GameplayEventsHandler.uc create mode 100644 Engine/Classes/GameplayEventsReader.uc create mode 100644 Engine/Classes/GameplayEventsUploadAnalytics.uc create mode 100644 Engine/Classes/GameplayEventsWriter.uc create mode 100644 Engine/Classes/GameplayEventsWriterBase.uc create mode 100644 Engine/Classes/GeneratedMeshAreaLight.uc create mode 100644 Engine/Classes/GenericParamListStatEntry.uc create mode 100644 Engine/Classes/Goal_AtActor.uc create mode 100644 Engine/Classes/Goal_Null.uc create mode 100644 Engine/Classes/GravityVolume.uc create mode 100644 Engine/Classes/HUD.uc create mode 100644 Engine/Classes/HeadTrackingComponent.uc create mode 100644 Engine/Classes/HeightFog.uc create mode 100644 Engine/Classes/HeightFogComponent.uc create mode 100644 Engine/Classes/HttpBaseInterface.uc create mode 100644 Engine/Classes/HttpFactory.uc create mode 100644 Engine/Classes/HttpRequestInterface.uc create mode 100644 Engine/Classes/HttpResponseInterface.uc create mode 100644 Engine/Classes/HttpStatusCodes.uci create mode 100644 Engine/Classes/ImageBasedReflectionComponent.uc create mode 100644 Engine/Classes/ImageReflection.uc create mode 100644 Engine/Classes/ImageReflectionComponent.uc create mode 100644 Engine/Classes/ImageReflectionSceneCapture.uc create mode 100644 Engine/Classes/ImageReflectionShadowPlane.uc create mode 100644 Engine/Classes/ImageReflectionShadowPlaneComponent.uc create mode 100644 Engine/Classes/InAppMessageBase.uc create mode 100644 Engine/Classes/InGameAdManager.uc create mode 100644 Engine/Classes/Info.uc create mode 100644 Engine/Classes/IniLocPatcher.uc create mode 100644 Engine/Classes/Input.uc create mode 100644 Engine/Classes/InstancedFoliageActor.uc create mode 100644 Engine/Classes/InstancedFoliageSettings.uc create mode 100644 Engine/Classes/InstancedStaticMeshComponent.uc create mode 100644 Engine/Classes/Interaction.uc create mode 100644 Engine/Classes/InteractiveFoliageActor.uc create mode 100644 Engine/Classes/InteractiveFoliageComponent.uc create mode 100644 Engine/Classes/Interface_NavMeshPathObject.uc create mode 100644 Engine/Classes/Interface_NavMeshPathObstacle.uc create mode 100644 Engine/Classes/Interface_NavMeshPathSwitch.uc create mode 100644 Engine/Classes/Interface_NavigationHandle.uc create mode 100644 Engine/Classes/Interface_PylonGeometryProvider.uc create mode 100644 Engine/Classes/Interface_RVO.uc create mode 100644 Engine/Classes/Interface_Speaker.uc create mode 100644 Engine/Classes/InterpActor.uc create mode 100644 Engine/Classes/InterpActor_ForCinematic.uc create mode 100644 Engine/Classes/InterpCurveEdSetup.uc create mode 100644 Engine/Classes/InterpData.uc create mode 100644 Engine/Classes/InterpFilter.uc create mode 100644 Engine/Classes/InterpFilter_Classes.uc create mode 100644 Engine/Classes/InterpFilter_Custom.uc create mode 100644 Engine/Classes/InterpGroup.uc create mode 100644 Engine/Classes/InterpGroupAI.uc create mode 100644 Engine/Classes/InterpGroupCamera.uc create mode 100644 Engine/Classes/InterpGroupDirector.uc create mode 100644 Engine/Classes/InterpGroupInst.uc create mode 100644 Engine/Classes/InterpGroupInstAI.uc create mode 100644 Engine/Classes/InterpGroupInstCamera.uc create mode 100644 Engine/Classes/InterpGroupInstDirector.uc create mode 100644 Engine/Classes/InterpTrack.uc create mode 100644 Engine/Classes/InterpTrackAnimControl.uc create mode 100644 Engine/Classes/InterpTrackAudioMaster.uc create mode 100644 Engine/Classes/InterpTrackBoolProp.uc create mode 100644 Engine/Classes/InterpTrackColorProp.uc create mode 100644 Engine/Classes/InterpTrackColorScale.uc create mode 100644 Engine/Classes/InterpTrackDirector.uc create mode 100644 Engine/Classes/InterpTrackEvent.uc create mode 100644 Engine/Classes/InterpTrackFaceFX.uc create mode 100644 Engine/Classes/InterpTrackFade.uc create mode 100644 Engine/Classes/InterpTrackFloatBase.uc create mode 100644 Engine/Classes/InterpTrackFloatMaterialParam.uc create mode 100644 Engine/Classes/InterpTrackFloatParticleParam.uc create mode 100644 Engine/Classes/InterpTrackFloatProp.uc create mode 100644 Engine/Classes/InterpTrackHeadTracking.uc create mode 100644 Engine/Classes/InterpTrackInst.uc create mode 100644 Engine/Classes/InterpTrackInstAnimControl.uc create mode 100644 Engine/Classes/InterpTrackInstAudioMaster.uc create mode 100644 Engine/Classes/InterpTrackInstBoolProp.uc create mode 100644 Engine/Classes/InterpTrackInstColorProp.uc create mode 100644 Engine/Classes/InterpTrackInstColorScale.uc create mode 100644 Engine/Classes/InterpTrackInstDirector.uc create mode 100644 Engine/Classes/InterpTrackInstEvent.uc create mode 100644 Engine/Classes/InterpTrackInstFaceFX.uc create mode 100644 Engine/Classes/InterpTrackInstFade.uc create mode 100644 Engine/Classes/InterpTrackInstFloatMaterialParam.uc create mode 100644 Engine/Classes/InterpTrackInstFloatParticleParam.uc create mode 100644 Engine/Classes/InterpTrackInstFloatProp.uc create mode 100644 Engine/Classes/InterpTrackInstHeadTracking.uc create mode 100644 Engine/Classes/InterpTrackInstLinearColorProp.uc create mode 100644 Engine/Classes/InterpTrackInstMorphWeight.uc create mode 100644 Engine/Classes/InterpTrackInstMove.uc create mode 100644 Engine/Classes/InterpTrackInstNotify.uc create mode 100644 Engine/Classes/InterpTrackInstParticleReplay.uc create mode 100644 Engine/Classes/InterpTrackInstProperty.uc create mode 100644 Engine/Classes/InterpTrackInstSkelControlScale.uc create mode 100644 Engine/Classes/InterpTrackInstSkelControlStrength.uc create mode 100644 Engine/Classes/InterpTrackInstSlomo.uc create mode 100644 Engine/Classes/InterpTrackInstSound.uc create mode 100644 Engine/Classes/InterpTrackInstToggle.uc create mode 100644 Engine/Classes/InterpTrackInstVectorMaterialParam.uc create mode 100644 Engine/Classes/InterpTrackInstVectorProp.uc create mode 100644 Engine/Classes/InterpTrackInstVisibility.uc create mode 100644 Engine/Classes/InterpTrackLinearColorBase.uc create mode 100644 Engine/Classes/InterpTrackLinearColorProp.uc create mode 100644 Engine/Classes/InterpTrackMorphWeight.uc create mode 100644 Engine/Classes/InterpTrackMove.uc create mode 100644 Engine/Classes/InterpTrackMoveAxis.uc create mode 100644 Engine/Classes/InterpTrackNotify.uc create mode 100644 Engine/Classes/InterpTrackParticleReplay.uc create mode 100644 Engine/Classes/InterpTrackSkelControlScale.uc create mode 100644 Engine/Classes/InterpTrackSkelControlStrength.uc create mode 100644 Engine/Classes/InterpTrackSlomo.uc create mode 100644 Engine/Classes/InterpTrackSound.uc create mode 100644 Engine/Classes/InterpTrackToggle.uc create mode 100644 Engine/Classes/InterpTrackVectorBase.uc create mode 100644 Engine/Classes/InterpTrackVectorMaterialParam.uc create mode 100644 Engine/Classes/InterpTrackVectorProp.uc create mode 100644 Engine/Classes/InterpTrackVisibility.uc create mode 100644 Engine/Classes/Inventory.uc create mode 100644 Engine/Classes/InventoryManager.uc create mode 100644 Engine/Classes/JsonObject.uc create mode 100644 Engine/Classes/KActor.uc create mode 100644 Engine/Classes/KActorFromStatic.uc create mode 100644 Engine/Classes/KActorSpawnable.uc create mode 100644 Engine/Classes/KAsset.uc create mode 100644 Engine/Classes/KAssetSpawnable.uc create mode 100644 Engine/Classes/KMeshProps.uc create mode 100644 Engine/Classes/Keypoint.uc create mode 100644 Engine/Classes/KillZDamageType.uc create mode 100644 Engine/Classes/KismetBookMark.uc create mode 100644 Engine/Classes/Ladder.uc create mode 100644 Engine/Classes/LadderReachSpec.uc create mode 100644 Engine/Classes/LadderVolume.uc create mode 100644 Engine/Classes/Landscape.uc create mode 100644 Engine/Classes/LandscapeComponent.uc create mode 100644 Engine/Classes/LandscapeGizmoActiveActor.uc create mode 100644 Engine/Classes/LandscapeGizmoActor.uc create mode 100644 Engine/Classes/LandscapeGizmoRenderComponent.uc create mode 100644 Engine/Classes/LandscapeHeightfieldCollisionComponent.uc create mode 100644 Engine/Classes/LandscapeInfo.uc create mode 100644 Engine/Classes/LandscapeLayerInfoObject.uc create mode 100644 Engine/Classes/LandscapeMaterialInstanceConstant.uc create mode 100644 Engine/Classes/LandscapeProxy.uc create mode 100644 Engine/Classes/LensFlare.uc create mode 100644 Engine/Classes/LensFlareComponent.uc create mode 100644 Engine/Classes/LensFlareSource.uc create mode 100644 Engine/Classes/LevelGridVolume.uc create mode 100644 Engine/Classes/LevelGridVolumeRenderingComponent.uc create mode 100644 Engine/Classes/LevelStreaming.uc create mode 100644 Engine/Classes/LevelStreamingAlwaysLoaded.uc create mode 100644 Engine/Classes/LevelStreamingDistance.uc create mode 100644 Engine/Classes/LevelStreamingKismet.uc create mode 100644 Engine/Classes/LevelStreamingPersistent.uc create mode 100644 Engine/Classes/LevelStreamingVolume.uc create mode 100644 Engine/Classes/LiftCenter.uc create mode 100644 Engine/Classes/LiftExit.uc create mode 100644 Engine/Classes/Light.uc create mode 100644 Engine/Classes/LightComponent.uc create mode 100644 Engine/Classes/LightEnvironmentComponent.uc create mode 100644 Engine/Classes/LightFunction.uc create mode 100644 Engine/Classes/LightmappedSurfaceCollection.uc create mode 100644 Engine/Classes/LightmassCharacterIndirectDetailVolume.uc create mode 100644 Engine/Classes/LightmassImportanceVolume.uc create mode 100644 Engine/Classes/LightmassLevelSettings.uc create mode 100644 Engine/Classes/LightmassPrimitiveSettingsObject.uc create mode 100644 Engine/Classes/LineBatchComponent.uc create mode 100644 Engine/Classes/LocalMessage.uc create mode 100644 Engine/Classes/LocalPlayer.uc create mode 100644 Engine/Classes/LogitechLEDInterface.uc create mode 100644 Engine/Classes/MantleReachSpec.uc create mode 100644 Engine/Classes/MapInfo.uc create mode 100644 Engine/Classes/MassiveLODOverrideVolume.uc create mode 100644 Engine/Classes/Material.uc create mode 100644 Engine/Classes/MaterialEffect.uc create mode 100644 Engine/Classes/MaterialExpression.uc create mode 100644 Engine/Classes/MaterialExpressionAbs.uc create mode 100644 Engine/Classes/MaterialExpressionActorWorldPosition.uc create mode 100644 Engine/Classes/MaterialExpressionAdd.uc create mode 100644 Engine/Classes/MaterialExpressionAntialiasedTextureMask.uc create mode 100644 Engine/Classes/MaterialExpressionAppendVector.uc create mode 100644 Engine/Classes/MaterialExpressionBumpOffset.uc create mode 100644 Engine/Classes/MaterialExpressionCameraVector.uc create mode 100644 Engine/Classes/MaterialExpressionCameraWorldPosition.uc create mode 100644 Engine/Classes/MaterialExpressionCeil.uc create mode 100644 Engine/Classes/MaterialExpressionClamp.uc create mode 100644 Engine/Classes/MaterialExpressionComment.uc create mode 100644 Engine/Classes/MaterialExpressionComponentMask.uc create mode 100644 Engine/Classes/MaterialExpressionConstant.uc create mode 100644 Engine/Classes/MaterialExpressionConstant2Vector.uc create mode 100644 Engine/Classes/MaterialExpressionConstant3Vector.uc create mode 100644 Engine/Classes/MaterialExpressionConstant4Vector.uc create mode 100644 Engine/Classes/MaterialExpressionConstantBiasScale.uc create mode 100644 Engine/Classes/MaterialExpressionConstantClamp.uc create mode 100644 Engine/Classes/MaterialExpressionCosine.uc create mode 100644 Engine/Classes/MaterialExpressionCrossProduct.uc create mode 100644 Engine/Classes/MaterialExpressionCustom.uc create mode 100644 Engine/Classes/MaterialExpressionCustomTexture.uc create mode 100644 Engine/Classes/MaterialExpressionDepthBiasBlend.uc create mode 100644 Engine/Classes/MaterialExpressionDepthBiasedAlpha.uc create mode 100644 Engine/Classes/MaterialExpressionDepthBiasedBlend.uc create mode 100644 Engine/Classes/MaterialExpressionDepthOfFieldFunction.uc create mode 100644 Engine/Classes/MaterialExpressionDeriveNormalZ.uc create mode 100644 Engine/Classes/MaterialExpressionDesaturation.uc create mode 100644 Engine/Classes/MaterialExpressionDestColor.uc create mode 100644 Engine/Classes/MaterialExpressionDestDepth.uc create mode 100644 Engine/Classes/MaterialExpressionDistance.uc create mode 100644 Engine/Classes/MaterialExpressionDivide.uc create mode 100644 Engine/Classes/MaterialExpressionDotProduct.uc create mode 100644 Engine/Classes/MaterialExpressionDynamicParameter.uc create mode 100644 Engine/Classes/MaterialExpressionFlipBookSample.uc create mode 100644 Engine/Classes/MaterialExpressionFloor.uc create mode 100644 Engine/Classes/MaterialExpressionFluidNormal.uc create mode 100644 Engine/Classes/MaterialExpressionFmod.uc create mode 100644 Engine/Classes/MaterialExpressionFoliageImpulseDirection.uc create mode 100644 Engine/Classes/MaterialExpressionFoliageNormalizedRotationAxisAndAngle.uc create mode 100644 Engine/Classes/MaterialExpressionFontSample.uc create mode 100644 Engine/Classes/MaterialExpressionFontSampleParameter.uc create mode 100644 Engine/Classes/MaterialExpressionFrac.uc create mode 100644 Engine/Classes/MaterialExpressionFresnel.uc create mode 100644 Engine/Classes/MaterialExpressionFunctionInput.uc create mode 100644 Engine/Classes/MaterialExpressionFunctionOutput.uc create mode 100644 Engine/Classes/MaterialExpressionIf.uc create mode 100644 Engine/Classes/MaterialExpressionLandscapeLayerBlend.uc create mode 100644 Engine/Classes/MaterialExpressionLensFlareIntensity.uc create mode 100644 Engine/Classes/MaterialExpressionLensFlareOcclusion.uc create mode 100644 Engine/Classes/MaterialExpressionLensFlareRadialDistance.uc create mode 100644 Engine/Classes/MaterialExpressionLensFlareRayDistance.uc create mode 100644 Engine/Classes/MaterialExpressionLensFlareSourceDistance.uc create mode 100644 Engine/Classes/MaterialExpressionLightVector.uc create mode 100644 Engine/Classes/MaterialExpressionLightmapUVs.uc create mode 100644 Engine/Classes/MaterialExpressionLightmassReplace.uc create mode 100644 Engine/Classes/MaterialExpressionLinearInterpolate.uc create mode 100644 Engine/Classes/MaterialExpressionMaterialFunctionCall.uc create mode 100644 Engine/Classes/MaterialExpressionMeshEmitterDynamicParameter.uc create mode 100644 Engine/Classes/MaterialExpressionMeshEmitterVertexColor.uc create mode 100644 Engine/Classes/MaterialExpressionMeshSubUV.uc create mode 100644 Engine/Classes/MaterialExpressionMeshSubUVBlend.uc create mode 100644 Engine/Classes/MaterialExpressionMultiply.uc create mode 100644 Engine/Classes/MaterialExpressionNormalize.uc create mode 100644 Engine/Classes/MaterialExpressionObjectOrientation.uc create mode 100644 Engine/Classes/MaterialExpressionObjectRadius.uc create mode 100644 Engine/Classes/MaterialExpressionObjectWorldPosition.uc create mode 100644 Engine/Classes/MaterialExpressionOcclusionPercentage.uc create mode 100644 Engine/Classes/MaterialExpressionOneMinus.uc create mode 100644 Engine/Classes/MaterialExpressionPanner.uc create mode 100644 Engine/Classes/MaterialExpressionParameter.uc create mode 100644 Engine/Classes/MaterialExpressionParticleMacroUV.uc create mode 100644 Engine/Classes/MaterialExpressionParticleSubUV.uc create mode 100644 Engine/Classes/MaterialExpressionPerInstanceRandom.uc create mode 100644 Engine/Classes/MaterialExpressionPixelDepth.uc create mode 100644 Engine/Classes/MaterialExpressionPower.uc create mode 100644 Engine/Classes/MaterialExpressionQualitySwitch.uc create mode 100644 Engine/Classes/MaterialExpressionReflectionVector.uc create mode 100644 Engine/Classes/MaterialExpressionRotateAboutAxis.uc create mode 100644 Engine/Classes/MaterialExpressionRotator.uc create mode 100644 Engine/Classes/MaterialExpressionSPHFluidNormal.uc create mode 100644 Engine/Classes/MaterialExpressionSPHFluidThickness.uc create mode 100644 Engine/Classes/MaterialExpressionSPHFluidVertexColor.uc create mode 100644 Engine/Classes/MaterialExpressionScalarParameter.uc create mode 100644 Engine/Classes/MaterialExpressionSceneDepth.uc create mode 100644 Engine/Classes/MaterialExpressionSceneTexture.uc create mode 100644 Engine/Classes/MaterialExpressionScreenPosition.uc create mode 100644 Engine/Classes/MaterialExpressionScreenSize.uc create mode 100644 Engine/Classes/MaterialExpressionSine.uc create mode 100644 Engine/Classes/MaterialExpressionSphereMask.uc create mode 100644 Engine/Classes/MaterialExpressionSquareRoot.uc create mode 100644 Engine/Classes/MaterialExpressionStaticBool.uc create mode 100644 Engine/Classes/MaterialExpressionStaticBoolParameter.uc create mode 100644 Engine/Classes/MaterialExpressionStaticComponentMaskParameter.uc create mode 100644 Engine/Classes/MaterialExpressionStaticSwitch.uc create mode 100644 Engine/Classes/MaterialExpressionStaticSwitchParameter.uc create mode 100644 Engine/Classes/MaterialExpressionSubtract.uc create mode 100644 Engine/Classes/MaterialExpressionTerrainLayerCoords.uc create mode 100644 Engine/Classes/MaterialExpressionTerrainLayerSwitch.uc create mode 100644 Engine/Classes/MaterialExpressionTerrainLayerWeight.uc create mode 100644 Engine/Classes/MaterialExpressionTexelSize.uc create mode 100644 Engine/Classes/MaterialExpressionTextureCoordinate.uc create mode 100644 Engine/Classes/MaterialExpressionTextureObject.uc create mode 100644 Engine/Classes/MaterialExpressionTextureObjectParameter.uc create mode 100644 Engine/Classes/MaterialExpressionTextureSample.uc create mode 100644 Engine/Classes/MaterialExpressionTextureSampleParameter.uc create mode 100644 Engine/Classes/MaterialExpressionTextureSampleParameter2D.uc create mode 100644 Engine/Classes/MaterialExpressionTextureSampleParameterCube.uc create mode 100644 Engine/Classes/MaterialExpressionTextureSampleParameterFlipbook.uc create mode 100644 Engine/Classes/MaterialExpressionTextureSampleParameterMeshSubUV.uc create mode 100644 Engine/Classes/MaterialExpressionTextureSampleParameterMeshSubUVBlend.uc create mode 100644 Engine/Classes/MaterialExpressionTextureSampleParameterMovie.uc create mode 100644 Engine/Classes/MaterialExpressionTextureSampleParameterNormal.uc create mode 100644 Engine/Classes/MaterialExpressionTextureSampleParameterSubUV.uc create mode 100644 Engine/Classes/MaterialExpressionTime.uc create mode 100644 Engine/Classes/MaterialExpressionTransform.uc create mode 100644 Engine/Classes/MaterialExpressionTransformPosition.uc create mode 100644 Engine/Classes/MaterialExpressionTwoSidedSign.uc create mode 100644 Engine/Classes/MaterialExpressionVectorParameter.uc create mode 100644 Engine/Classes/MaterialExpressionVertexColor.uc create mode 100644 Engine/Classes/MaterialExpressionWindDirectionAndSpeed.uc create mode 100644 Engine/Classes/MaterialExpressionWorldNormal.uc create mode 100644 Engine/Classes/MaterialExpressionWorldPosition.uc create mode 100644 Engine/Classes/MaterialFunction.uc create mode 100644 Engine/Classes/MaterialInstance.uc create mode 100644 Engine/Classes/MaterialInstanceActor.uc create mode 100644 Engine/Classes/MaterialInstanceConstant.uc create mode 100644 Engine/Classes/MaterialInstanceTimeVarying.uc create mode 100644 Engine/Classes/MaterialInstanceTimeVaryingActor.uc create mode 100644 Engine/Classes/MaterialInterface.uc create mode 100644 Engine/Classes/MatineeActor.uc create mode 100644 Engine/Classes/MatineePawn.uc create mode 100644 Engine/Classes/MeshComponent.uc create mode 100644 Engine/Classes/MeshComponentFactory.uc create mode 100644 Engine/Classes/MicroTransactionBase.uc create mode 100644 Engine/Classes/MixerIntegration.uc create mode 100644 Engine/Classes/ModelComponent.uc create mode 100644 Engine/Classes/MorphNodeBase.uc create mode 100644 Engine/Classes/MorphNodeMultiPose.uc create mode 100644 Engine/Classes/MorphNodePose.uc create mode 100644 Engine/Classes/MorphNodeWeight.uc create mode 100644 Engine/Classes/MorphNodeWeightBase.uc create mode 100644 Engine/Classes/MorphNodeWeightByBoneAngle.uc create mode 100644 Engine/Classes/MorphNodeWeightByBoneRotation.uc create mode 100644 Engine/Classes/MorphTarget.uc create mode 100644 Engine/Classes/MorphTargetSet.uc create mode 100644 Engine/Classes/MorphWeightSequence.uc create mode 100644 Engine/Classes/MotionBlurEffect.uc create mode 100644 Engine/Classes/MultiCueSplineAudioComponent.uc create mode 100644 Engine/Classes/MultiFont.uc create mode 100644 Engine/Classes/MultiProviderAnalytics.uc create mode 100644 Engine/Classes/MusicTrackDataStructures.uc create mode 100644 Engine/Classes/Mutator.uc create mode 100644 Engine/Classes/NavMeshBoundsVolume.uc create mode 100644 Engine/Classes/NavMeshGoalFilter_MinPathDistance.uc create mode 100644 Engine/Classes/NavMeshGoalFilter_NotNearOtherAI.uc create mode 100644 Engine/Classes/NavMeshGoalFilter_OutOfViewFrom.uc create mode 100644 Engine/Classes/NavMeshGoalFilter_OutsideOfDotProductWedge.uc create mode 100644 Engine/Classes/NavMeshGoalFilter_PolyEncompassesAI.uc create mode 100644 Engine/Classes/NavMeshGoal_At.uc create mode 100644 Engine/Classes/NavMeshGoal_ClosestActorInList.uc create mode 100644 Engine/Classes/NavMeshGoal_Filter.uc create mode 100644 Engine/Classes/NavMeshGoal_GenericFilterContainer.uc create mode 100644 Engine/Classes/NavMeshGoal_Null.uc create mode 100644 Engine/Classes/NavMeshGoal_PolyEncompassesAI.uc create mode 100644 Engine/Classes/NavMeshGoal_Random.uc create mode 100644 Engine/Classes/NavMeshGoal_WithinDistanceEnvelope.uc create mode 100644 Engine/Classes/NavMeshObstacle.uc create mode 100644 Engine/Classes/NavMeshPathConstraint.uc create mode 100644 Engine/Classes/NavMeshPathGoalEvaluator.uc create mode 100644 Engine/Classes/NavMeshPath_AlongLine.uc create mode 100644 Engine/Classes/NavMeshPath_EnforceTwoWayEdges.uc create mode 100644 Engine/Classes/NavMeshPath_MinDistBetweenSpecsOfType.uc create mode 100644 Engine/Classes/NavMeshPath_SameCoverLink.uc create mode 100644 Engine/Classes/NavMeshPath_Toward.uc create mode 100644 Engine/Classes/NavMeshPath_WithinDistanceEnvelope.uc create mode 100644 Engine/Classes/NavMeshPath_WithinTraversalDist.uc create mode 100644 Engine/Classes/NavMeshRenderingComponent.uc create mode 100644 Engine/Classes/NavigationHandle.uc create mode 100644 Engine/Classes/NavigationPoint.uc create mode 100644 Engine/Classes/Note.uc create mode 100644 Engine/Classes/NxCylindricalForceField.uc create mode 100644 Engine/Classes/NxCylindricalForceFieldCapsule.uc create mode 100644 Engine/Classes/NxForceField.uc create mode 100644 Engine/Classes/NxForceFieldComponent.uc create mode 100644 Engine/Classes/NxForceFieldCylindricalComponent.uc create mode 100644 Engine/Classes/NxForceFieldGeneric.uc create mode 100644 Engine/Classes/NxForceFieldGenericComponent.uc create mode 100644 Engine/Classes/NxForceFieldRadial.uc create mode 100644 Engine/Classes/NxForceFieldRadialComponent.uc create mode 100644 Engine/Classes/NxForceFieldSpawnable.uc create mode 100644 Engine/Classes/NxForceFieldTornado.uc create mode 100644 Engine/Classes/NxForceFieldTornadoComponent.uc create mode 100644 Engine/Classes/NxGenericForceField.uc create mode 100644 Engine/Classes/NxGenericForceFieldBox.uc create mode 100644 Engine/Classes/NxGenericForceFieldBrush.uc create mode 100644 Engine/Classes/NxGenericForceFieldCapsule.uc create mode 100644 Engine/Classes/NxRadialCustomForceField.uc create mode 100644 Engine/Classes/NxRadialForceField.uc create mode 100644 Engine/Classes/NxTornadoAngularForceField.uc create mode 100644 Engine/Classes/NxTornadoAngularForceFieldCapsule.uc create mode 100644 Engine/Classes/NxTornadoForceField.uc create mode 100644 Engine/Classes/NxTornadoForceFieldCapsule.uc create mode 100644 Engine/Classes/ObjectReferencer.uc create mode 100644 Engine/Classes/OnlineAccountInterface.uc create mode 100644 Engine/Classes/OnlineAuthInterface.uc create mode 100644 Engine/Classes/OnlineCommunityContentInterface.uc create mode 100644 Engine/Classes/OnlineContentInterface.uc create mode 100644 Engine/Classes/OnlineEventsInterface.uc create mode 100644 Engine/Classes/OnlineGameDVRInterface.uc create mode 100644 Engine/Classes/OnlineGameDownloadInterface.uc create mode 100644 Engine/Classes/OnlineGameInterface.uc create mode 100644 Engine/Classes/OnlineGameSearch.uc create mode 100644 Engine/Classes/OnlineGameSettings.uc create mode 100644 Engine/Classes/OnlineMarketplaceInterface.uc create mode 100644 Engine/Classes/OnlineMatchmakingStats.uc create mode 100644 Engine/Classes/OnlineNewsInterface.uc create mode 100644 Engine/Classes/OnlinePartyChatInterface.uc create mode 100644 Engine/Classes/OnlinePartyInterface.uc create mode 100644 Engine/Classes/OnlinePlayerInterface.uc create mode 100644 Engine/Classes/OnlinePlayerInterfaceEx.uc create mode 100644 Engine/Classes/OnlinePlayerStorage.uc create mode 100644 Engine/Classes/OnlinePlaylistGameTypeProvider.uc create mode 100644 Engine/Classes/OnlineProfileSettings.uc create mode 100644 Engine/Classes/OnlineRecentPlayersList.uc create mode 100644 Engine/Classes/OnlineSocialInterface.uc create mode 100644 Engine/Classes/OnlineStats.uc create mode 100644 Engine/Classes/OnlineStatsInterface.uc create mode 100644 Engine/Classes/OnlineStatsRead.uc create mode 100644 Engine/Classes/OnlineStatsWrite.uc create mode 100644 Engine/Classes/OnlineSubsystem.uc create mode 100644 Engine/Classes/OnlineSuppliedUIInterface.uc create mode 100644 Engine/Classes/OnlineSystemInterface.uc create mode 100644 Engine/Classes/OnlineTitleFileCacheInterface.uc create mode 100644 Engine/Classes/OnlineTitleFileInterface.uc create mode 100644 Engine/Classes/OnlineVoiceInterface.uc create mode 100644 Engine/Classes/PBRuleNodeAlternate.uc create mode 100644 Engine/Classes/PBRuleNodeBase.uc create mode 100644 Engine/Classes/PBRuleNodeComment.uc create mode 100644 Engine/Classes/PBRuleNodeCorner.uc create mode 100644 Engine/Classes/PBRuleNodeCycle.uc create mode 100644 Engine/Classes/PBRuleNodeEdgeAngle.uc create mode 100644 Engine/Classes/PBRuleNodeEdgeMesh.uc create mode 100644 Engine/Classes/PBRuleNodeExtractTopBottom.uc create mode 100644 Engine/Classes/PBRuleNodeLODQuad.uc create mode 100644 Engine/Classes/PBRuleNodeMesh.uc create mode 100644 Engine/Classes/PBRuleNodeOcclusion.uc create mode 100644 Engine/Classes/PBRuleNodeQuad.uc create mode 100644 Engine/Classes/PBRuleNodeRandom.uc create mode 100644 Engine/Classes/PBRuleNodeRepeat.uc create mode 100644 Engine/Classes/PBRuleNodeSize.uc create mode 100644 Engine/Classes/PBRuleNodeSplit.uc create mode 100644 Engine/Classes/PBRuleNodeSubRuleset.uc create mode 100644 Engine/Classes/PBRuleNodeTransform.uc create mode 100644 Engine/Classes/PBRuleNodeVariation.uc create mode 100644 Engine/Classes/PBRuleNodeWindowWall.uc create mode 100644 Engine/Classes/ParticleEmitter.uc create mode 100644 Engine/Classes/ParticleEventManager.uc create mode 100644 Engine/Classes/ParticleLODLevel.uc create mode 100644 Engine/Classes/ParticleLightEnvironmentComponent.uc create mode 100644 Engine/Classes/ParticleModule.uc create mode 100644 Engine/Classes/ParticleModuleAcceleration.uc create mode 100644 Engine/Classes/ParticleModuleAccelerationBase.uc create mode 100644 Engine/Classes/ParticleModuleAccelerationOverLifetime.uc create mode 100644 Engine/Classes/ParticleModuleAttractorBase.uc create mode 100644 Engine/Classes/ParticleModuleAttractorBoneSocket.uc create mode 100644 Engine/Classes/ParticleModuleAttractorLine.uc create mode 100644 Engine/Classes/ParticleModuleAttractorParticle.uc create mode 100644 Engine/Classes/ParticleModuleAttractorPoint.uc create mode 100644 Engine/Classes/ParticleModuleAttractorSkelVertSurface.uc create mode 100644 Engine/Classes/ParticleModuleBeamBase.uc create mode 100644 Engine/Classes/ParticleModuleBeamModifier.uc create mode 100644 Engine/Classes/ParticleModuleBeamNoise.uc create mode 100644 Engine/Classes/ParticleModuleBeamSource.uc create mode 100644 Engine/Classes/ParticleModuleBeamTarget.uc create mode 100644 Engine/Classes/ParticleModuleCameraBase.uc create mode 100644 Engine/Classes/ParticleModuleCameraOffset.uc create mode 100644 Engine/Classes/ParticleModuleCollision.uc create mode 100644 Engine/Classes/ParticleModuleCollisionActor.uc create mode 100644 Engine/Classes/ParticleModuleCollisionBase.uc create mode 100644 Engine/Classes/ParticleModuleColor.uc create mode 100644 Engine/Classes/ParticleModuleColorBase.uc create mode 100644 Engine/Classes/ParticleModuleColorByParameter.uc create mode 100644 Engine/Classes/ParticleModuleColorOverDensity.uc create mode 100644 Engine/Classes/ParticleModuleColorOverLife.uc create mode 100644 Engine/Classes/ParticleModuleColorScaleOverDensity.uc create mode 100644 Engine/Classes/ParticleModuleColorScaleOverLife.uc create mode 100644 Engine/Classes/ParticleModuleColor_Seeded.uc create mode 100644 Engine/Classes/ParticleModuleEventBase.uc create mode 100644 Engine/Classes/ParticleModuleEventGenerator.uc create mode 100644 Engine/Classes/ParticleModuleEventReceiverBase.uc create mode 100644 Engine/Classes/ParticleModuleEventReceiverKillParticles.uc create mode 100644 Engine/Classes/ParticleModuleEventReceiverSpawn.uc create mode 100644 Engine/Classes/ParticleModuleEventSendToGame.uc create mode 100644 Engine/Classes/ParticleModuleFlexForceField.uc create mode 100644 Engine/Classes/ParticleModuleFlexSpawn.uc create mode 100644 Engine/Classes/ParticleModuleForceFieldBase.uc create mode 100644 Engine/Classes/ParticleModuleForceFieldCylindrical.uc create mode 100644 Engine/Classes/ParticleModuleForceFieldGeneric.uc create mode 100644 Engine/Classes/ParticleModuleForceFieldRadial.uc create mode 100644 Engine/Classes/ParticleModuleForceFieldTornado.uc create mode 100644 Engine/Classes/ParticleModuleKillBase.uc create mode 100644 Engine/Classes/ParticleModuleKillBox.uc create mode 100644 Engine/Classes/ParticleModuleKillHeight.uc create mode 100644 Engine/Classes/ParticleModuleLifetime.uc create mode 100644 Engine/Classes/ParticleModuleLifetimeBase.uc create mode 100644 Engine/Classes/ParticleModuleLifetime_Seeded.uc create mode 100644 Engine/Classes/ParticleModuleLocation.uc create mode 100644 Engine/Classes/ParticleModuleLocationBase.uc create mode 100644 Engine/Classes/ParticleModuleLocationBoneSocket.uc create mode 100644 Engine/Classes/ParticleModuleLocationDirect.uc create mode 100644 Engine/Classes/ParticleModuleLocationEmitter.uc create mode 100644 Engine/Classes/ParticleModuleLocationEmitterDirect.uc create mode 100644 Engine/Classes/ParticleModuleLocationPrimitiveBase.uc create mode 100644 Engine/Classes/ParticleModuleLocationPrimitiveCylinder.uc create mode 100644 Engine/Classes/ParticleModuleLocationPrimitiveCylinder_Seeded.uc create mode 100644 Engine/Classes/ParticleModuleLocationPrimitiveSphere.uc create mode 100644 Engine/Classes/ParticleModuleLocationPrimitiveSphere_Seeded.uc create mode 100644 Engine/Classes/ParticleModuleLocationSkelVertSurface.uc create mode 100644 Engine/Classes/ParticleModuleLocationStaticVertSurface.uc create mode 100644 Engine/Classes/ParticleModuleLocationWorldOffset.uc create mode 100644 Engine/Classes/ParticleModuleLocationWorldOffset_Seeded.uc create mode 100644 Engine/Classes/ParticleModuleLocation_Seeded.uc create mode 100644 Engine/Classes/ParticleModuleMaterialBase.uc create mode 100644 Engine/Classes/ParticleModuleMaterialByParameter.uc create mode 100644 Engine/Classes/ParticleModuleMeshMaterial.uc create mode 100644 Engine/Classes/ParticleModuleMeshRotation.uc create mode 100644 Engine/Classes/ParticleModuleMeshRotationRate.uc create mode 100644 Engine/Classes/ParticleModuleMeshRotationRateMultiplyLife.uc create mode 100644 Engine/Classes/ParticleModuleMeshRotationRateOverLife.uc create mode 100644 Engine/Classes/ParticleModuleMeshRotationRate_Seeded.uc create mode 100644 Engine/Classes/ParticleModuleMeshRotation_Seeded.uc create mode 100644 Engine/Classes/ParticleModuleOrbit.uc create mode 100644 Engine/Classes/ParticleModuleOrbitBase.uc create mode 100644 Engine/Classes/ParticleModuleOrientationAxisLock.uc create mode 100644 Engine/Classes/ParticleModuleOrientationBase.uc create mode 100644 Engine/Classes/ParticleModuleParameterBase.uc create mode 100644 Engine/Classes/ParticleModuleParameterDynamic.uc create mode 100644 Engine/Classes/ParticleModuleParameterDynamic_Seeded.uc create mode 100644 Engine/Classes/ParticleModulePhysicsVolumes.uc create mode 100644 Engine/Classes/ParticleModuleRequired.uc create mode 100644 Engine/Classes/ParticleModuleRotation.uc create mode 100644 Engine/Classes/ParticleModuleRotationBase.uc create mode 100644 Engine/Classes/ParticleModuleRotationOverLifetime.uc create mode 100644 Engine/Classes/ParticleModuleRotationRate.uc create mode 100644 Engine/Classes/ParticleModuleRotationRateBase.uc create mode 100644 Engine/Classes/ParticleModuleRotationRateMultiplyLife.uc create mode 100644 Engine/Classes/ParticleModuleRotationRate_Seeded.uc create mode 100644 Engine/Classes/ParticleModuleRotation_Seeded.uc create mode 100644 Engine/Classes/ParticleModuleSize.uc create mode 100644 Engine/Classes/ParticleModuleSizeBase.uc create mode 100644 Engine/Classes/ParticleModuleSizeMultiplyLife.uc create mode 100644 Engine/Classes/ParticleModuleSizeMultiplyVelocity.uc create mode 100644 Engine/Classes/ParticleModuleSizeScale.uc create mode 100644 Engine/Classes/ParticleModuleSizeScaleByTime.uc create mode 100644 Engine/Classes/ParticleModuleSizeScaleOverDensity.uc create mode 100644 Engine/Classes/ParticleModuleSize_Seeded.uc create mode 100644 Engine/Classes/ParticleModuleSourceMovement.uc create mode 100644 Engine/Classes/ParticleModuleSpawn.uc create mode 100644 Engine/Classes/ParticleModuleSpawnBase.uc create mode 100644 Engine/Classes/ParticleModuleSpawnPerUnit.uc create mode 100644 Engine/Classes/ParticleModuleStoreSpawnTime.uc create mode 100644 Engine/Classes/ParticleModuleStoreSpawnTimeBase.uc create mode 100644 Engine/Classes/ParticleModuleSubUV.uc create mode 100644 Engine/Classes/ParticleModuleSubUVBase.uc create mode 100644 Engine/Classes/ParticleModuleSubUVDirect.uc create mode 100644 Engine/Classes/ParticleModuleSubUVMovie.uc create mode 100644 Engine/Classes/ParticleModuleSubUVSelect.uc create mode 100644 Engine/Classes/ParticleModuleTrailBase.uc create mode 100644 Engine/Classes/ParticleModuleTrailSource.uc create mode 100644 Engine/Classes/ParticleModuleTrailSpawn.uc create mode 100644 Engine/Classes/ParticleModuleTrailTaper.uc create mode 100644 Engine/Classes/ParticleModuleTypeDataAnimTrail.uc create mode 100644 Engine/Classes/ParticleModuleTypeDataApex.uc create mode 100644 Engine/Classes/ParticleModuleTypeDataBase.uc create mode 100644 Engine/Classes/ParticleModuleTypeDataBeam.uc create mode 100644 Engine/Classes/ParticleModuleTypeDataBeam2.uc create mode 100644 Engine/Classes/ParticleModuleTypeDataMesh.uc create mode 100644 Engine/Classes/ParticleModuleTypeDataMeshPhysX.uc create mode 100644 Engine/Classes/ParticleModuleTypeDataPhysX.uc create mode 100644 Engine/Classes/ParticleModuleTypeDataRibbon.uc create mode 100644 Engine/Classes/ParticleModuleTypeDataTrail.uc create mode 100644 Engine/Classes/ParticleModuleTypeDataTrail2.uc create mode 100644 Engine/Classes/ParticleModuleUberBase.uc create mode 100644 Engine/Classes/ParticleModuleUberLTISIVCL.uc create mode 100644 Engine/Classes/ParticleModuleUberLTISIVCLIL.uc create mode 100644 Engine/Classes/ParticleModuleUberLTISIVCLILIRSSBLIRR.uc create mode 100644 Engine/Classes/ParticleModuleUberRainDrops.uc create mode 100644 Engine/Classes/ParticleModuleUberRainImpacts.uc create mode 100644 Engine/Classes/ParticleModuleUberRainSplashA.uc create mode 100644 Engine/Classes/ParticleModuleUberRainSplashB.uc create mode 100644 Engine/Classes/ParticleModuleVelocity.uc create mode 100644 Engine/Classes/ParticleModuleVelocityBase.uc create mode 100644 Engine/Classes/ParticleModuleVelocityCone.uc create mode 100644 Engine/Classes/ParticleModuleVelocityInheritParent.uc create mode 100644 Engine/Classes/ParticleModuleVelocityOverLifetime.uc create mode 100644 Engine/Classes/ParticleModuleVelocity_Seeded.uc create mode 100644 Engine/Classes/ParticleModuleWorldAttractor.uc create mode 100644 Engine/Classes/ParticleModuleWorldForcesBase.uc create mode 100644 Engine/Classes/ParticleSpriteEmitter.uc create mode 100644 Engine/Classes/ParticleSystem.uc create mode 100644 Engine/Classes/ParticleSystemComponent.uc create mode 100644 Engine/Classes/ParticleSystemReplay.uc create mode 100644 Engine/Classes/PathBlockingVolume.uc create mode 100644 Engine/Classes/PathConstraint.uc create mode 100644 Engine/Classes/PathGoalEvaluator.uc create mode 100644 Engine/Classes/PathNode.uc create mode 100644 Engine/Classes/PathNode_Dynamic.uc create mode 100644 Engine/Classes/PathRenderingComponent.uc create mode 100644 Engine/Classes/PathTargetPoint.uc create mode 100644 Engine/Classes/Path_AlongLine.uc create mode 100644 Engine/Classes/Path_AvoidInEscapableNodes.uc create mode 100644 Engine/Classes/Path_MinDistBetweenSpecsOfType.uc create mode 100644 Engine/Classes/Path_TowardGoal.uc create mode 100644 Engine/Classes/Path_TowardPoint.uc create mode 100644 Engine/Classes/Path_WithinDistanceEnvelope.uc create mode 100644 Engine/Classes/Path_WithinTraversalDist.uc create mode 100644 Engine/Classes/Pawn.uc create mode 100644 Engine/Classes/PhysXParticleSystem.uc create mode 100644 Engine/Classes/PhysicalMaterial.uc create mode 100644 Engine/Classes/PhysicalMaterialPropertyBase.uc create mode 100644 Engine/Classes/PhysicsAsset.uc create mode 100644 Engine/Classes/PhysicsAssetInstance.uc create mode 100644 Engine/Classes/PhysicsLODVerticalEmitter.uc create mode 100644 Engine/Classes/PhysicsVolume.uc create mode 100644 Engine/Classes/PickupFactory.uc create mode 100644 Engine/Classes/PixelFormatEnum.uci create mode 100644 Engine/Classes/PlatformInterfaceBase.uc create mode 100644 Engine/Classes/PlatformInterfaceWebResponse.uc create mode 100644 Engine/Classes/Player.uc create mode 100644 Engine/Classes/PlayerController.uc create mode 100644 Engine/Classes/PlayerInput.uc create mode 100644 Engine/Classes/PlayerManagerInteraction.uc create mode 100644 Engine/Classes/PlayerReplicationInfo.uc create mode 100644 Engine/Classes/PlayerStart.uc create mode 100644 Engine/Classes/PlayfabInterface.uc create mode 100644 Engine/Classes/PointLight.uc create mode 100644 Engine/Classes/PointLightComponent.uc create mode 100644 Engine/Classes/PointLightMovable.uc create mode 100644 Engine/Classes/PointLightToggleable.uc create mode 100644 Engine/Classes/PortalMarker.uc create mode 100644 Engine/Classes/PortalTeleporter.uc create mode 100644 Engine/Classes/PortalVolume.uc create mode 100644 Engine/Classes/PostProcessChain.uc create mode 100644 Engine/Classes/PostProcessEffect.uc create mode 100644 Engine/Classes/PostProcessVolume.uc create mode 100644 Engine/Classes/PotentialClimbWatcher.uc create mode 100644 Engine/Classes/PrecomputedVisibilityOverrideVolume.uc create mode 100644 Engine/Classes/PrecomputedVisibilityVolume.uc create mode 100644 Engine/Classes/Prefab.uc create mode 100644 Engine/Classes/PrefabInstance.uc create mode 100644 Engine/Classes/PrefabSequence.uc create mode 100644 Engine/Classes/PrefabSequenceContainer.uc create mode 100644 Engine/Classes/PrimitiveComponent.uc create mode 100644 Engine/Classes/PrimitiveComponentFactory.uc create mode 100644 Engine/Classes/ProcBuilding.uc create mode 100644 Engine/Classes/ProcBuildingRuleset.uc create mode 100644 Engine/Classes/ProcBuilding_SimpleLODActor.uc create mode 100644 Engine/Classes/Projectile.uc create mode 100644 Engine/Classes/ProscribedReachSpec.uc create mode 100644 Engine/Classes/Pylon.uc create mode 100644 Engine/Classes/PylonSeed.uc create mode 100644 Engine/Classes/RB_BSJointActor.uc create mode 100644 Engine/Classes/RB_BSJointSetup.uc create mode 100644 Engine/Classes/RB_BodyInstance.uc create mode 100644 Engine/Classes/RB_BodySetup.uc create mode 100644 Engine/Classes/RB_ConstraintActor.uc create mode 100644 Engine/Classes/RB_ConstraintActorSpawnable.uc create mode 100644 Engine/Classes/RB_ConstraintDrawComponent.uc create mode 100644 Engine/Classes/RB_ConstraintInstance.uc create mode 100644 Engine/Classes/RB_ConstraintSetup.uc create mode 100644 Engine/Classes/RB_CylindricalForceActor.uc create mode 100644 Engine/Classes/RB_DistanceJointSetup.uc create mode 100644 Engine/Classes/RB_ForceFieldExcludeVolume.uc create mode 100644 Engine/Classes/RB_Handle.uc create mode 100644 Engine/Classes/RB_HingeActor.uc create mode 100644 Engine/Classes/RB_HingeSetup.uc create mode 100644 Engine/Classes/RB_LineImpulseActor.uc create mode 100644 Engine/Classes/RB_PrismaticActor.uc create mode 100644 Engine/Classes/RB_PrismaticSetup.uc create mode 100644 Engine/Classes/RB_PulleyJointActor.uc create mode 100644 Engine/Classes/RB_PulleyJointSetup.uc create mode 100644 Engine/Classes/RB_RadialForceActor.uc create mode 100644 Engine/Classes/RB_RadialImpulseActor.uc create mode 100644 Engine/Classes/RB_RadialImpulseComponent.uc create mode 100644 Engine/Classes/RB_SkelJointSetup.uc create mode 100644 Engine/Classes/RB_Spring.uc create mode 100644 Engine/Classes/RB_StayUprightSetup.uc create mode 100644 Engine/Classes/RB_Thruster.uc create mode 100644 Engine/Classes/RadialBlurActor.uc create mode 100644 Engine/Classes/RadialBlurComponent.uc create mode 100644 Engine/Classes/RazerLEDInterface.uc create mode 100644 Engine/Classes/ReachSpec.uc create mode 100644 Engine/Classes/ReplicationInfo.uc create mode 100644 Engine/Classes/ReverbVolume.uc create mode 100644 Engine/Classes/ReverbVolumeToggleable.uc create mode 100644 Engine/Classes/RigidBodyBase.uc create mode 100644 Engine/Classes/Route.uc create mode 100644 Engine/Classes/RouteRenderingComponent.uc create mode 100644 Engine/Classes/SVehicle.uc create mode 100644 Engine/Classes/SVehicleSimBase.uc create mode 100644 Engine/Classes/SVehicleSimCar.uc create mode 100644 Engine/Classes/SVehicleSimTank.uc create mode 100644 Engine/Classes/SVehicleWheel.uc create mode 100644 Engine/Classes/SaveGameSummary.uc create mode 100644 Engine/Classes/SavedMove.uc create mode 100644 Engine/Classes/Scene.uc create mode 100644 Engine/Classes/SceneCapture2DActor.uc create mode 100644 Engine/Classes/SceneCapture2DComponent.uc create mode 100644 Engine/Classes/SceneCapture2DHitMaskComponent.uc create mode 100644 Engine/Classes/SceneCaptureActor.uc create mode 100644 Engine/Classes/SceneCaptureComponent.uc create mode 100644 Engine/Classes/SceneCaptureCubeMapActor.uc create mode 100644 Engine/Classes/SceneCaptureCubeMapComponent.uc create mode 100644 Engine/Classes/SceneCapturePortalActor.uc create mode 100644 Engine/Classes/SceneCapturePortalComponent.uc create mode 100644 Engine/Classes/SceneCaptureReflectActor.uc create mode 100644 Engine/Classes/SceneCaptureReflectComponent.uc create mode 100644 Engine/Classes/Scout.uc create mode 100644 Engine/Classes/ScriptViewportClient.uc create mode 100644 Engine/Classes/ScriptedTexture.uc create mode 100644 Engine/Classes/SeqAct_AIAbortMoveToActor.uc create mode 100644 Engine/Classes/SeqAct_AIMoveToActor.uc create mode 100644 Engine/Classes/SeqAct_AccessObjectList.uc create mode 100644 Engine/Classes/SeqAct_ActivateRemoteEvent.uc create mode 100644 Engine/Classes/SeqAct_ActorFactory.uc create mode 100644 Engine/Classes/SeqAct_ActorFactoryEx.uc create mode 100644 Engine/Classes/SeqAct_AddFloat.uc create mode 100644 Engine/Classes/SeqAct_AddInt.uc create mode 100644 Engine/Classes/SeqAct_AddRemoveFaceFXAnimSet.uc create mode 100644 Engine/Classes/SeqAct_AndGate.uc create mode 100644 Engine/Classes/SeqAct_ApplySoundNode.uc create mode 100644 Engine/Classes/SeqAct_AssignController.uc create mode 100644 Engine/Classes/SeqAct_AttachToActor.uc create mode 100644 Engine/Classes/SeqAct_AttachToEvent.uc create mode 100644 Engine/Classes/SeqAct_CameraFade.uc create mode 100644 Engine/Classes/SeqAct_CameraLookAt.uc create mode 100644 Engine/Classes/SeqAct_CameraShake.uc create mode 100644 Engine/Classes/SeqAct_CastToFloat.uc create mode 100644 Engine/Classes/SeqAct_CastToInt.uc create mode 100644 Engine/Classes/SeqAct_ChangeCollision.uc create mode 100644 Engine/Classes/SeqAct_CommitMapChange.uc create mode 100644 Engine/Classes/SeqAct_ConsoleCommand.uc create mode 100644 Engine/Classes/SeqAct_ControlMovieTexture.uc create mode 100644 Engine/Classes/SeqAct_ConvertToString.uc create mode 100644 Engine/Classes/SeqAct_Delay.uc create mode 100644 Engine/Classes/SeqAct_DelaySwitch.uc create mode 100644 Engine/Classes/SeqAct_Destroy.uc create mode 100644 Engine/Classes/SeqAct_DivideFloat.uc create mode 100644 Engine/Classes/SeqAct_DivideInt.uc create mode 100644 Engine/Classes/SeqAct_DrawText.uc create mode 100644 Engine/Classes/SeqAct_FeatureTest.uc create mode 100644 Engine/Classes/SeqAct_FinishSequence.uc create mode 100644 Engine/Classes/SeqAct_FlyThroughHasEnded.uc create mode 100644 Engine/Classes/SeqAct_ForceFeedback.uc create mode 100644 Engine/Classes/SeqAct_ForceGarbageCollection.uc create mode 100644 Engine/Classes/SeqAct_Gate.uc create mode 100644 Engine/Classes/SeqAct_GetDistance.uc create mode 100644 Engine/Classes/SeqAct_GetLocationAndRotation.uc create mode 100644 Engine/Classes/SeqAct_GetProperty.uc create mode 100644 Engine/Classes/SeqAct_GetVectorComponents.uc create mode 100644 Engine/Classes/SeqAct_GetVelocity.uc create mode 100644 Engine/Classes/SeqAct_GiveInventory.uc create mode 100644 Engine/Classes/SeqAct_HeadTrackingControl.uc create mode 100644 Engine/Classes/SeqAct_Interp.uc create mode 100644 Engine/Classes/SeqAct_IsInObjectList.uc create mode 100644 Engine/Classes/SeqAct_Latent.uc create mode 100644 Engine/Classes/SeqAct_LevelStreaming.uc create mode 100644 Engine/Classes/SeqAct_LevelStreamingBase.uc create mode 100644 Engine/Classes/SeqAct_LevelVisibility.uc create mode 100644 Engine/Classes/SeqAct_Log.uc create mode 100644 Engine/Classes/SeqAct_MITV_Activate.uc create mode 100644 Engine/Classes/SeqAct_ModifyCover.uc create mode 100644 Engine/Classes/SeqAct_ModifyHealth.uc create mode 100644 Engine/Classes/SeqAct_ModifyObjectList.uc create mode 100644 Engine/Classes/SeqAct_MultiLevelStreaming.uc create mode 100644 Engine/Classes/SeqAct_MultiplyFloat.uc create mode 100644 Engine/Classes/SeqAct_MultiplyInt.uc create mode 100644 Engine/Classes/SeqAct_ParticleEventGenerator.uc create mode 100644 Engine/Classes/SeqAct_PhysXSwitch.uc create mode 100644 Engine/Classes/SeqAct_PlayCameraAnim.uc create mode 100644 Engine/Classes/SeqAct_PlayFaceFXAnim.uc create mode 100644 Engine/Classes/SeqAct_PlayMusicTrack.uc create mode 100644 Engine/Classes/SeqAct_PlaySound.uc create mode 100644 Engine/Classes/SeqAct_Possess.uc create mode 100644 Engine/Classes/SeqAct_PrepareMapChange.uc create mode 100644 Engine/Classes/SeqAct_ProjectileFactory.uc create mode 100644 Engine/Classes/SeqAct_RandomSwitch.uc create mode 100644 Engine/Classes/SeqAct_RangeSwitch.uc create mode 100644 Engine/Classes/SeqAct_SetActiveAnimChild.uc create mode 100644 Engine/Classes/SeqAct_SetApexClothingParam.uc create mode 100644 Engine/Classes/SeqAct_SetBlockRigidBody.uc create mode 100644 Engine/Classes/SeqAct_SetBool.uc create mode 100644 Engine/Classes/SeqAct_SetCameraTarget.uc create mode 100644 Engine/Classes/SeqAct_SetDOFParams.uc create mode 100644 Engine/Classes/SeqAct_SetDamageInstigator.uc create mode 100644 Engine/Classes/SeqAct_SetFloat.uc create mode 100644 Engine/Classes/SeqAct_SetInt.uc create mode 100644 Engine/Classes/SeqAct_SetLocation.uc create mode 100644 Engine/Classes/SeqAct_SetMatInstScalarParam.uc create mode 100644 Engine/Classes/SeqAct_SetMatInstTexParam.uc create mode 100644 Engine/Classes/SeqAct_SetMatInstVectorParam.uc create mode 100644 Engine/Classes/SeqAct_SetMaterial.uc create mode 100644 Engine/Classes/SeqAct_SetMesh.uc create mode 100644 Engine/Classes/SeqAct_SetMotionBlurParams.uc create mode 100644 Engine/Classes/SeqAct_SetObject.uc create mode 100644 Engine/Classes/SeqAct_SetParticleSysParam.uc create mode 100644 Engine/Classes/SeqAct_SetPhysics.uc create mode 100644 Engine/Classes/SeqAct_SetRigidBodyIgnoreVehicles.uc create mode 100644 Engine/Classes/SeqAct_SetSequenceVariable.uc create mode 100644 Engine/Classes/SeqAct_SetSkelControlTarget.uc create mode 100644 Engine/Classes/SeqAct_SetSoundMode.uc create mode 100644 Engine/Classes/SeqAct_SetString.uc create mode 100644 Engine/Classes/SeqAct_SetVector.uc create mode 100644 Engine/Classes/SeqAct_SetVectorComponents.uc create mode 100644 Engine/Classes/SeqAct_SetVelocity.uc create mode 100644 Engine/Classes/SeqAct_SetWorldAttractorParam.uc create mode 100644 Engine/Classes/SeqAct_StreamInTextures.uc create mode 100644 Engine/Classes/SeqAct_SubtractFloat.uc create mode 100644 Engine/Classes/SeqAct_SubtractInt.uc create mode 100644 Engine/Classes/SeqAct_Switch.uc create mode 100644 Engine/Classes/SeqAct_Teleport.uc create mode 100644 Engine/Classes/SeqAct_Timer.uc create mode 100644 Engine/Classes/SeqAct_Toggle.uc create mode 100644 Engine/Classes/SeqAct_ToggleAffectedByHitEffects.uc create mode 100644 Engine/Classes/SeqAct_ToggleCinematicMode.uc create mode 100644 Engine/Classes/SeqAct_ToggleConstraintDrive.uc create mode 100644 Engine/Classes/SeqAct_ToggleGodMode.uc create mode 100644 Engine/Classes/SeqAct_ToggleHUD.uc create mode 100644 Engine/Classes/SeqAct_ToggleHidden.uc create mode 100644 Engine/Classes/SeqAct_ToggleInput.uc create mode 100644 Engine/Classes/SeqAct_Trace.uc create mode 100644 Engine/Classes/SeqAct_UpdatePhysBonesFromAnim.uc create mode 100644 Engine/Classes/SeqAct_WaitForLevelsVisible.uc create mode 100644 Engine/Classes/SeqCond_CompareBool.uc create mode 100644 Engine/Classes/SeqCond_CompareFloat.uc create mode 100644 Engine/Classes/SeqCond_CompareInt.uc create mode 100644 Engine/Classes/SeqCond_CompareObject.uc create mode 100644 Engine/Classes/SeqCond_GetServerType.uc create mode 100644 Engine/Classes/SeqCond_Increment.uc create mode 100644 Engine/Classes/SeqCond_IncrementFloat.uc create mode 100644 Engine/Classes/SeqCond_IsAlive.uc create mode 100644 Engine/Classes/SeqCond_IsBenchmarking.uc create mode 100644 Engine/Classes/SeqCond_IsConsole.uc create mode 100644 Engine/Classes/SeqCond_IsInCombat.uc create mode 100644 Engine/Classes/SeqCond_IsLoggedIn.uc create mode 100644 Engine/Classes/SeqCond_IsPIE.uc create mode 100644 Engine/Classes/SeqCond_IsSameTeam.uc create mode 100644 Engine/Classes/SeqCond_MatureLanguage.uc create mode 100644 Engine/Classes/SeqCond_ShowGore.uc create mode 100644 Engine/Classes/SeqCond_SwitchBase.uc create mode 100644 Engine/Classes/SeqCond_SwitchClass.uc create mode 100644 Engine/Classes/SeqCond_SwitchObject.uc create mode 100644 Engine/Classes/SeqCond_SwitchPlatform.uc create mode 100644 Engine/Classes/SeqEvent_AIReachedRouteActor.uc create mode 100644 Engine/Classes/SeqEvent_AISeeEnemy.uc create mode 100644 Engine/Classes/SeqEvent_AnalogInput.uc create mode 100644 Engine/Classes/SeqEvent_AnimNotify.uc create mode 100644 Engine/Classes/SeqEvent_Console.uc create mode 100644 Engine/Classes/SeqEvent_ConstraintBroken.uc create mode 100644 Engine/Classes/SeqEvent_Death.uc create mode 100644 Engine/Classes/SeqEvent_Destroyed.uc create mode 100644 Engine/Classes/SeqEvent_GetInventory.uc create mode 100644 Engine/Classes/SeqEvent_HitWall.uc create mode 100644 Engine/Classes/SeqEvent_Input.uc create mode 100644 Engine/Classes/SeqEvent_LOS.uc create mode 100644 Engine/Classes/SeqEvent_LevelBeginning.uc create mode 100644 Engine/Classes/SeqEvent_LevelLoaded.uc create mode 100644 Engine/Classes/SeqEvent_LevelStartup.uc create mode 100644 Engine/Classes/SeqEvent_MobileTouch.uc create mode 100644 Engine/Classes/SeqEvent_Mover.uc create mode 100644 Engine/Classes/SeqEvent_ParticleEvent.uc create mode 100644 Engine/Classes/SeqEvent_PickupStatusChange.uc create mode 100644 Engine/Classes/SeqEvent_PlayerSpawned.uc create mode 100644 Engine/Classes/SeqEvent_ProjectileLanded.uc create mode 100644 Engine/Classes/SeqEvent_RemoteEvent.uc create mode 100644 Engine/Classes/SeqEvent_RigidBodyCollision.uc create mode 100644 Engine/Classes/SeqEvent_SeeDeath.uc create mode 100644 Engine/Classes/SeqEvent_SequenceActivated.uc create mode 100644 Engine/Classes/SeqEvent_TakeDamage.uc create mode 100644 Engine/Classes/SeqEvent_Touch.uc create mode 100644 Engine/Classes/SeqEvent_TouchInput.uc create mode 100644 Engine/Classes/SeqEvent_Used.uc create mode 100644 Engine/Classes/SeqVar_Bool.uc create mode 100644 Engine/Classes/SeqVar_Byte.uc create mode 100644 Engine/Classes/SeqVar_Character.uc create mode 100644 Engine/Classes/SeqVar_External.uc create mode 100644 Engine/Classes/SeqVar_Float.uc create mode 100644 Engine/Classes/SeqVar_Group.uc create mode 100644 Engine/Classes/SeqVar_Int.uc create mode 100644 Engine/Classes/SeqVar_Name.uc create mode 100644 Engine/Classes/SeqVar_Named.uc create mode 100644 Engine/Classes/SeqVar_Object.uc create mode 100644 Engine/Classes/SeqVar_ObjectList.uc create mode 100644 Engine/Classes/SeqVar_ObjectVolume.uc create mode 100644 Engine/Classes/SeqVar_Player.uc create mode 100644 Engine/Classes/SeqVar_RandomFloat.uc create mode 100644 Engine/Classes/SeqVar_RandomInt.uc create mode 100644 Engine/Classes/SeqVar_String.uc create mode 100644 Engine/Classes/SeqVar_Union.uc create mode 100644 Engine/Classes/SeqVar_Vector.uc create mode 100644 Engine/Classes/Sequence.uc create mode 100644 Engine/Classes/SequenceAction.uc create mode 100644 Engine/Classes/SequenceCondition.uc create mode 100644 Engine/Classes/SequenceEvent.uc create mode 100644 Engine/Classes/SequenceFrame.uc create mode 100644 Engine/Classes/SequenceFrameWrapped.uc create mode 100644 Engine/Classes/SequenceObject.uc create mode 100644 Engine/Classes/SequenceOp.uc create mode 100644 Engine/Classes/SequenceVariable.uc create mode 100644 Engine/Classes/Settings.uc create mode 100644 Engine/Classes/ShadowMap2D.uc create mode 100644 Engine/Classes/ShadowMapTexture2D.uc create mode 100644 Engine/Classes/SharedCloudFileInterface.uc create mode 100644 Engine/Classes/SimpleSplineAudioComponent.uc create mode 100644 Engine/Classes/SimpleSplineNonLoopAudioComponent.uc create mode 100644 Engine/Classes/SkelControlBase.uc create mode 100644 Engine/Classes/SkelControlFootPlacement.uc create mode 100644 Engine/Classes/SkelControlHandlebars.uc create mode 100644 Engine/Classes/SkelControlLimb.uc create mode 100644 Engine/Classes/SkelControlLookAt.uc create mode 100644 Engine/Classes/SkelControlSingleBone.uc create mode 100644 Engine/Classes/SkelControlSpline.uc create mode 100644 Engine/Classes/SkelControlTrail.uc create mode 100644 Engine/Classes/SkelControlWheel.uc create mode 100644 Engine/Classes/SkelControl_CCD_IK.uc create mode 100644 Engine/Classes/SkelControl_Multiply.uc create mode 100644 Engine/Classes/SkelControl_TwistBone.uc create mode 100644 Engine/Classes/SkeletalMesh.uc create mode 100644 Engine/Classes/SkeletalMeshActor.uc create mode 100644 Engine/Classes/SkeletalMeshActorBasedOnExtremeContent.uc create mode 100644 Engine/Classes/SkeletalMeshActorMAT.uc create mode 100644 Engine/Classes/SkeletalMeshActorMATSpawnable.uc create mode 100644 Engine/Classes/SkeletalMeshActorMATWalkable.uc create mode 100644 Engine/Classes/SkeletalMeshActorSpawnable.uc create mode 100644 Engine/Classes/SkeletalMeshCinematicActor.uc create mode 100644 Engine/Classes/SkeletalMeshComponent.uc create mode 100644 Engine/Classes/SkeletalMeshSocket.uc create mode 100644 Engine/Classes/SkyLight.uc create mode 100644 Engine/Classes/SkyLightComponent.uc create mode 100644 Engine/Classes/SkyLightToggleable.uc create mode 100644 Engine/Classes/SlotToSlotReachSpec.uc create mode 100644 Engine/Classes/SoundClass.uc create mode 100644 Engine/Classes/SoundCue.uc create mode 100644 Engine/Classes/SoundMode.uc create mode 100644 Engine/Classes/SoundNode.uc create mode 100644 Engine/Classes/SoundNodeAmbient.uc create mode 100644 Engine/Classes/SoundNodeAmbientNonLoop.uc create mode 100644 Engine/Classes/SoundNodeAmbientNonLoopToggle.uc create mode 100644 Engine/Classes/SoundNodeAttenuation.uc create mode 100644 Engine/Classes/SoundNodeAttenuationAndGain.uc create mode 100644 Engine/Classes/SoundNodeConcatenator.uc create mode 100644 Engine/Classes/SoundNodeConcatenatorRadio.uc create mode 100644 Engine/Classes/SoundNodeDelay.uc create mode 100644 Engine/Classes/SoundNodeDistanceCrossFade.uc create mode 100644 Engine/Classes/SoundNodeDoppler.uc create mode 100644 Engine/Classes/SoundNodeEnveloper.uc create mode 100644 Engine/Classes/SoundNodeLooping.uc create mode 100644 Engine/Classes/SoundNodeMature.uc create mode 100644 Engine/Classes/SoundNodeMixer.uc create mode 100644 Engine/Classes/SoundNodeModulator.uc create mode 100644 Engine/Classes/SoundNodeModulatorContinuous.uc create mode 100644 Engine/Classes/SoundNodeOscillator.uc create mode 100644 Engine/Classes/SoundNodeRandom.uc create mode 100644 Engine/Classes/SoundNodeWave.uc create mode 100644 Engine/Classes/SoundNodeWaveParam.uc create mode 100644 Engine/Classes/SoundNodeWaveStreaming.uc create mode 100644 Engine/Classes/SpeechRecognition.uc create mode 100644 Engine/Classes/SpeedTree.uc create mode 100644 Engine/Classes/SpeedTreeActor.uc create mode 100644 Engine/Classes/SpeedTreeActorFactory.uc create mode 100644 Engine/Classes/SpeedTreeComponent.uc create mode 100644 Engine/Classes/SpeedTreeComponentFactory.uc create mode 100644 Engine/Classes/SphericalHarmonicLightComponent.uc create mode 100644 Engine/Classes/SplineActor.uc create mode 100644 Engine/Classes/SplineAudioComponent.uc create mode 100644 Engine/Classes/SplineComponent.uc create mode 100644 Engine/Classes/SplineComponentSimplified.uc create mode 100644 Engine/Classes/SplineLoftActor.uc create mode 100644 Engine/Classes/SplineLoftActorMovable.uc create mode 100644 Engine/Classes/SplineMeshComponent.uc create mode 100644 Engine/Classes/SpotLight.uc create mode 100644 Engine/Classes/SpotLightComponent.uc create mode 100644 Engine/Classes/SpotLightMovable.uc create mode 100644 Engine/Classes/SpotLightToggleable.uc create mode 100644 Engine/Classes/SpriteComponent.uc create mode 100644 Engine/Classes/StaticLightCollectionActor.uc create mode 100644 Engine/Classes/StaticMeshActor.uc create mode 100644 Engine/Classes/StaticMeshActorBase.uc create mode 100644 Engine/Classes/StaticMeshActorBasedOnExtremeContent.uc create mode 100644 Engine/Classes/StaticMeshCollectionActor.uc create mode 100644 Engine/Classes/StaticMeshComponent.uc create mode 100644 Engine/Classes/StaticMeshComponentFactory.uc create mode 100644 Engine/Classes/StringsTag.uc create mode 100644 Engine/Classes/Surface.uc create mode 100644 Engine/Classes/SwatTurnReachSpec.uc create mode 100644 Engine/Classes/TWDeferredWorkManager.uc create mode 100644 Engine/Classes/TWFixupSplattermapUVCommandlet.uc create mode 100644 Engine/Classes/TWGenerateLightmapUVCommandlet.uc create mode 100644 Engine/Classes/TWIndoorLightingVolume.uc create mode 100644 Engine/Classes/TWMaterialExpressionLightBrightnessMultiplier.uc create mode 100644 Engine/Classes/TWOnlineLobby.uc create mode 100644 Engine/Classes/TWOnlineUGCInterface.uc create mode 100644 Engine/Classes/TWOutdoorLightingVolume.uc create mode 100644 Engine/Classes/TWParticleModuleEventReceiverBlood.uc create mode 100644 Engine/Classes/TWParticleModuleEventReceiverSFX.uc create mode 100644 Engine/Classes/TWPostProcessEffect.uc create mode 100644 Engine/Classes/TWSceneCapture2DDPGComponent.uc create mode 100644 Engine/Classes/TWSeqEvent_LightFlicker.uc create mode 100644 Engine/Classes/TWSplatterMap2D.uc create mode 100644 Engine/Classes/TWSplatterMapTexture2D.uc create mode 100644 Engine/Classes/TargetPoint.uc create mode 100644 Engine/Classes/TeamInfo.uc create mode 100644 Engine/Classes/TeleportReachSpec.uc create mode 100644 Engine/Classes/Teleporter.uc create mode 100644 Engine/Classes/Terrain.uc create mode 100644 Engine/Classes/TerrainComponent.uc create mode 100644 Engine/Classes/TerrainLayerSetup.uc create mode 100644 Engine/Classes/TerrainMaterial.uc create mode 100644 Engine/Classes/TerrainWeightMapTexture.uc create mode 100644 Engine/Classes/TestSplittingVolume.uc create mode 100644 Engine/Classes/Texture.uc create mode 100644 Engine/Classes/Texture2D.uc create mode 100644 Engine/Classes/Texture2DComposite.uc create mode 100644 Engine/Classes/Texture2DDynamic.uc create mode 100644 Engine/Classes/TextureCube.uc create mode 100644 Engine/Classes/TextureFlipBook.uc create mode 100644 Engine/Classes/TextureMovie.uc create mode 100644 Engine/Classes/TextureRenderTarget.uc create mode 100644 Engine/Classes/TextureRenderTarget2D.uc create mode 100644 Engine/Classes/TextureRenderTargetCube.uc create mode 100644 Engine/Classes/TranslationContext.uc create mode 100644 Engine/Classes/TranslatorTag.uc create mode 100644 Engine/Classes/Trigger.uc create mode 100644 Engine/Classes/TriggerStreamingLevel.uc create mode 100644 Engine/Classes/TriggerVolume.uc create mode 100644 Engine/Classes/Trigger_Dynamic.uc create mode 100644 Engine/Classes/Trigger_LOS.uc create mode 100644 Engine/Classes/Trigger_PawnsOnly.uc create mode 100644 Engine/Classes/TriggeredPath.uc create mode 100644 Engine/Classes/TwitterIntegrationBase.uc create mode 100644 Engine/Classes/UICharacterSummary.uc create mode 100644 Engine/Classes/UIDataProvider.uc create mode 100644 Engine/Classes/UIDataProvider_MenuItem.uc create mode 100644 Engine/Classes/UIDataProvider_OnlineFriendMessages.uc create mode 100644 Engine/Classes/UIDataProvider_OnlineFriends.uc create mode 100644 Engine/Classes/UIDataProvider_OnlinePartyChatList.uc create mode 100644 Engine/Classes/UIDataProvider_OnlinePlayerDataBase.uc create mode 100644 Engine/Classes/UIDataProvider_OnlinePlayerStorage.uc create mode 100644 Engine/Classes/UIDataProvider_OnlinePlayerStorageArray.uc create mode 100644 Engine/Classes/UIDataProvider_OnlineProfileSettings.uc create mode 100644 Engine/Classes/UIDataProvider_PlayerAchievements.uc create mode 100644 Engine/Classes/UIDataProvider_Settings.uc create mode 100644 Engine/Classes/UIDataProvider_SettingsArray.uc create mode 100644 Engine/Classes/UIDataStore.uc create mode 100644 Engine/Classes/UIDataStorePublisher.uc create mode 100644 Engine/Classes/UIDataStoreSubscriber.uc create mode 100644 Engine/Classes/UIDataStore_DynamicResource.uc create mode 100644 Engine/Classes/UIDataStore_Fonts.uc create mode 100644 Engine/Classes/UIDataStore_GameResource.uc create mode 100644 Engine/Classes/UIDataStore_GameState.uc create mode 100644 Engine/Classes/UIDataStore_InputAlias.uc create mode 100644 Engine/Classes/UIDataStore_MenuItems.uc create mode 100644 Engine/Classes/UIDataStore_OnlineGameSearch.uc create mode 100644 Engine/Classes/UIDataStore_OnlineGameSettings.uc create mode 100644 Engine/Classes/UIDataStore_OnlinePlayerData.uc create mode 100644 Engine/Classes/UIDataStore_OnlineStats.uc create mode 100644 Engine/Classes/UIDataStore_Registry.uc create mode 100644 Engine/Classes/UIDataStore_Remote.uc create mode 100644 Engine/Classes/UIDataStore_Settings.uc create mode 100644 Engine/Classes/UIDataStore_StringAliasMap.uc create mode 100644 Engine/Classes/UIDataStore_StringBase.uc create mode 100644 Engine/Classes/UIDev.uci create mode 100644 Engine/Classes/UIGameInfoSummary.uc create mode 100644 Engine/Classes/UIInteraction.uc create mode 100644 Engine/Classes/UIManager.uc create mode 100644 Engine/Classes/UIMapSummary.uc create mode 100644 Engine/Classes/UIPropertyDataProvider.uc create mode 100644 Engine/Classes/UIResourceCombinationProvider.uc create mode 100644 Engine/Classes/UIResourceDataProvider.uc create mode 100644 Engine/Classes/UIRoot.uc create mode 100644 Engine/Classes/UISceneClient.uc create mode 100644 Engine/Classes/UISoundTheme.uc create mode 100644 Engine/Classes/UIWeaponSummary.uc create mode 100644 Engine/Classes/UberPostProcessEffect.uc create mode 100644 Engine/Classes/UserCloudFileCloudSaveSystemDataBlobStore.uc create mode 100644 Engine/Classes/UserCloudFileInterface.uc create mode 100644 Engine/Classes/Vehicle.uc create mode 100644 Engine/Classes/Volume.uc create mode 100644 Engine/Classes/VolumePathNode.uc create mode 100644 Engine/Classes/VolumeTimer.uc create mode 100644 Engine/Classes/WallTransReachSpec.uc create mode 100644 Engine/Classes/WaterVolume.uc create mode 100644 Engine/Classes/WaveFormBase.uc create mode 100644 Engine/Classes/Weapon.uc create mode 100644 Engine/Classes/WindDirectionalSource.uc create mode 100644 Engine/Classes/WindDirectionalSourceComponent.uc create mode 100644 Engine/Classes/WindPointSource.uc create mode 100644 Engine/Classes/WindPointSourceComponent.uc create mode 100644 Engine/Classes/WorldAttractor.uc create mode 100644 Engine/Classes/WorldInfo.uc create mode 100644 Engine/Classes/ZoneInfo.uc create mode 100644 GFxUI/Classes/FlashMovie.uc create mode 100644 GFxUI/Classes/GFxAction_CloseMovie.uc create mode 100644 GFxUI/Classes/GFxAction_GetVariable.uc create mode 100644 GFxUI/Classes/GFxAction_Invoke.uc create mode 100644 GFxUI/Classes/GFxAction_OpenMovie.uc create mode 100644 GFxUI/Classes/GFxAction_SetCaptureKeys.uc create mode 100644 GFxUI/Classes/GFxAction_SetVariable.uc create mode 100644 GFxUI/Classes/GFxClikWidget.uc create mode 100644 GFxUI/Classes/GFxEngine.uc create mode 100644 GFxUI/Classes/GFxEvent_FsCommand.uc create mode 100644 GFxUI/Classes/GFxFSCmdHandler.uc create mode 100644 GFxUI/Classes/GFxFSCmdHandler_Kismet.uc create mode 100644 GFxUI/Classes/GFxInteraction.uc create mode 100644 GFxUI/Classes/GFxMoviePlayer.uc create mode 100644 GFxUI/Classes/GFxObject.uc create mode 100644 GFxUI/Classes/GFxRawData.uc create mode 100644 GFxUI/Classes/SwfMovie.uc create mode 100644 GFxUIEditor/Classes/GFxImportCommandlet.uc create mode 100644 GFxUIEditor/Classes/GFxMovieFactory.uc create mode 100644 GFxUIEditor/Classes/GFxReimportCommandlet.uc create mode 100644 GFxUIEditor/Classes/GenericBrowserType_GFxMovie.uc create mode 100644 GameFramework/Classes/DebugCameraController.uc create mode 100644 GameFramework/Classes/DebugCameraHUD.uc create mode 100644 GameFramework/Classes/DebugCameraInput.uc create mode 100644 GameFramework/Classes/DynamicGameCrowdDestination.uc create mode 100644 GameFramework/Classes/DynamicSpriteComponent.uc create mode 100644 GameFramework/Classes/FrameworkGame.uc create mode 100644 GameFramework/Classes/GameAICmd_Hover_MoveToGoal.uc create mode 100644 GameFramework/Classes/GameAICmd_Hover_MoveToGoal_Mesh.uc create mode 100644 GameFramework/Classes/GameAICommand.uc create mode 100644 GameFramework/Classes/GameAIController.uc create mode 100644 GameFramework/Classes/GameCameraBase.uc create mode 100644 GameFramework/Classes/GameCameraBlockingVolume.uc create mode 100644 GameFramework/Classes/GameCheatManager.uc create mode 100644 GameFramework/Classes/GameCrowdAgent.uc create mode 100644 GameFramework/Classes/GameCrowdAgentBehavior.uc create mode 100644 GameFramework/Classes/GameCrowdAgentSM.uc create mode 100644 GameFramework/Classes/GameCrowdAgentSkeletal.uc create mode 100644 GameFramework/Classes/GameCrowdBehaviorPoint.uc create mode 100644 GameFramework/Classes/GameCrowdBehavior_PlayAnimation.uc create mode 100644 GameFramework/Classes/GameCrowdBehavior_RunFromPanic.uc create mode 100644 GameFramework/Classes/GameCrowdBehavior_WaitForGroup.uc create mode 100644 GameFramework/Classes/GameCrowdBehavior_WaitInQueue.uc create mode 100644 GameFramework/Classes/GameCrowdDestination.uc create mode 100644 GameFramework/Classes/GameCrowdDestinationQueuePoint.uc create mode 100644 GameFramework/Classes/GameCrowdGroup.uc create mode 100644 GameFramework/Classes/GameCrowdInfoVolume.uc create mode 100644 GameFramework/Classes/GameCrowdInteractionDestination.uc create mode 100644 GameFramework/Classes/GameCrowdInteractionPoint.uc create mode 100644 GameFramework/Classes/GameCrowdPopulationManager.uc create mode 100644 GameFramework/Classes/GameCrowdReplicationActor.uc create mode 100644 GameFramework/Classes/GameCrowdSpawnInterface.uc create mode 100644 GameFramework/Classes/GameCrowdSpawnRelativeActor.uc create mode 100644 GameFramework/Classes/GameCrowdSpawnerInterface.uc create mode 100644 GameFramework/Classes/GameCrowd_ListOfAgents.uc create mode 100644 GameFramework/Classes/GameDestinationConnRenderingComponent.uc create mode 100644 GameFramework/Classes/GameExplosion.uc create mode 100644 GameFramework/Classes/GameExplosionActor.uc create mode 100644 GameFramework/Classes/GameExplosionContent.uc create mode 100644 GameFramework/Classes/GameFixedCamera.uc create mode 100644 GameFramework/Classes/GameKActorSpawnableEffect.uc create mode 100644 GameFramework/Classes/GamePawn.uc create mode 100644 GameFramework/Classes/GamePlayerCamera.uc create mode 100644 GameFramework/Classes/GamePlayerController.uc create mode 100644 GameFramework/Classes/GameSkelCtrl_Recoil.uc create mode 100644 GameFramework/Classes/GameSpecialMove.uc create mode 100644 GameFramework/Classes/GameStateObject.uc create mode 100644 GameFramework/Classes/GameStatsAggregator.uc create mode 100644 GameFramework/Classes/GameThirdPersonCamera.uc create mode 100644 GameFramework/Classes/GameThirdPersonCameraMode.uc create mode 100644 GameFramework/Classes/GameThirdPersonCameraMode_Default.uc create mode 100644 GameFramework/Classes/GameTypes.uc create mode 100644 GameFramework/Classes/GameWaveForms.uc create mode 100644 GameFramework/Classes/MobileDebugCameraController.uc create mode 100644 GameFramework/Classes/MobileDebugCameraHUD.uc create mode 100644 GameFramework/Classes/MobileDebugCameraInput.uc create mode 100644 GameFramework/Classes/MobileHUD.uc create mode 100644 GameFramework/Classes/MobileInputZone.uc create mode 100644 GameFramework/Classes/MobileMenuBar.uc create mode 100644 GameFramework/Classes/MobileMenuBarItem.uc create mode 100644 GameFramework/Classes/MobileMenuButton.uc create mode 100644 GameFramework/Classes/MobileMenuElement.uc create mode 100644 GameFramework/Classes/MobileMenuGame.uc create mode 100644 GameFramework/Classes/MobileMenuImage.uc create mode 100644 GameFramework/Classes/MobileMenuInventory.uc create mode 100644 GameFramework/Classes/MobileMenuLabel.uc create mode 100644 GameFramework/Classes/MobileMenuList.uc create mode 100644 GameFramework/Classes/MobileMenuListItem.uc create mode 100644 GameFramework/Classes/MobileMenuObject.uc create mode 100644 GameFramework/Classes/MobileMenuObjectProxy.uc create mode 100644 GameFramework/Classes/MobileMenuPlayerController.uc create mode 100644 GameFramework/Classes/MobileMenuScene.uc create mode 100644 GameFramework/Classes/MobilePlayerInput.uc create mode 100644 GameFramework/Classes/MobileSecondaryViewportClient.uc create mode 100644 GameFramework/Classes/MobileTouchInputVolume.uc create mode 100644 GameFramework/Classes/NavMeshGoal_OutOfViewFrom.uc create mode 100644 GameFramework/Classes/NavMeshPath_BiasAgainstPolysWithinDistanceOfLocations.uc create mode 100644 GameFramework/Classes/PMESTG_LeaveADecalBase.uc create mode 100644 GameFramework/Classes/PlayerCollectorGame.uc create mode 100644 GameFramework/Classes/SecondaryViewportClient.uc create mode 100644 GameFramework/Classes/SeqAct_ControlGameMovie.uc create mode 100644 GameFramework/Classes/SeqAct_Deproject.uc create mode 100644 GameFramework/Classes/SeqAct_GameCrowdPopulationManagerToggle.uc create mode 100644 GameFramework/Classes/SeqAct_GameCrowdSpawner.uc create mode 100644 GameFramework/Classes/SeqAct_MobileAddInputZones.uc create mode 100644 GameFramework/Classes/SeqAct_MobileClearInputZones.uc create mode 100644 GameFramework/Classes/SeqAct_MobileRemoveInputZone.uc create mode 100644 GameFramework/Classes/SeqAct_MobileSaveLoadValue.uc create mode 100644 GameFramework/Classes/SeqAct_ModifyProperty.uc create mode 100644 GameFramework/Classes/SeqAct_PlayAgentAnimation.uc create mode 100644 GameFramework/Classes/SeqAct_ToggleMouseCursor.uc create mode 100644 GameFramework/Classes/SeqEvent_CrowdAgentReachedDestination.uc create mode 100644 GameFramework/Classes/SeqEvent_HudRender.uc create mode 100644 GameFramework/Classes/SeqEvent_HudRenderImage.uc create mode 100644 GameFramework/Classes/SeqEvent_HudRenderText.uc create mode 100644 GameFramework/Classes/SeqEvent_MobileBase.uc create mode 100644 GameFramework/Classes/SeqEvent_MobileButton.uc create mode 100644 GameFramework/Classes/SeqEvent_MobileInput.uc create mode 100644 GameFramework/Classes/SeqEvent_MobileLook.uc create mode 100644 GameFramework/Classes/SeqEvent_MobileMotion.uc create mode 100644 GameFramework/Classes/SeqEvent_MobileObjectPicker.uc create mode 100644 GameFramework/Classes/SeqEvent_MobileRawInput.uc create mode 100644 GameFramework/Classes/SeqEvent_MobileSwipe.uc create mode 100644 GameFramework/Classes/SeqEvent_MobileTouchInputVolume.uc create mode 100644 GameFramework/Classes/SeqEvent_MobileZoneBase.uc create mode 100644 GameFramework/Classes/TouchableElement3D.uc create mode 100644 GameFramework/Globals.uci create mode 100644 IpDrv/Classes/ClientBeaconAddressResolver.uc create mode 100644 IpDrv/Classes/HelloWeb.uc create mode 100644 IpDrv/Classes/ImageServer.uc create mode 100644 IpDrv/Classes/InternetLink.uc create mode 100644 IpDrv/Classes/MCPBase.uc create mode 100644 IpDrv/Classes/McpClashMobBase.uc create mode 100644 IpDrv/Classes/McpClashMobFileDownload.uc create mode 100644 IpDrv/Classes/McpClashMobManager.uc create mode 100644 IpDrv/Classes/McpGroupsBase.uc create mode 100644 IpDrv/Classes/McpGroupsManager.uc create mode 100644 IpDrv/Classes/McpIdMappingBase.uc create mode 100644 IpDrv/Classes/McpIdMappingManager.uc create mode 100644 IpDrv/Classes/McpManagedValueManager.uc create mode 100644 IpDrv/Classes/McpManagedValueManagerBase.uc create mode 100644 IpDrv/Classes/McpMessageBase.uc create mode 100644 IpDrv/Classes/McpMessageManager.uc create mode 100644 IpDrv/Classes/McpServerTimeBase.uc create mode 100644 IpDrv/Classes/McpServerTimeManager.uc create mode 100644 IpDrv/Classes/McpServiceBase.uc create mode 100644 IpDrv/Classes/McpServiceConfig.uc create mode 100644 IpDrv/Classes/McpUserCloudFileDownload.uc create mode 100644 IpDrv/Classes/McpUserInventoryBase.uc create mode 100644 IpDrv/Classes/McpUserInventoryManager.uc create mode 100644 IpDrv/Classes/McpUserManager.uc create mode 100644 IpDrv/Classes/McpUserManagerBase.uc create mode 100644 IpDrv/Classes/MeshBeacon.uc create mode 100644 IpDrv/Classes/MeshBeaconClient.uc create mode 100644 IpDrv/Classes/MeshBeaconHost.uc create mode 100644 IpDrv/Classes/OnlineAuthInterfaceImpl.uc create mode 100644 IpDrv/Classes/OnlineEventsInterfaceMcp.uc create mode 100644 IpDrv/Classes/OnlineGameInterfaceImpl.uc create mode 100644 IpDrv/Classes/OnlineImageDownloaderWeb.uc create mode 100644 IpDrv/Classes/OnlineNewsInterfaceMcp.uc create mode 100644 IpDrv/Classes/OnlinePlaylistManager.uc create mode 100644 IpDrv/Classes/OnlinePlaylistProvider.uc create mode 100644 IpDrv/Classes/OnlineSubsystemCommonImpl.uc create mode 100644 IpDrv/Classes/OnlineTitleFileDownloadBase.uc create mode 100644 IpDrv/Classes/OnlineTitleFileDownloadMcp.uc create mode 100644 IpDrv/Classes/OnlineTitleFileDownloadWeb.uc create mode 100644 IpDrv/Classes/PartyBeacon.uc create mode 100644 IpDrv/Classes/PartyBeaconClient.uc create mode 100644 IpDrv/Classes/PartyBeaconHost.uc create mode 100644 IpDrv/Classes/TcpLink.uc create mode 100644 IpDrv/Classes/TitleFileDownloadCache.uc create mode 100644 IpDrv/Classes/UIDataStore_OnlinePlaylists.uc create mode 100644 IpDrv/Classes/WebApplication.uc create mode 100644 IpDrv/Classes/WebConnection.uc create mode 100644 IpDrv/Classes/WebRequest.uc create mode 100644 IpDrv/Classes/WebResponse.uc create mode 100644 IpDrv/Classes/WebServer.uc create mode 100644 KFGame/Classes/AICommand.uc create mode 100644 KFGame/Classes/AICommand_Attack_Grab.uc create mode 100644 KFGame/Classes/AICommand_Attack_Kick.uc create mode 100644 KFGame/Classes/AICommand_Attack_Melee.uc create mode 100644 KFGame/Classes/AICommand_Base_Boss.uc create mode 100644 KFGame/Classes/AICommand_Base_Combat.uc create mode 100644 KFGame/Classes/AICommand_Base_Crawler.uc create mode 100644 KFGame/Classes/AICommand_Base_Fleshpound.uc create mode 100644 KFGame/Classes/AICommand_Base_Hans.uc create mode 100644 KFGame/Classes/AICommand_Base_Zed.uc create mode 100644 KFGame/Classes/AICommand_BossTheatrics.uc create mode 100644 KFGame/Classes/AICommand_CrawlerEmerge.uc create mode 100644 KFGame/Classes/AICommand_Crawler_LeapToWall.uc create mode 100644 KFGame/Classes/AICommand_Crawler_MoveToGoal.uc create mode 100644 KFGame/Classes/AICommand_Debug.uc create mode 100644 KFGame/Classes/AICommand_DebugTurn.uc create mode 100644 KFGame/Classes/AICommand_Evade.uc create mode 100644 KFGame/Classes/AICommand_Flee.uc create mode 100644 KFGame/Classes/AICommand_Hans_GunStance.uc create mode 100644 KFGame/Classes/AICommand_HeadlessWander.uc create mode 100644 KFGame/Classes/AICommand_MoveToEnemy.uc create mode 100644 KFGame/Classes/AICommand_MoveToGoal.uc create mode 100644 KFGame/Classes/AICommand_PanicWander.uc create mode 100644 KFGame/Classes/AICommand_Pause.uc create mode 100644 KFGame/Classes/AICommand_PushedBySM.uc create mode 100644 KFGame/Classes/AICommand_SM_Attack.uc create mode 100644 KFGame/Classes/AICommand_ScriptedPawn_TraverseSpline.uc create mode 100644 KFGame/Classes/AICommand_SpecialMove.uc create mode 100644 KFGame/Classes/AICommand_StepAside.uc create mode 100644 KFGame/Classes/AICommand_Stumble.uc create mode 100644 KFGame/Classes/AICommand_SummonZeds.uc create mode 100644 KFGame/Classes/AICommand_TauntEnemy.uc create mode 100644 KFGame/Classes/AICommand_ThrowGrenade.uc create mode 100644 KFGame/Classes/AICommand_Wander.uc create mode 100644 KFGame/Classes/AIDebugGoal.uc create mode 100644 KFGame/Classes/ActorFactoryKFPathnode.uc create mode 100644 KFGame/Classes/ActorFactoryKFScriptedPlayerPathGoal.uc create mode 100644 KFGame/Classes/ActorFactoryKFWallPathNode.uc create mode 100644 KFGame/Classes/EphemeralMatchStats.uc create mode 100644 KFGame/Classes/FloorToWallReachSpec.uc create mode 100644 KFGame/Classes/Goal_AwayFromPosition.uc create mode 100644 KFGame/Classes/Goal_Random.uc create mode 100644 KFGame/Classes/Goal_WallToEnemy.uc create mode 100644 KFGame/Classes/GroundFireEmitterPool.uc create mode 100644 KFGame/Classes/KFAIController.uc create mode 100644 KFGame/Classes/KFAIController_Hans.uc create mode 100644 KFGame/Classes/KFAIController_Monster.uc create mode 100644 KFGame/Classes/KFAIController_ScriptedPawn.uc create mode 100644 KFGame/Classes/KFAIController_ZedBoss.uc create mode 100644 KFGame/Classes/KFAIController_ZedClot.uc create mode 100644 KFGame/Classes/KFAIController_ZedCrawler.uc create mode 100644 KFGame/Classes/KFAIController_ZedFleshpound.uc create mode 100644 KFGame/Classes/KFAIDirector.uc create mode 100644 KFGame/Classes/KFAIPluginRage_Fleshpound.uc create mode 100644 KFGame/Classes/KFAISpawnManager.uc create mode 100644 KFGame/Classes/KFAISpawnManager_Long.uc create mode 100644 KFGame/Classes/KFAISpawnManager_Normal.uc create mode 100644 KFGame/Classes/KFAISpawnManager_Short.uc create mode 100644 KFGame/Classes/KFAISpawnSquad.uc create mode 100644 KFGame/Classes/KFAISteering.uc create mode 100644 KFGame/Classes/KFAISubsystem.uc create mode 100644 KFGame/Classes/KFAIWaveInfo.uc create mode 100644 KFGame/Classes/KFAccessControl.uc create mode 100644 KFGame/Classes/KFActor_DoshPile.uc create mode 100644 KFGame/Classes/KFAfflictionAdvanced.uc create mode 100644 KFGame/Classes/KFAfflictionBase.uc create mode 100644 KFGame/Classes/KFAfflictionManager.uc create mode 100644 KFGame/Classes/KFAffliction_Bleed.uc create mode 100644 KFGame/Classes/KFAffliction_EMP.uc create mode 100644 KFGame/Classes/KFAffliction_EMPDisrupt.uc create mode 100644 KFGame/Classes/KFAffliction_EvilDAR_EMP.uc create mode 100644 KFGame/Classes/KFAffliction_Fire.uc create mode 100644 KFGame/Classes/KFAffliction_Freeze.uc create mode 100644 KFGame/Classes/KFAffliction_HeavyRecovery.uc create mode 100644 KFGame/Classes/KFAffliction_Knockdown.uc create mode 100644 KFGame/Classes/KFAffliction_MediumRecovery.uc create mode 100644 KFGame/Classes/KFAffliction_Microwave.uc create mode 100644 KFGame/Classes/KFAffliction_Poison.uc create mode 100644 KFGame/Classes/KFAffliction_Snare.uc create mode 100644 KFGame/Classes/KFAffliction_Stumble.uc create mode 100644 KFGame/Classes/KFAffliction_Stun.uc create mode 100644 KFGame/Classes/KFAiBaseRangedBehavior.uc create mode 100644 KFGame/Classes/KFAiBehaviorTypes.uc create mode 100644 KFGame/Classes/KFAiDirectProjectileFireBehavior.uc create mode 100644 KFGame/Classes/KFAiLeapBehavior.uc create mode 100644 KFGame/Classes/KFAnimNotify_AkEvent_IfActiveMGTarget.uc create mode 100644 KFGame/Classes/KFAnimNotify_AkEvent_NotEmpty_1P.uc create mode 100644 KFGame/Classes/KFAnimNotify_CameraAnim.uc create mode 100644 KFGame/Classes/KFAnimNotify_Decal.uc create mode 100644 KFGame/Classes/KFAnimNotify_HideBone.uc create mode 100644 KFGame/Classes/KFAnimNotify_Interrupt.uc create mode 100644 KFGame/Classes/KFAnimNotify_MeleeImpact.uc create mode 100644 KFGame/Classes/KFAnimNotify_MeleeImpact_1P.uc create mode 100644 KFGame/Classes/KFAnimNotify_MeleeTrails.uc create mode 100644 KFGame/Classes/KFAnimNotify_PlayDialog.uc create mode 100644 KFGame/Classes/KFAnimNotify_ReloadAmmo.uc create mode 100644 KFGame/Classes/KFAnimNotify_SpawnKActor.uc create mode 100644 KFGame/Classes/KFAnimNotify_ZedVoiceAkEvent.uc create mode 100644 KFGame/Classes/KFAnimSeq_ByWeaponClass.uc create mode 100644 KFGame/Classes/KFAnimSeq_Directional.uc create mode 100644 KFGame/Classes/KFAnimSeq_TurnInPlace.uc create mode 100644 KFGame/Classes/KFAnimSeq_Tween.uc create mode 100644 KFGame/Classes/KFAnim_AimOffset.uc create mode 100644 KFGame/Classes/KFAnim_BlendByTargetingMode.uc create mode 100644 KFGame/Classes/KFAnim_BlendFacialExpression.uc create mode 100644 KFGame/Classes/KFAnim_BlendList.uc create mode 100644 KFGame/Classes/KFAnim_Health.uc create mode 100644 KFGame/Classes/KFAnim_Movement.uc create mode 100644 KFGame/Classes/KFAnim_PhysFalling.uc create mode 100644 KFGame/Classes/KFAnim_Random.uc create mode 100644 KFGame/Classes/KFAnim_RandomScripted.uc create mode 100644 KFGame/Classes/KFAnim_ScaleRateBySpeed.uc create mode 100644 KFGame/Classes/KFAnim_Slot.uc create mode 100644 KFGame/Classes/KFAnim_TurnInPlace.uc create mode 100644 KFGame/Classes/KFAnim_TurnInPlace_Rotator.uc create mode 100644 KFGame/Classes/KFAutoPurchaseHelper.uc create mode 100644 KFGame/Classes/KFBossCamera.uc create mode 100644 KFGame/Classes/KFBulletSkeletalMeshComponent.uc create mode 100644 KFGame/Classes/KFCameraLensEmit_BloodBase.uc create mode 100644 KFGame/Classes/KFCameraLensEmit_BloodGorge.uc create mode 100644 KFGame/Classes/KFCameraLensEmit_EMP.uc create mode 100644 KFGame/Classes/KFCameraLensEmit_Fire.uc create mode 100644 KFGame/Classes/KFCameraLensEmit_PowerUp_HellishRage.uc create mode 100644 KFGame/Classes/KFCameraLensEmit_Puke.uc create mode 100644 KFGame/Classes/KFCameraLensEmit_Puke_Light.uc create mode 100644 KFGame/Classes/KFCameraShake.uc create mode 100644 KFGame/Classes/KFCarryableObject.uc create mode 100644 KFGame/Classes/KFCharacterAttachment.uc create mode 100644 KFGame/Classes/KFCharacterInfoBase.uc create mode 100644 KFGame/Classes/KFCharacterInfo_Human.uc create mode 100644 KFGame/Classes/KFCharacterInfo_Monster.uc create mode 100644 KFGame/Classes/KFCharacterInfo_ScriptedPawn.uc create mode 100644 KFGame/Classes/KFCheatManager.uc create mode 100644 KFGame/Classes/KFCommon_LocalizedStrings.uc create mode 100644 KFGame/Classes/KFCostTimerNode.uc create mode 100644 KFGame/Classes/KFCustomizationCamera.uc create mode 100644 KFGame/Classes/KFCustomizationPoint.uc create mode 100644 KFGame/Classes/KFDT_Ballistic.uc create mode 100644 KFGame/Classes/KFDT_Ballistic_Shell.uc create mode 100644 KFGame/Classes/KFDT_Bleeding.uc create mode 100644 KFGame/Classes/KFDT_Bludgeon.uc create mode 100644 KFGame/Classes/KFDT_DemoNuke_Toxic_Lingering.uc create mode 100644 KFGame/Classes/KFDT_DrainHealth.uc create mode 100644 KFGame/Classes/KFDT_EMP.uc create mode 100644 KFGame/Classes/KFDT_Environment_KActorImpulse.uc create mode 100644 KFGame/Classes/KFDT_Explosive.uc create mode 100644 KFGame/Classes/KFDT_ExplosiveSubmunition_HX25.uc create mode 100644 KFGame/Classes/KFDT_Explosive_DoorTrap.uc create mode 100644 KFGame/Classes/KFDT_Explosive_Sacrifice.uc create mode 100644 KFGame/Classes/KFDT_Explosive_Shrapnel.uc create mode 100644 KFGame/Classes/KFDT_Falling.uc create mode 100644 KFGame/Classes/KFDT_Fire.uc create mode 100644 KFGame/Classes/KFDT_Fire_Ground.uc create mode 100644 KFGame/Classes/KFDT_Fire_HellishRage.uc create mode 100644 KFGame/Classes/KFDT_Fire_Mac10DoT.uc create mode 100644 KFGame/Classes/KFDT_Fire_MicrowaveRifleDoT.uc create mode 100644 KFGame/Classes/KFDT_Fire_Napalm.uc create mode 100644 KFGame/Classes/KFDT_Freeze.uc create mode 100644 KFGame/Classes/KFDT_Freeze_Ground.uc create mode 100644 KFGame/Classes/KFDT_Healing.uc create mode 100644 KFGame/Classes/KFDT_HellishRageCost.uc create mode 100644 KFGame/Classes/KFDT_HuskCannonDot.uc create mode 100644 KFGame/Classes/KFDT_Knockdown.uc create mode 100644 KFGame/Classes/KFDT_Microwave.uc create mode 100644 KFGame/Classes/KFDT_NPCBump.uc create mode 100644 KFGame/Classes/KFDT_NPCBump_Large.uc create mode 100644 KFGame/Classes/KFDT_NoGoVolume.uc create mode 100644 KFGame/Classes/KFDT_Piercing.uc create mode 100644 KFGame/Classes/KFDT_SWATBatteringRam.uc create mode 100644 KFGame/Classes/KFDT_Slashing.uc create mode 100644 KFGame/Classes/KFDT_Sonic.uc create mode 100644 KFGame/Classes/KFDT_Toxic.uc create mode 100644 KFGame/Classes/KFDT_Toxic_AcidicRounds.uc create mode 100644 KFGame/Classes/KFDT_Toxic_DemoNuke.uc create mode 100644 KFGame/Classes/KFDT_Toxic_HRGHealthrower.uc create mode 100644 KFGame/Classes/KFDT_Toxic_MedicGrenade.uc create mode 100644 KFGame/Classes/KFDT_Toxic_MedicGrenadeLauncher.uc create mode 100644 KFGame/Classes/KFDT_Toxic_ZedativeCloud.uc create mode 100644 KFGame/Classes/KFDamageType.uc create mode 100644 KFGame/Classes/KFDataStore_OnlineGameSearch.uc create mode 100644 KFGame/Classes/KFDebugCameraController.uc create mode 100644 KFGame/Classes/KFDebugCameraHUD.uc create mode 100644 KFGame/Classes/KFDebugCameraInput.uc create mode 100644 KFGame/Classes/KFDebugFlare.uc create mode 100644 KFGame/Classes/KFDebugLines.uc create mode 100644 KFGame/Classes/KFDemoRecSpectator.uc create mode 100644 KFGame/Classes/KFDestructibleActor.uc create mode 100644 KFGame/Classes/KFDialogEnvironmentVolume.uc create mode 100644 KFGame/Classes/KFDialogManager.uc create mode 100644 KFGame/Classes/KFDominantDirectionalLightning.uc create mode 100644 KFGame/Classes/KFDoorActor.uc create mode 100644 KFGame/Classes/KFDoorMarker.uc create mode 100644 KFGame/Classes/KFDoorReachSpec.uc create mode 100644 KFGame/Classes/KFDoorTrigger.uc create mode 100644 KFGame/Classes/KFDroppedPickup.uc create mode 100644 KFGame/Classes/KFDroppedPickup_Cash.uc create mode 100644 KFGame/Classes/KFDummyReplicationInfo.uc create mode 100644 KFGame/Classes/KFDynamicFogAndDamageVolumeInfo.uc create mode 100644 KFGame/Classes/KFEmit_CameraEffect.uc create mode 100644 KFGame/Classes/KFEmit_Path.uc create mode 100644 KFGame/Classes/KFEmit_ScriptedPath.uc create mode 100644 KFGame/Classes/KFEmit_TraderPath.uc create mode 100644 KFGame/Classes/KFEmitter.uc create mode 100644 KFGame/Classes/KFEmoteCamera.uc create mode 100644 KFGame/Classes/KFEmoteCameraMode.uc create mode 100644 KFGame/Classes/KFEmoteList.uc create mode 100644 KFGame/Classes/KFExplosionActor.uc create mode 100644 KFGame/Classes/KFExplosionActorLingering.uc create mode 100644 KFGame/Classes/KFExplosionActorPlaceable.uc create mode 100644 KFGame/Classes/KFExplosionActorReplicated.uc create mode 100644 KFGame/Classes/KFExplosionLight.uc create mode 100644 KFGame/Classes/KFExplosionLightComponent.uc create mode 100644 KFGame/Classes/KFExplosion_AirborneAgent.uc create mode 100644 KFGame/Classes/KFExplosion_Nuke.uc create mode 100644 KFGame/Classes/KFExplosion_ReplicatedNuke.uc create mode 100644 KFGame/Classes/KFExplosion_ZedativeCloud.uc create mode 100644 KFGame/Classes/KFExportSteamItemsCommandlet.uc create mode 100644 KFGame/Classes/KFFirstPersonCamera.uc create mode 100644 KFGame/Classes/KFFixupCosmeticReferencesCommandlet.uc create mode 100644 KFGame/Classes/KFFixupCosmeticUITexturesCommandlet.uc create mode 100644 KFGame/Classes/KFFlashlightAttachment.uc create mode 100644 KFGame/Classes/KFForcedReachSpec.uc create mode 100644 KFGame/Classes/KFFracturedMeshActor.uc create mode 100644 KFGame/Classes/KFFracturedMeshGlass.uc create mode 100644 KFGame/Classes/KFGFXSpecialEventObjectivesContainer_Fall2020.uc create mode 100644 KFGame/Classes/KFGFXSpecialEventObjectivesContainer_Spring2020.uc create mode 100644 KFGame/Classes/KFGFxChristmasObjectivesContainer.uc create mode 100644 KFGame/Classes/KFGFxCollapsedObjectivesContainer.uc create mode 100644 KFGame/Classes/KFGFxControlsContainer_ControllerPresets.uc create mode 100644 KFGame/Classes/KFGFxControlsContainer_Input.uc create mode 100644 KFGame/Classes/KFGFxControlsContainer_Keybinding.uc create mode 100644 KFGame/Classes/KFGFxDailyObjectivesContainer.uc create mode 100644 KFGame/Classes/KFGFxEndlessDARObjectivesContainer.uc create mode 100644 KFGame/Classes/KFGFxExpandedObjectivesContainer.uc create mode 100644 KFGame/Classes/KFGFxFall2019ObjectivesContainer.uc create mode 100644 KFGame/Classes/KFGFxFallObjectivesContainer.uc create mode 100644 KFGame/Classes/KFGFxGearContainer_PerksSelection.uc create mode 100644 KFGame/Classes/KFGFxHUD_ChatBoxWidget.uc create mode 100644 KFGame/Classes/KFGFxHUD_ObjectiveConatiner.uc create mode 100644 KFGame/Classes/KFGFxHUD_PlayerBackpack.uc create mode 100644 KFGame/Classes/KFGFxHUD_PlayerMoveList.uc create mode 100644 KFGame/Classes/KFGFxHUD_PlayerStatus.uc create mode 100644 KFGame/Classes/KFGFxHUD_PostRoundMenu.uc create mode 100644 KFGame/Classes/KFGFxHUD_ScoreboardMapInfoContainer.uc create mode 100644 KFGame/Classes/KFGFxHUD_ScoreboardVersusWidget.uc create mode 100644 KFGame/Classes/KFGFxHUD_ScoreboardWidget.uc create mode 100644 KFGame/Classes/KFGFxHUD_SpectatorInfo.uc create mode 100644 KFGame/Classes/KFGFxHUD_SpectatorInfo_Versus.uc create mode 100644 KFGame/Classes/KFGFxHUD_TraderCompass.uc create mode 100644 KFGame/Classes/KFGFxHUD_WaveInfo.uc create mode 100644 KFGame/Classes/KFGFxHUD_WeaponSelectWidget.uc create mode 100644 KFGame/Classes/KFGFxHudWrapper.uc create mode 100644 KFGame/Classes/KFGFxHud_PlayerRosterWidget.uc create mode 100644 KFGame/Classes/KFGFxMenu_DoshVault.uc create mode 100644 KFGame/Classes/KFGFxMenu_Exit.uc create mode 100644 KFGame/Classes/KFGFxMenu_Gear.uc create mode 100644 KFGame/Classes/KFGFxMenu_IIS.uc create mode 100644 KFGame/Classes/KFGFxMenu_Inventory.uc create mode 100644 KFGame/Classes/KFGFxMenu_Perks.uc create mode 100644 KFGame/Classes/KFGFxMenu_PostGameReport.uc create mode 100644 KFGame/Classes/KFGFxMenu_ServerBrowser.uc create mode 100644 KFGame/Classes/KFGFxMenu_Store.uc create mode 100644 KFGame/Classes/KFGFxMissionObjectivesContainer.uc create mode 100644 KFGame/Classes/KFGFxMoviePlayer_HUD.uc create mode 100644 KFGame/Classes/KFGFxMoviePlayer_Manager_Versus.uc create mode 100644 KFGame/Classes/KFGFxMoviePlayer_NaughtyList.uc create mode 100644 KFGame/Classes/KFGFxMoviePlayer_PlayerInfo.uc create mode 100644 KFGame/Classes/KFGFxMoviePlayer_PostRoundMenu.uc create mode 100644 KFGame/Classes/KFGFxMoviePlayer_ScoreBoard.uc create mode 100644 KFGame/Classes/KFGFxMoviePlayer_ScreenSize.uc create mode 100644 KFGame/Classes/KFGFxNaughtyList.uc create mode 100644 KFGame/Classes/KFGFxObject_Container.uc create mode 100644 KFGame/Classes/KFGFxObject_Popup.uc create mode 100644 KFGame/Classes/KFGFxOptionsMenu_Audio.uc create mode 100644 KFGame/Classes/KFGFxOptionsMenu_Controls.uc create mode 100644 KFGame/Classes/KFGFxOptionsMenu_GameSettings.uc create mode 100644 KFGame/Classes/KFGFxOptionsMenu_Graphics.uc create mode 100644 KFGame/Classes/KFGFxOptionsMenu_Graphics_DX10.uc create mode 100644 KFGame/Classes/KFGFxOptionsMenu_Selection.uc create mode 100644 KFGame/Classes/KFGFxPerksContainer.uc create mode 100644 KFGame/Classes/KFGFxPerksContainer_Details.uc create mode 100644 KFGame/Classes/KFGFxPerksContainer_Header.uc create mode 100644 KFGame/Classes/KFGFxPerksContainer_Prestige.uc create mode 100644 KFGame/Classes/KFGFxPerksContainer_Selection.uc create mode 100644 KFGame/Classes/KFGFxPerksContainer_Skills.uc create mode 100644 KFGame/Classes/KFGFxPerksContainer_SkillsSummary.uc create mode 100644 KFGame/Classes/KFGFxPopup_Confirmation.uc create mode 100644 KFGame/Classes/KFGFxPopup_ConnectionError.uc create mode 100644 KFGame/Classes/KFGFxPopup_FriendsConfirm.uc create mode 100644 KFGame/Classes/KFGFxPopup_FriendsList.uc create mode 100644 KFGame/Classes/KFGFxPopup_InputPrompt.uc create mode 100644 KFGame/Classes/KFGFxPopup_OptionMic.uc create mode 100644 KFGame/Classes/KFGFxPostGameContainer_MapVote.uc create mode 100644 KFGame/Classes/KFGFxPostGameContainer_PlayerStats.uc create mode 100644 KFGame/Classes/KFGFxPostGameContainer_PlayerXP.uc create mode 100644 KFGame/Classes/KFGFxPostGameContainer_TeamAwards.uc create mode 100644 KFGame/Classes/KFGFxPostRoundContainer_Team.uc create mode 100644 KFGame/Classes/KFGFxScreenSizeContainer.uc create mode 100644 KFGame/Classes/KFGFxServerBrowser_Filters.uc create mode 100644 KFGame/Classes/KFGFxServerBrowser_ServerDetails.uc create mode 100644 KFGame/Classes/KFGFxServerBrowser_ServerList.uc create mode 100644 KFGame/Classes/KFGFxSpecialEventObjectivesContainer_Summer2020.uc create mode 100644 KFGame/Classes/KFGFxSpecialEventObjectivesContainer_Xmas2019.uc create mode 100644 KFGame/Classes/KFGFxSpecialeventObjectivesContainer.uc create mode 100644 KFGame/Classes/KFGFxSpring2019ObjectivesContainer.uc create mode 100644 KFGame/Classes/KFGFxStartContainer_InGameOverview.uc create mode 100644 KFGame/Classes/KFGFxStartContainer_NewsImageHolder.uc create mode 100644 KFGame/Classes/KFGFxStartContainer_ServerBrowserOverview.uc create mode 100644 KFGame/Classes/KFGFxStartGameContainer_FindGame.uc create mode 100644 KFGame/Classes/KFGFxStartGameContainer_Options.uc create mode 100644 KFGame/Classes/KFGFxStoreContainer_Cart.uc create mode 100644 KFGame/Classes/KFGFxStoreContainer_Details.uc create mode 100644 KFGame/Classes/KFGFxStoreContainer_Main.uc create mode 100644 KFGame/Classes/KFGFxSummer2019ObjectivesContainer.uc create mode 100644 KFGame/Classes/KFGFxSummerSideShowObjectivesContainer.uc create mode 100644 KFGame/Classes/KFGFxTraderContainer_ErrorMessage.uc create mode 100644 KFGame/Classes/KFGFxTraderContainer_Filter.uc create mode 100644 KFGame/Classes/KFGFxTraderContainer_GameInfo.uc create mode 100644 KFGame/Classes/KFGFxTraderContainer_ItemDetails.uc create mode 100644 KFGame/Classes/KFGFxTraderContainer_PlayerInfo.uc create mode 100644 KFGame/Classes/KFGFxTraderContainer_PlayerInventory.uc create mode 100644 KFGame/Classes/KFGFxTraderContainer_Store.uc create mode 100644 KFGame/Classes/KFGFxWeeklyObjectivesContainer.uc create mode 100644 KFGame/Classes/KFGFxWidget_BackendStatusIndicatorWidget.uc create mode 100644 KFGame/Classes/KFGFxWidget_BaseParty.uc create mode 100644 KFGame/Classes/KFGFxWidget_BossHealthBar.uc create mode 100644 KFGame/Classes/KFGFxWidget_ButtonPrompt.uc create mode 100644 KFGame/Classes/KFGFxWidget_KickVote.uc create mode 100644 KFGame/Classes/KFGFxWidget_LevelUpNotification.uc create mode 100644 KFGame/Classes/KFGFxWidget_MenuBar.uc create mode 100644 KFGame/Classes/KFGFxWidget_MenuBarVersus.uc create mode 100644 KFGame/Classes/KFGFxWidget_MusicNotification.uc create mode 100644 KFGame/Classes/KFGFxWidget_NonCriticalGameMessage.uc create mode 100644 KFGame/Classes/KFGFxWidget_PartyInGame.uc create mode 100644 KFGame/Classes/KFGFxWidget_PartyInGame_Versus.uc create mode 100644 KFGame/Classes/KFGFxWidget_PartyMainMenu.uc create mode 100644 KFGame/Classes/KFGFxWidget_RhythmCounter.uc create mode 100644 KFGame/Classes/KFGFxWidget_VoiceComms.uc create mode 100644 KFGame/Classes/KFGFxWorld_C4Screen.uc create mode 100644 KFGame/Classes/KFGFxWorld_MedicOptics.uc create mode 100644 KFGame/Classes/KFGameConductor.uc create mode 100644 KFGame/Classes/KFGameDifficultyInfo.uc create mode 100644 KFGame/Classes/KFGameEngine.uc create mode 100644 KFGame/Classes/KFGameExplosion.uc create mode 100644 KFGame/Classes/KFGameInfo.uc create mode 100644 KFGame/Classes/KFGameInfoSummary.uc create mode 100644 KFGame/Classes/KFGameInfo_Entry.uc create mode 100644 KFGame/Classes/KFGameReplicationInfo.uc create mode 100644 KFGame/Classes/KFGameViewportClient.uc create mode 100644 KFGame/Classes/KFGameWaveforms.uc create mode 100644 KFGame/Classes/KFGamepadLayoutManager.uc create mode 100644 KFGame/Classes/KFGameplayEventsWriter.uc create mode 100644 KFGame/Classes/KFGameplayPoolManager.uc create mode 100644 KFGame/Classes/KFGfxMenu_StartGame.uc create mode 100644 KFGame/Classes/KFGfxMenu_Trader.uc create mode 100644 KFGame/Classes/KFGfxMoviePlayer_Manager.uc create mode 100644 KFGame/Classes/KFGfxMoviePlayer_World.uc create mode 100644 KFGame/Classes/KFGfxObject_Menu.uc create mode 100644 KFGame/Classes/KFGfxObject_TraderItems.uc create mode 100644 KFGame/Classes/KFGfxPopup_Gamma.uc create mode 100644 KFGame/Classes/KFGfxWorld_HealerScreen.uc create mode 100644 KFGame/Classes/KFGfxWorld_WelderScreen.uc create mode 100644 KFGame/Classes/KFGibSkeletalMeshComponent.uc create mode 100644 KFGame/Classes/KFGibStaticMeshComponent.uc create mode 100644 KFGame/Classes/KFGiblet.uc create mode 100644 KFGame/Classes/KFGibletInfo.uc create mode 100644 KFGame/Classes/KFGoreChunkAttachmentInfo.uc create mode 100644 KFGame/Classes/KFGoreChunkAttachment_Skull.uc create mode 100644 KFGame/Classes/KFGoreJointInfo.uc create mode 100644 KFGame/Classes/KFGoreManager.uc create mode 100644 KFGame/Classes/KFHTTPImageDownloader.uc create mode 100644 KFGame/Classes/KFHUDBase.uc create mode 100644 KFGame/Classes/KFHeadShotEffectList.uc create mode 100644 KFGame/Classes/KFImpactEffectInfo.uc create mode 100644 KFGame/Classes/KFImpactEffectManager.uc create mode 100644 KFGame/Classes/KFImpactFXEmitterPool.uc create mode 100644 KFGame/Classes/KFInterface_DamageCauser.uc create mode 100644 KFGame/Classes/KFInterface_MapObjective.uc create mode 100644 KFGame/Classes/KFInterface_MinigameActor.uc create mode 100644 KFGame/Classes/KFInterface_MinigameTarget.uc create mode 100644 KFGame/Classes/KFInterface_MonsterBoss.uc create mode 100644 KFGame/Classes/KFInterface_TriggerOwner.uc create mode 100644 KFGame/Classes/KFInterface_Usable.uc create mode 100644 KFGame/Classes/KFInterface_UsableTriggerTarget.uc create mode 100644 KFGame/Classes/KFInventoryCatalog.uc create mode 100644 KFGame/Classes/KFInventoryManager.uc create mode 100644 KFGame/Classes/KFKActor.uc create mode 100644 KFGame/Classes/KFKActorSpawnable.uc create mode 100644 KFGame/Classes/KFKActorSpawnable_Door.uc create mode 100644 KFGame/Classes/KFKAsset.uc create mode 100644 KFGame/Classes/KFLEDEffectsManager.uc create mode 100644 KFGame/Classes/KFLaserSightAttachment.uc create mode 100644 KFGame/Classes/KFLeapReachSpec.uc create mode 100644 KFGame/Classes/KFLightPool.uc create mode 100644 KFGame/Classes/KFLocalMessage.uc create mode 100644 KFGame/Classes/KFLocalMessage_Game.uc create mode 100644 KFGame/Classes/KFLocalMessage_Interaction.uc create mode 100644 KFGame/Classes/KFLocalMessage_PlayerKills.uc create mode 100644 KFGame/Classes/KFLocalMessage_Priority.uc create mode 100644 KFGame/Classes/KFLocalMessage_ServerNotification.uc create mode 100644 KFGame/Classes/KFLocalMessage_VoiceComms.uc create mode 100644 KFGame/Classes/KFMapInfo.uc create mode 100644 KFGame/Classes/KFMapMutator.uc create mode 100644 KFGame/Classes/KFMapObjective_ActorBase.uc create mode 100644 KFGame/Classes/KFMapObjective_CommonVars.uci create mode 100644 KFGame/Classes/KFMapObjective_VolumeBase.uc create mode 100644 KFGame/Classes/KFMapSummary.uc create mode 100644 KFGame/Classes/KFMapTravelData.uc create mode 100644 KFGame/Classes/KFMedicWeaponComponent.uc create mode 100644 KFGame/Classes/KFMeleeHelperAI.uc create mode 100644 KFGame/Classes/KFMeleeHelperBase.uc create mode 100644 KFGame/Classes/KFMeleeHelperWeapon.uc create mode 100644 KFGame/Classes/KFMission_LocalizedStrings.uc create mode 100644 KFGame/Classes/KFMonsterDifficultyInfo.uc create mode 100644 KFGame/Classes/KFMusicStingerHelper.uc create mode 100644 KFGame/Classes/KFMusicTrackInfo.uc create mode 100644 KFGame/Classes/KFMutator.uc create mode 100644 KFGame/Classes/KFMutatorSummary.uc create mode 100644 KFGame/Classes/KFMuzzleFlash.uc create mode 100644 KFGame/Classes/KFNaughtyListActor.uc create mode 100644 KFGame/Classes/KFOnlineGameSearch.uc create mode 100644 KFGame/Classes/KFOnlineGameSettings.uc create mode 100644 KFGame/Classes/KFOnlineGameSettingsVersus.uc create mode 100644 KFGame/Classes/KFOnlineStatsRead.uc create mode 100644 KFGame/Classes/KFOnlineStatsReadDingo.uc create mode 100644 KFGame/Classes/KFOnlineStatsWrite.uc create mode 100644 KFGame/Classes/KFOnlineStatsWriteDingo.uc create mode 100644 KFGame/Classes/KFOutbreakEvent.uc create mode 100644 KFGame/Classes/KFParticleSystemComponent.uc create mode 100644 KFGame/Classes/KFPathnode.uc create mode 100644 KFGame/Classes/KFPawn.uc create mode 100644 KFGame/Classes/KFPawnAnimInfo.uc create mode 100644 KFGame/Classes/KFPawnBlockingVolume.uc create mode 100644 KFGame/Classes/KFPawnSoundGroup.uc create mode 100644 KFGame/Classes/KFPawnVoiceGroup.uc create mode 100644 KFGame/Classes/KFPawnVoiceGroupEventData.uc create mode 100644 KFGame/Classes/KFPawn_Customization.uc create mode 100644 KFGame/Classes/KFPawn_Human.uc create mode 100644 KFGame/Classes/KFPawn_Monster.uc create mode 100644 KFGame/Classes/KFPawn_MonsterBoss.uc create mode 100644 KFGame/Classes/KFPawn_Scripted.uc create mode 100644 KFGame/Classes/KFPawn_ZedHansBase.uc create mode 100644 KFGame/Classes/KFPerk.uc create mode 100644 KFGame/Classes/KFPerkFXEmitterPool.uc create mode 100644 KFGame/Classes/KFPerk_Berserker.uc create mode 100644 KFGame/Classes/KFPerk_Commando.uc create mode 100644 KFGame/Classes/KFPerk_Demolitionist.uc create mode 100644 KFGame/Classes/KFPerk_FieldMedic.uc create mode 100644 KFGame/Classes/KFPerk_Firebug.uc create mode 100644 KFGame/Classes/KFPerk_Gunslinger.uc create mode 100644 KFGame/Classes/KFPerk_Monster.uc create mode 100644 KFGame/Classes/KFPerk_Sharpshooter.uc create mode 100644 KFGame/Classes/KFPerk_Support.uc create mode 100644 KFGame/Classes/KFPerk_Survivalist.uc create mode 100644 KFGame/Classes/KFPerk_Swat.uc create mode 100644 KFGame/Classes/KFPersistentBloodActor.uc create mode 100644 KFGame/Classes/KFPhysicalMaterialProperty.uc create mode 100644 KFGame/Classes/KFPickupFactory.uc create mode 100644 KFGame/Classes/KFPickupFactory_Item.uc create mode 100644 KFGame/Classes/KFPlayerCamera.uc create mode 100644 KFGame/Classes/KFPlayerController.uc create mode 100644 KFGame/Classes/KFPlayerController_WeeklySurvival.uc create mode 100644 KFGame/Classes/KFPlayerInput.uc create mode 100644 KFGame/Classes/KFPlayerReplicationInfo.uc create mode 100644 KFGame/Classes/KFPlayerReplicationInfoVersus.uc create mode 100644 KFGame/Classes/KFPlayerStart.uc create mode 100644 KFGame/Classes/KFPowerUp.uc create mode 100644 KFGame/Classes/KFPowerUp_HellishRage.uc create mode 100644 KFGame/Classes/KFProfileSettings.uc create mode 100644 KFGame/Classes/KFProj_BallisticExplosive.uc create mode 100644 KFGame/Classes/KFProj_Bullet.uc create mode 100644 KFGame/Classes/KFProj_ExplosiveSubmunition_HX25.uc create mode 100644 KFGame/Classes/KFProj_Grenade.uc create mode 100644 KFGame/Classes/KFProj_HealingDart.uc create mode 100644 KFGame/Classes/KFProj_PinningBullet.uc create mode 100644 KFGame/Classes/KFProj_RicochetBullet.uc create mode 100644 KFGame/Classes/KFProj_RicochetStickBullet.uc create mode 100644 KFGame/Classes/KFProjectile.uc create mode 100644 KFGame/Classes/KFProjectileStickHelper.uc create mode 100644 KFGame/Classes/KFProjectileStickHelper_HRGScorcher.uc create mode 100644 KFGame/Classes/KFPruneSkeletalMeshCommandlet.uc create mode 100644 KFGame/Classes/KFReachSpec.uc create mode 100644 KFGame/Classes/KFRealtimeTimerHelper.uc create mode 100644 KFGame/Classes/KFRepairableActor.uc create mode 100644 KFGame/Classes/KFRepairableActorTrigger.uc create mode 100644 KFGame/Classes/KFReplicatedShowPathActor.uc create mode 100644 KFGame/Classes/KFReverbVolume.uc create mode 100644 KFGame/Classes/KFSFXVolume.uc create mode 100644 KFGame/Classes/KFSM_BloatKingGorgeVictim.uc create mode 100644 KFGame/Classes/KFSM_Block.uc create mode 100644 KFGame/Classes/KFSM_DeathAnim.uc create mode 100644 KFGame/Classes/KFSM_DisabledGrappleVictim.uc create mode 100644 KFGame/Classes/KFSM_DoorMeleeAttack.uc create mode 100644 KFGame/Classes/KFSM_Emerge.uc create mode 100644 KFGame/Classes/KFSM_Evade.uc create mode 100644 KFGame/Classes/KFSM_EvilDAR_EMPGrapple.uc create mode 100644 KFGame/Classes/KFSM_Frozen.uc create mode 100644 KFGame/Classes/KFSM_GrappleCombined.uc create mode 100644 KFGame/Classes/KFSM_GrappleVictim.uc create mode 100644 KFGame/Classes/KFSM_HansGrappleVictim.uc create mode 100644 KFGame/Classes/KFSM_InteractionPawnFollower.uc create mode 100644 KFGame/Classes/KFSM_InteractionPawnLeader.uc create mode 100644 KFGame/Classes/KFSM_MeleeAttack.uc create mode 100644 KFGame/Classes/KFSM_Patriarch_Grapple.uc create mode 100644 KFGame/Classes/KFSM_PlaySingleAnim.uc create mode 100644 KFGame/Classes/KFSM_PlaySingleAnim_ScriptedPawn.uc create mode 100644 KFGame/Classes/KFSM_PlayerMeleeBase.uc create mode 100644 KFGame/Classes/KFSM_Player_Emote.uc create mode 100644 KFGame/Classes/KFSM_RagdollKnockdown.uc create mode 100644 KFGame/Classes/KFSM_RangedAttack.uc create mode 100644 KFGame/Classes/KFSM_RecoverFromRagdoll.uc create mode 100644 KFGame/Classes/KFSM_StartSprintAnim.uc create mode 100644 KFGame/Classes/KFSM_Stumble.uc create mode 100644 KFGame/Classes/KFSM_Stunned.uc create mode 100644 KFGame/Classes/KFSM_TentacleGrappleBase.uc create mode 100644 KFGame/Classes/KFSM_Zed_Boss_Theatrics.uc create mode 100644 KFGame/Classes/KFSM_Zed_Taunt.uc create mode 100644 KFGame/Classes/KFSM_Zed_WalkingTaunt.uc create mode 100644 KFGame/Classes/KFSceneCaptureDebugCam.uc create mode 100644 KFGame/Classes/KFScout.uc create mode 100644 KFGame/Classes/KFScriptedPawnSpawner.uc create mode 100644 KFGame/Classes/KFScriptedPlayerPathGoal.uc create mode 100644 KFGame/Classes/KFSeasonalEventStats.uc create mode 100644 KFGame/Classes/KFSeqAct_DisableDoor.uc create mode 100644 KFGame/Classes/KFSeqAct_FlickerLightning.uc create mode 100644 KFGame/Classes/KFSeqAct_MovePawnsNotInVolume.uc create mode 100644 KFGame/Classes/KFSeqAct_RestartScriptedPawn.uc create mode 100644 KFGame/Classes/KFSeqAct_SetMonsterProperties.uc create mode 100644 KFGame/Classes/KFSeqAct_SetPathnodeExtraCost.uc create mode 100644 KFGame/Classes/KFSeqAct_SetPawnIconVisibility.uc create mode 100644 KFGame/Classes/KFSeqAct_SetTeleporterURLNum.uc create mode 100644 KFGame/Classes/KFSeqAct_SetTrader.uc create mode 100644 KFGame/Classes/KFSeqAct_SetTraderEnabled.uc create mode 100644 KFGame/Classes/KFSeqAct_SetTraderVolumeIgnore.uc create mode 100644 KFGame/Classes/KFSeqAct_ShowPath.uc create mode 100644 KFGame/Classes/KFSeqAct_StartScriptedPawn.uc create mode 100644 KFGame/Classes/KFSeqAct_ToggleEx.uc create mode 100644 KFGame/Classes/KFSeqAct_UnlockAchievement.uc create mode 100644 KFGame/Classes/KFSeqAction_DoshVault.uc create mode 100644 KFGame/Classes/KFSeqEvent_ActivateTriggerProgress.uc create mode 100644 KFGame/Classes/KFSeqEvent_CollectTrigger.uc create mode 100644 KFGame/Classes/KFSeqEvent_DoshVault.uc create mode 100644 KFGame/Classes/KFSeqEvent_LevelLoaded.uc create mode 100644 KFGame/Classes/KFSeqEvent_MapObjectiveActivated.uc create mode 100644 KFGame/Classes/KFSeqEvent_MinigameActivated.uc create mode 100644 KFGame/Classes/KFSeqEvent_MinigameStateChanged.uc create mode 100644 KFGame/Classes/KFSeqEvent_ObjectiveProgress.uc create mode 100644 KFGame/Classes/KFSeqEvent_PawnTeleported.uc create mode 100644 KFGame/Classes/KFSeqEvent_PlayerDied.uc create mode 100644 KFGame/Classes/KFSeqEvent_PowerUpActivated.uc create mode 100644 KFGame/Classes/KFSeqEvent_RepairableActor.uc create mode 100644 KFGame/Classes/KFSeqEvent_TraderClosed.uc create mode 100644 KFGame/Classes/KFSeqEvent_TraderOpened.uc create mode 100644 KFGame/Classes/KFSeqEvent_WaveEnd.uc create mode 100644 KFGame/Classes/KFSeqEvent_WaveProgress.uc create mode 100644 KFGame/Classes/KFSeqEvent_WaveStart.uc create mode 100644 KFGame/Classes/KFSkelControl_AmmoSlider.uc create mode 100644 KFGame/Classes/KFSkelControl_FootPlacement.uc create mode 100644 KFGame/Classes/KFSkelControl_SpinBone.uc create mode 100644 KFGame/Classes/KFSkelControl_SprayScaling.uc create mode 100644 KFGame/Classes/KFSkelControl_SprayWhipDir.uc create mode 100644 KFGame/Classes/KFSkelControl_WeaponTilt.uc create mode 100644 KFGame/Classes/KFSkeletalMeshActor.uc create mode 100644 KFGame/Classes/KFSkeletalMeshComponent.uc create mode 100644 KFGame/Classes/KFSkinTypeEffects.uc create mode 100644 KFGame/Classes/KFSpawnRenderingComponent.uc create mode 100644 KFGame/Classes/KFSpawnVolume.uc create mode 100644 KFGame/Classes/KFSpawner.uc create mode 100644 KFGame/Classes/KFSpecialMove.uc create mode 100644 KFGame/Classes/KFSpecialMoveHandler.uc create mode 100644 KFGame/Classes/KFSprayActor.uc create mode 100644 KFGame/Classes/KFSteamWebAPICall.uc create mode 100644 KFGame/Classes/KFSteamWebUpToDateCheck.uc create mode 100644 KFGame/Classes/KFTargetingWeaponComponent.uc create mode 100644 KFGame/Classes/KFTeamInfo_Human.uc create mode 100644 KFGame/Classes/KFTeleporter.uc create mode 100644 KFGame/Classes/KFThirdPersonCamera.uc create mode 100644 KFGame/Classes/KFThirdPersonCameraMode.uc create mode 100644 KFGame/Classes/KFTraderDialogManager.uc create mode 100644 KFGame/Classes/KFTraderTrigger.uc create mode 100644 KFGame/Classes/KFTraderVoiceGroupBase.uc create mode 100644 KFGame/Classes/KFTrigger_ChokePoint.uc create mode 100644 KFGame/Classes/KFTrigger_DoshActivated.uc create mode 100644 KFGame/Classes/KFTrigger_MinigameButton.uc create mode 100644 KFGame/Classes/KFTrigger_MinigameCash.uc create mode 100644 KFGame/Classes/KFTrigger_NotifyOwner.uc create mode 100644 KFGame/Classes/KFTrigger_PowerUp.uc create mode 100644 KFGame/Classes/KFUIDataProvider_SearchResult.uc create mode 100644 KFGame/Classes/KFUIDataStore_GameResource.uc create mode 100644 KFGame/Classes/KFUnlockManager.uc create mode 100644 KFGame/Classes/KFUnlockableAsset.uc create mode 100644 KFGame/Classes/KFUsablePerkTrigger.uc create mode 100644 KFGame/Classes/KFUsableTrigger.uc create mode 100644 KFGame/Classes/KFVehicleMovementEffect.uc create mode 100644 KFGame/Classes/KFVersusNoGoVolume.uc create mode 100644 KFGame/Classes/KFVersusNoTakeoverVolume.uc create mode 100644 KFGame/Classes/KFVoiceInfo.uc create mode 100644 KFGame/Classes/KFVoteCollector.uc create mode 100644 KFGame/Classes/KFWallPathNode.uc create mode 100644 KFGame/Classes/KFWaterMeshActor.uc create mode 100644 KFGame/Classes/KFWeapAttach_DualBase.uc create mode 100644 KFGame/Classes/KFWeapAttach_Minigun.uc create mode 100644 KFGame/Classes/KFWeapAttach_SprayBase.uc create mode 100644 KFGame/Classes/KFWeapDef_9mm.uc create mode 100644 KFGame/Classes/KFWeapDef_9mmDual.uc create mode 100644 KFGame/Classes/KFWeapDef_AA12.uc create mode 100644 KFGame/Classes/KFWeapDef_AF2011.uc create mode 100644 KFGame/Classes/KFWeapDef_AF2011Dual.uc create mode 100644 KFGame/Classes/KFWeapDef_AR15.uc create mode 100644 KFGame/Classes/KFWeapDef_AbominationAxe.uc create mode 100644 KFGame/Classes/KFWeapDef_Ak12.uc create mode 100644 KFGame/Classes/KFWeapDef_Armor.uc create mode 100644 KFGame/Classes/KFWeapDef_Blunderbuss.uc create mode 100644 KFGame/Classes/KFWeapDef_Bullpup.uc create mode 100644 KFGame/Classes/KFWeapDef_C4.uc create mode 100644 KFGame/Classes/KFWeapDef_CaulkBurn.uc create mode 100644 KFGame/Classes/KFWeapDef_CenterfireMB464.uc create mode 100644 KFGame/Classes/KFWeapDef_ChainBat.uc create mode 100644 KFGame/Classes/KFWeapDef_ChiappaRhino.uc create mode 100644 KFGame/Classes/KFWeapDef_ChiappaRhinoDual.uc create mode 100644 KFGame/Classes/KFWeapDef_Colt1911.uc create mode 100644 KFGame/Classes/KFWeapDef_Colt1911Dual.uc create mode 100644 KFGame/Classes/KFWeapDef_CompoundBow.uc create mode 100644 KFGame/Classes/KFWeapDef_Crossbow.uc create mode 100644 KFGame/Classes/KFWeapDef_Crovel.uc create mode 100644 KFGame/Classes/KFWeapDef_Deagle.uc create mode 100644 KFGame/Classes/KFWeapDef_DeagleDual.uc create mode 100644 KFGame/Classes/KFWeapDef_DoubleBarrel.uc create mode 100644 KFGame/Classes/KFWeapDef_DragonsBreath.uc create mode 100644 KFGame/Classes/KFWeapDef_ElephantGun.uc create mode 100644 KFGame/Classes/KFWeapDef_Eviscerator.uc create mode 100644 KFGame/Classes/KFWeapDef_FNFal.uc create mode 100644 KFGame/Classes/KFWeapDef_FireAxe.uc create mode 100644 KFGame/Classes/KFWeapDef_FlameThrower.uc create mode 100644 KFGame/Classes/KFWeapDef_FlareGun.uc create mode 100644 KFGame/Classes/KFWeapDef_FlareGunDual.uc create mode 100644 KFGame/Classes/KFWeapDef_FreezeThrower.uc create mode 100644 KFGame/Classes/KFWeapDef_G18.uc create mode 100644 KFGame/Classes/KFWeapDef_Grenade_Berserker.uc create mode 100644 KFGame/Classes/KFWeapDef_Grenade_Commando.uc create mode 100644 KFGame/Classes/KFWeapDef_Grenade_Demo.uc create mode 100644 KFGame/Classes/KFWeapDef_Grenade_Firebug.uc create mode 100644 KFGame/Classes/KFWeapDef_Grenade_Gunslinger.uc create mode 100644 KFGame/Classes/KFWeapDef_Grenade_Medic.uc create mode 100644 KFGame/Classes/KFWeapDef_Grenade_SWAT.uc create mode 100644 KFGame/Classes/KFWeapDef_Grenade_Sharpshooter.uc create mode 100644 KFGame/Classes/KFWeapDef_Grenade_Support.uc create mode 100644 KFGame/Classes/KFWeapDef_HK_UMP.uc create mode 100644 KFGame/Classes/KFWeapDef_HRGIncendiaryRifle.uc create mode 100644 KFGame/Classes/KFWeapDef_HRGIncision.uc create mode 100644 KFGame/Classes/KFWeapDef_HRGScorcher.uc create mode 100644 KFGame/Classes/KFWeapDef_HRGWinterbite.uc create mode 100644 KFGame/Classes/KFWeapDef_HRGWinterbiteDual.uc create mode 100644 KFGame/Classes/KFWeapDef_HRG_EMP_ArcGenerator.uc create mode 100644 KFGame/Classes/KFWeapDef_HRG_Kaboomstick.uc create mode 100644 KFGame/Classes/KFWeapDef_HX25.uc create mode 100644 KFGame/Classes/KFWeapDef_HZ12.uc create mode 100644 KFGame/Classes/KFWeapDef_Healer.uc create mode 100644 KFGame/Classes/KFWeapDef_Healthrower_HRG.uc create mode 100644 KFGame/Classes/KFWeapDef_Hemogoblin.uc create mode 100644 KFGame/Classes/KFWeapDef_HuskCannon.uc create mode 100644 KFGame/Classes/KFWeapDef_IonThruster.uc create mode 100644 KFGame/Classes/KFWeapDef_Katana.uc create mode 100644 KFGame/Classes/KFWeapDef_Knife_Berserker.uc create mode 100644 KFGame/Classes/KFWeapDef_Knife_Commando.uc create mode 100644 KFGame/Classes/KFWeapDef_Knife_Demo.uc create mode 100644 KFGame/Classes/KFWeapDef_Knife_Firebug.uc create mode 100644 KFGame/Classes/KFWeapDef_Knife_Gunslinger.uc create mode 100644 KFGame/Classes/KFWeapDef_Knife_Medic.uc create mode 100644 KFGame/Classes/KFWeapDef_Knife_SWAT.uc create mode 100644 KFGame/Classes/KFWeapDef_Knife_Sharpshooter.uc create mode 100644 KFGame/Classes/KFWeapDef_Knife_Support.uc create mode 100644 KFGame/Classes/KFWeapDef_Knife_Survivalist.uc create mode 100644 KFGame/Classes/KFWeapDef_Kriss.uc create mode 100644 KFGame/Classes/KFWeapDef_LazerCutter.uc create mode 100644 KFGame/Classes/KFWeapDef_M14EBR.uc create mode 100644 KFGame/Classes/KFWeapDef_M16M203.uc create mode 100644 KFGame/Classes/KFWeapDef_M32.uc create mode 100644 KFGame/Classes/KFWeapDef_M4.uc create mode 100644 KFGame/Classes/KFWeapDef_M79.uc create mode 100644 KFGame/Classes/KFWeapDef_M99.uc create mode 100644 KFGame/Classes/KFWeapDef_MB500.uc create mode 100644 KFGame/Classes/KFWeapDef_MKB42.uc create mode 100644 KFGame/Classes/KFWeapDef_MP5RAS.uc create mode 100644 KFGame/Classes/KFWeapDef_MP7.uc create mode 100644 KFGame/Classes/KFWeapDef_Mac10.uc create mode 100644 KFGame/Classes/KFWeapDef_MaceAndShield.uc create mode 100644 KFGame/Classes/KFWeapDef_MedicBat.uc create mode 100644 KFGame/Classes/KFWeapDef_MedicPistol.uc create mode 100644 KFGame/Classes/KFWeapDef_MedicRifle.uc create mode 100644 KFGame/Classes/KFWeapDef_MedicRifleGrenadeLauncher.uc create mode 100644 KFGame/Classes/KFWeapDef_MedicSMG.uc create mode 100644 KFGame/Classes/KFWeapDef_MedicShotgun.uc create mode 100644 KFGame/Classes/KFWeapDef_MicrowaveGun.uc create mode 100644 KFGame/Classes/KFWeapDef_MicrowaveRifle.uc create mode 100644 KFGame/Classes/KFWeapDef_Mine_Reconstructor.uc create mode 100644 KFGame/Classes/KFWeapDef_Minigun.uc create mode 100644 KFGame/Classes/KFWeapDef_MosinNagant.uc create mode 100644 KFGame/Classes/KFWeapDef_NailGun.uc create mode 100644 KFGame/Classes/KFWeapDef_NailGun_HRG.uc create mode 100644 KFGame/Classes/KFWeapDef_P90.uc create mode 100644 KFGame/Classes/KFWeapDef_Pistol_DualG18.uc create mode 100644 KFGame/Classes/KFWeapDef_Pistol_G18C.uc create mode 100644 KFGame/Classes/KFWeapDef_PowerGloves.uc create mode 100644 KFGame/Classes/KFWeapDef_Pulverizer.uc create mode 100644 KFGame/Classes/KFWeapDef_RPG7.uc create mode 100644 KFGame/Classes/KFWeapDef_RailGun.uc create mode 100644 KFGame/Classes/KFWeapDef_Random.uc create mode 100644 KFGame/Classes/KFWeapDef_Remington1858.uc create mode 100644 KFGame/Classes/KFWeapDef_Remington1858Dual.uc create mode 100644 KFGame/Classes/KFWeapDef_SCAR.uc create mode 100644 KFGame/Classes/KFWeapDef_SW500.uc create mode 100644 KFGame/Classes/KFWeapDef_SW500Dual.uc create mode 100644 KFGame/Classes/KFWeapDef_SW500Dual_HRG.uc create mode 100644 KFGame/Classes/KFWeapDef_SW500_HRG.uc create mode 100644 KFGame/Classes/KFWeapDef_SealSqueal.uc create mode 100644 KFGame/Classes/KFWeapDef_Seeker6.uc create mode 100644 KFGame/Classes/KFWeapDef_Stoner63A.uc create mode 100644 KFGame/Classes/KFWeapDef_Thompson.uc create mode 100644 KFGame/Classes/KFWeapDef_Welder.uc create mode 100644 KFGame/Classes/KFWeapDef_Winchester1894.uc create mode 100644 KFGame/Classes/KFWeapDef_Zweihander.uc create mode 100644 KFGame/Classes/KFWeap_DualBase.uc create mode 100644 KFGame/Classes/KFWeap_FlameBase.uc create mode 100644 KFGame/Classes/KFWeap_GrenadeLauncher_Base.uc create mode 100644 KFGame/Classes/KFWeap_GrenadeLauncher_CylinderBase.uc create mode 100644 KFGame/Classes/KFWeap_HealerBase.uc create mode 100644 KFGame/Classes/KFWeap_MedicBase.uc create mode 100644 KFGame/Classes/KFWeap_MeleeBase.uc create mode 100644 KFGame/Classes/KFWeap_MinigunBase.uc create mode 100644 KFGame/Classes/KFWeap_PistolBase.uc create mode 100644 KFGame/Classes/KFWeap_RifleBase.uc create mode 100644 KFGame/Classes/KFWeap_SMGBase.uc create mode 100644 KFGame/Classes/KFWeap_ScopedBase.uc create mode 100644 KFGame/Classes/KFWeap_ShotgunBase.uc create mode 100644 KFGame/Classes/KFWeap_ThrownBase.uc create mode 100644 KFGame/Classes/KFWeapon.uc create mode 100644 KFGame/Classes/KFWeaponAmbientEchoHandler.uc create mode 100644 KFGame/Classes/KFWeaponAttachment.uc create mode 100644 KFGame/Classes/KFWeaponDefinition.uc create mode 100644 KFGame/Classes/KFWeaponSkinList.uc create mode 100644 KFGame/Classes/KFWeeklyOutbreakInformation.uc create mode 100644 KFGame/Classes/KFWeldableActor.uc create mode 100644 KFGame/Classes/KFWeldableComponent.uc create mode 100644 KFGame/Classes/KFWeldableTrigger.uc create mode 100644 KFGame/Classes/KFWireConnector.uc create mode 100644 KFGame/Classes/KFWireStart.uc create mode 100644 KFGame/Classes/KFZedArmorInfo.uc create mode 100644 KFGame/Classes/KFweapDef_Knife_Base.uc create mode 100644 KFGame/Classes/Path_AroundDestructibles.uc create mode 100644 KFGame/Classes/Path_AvoidChokePoints.uc create mode 100644 KFGame/Classes/Path_AvoidClosedDoors.uc create mode 100644 KFGame/Classes/Path_PreferDarkness.uc create mode 100644 KFGame/Classes/Path_PreferWalls.uc create mode 100644 KFGame/Classes/Path_ToTrader.uc create mode 100644 KFGame/Classes/WallReachSpec.uc create mode 100644 KFGame/Classes/WallToFloorReachSpec.uc create mode 100644 KFGame/Globals.uci create mode 100644 KFGame/KFGameAnalytics.uci create mode 100644 KFGame/KFGameDialog.uci create mode 100644 KFGame/KFMatchStats.uci create mode 100644 KFGame/KFOnlineStats.uci create mode 100644 KFGame/KFProfileSettings.uci create mode 100644 KFGameContent/Classes/AICommand_Base_Matriarch.uc create mode 100644 KFGameContent/Classes/AICommand_Base_Patriarch.uc create mode 100644 KFGameContent/Classes/AICommand_BloatKingSubspawn_Explode.uc create mode 100644 KFGameContent/Classes/AICommand_BloatKing_Gorge.uc create mode 100644 KFGameContent/Classes/AICommand_DAR_EMPAttack.uc create mode 100644 KFGameContent/Classes/AICommand_DAR_LaserAttack.uc create mode 100644 KFGameContent/Classes/AICommand_DAR_RocketAttack.uc create mode 100644 KFGameContent/Classes/AICommand_FleshpoundKing_ChestBeamAttack.uc create mode 100644 KFGameContent/Classes/AICommand_HuskFireBallAttack.uc create mode 100644 KFGameContent/Classes/AICommand_HuskFlameThrowerAttack.uc create mode 100644 KFGameContent/Classes/AICommand_Husk_Suicide.uc create mode 100644 KFGameContent/Classes/AICommand_MatriarchPlasmaCannon.uc create mode 100644 KFGameContent/Classes/AICommand_Matriarch_LightningStorm.uc create mode 100644 KFGameContent/Classes/AICommand_Matriarch_ScorpionWhip.uc create mode 100644 KFGameContent/Classes/AICommand_Matriarch_SweepingClaw.uc create mode 100644 KFGameContent/Classes/AICommand_Matriarch_TeslaBlast.uc create mode 100644 KFGameContent/Classes/AICommand_Matriarch_WarningSiren.uc create mode 100644 KFGameContent/Classes/AICommand_Patriarch_Grab.uc create mode 100644 KFGameContent/Classes/AICommand_Patriarch_MinigunBarrage.uc create mode 100644 KFGameContent/Classes/AICommand_Patriarch_MissileAttack.uc create mode 100644 KFGameContent/Classes/AICommand_Patriarch_MortarAttack.uc create mode 100644 KFGameContent/Classes/AICommand_RangedAttack.uc create mode 100644 KFGameContent/Classes/AICommand_Siren_Scream.uc create mode 100644 KFGameContent/Classes/KFAIController_HansFriendlyTest.uc create mode 100644 KFGameContent/Classes/KFAIController_HuskFriendlyTest.uc create mode 100644 KFGameContent/Classes/KFAIController_Ranged.uc create mode 100644 KFGameContent/Classes/KFAIController_ZedBloat.uc create mode 100644 KFGameContent/Classes/KFAIController_ZedBloatKing.uc create mode 100644 KFGameContent/Classes/KFAIController_ZedBloatKingSubspawn.uc create mode 100644 KFGameContent/Classes/KFAIController_ZedClot_Alpha.uc create mode 100644 KFGameContent/Classes/KFAIController_ZedClot_AlphaKing.uc create mode 100644 KFGameContent/Classes/KFAIController_ZedClot_Cyst.uc create mode 100644 KFGameContent/Classes/KFAIController_ZedClot_Slasher.uc create mode 100644 KFGameContent/Classes/KFAIController_ZedCrawlerKing.uc create mode 100644 KFGameContent/Classes/KFAIController_ZedDAR.uc create mode 100644 KFGameContent/Classes/KFAIController_ZedDAR_EMP.uc create mode 100644 KFGameContent/Classes/KFAIController_ZedDAR_Laser.uc create mode 100644 KFGameContent/Classes/KFAIController_ZedDAR_Rocket.uc create mode 100644 KFGameContent/Classes/KFAIController_ZedFleshpoundKing.uc create mode 100644 KFGameContent/Classes/KFAIController_ZedGorefast.uc create mode 100644 KFGameContent/Classes/KFAIController_ZedGorefastDualBlade.uc create mode 100644 KFGameContent/Classes/KFAIController_ZedHusk.uc create mode 100644 KFGameContent/Classes/KFAIController_ZedMatriarch.uc create mode 100644 KFGameContent/Classes/KFAIController_ZedPatriarch.uc create mode 100644 KFGameContent/Classes/KFAIController_ZedScrake.uc create mode 100644 KFGameContent/Classes/KFAIController_ZedSiren.uc create mode 100644 KFGameContent/Classes/KFAIController_ZedStalker.uc create mode 100644 KFGameContent/Classes/KFAISpawnManager_Endless.uc create mode 100644 KFGameContent/Classes/KFAISpawnManager_Tutorial.uc create mode 100644 KFGameContent/Classes/KFAISpawnManager_Versus.uc create mode 100644 KFGameContent/Classes/KFActor_DestructibleTracker.uc create mode 100644 KFGameContent/Classes/KFAffliction_Fire_Patriarch.uc create mode 100644 KFGameContent/Classes/KFBloodRainVolume.uc create mode 100644 KFGameContent/Classes/KFCarryableObject_Collectible.uc create mode 100644 KFGameContent/Classes/KFCarryable_Datapad.uc create mode 100644 KFGameContent/Classes/KFCarryable_Gear.uc create mode 100644 KFGameContent/Classes/KFCollectibleActor.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_9mm.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_AA12Shotgun.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_AF2011.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_AK12.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_AR15.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_AssaultRifle.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_Assault_Medic.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_BlunderbussImpact.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_BlunderbussShards.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_Bullpup.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_CenterfireMB464.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_ChiappaRhino.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_Colt1911.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_DBShotgun.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_Deagle.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_DragonsBreath.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_ElephantGun.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_FNFal.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_G18.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_G18C.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_HK_UMP.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_HRGBuckshot.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_HRGIncendiaryRifle.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_HRGIncendiaryRifleGrenadeImpact.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_HRGIncisionHeal.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_HRGIncisionHurt.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_HRGNailgun.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_HRGScorcherBrokenImpact.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_HRGScorcherLightingImpact.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_HRGTeslauncher.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_HRGTeslauncherGrenadeImpact.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_HRG_Kaboomstick.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_HX25Impact.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_HX25SubmunitionImpact.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_HZ12.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_Handgun.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_HansAK12.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_Hemogoblin.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_Kriss.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_LazerCutter.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_M14EBR.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_M16M203.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_M203Impact.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_M32Impact.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_M4Shotgun.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_M79Impact.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_M99.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_MB500.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_MKB42.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_MP5RAS.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_MP7.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_MedicRifleGrenadeLauncher.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_MedicRifleGrenadeLauncherImpact.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_MicrowaveRifle.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_Minigun.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_MosinNagant.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_MosinNagantSpecial.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_NailShotgun.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_P90.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_PatMinigun.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_Pistol_Medic.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_RPG7Impact.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_RailGun.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_Rem1858.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_Rem1858_Dual.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_Rifle.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_SCAR.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_SMG_Medic.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_SW500.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_SW500_Dual.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_SealSquealImpact.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_Seeker6Impact.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_Shotgun.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_Shotgun_Medic.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_Stoner63A.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_Submachinegun.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_Thompson.uc create mode 100644 KFGameContent/Classes/KFDT_Ballistic_Winchester.uc create mode 100644 KFGameContent/Classes/KFDT_BellTrap.uc create mode 100644 KFGameContent/Classes/KFDT_Bleeding_Hemogoblin.uc create mode 100644 KFGameContent/Classes/KFDT_BloatKingSubspawn_Death.uc create mode 100644 KFGameContent/Classes/KFDT_BloatPuke.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_9mm.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_AA12Shotgun.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_AF2011.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_AK12.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_AR15.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_ArcGenerator.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Assault_Medic.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_BloatKing.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_BloatKingGorge.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Blunderbuss.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Bullpup.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_C4.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Carryable.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_CaulkBurn.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_CenterfireMB464.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_ChainBat.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_ChainBatBash.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_ChainBatHeavy.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_ChiappaRhino.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Colt1911.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Crossbow.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Crovel.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_CrovelBash.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_DBShotgun.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Deagle.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_DragonsBreath.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_ElephantGun.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_FNFal.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_FireAxeBash.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Flamethrower.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_FlareGun.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Fleshpound.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Fleshpound_AOE.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_FreezeThrower.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_G18C.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_G18Shield.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_G18Shield_Impulse.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_HK_UMP.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_HRGBuckshot.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_HRGHealthrower.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_HRGIncendiaryRifle.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_HRGIncision.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_HRGNailgun.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_HRGScorcher.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_HRGTeslauncher.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_HRGWinterbite.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_HRG_Kaboomstick.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_HX25.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_HZ12.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Healer.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Hemogoblin.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_HuskCannon.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Kriss.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_LazerCutter.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_M14EBR.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_M16M203.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_M32.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_M4Shotgun.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_M79.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_M99.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_MB500.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_MKB42.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_MP5RAS.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_MP7.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Mac10.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_MaceAndShield.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_MaceAndShield_Bash.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_MaceAndShield_MaceHeavy.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_MaceAndShield_ShieldHeavy.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_MaceAndShield_ShieldLight.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Matriarch.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_MedicBatBash.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_MedicBatHeavy.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_MedicBatLight.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_MedicRifleGrenadeLauncher.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_MicrowaveGun.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_MicrowaveRifle.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Mine_Reconstructor.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Minigun.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_NailShotgun.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_P90.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Patriarch.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_PatriarchKick.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_PatriarchMetal.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Pistol_Medic.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_PowerGloves.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_PowerGlovesBash.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_PowerGlovesHeavy.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Pulverizer.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_PulverizerBash.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_PulverizerHeavy.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_RPG7.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_RailGun.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Rem1858.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_RifleButt.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_SCAR.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_SMG_Medic.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_SW500.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_SealSqueal.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Seeker6.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Shotgun_Medic.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Stoner63A.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Thompson.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Welder.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_Winchester.uc create mode 100644 KFGameContent/Classes/KFDT_Bludgeon_ZedJump.uc create mode 100644 KFGameContent/Classes/KFDT_DAR_EMPBlast.uc create mode 100644 KFGameContent/Classes/KFDT_Dart_Healing.uc create mode 100644 KFGameContent/Classes/KFDT_Dart_Toxic.uc create mode 100644 KFGameContent/Classes/KFDT_EMPTrap.uc create mode 100644 KFGameContent/Classes/KFDT_EMP_ArcGeneratorSphereImpact.uc create mode 100644 KFGameContent/Classes/KFDT_EMP_ArcGenerator_AltFiremodeZapDamage.uc create mode 100644 KFGameContent/Classes/KFDT_EMP_ArcGenerator_Beam.uc create mode 100644 KFGameContent/Classes/KFDT_EMP_ArcGenerator_DefaultFiremodeZapDamage.uc create mode 100644 KFGameContent/Classes/KFDT_EMP_EMPGrenade.uc create mode 100644 KFGameContent/Classes/KFDT_EMP_MatriarchLightningStorm.uc create mode 100644 KFGameContent/Classes/KFDT_EMP_MatriarchPlasmaCannon.uc create mode 100644 KFGameContent/Classes/KFDT_EMP_MatriarchTeslaBlast.uc create mode 100644 KFGameContent/Classes/KFDT_EMP_TeslauncherEMPGrenade.uc create mode 100644 KFGameContent/Classes/KFDT_EvilDAR_Laser.uc create mode 100644 KFGameContent/Classes/KFDT_EvilDAR_Rocket.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_Blunderbuss.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_C4.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_CrawlerSuicide.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_DynamiteGrenade.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_FlashBangGrenade.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_FleshpoundKingRage_Heavy.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_FleshpoundKingRage_Light.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_FragGrenade.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_HEGrenade.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_HRGIncendiaryRifle.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_HRGWinterbite.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_HRG_Kaboomstick.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_HX25.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_HansHEGrenade.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_HuskCannon.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_HuskCannonImpact.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_HuskSuicide.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_M16M203.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_M32.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_M79.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_NailBombGrenade.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_PatMissile.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_PatMortar.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_PlayerZedTakeover.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_Pulverizer.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_RPG7.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_RPG7BackBlast.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_SealSqueal.uc create mode 100644 KFGameContent/Classes/KFDT_Explosive_Seeker6.uc create mode 100644 KFGameContent/Classes/KFDT_FireTrap.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_CaulkBurn.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_DragonsBreathDoT.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_Environment.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_EnvironmentTrap.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_FlameThrower.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_FlareGun.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_FlareGunDoT.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_FlareGun_Dual.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_Ground_CaulkNBurn.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_Ground_DragonsBreath.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_Ground_FlameThrower.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_Ground_FlareGun.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_Ground_HRGIncendiaryRifle.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_Ground_HRGScorcher.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_Ground_HuskCannon.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_Ground_MicrowaveGun.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_Ground_MolotovGrenade.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_HRGIncendiaryRifleBulletDoT.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_HRGIncendiaryRifleGrenadeDoT.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_HRGScorcherDoT.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_HRGTeslauncherDoT.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_HuskFireball.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_HuskFlamethrower.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_IonThrusterDoT.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_Mac10.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_MolotovGrenade.uc create mode 100644 KFGameContent/Classes/KFDT_Fire_ZedGround.uc create mode 100644 KFGameContent/Classes/KFDT_FleshpoundKing_ChestBeam.uc create mode 100644 KFGameContent/Classes/KFDT_Freeze_CompoundBowCryExplosion.uc create mode 100644 KFGameContent/Classes/KFDT_Freeze_DualHRGWinterbiteImpact.uc create mode 100644 KFGameContent/Classes/KFDT_Freeze_FreezeGrenade.uc create mode 100644 KFGameContent/Classes/KFDT_Freeze_FreezeThrower.uc create mode 100644 KFGameContent/Classes/KFDT_Freeze_FreezeThrower_IceShards.uc create mode 100644 KFGameContent/Classes/KFDT_Freeze_Ground_FreezeThrower.uc create mode 100644 KFGameContent/Classes/KFDT_Freeze_HRGWinterbiteImpact.uc create mode 100644 KFGameContent/Classes/KFDT_Healing_MedicGrenade.uc create mode 100644 KFGameContent/Classes/KFDT_HeavyZedBump.uc create mode 100644 KFGameContent/Classes/KFDT_Krampus_ChipperPit.uc create mode 100644 KFGameContent/Classes/KFDT_LazerCutter_Beam.uc create mode 100644 KFGameContent/Classes/KFDT_MediumZedBump.uc create mode 100644 KFGameContent/Classes/KFDT_Microwave_Beam.uc create mode 100644 KFGameContent/Classes/KFDT_Microwave_Blast.uc create mode 100644 KFGameContent/Classes/KFDT_Mine_Reconstructor_BileExplosionDoT.uc create mode 100644 KFGameContent/Classes/KFDT_PiercingTrap.uc create mode 100644 KFGameContent/Classes/KFDT_Piercing_AbominationAxeStab.uc create mode 100644 KFGameContent/Classes/KFDT_Piercing_ChiappaShrapnel.uc create mode 100644 KFGameContent/Classes/KFDT_Piercing_CompoundBowCryoImpact.uc create mode 100644 KFGameContent/Classes/KFDT_Piercing_CompoundBowSharpImpact.uc create mode 100644 KFGameContent/Classes/KFDT_Piercing_Crossbow.uc create mode 100644 KFGameContent/Classes/KFDT_Piercing_IonThrusterStab.uc create mode 100644 KFGameContent/Classes/KFDT_Piercing_KatanaStab.uc create mode 100644 KFGameContent/Classes/KFDT_Piercing_KnifeStab.uc create mode 100644 KFGameContent/Classes/KFDT_Piercing_KnifeStab_Berserker.uc create mode 100644 KFGameContent/Classes/KFDT_Piercing_KnifeStab_FieldMedic.uc create mode 100644 KFGameContent/Classes/KFDT_Piercing_KnifeStab_SWAT.uc create mode 100644 KFGameContent/Classes/KFDT_Piercing_KnifeStab_Survivalist.uc create mode 100644 KFGameContent/Classes/KFDT_Piercing_MosinNagant.uc create mode 100644 KFGameContent/Classes/KFDT_Piercing_NadeFragment.uc create mode 100644 KFGameContent/Classes/KFDT_Piercing_NailFragment.uc create mode 100644 KFGameContent/Classes/KFDT_Piercing_ZweihanderStab.uc create mode 100644 KFGameContent/Classes/KFDT_Pirecing_CompoundBow.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_AbominationAxe.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_AbominationAxeHeavy.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_Crovel.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_Eviscerator.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_EvisceratorProj.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_FireAxe.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_FireAxeHeavy.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_Gorefast.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_Gorefast_AOE.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_Hans.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_IonThruster.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_IonThrusterHeavy.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_IonThrusterSpecial.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_Katana.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_KatanaHeavy.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_Knife.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_KnifeHeavy.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_KnifeHeavy_Berserker.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_KnifeHeavy_Medic.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_KnifeHeavy_SWAT.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_KnifeHeavy_Survivalist.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_Knife_Berserker.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_Knife_Medic.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_Knife_SWAT.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_Knife_Survivalist.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_MatriarchTentacle.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_PatTentacle.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_Patriarch.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_PowerGloves.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_Scrake.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_Scrake_AOE.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_ZedWeak.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_Zweihander.uc create mode 100644 KFGameContent/Classes/KFDT_Slashing_ZweihanderHeavy.uc create mode 100644 KFGameContent/Classes/KFDT_Sonic_MatriarchWarningSiren.uc create mode 100644 KFGameContent/Classes/KFDT_Sonic_VortexScream.uc create mode 100644 KFGameContent/Classes/KFDT_SwingMinigame.uc create mode 100644 KFGameContent/Classes/KFDT_Toxic_BloatKingFart.uc create mode 100644 KFGameContent/Classes/KFDT_Toxic_BloatKingPukeMine.uc create mode 100644 KFGameContent/Classes/KFDT_Toxic_BloatKingSubspawnExplosion.uc create mode 100644 KFGameContent/Classes/KFDT_Toxic_BloatPukeMine.uc create mode 100644 KFGameContent/Classes/KFDT_Toxic_EnvironmentGas.uc create mode 100644 KFGameContent/Classes/KFDT_Toxic_HansGrenade.uc create mode 100644 KFGameContent/Classes/KFDT_Toxic_MedicBatDoT.uc create mode 100644 KFGameContent/Classes/KFDT_Toxic_MedicBatGas.uc create mode 100644 KFGameContent/Classes/KFDT_Toxic_MineReconstructorExplosion.uc create mode 100644 KFGameContent/Classes/KFDT_Toxic_MineReconstructorImpact.uc create mode 100644 KFGameContent/Classes/KFDT_Toxic_MineReconstructorImpactHeavy.uc create mode 100644 KFGameContent/Classes/KFDT_Toxic_PlayerCrawlerSuicide.uc create mode 100644 KFGameContent/Classes/KFDT_Trap_BiolapseBloodBlender.uc create mode 100644 KFGameContent/Classes/KFDT_Trap_BiolapseTrapDoor.uc create mode 100644 KFGameContent/Classes/KFDT_Trap_SanitariumSuction.uc create mode 100644 KFGameContent/Classes/KFDT_Trap_SanitariumTentacle.uc create mode 100644 KFGameContent/Classes/KFDifficulty_Bloat.uc create mode 100644 KFGameContent/Classes/KFDifficulty_BloatKing.uc create mode 100644 KFGameContent/Classes/KFDifficulty_BloatKingSubspawn.uc create mode 100644 KFGameContent/Classes/KFDifficulty_ClotAlpha.uc create mode 100644 KFGameContent/Classes/KFDifficulty_ClotAlphaKing.uc create mode 100644 KFGameContent/Classes/KFDifficulty_ClotCyst.uc create mode 100644 KFGameContent/Classes/KFDifficulty_ClotSlasher.uc create mode 100644 KFGameContent/Classes/KFDifficulty_Crawler.uc create mode 100644 KFGameContent/Classes/KFDifficulty_CrawlerKing.uc create mode 100644 KFGameContent/Classes/KFDifficulty_DAR.uc create mode 100644 KFGameContent/Classes/KFDifficulty_DAR_EMP.uc create mode 100644 KFGameContent/Classes/KFDifficulty_DAR_Laser.uc create mode 100644 KFGameContent/Classes/KFDifficulty_DAR_Rocket.uc create mode 100644 KFGameContent/Classes/KFDifficulty_Fleshpound.uc create mode 100644 KFGameContent/Classes/KFDifficulty_FleshpoundKing.uc create mode 100644 KFGameContent/Classes/KFDifficulty_FleshpoundMini.uc create mode 100644 KFGameContent/Classes/KFDifficulty_Gorefast.uc create mode 100644 KFGameContent/Classes/KFDifficulty_GorefastDualBlade.uc create mode 100644 KFGameContent/Classes/KFDifficulty_Hans.uc create mode 100644 KFGameContent/Classes/KFDifficulty_Husk.uc create mode 100644 KFGameContent/Classes/KFDifficulty_Matriarch.uc create mode 100644 KFGameContent/Classes/KFDifficulty_Patriarch.uc create mode 100644 KFGameContent/Classes/KFDifficulty_Scrake.uc create mode 100644 KFGameContent/Classes/KFDifficulty_Siren.uc create mode 100644 KFGameContent/Classes/KFDifficulty_Stalker.uc create mode 100644 KFGameContent/Classes/KFDroppedPickup_Carryable.uc create mode 100644 KFGameContent/Classes/KFDynamicPhysicsVolume.uc create mode 100644 KFGameContent/Classes/KFExplosionActorC4.uc create mode 100644 KFGameContent/Classes/KFExplosionActor_HuskCannon.uc create mode 100644 KFGameContent/Classes/KFExplosion_BloatKingFart.uc create mode 100644 KFGameContent/Classes/KFExplosion_BloatKingSubspawn.uc create mode 100644 KFGameContent/Classes/KFExplosion_BlunderbussCannonball.uc create mode 100644 KFGameContent/Classes/KFExplosion_GroundFire.uc create mode 100644 KFGameContent/Classes/KFExplosion_GroundIce.uc create mode 100644 KFGameContent/Classes/KFExplosion_HRGIncendiaryRifleGroundFire.uc create mode 100644 KFGameContent/Classes/KFExplosion_HRGScorcherGroundFire.uc create mode 100644 KFGameContent/Classes/KFExplosion_HansNerveGasGrenade.uc create mode 100644 KFGameContent/Classes/KFExplosion_HansSmokeGrenade.uc create mode 100644 KFGameContent/Classes/KFExplosion_HuskCannonFireballGroundFire.uc create mode 100644 KFGameContent/Classes/KFExplosion_HuskFireballGroundFire.uc create mode 100644 KFGameContent/Classes/KFExplosion_MedicGrenade.uc create mode 100644 KFGameContent/Classes/KFExplosion_MedicGrenadeMini.uc create mode 100644 KFGameContent/Classes/KFExplosion_MineReconstructor.uc create mode 100644 KFGameContent/Classes/KFExplosion_Molotov.uc create mode 100644 KFGameContent/Classes/KFExplosion_PlayerBloatPukeMine.uc create mode 100644 KFGameContent/Classes/KFExplosion_PlayerCrawlerSuicide.uc create mode 100644 KFGameContent/Classes/KFExplosion_ReplicatedMedicGrenade.uc create mode 100644 KFGameContent/Classes/KFExplosion_SirenScream.uc create mode 100644 KFGameContent/Classes/KFGFXHudWrapper_Versus.uc create mode 100644 KFGameContent/Classes/KFGFxHUD_PlayerStatusVersus.uc create mode 100644 KFGameContent/Classes/KFGFxMoviePlayer_HUD_Versus.uc create mode 100644 KFGameContent/Classes/KFGFxMoviePlayer_Manager_Tutorial.uc create mode 100644 KFGameContent/Classes/KFGFxMoviePlayer_Tutorial.uc create mode 100644 KFGameContent/Classes/KFGFxTutorialContainer.uc create mode 100644 KFGameContent/Classes/KFGameConductorVersus.uc create mode 100644 KFGameContent/Classes/KFGameContentRoot.uc create mode 100644 KFGameContent/Classes/KFGameDifficulty_Endless.uc create mode 100644 KFGameContent/Classes/KFGameDifficulty_Endless_Console.uc create mode 100644 KFGameContent/Classes/KFGameDifficulty_Objective.uc create mode 100644 KFGameContent/Classes/KFGameDifficulty_Objective_Console.uc create mode 100644 KFGameContent/Classes/KFGameDifficulty_Survival.uc create mode 100644 KFGameContent/Classes/KFGameDifficulty_Survival_Console.uc create mode 100644 KFGameContent/Classes/KFGameDifficulty_Versus.uc create mode 100644 KFGameContent/Classes/KFGameDifficulty_Versus_Console.uc create mode 100644 KFGameContent/Classes/KFGameInfo_Endless.uc create mode 100644 KFGameContent/Classes/KFGameInfo_Objective.uc create mode 100644 KFGameContent/Classes/KFGameInfo_Survival.uc create mode 100644 KFGameContent/Classes/KFGameInfo_Tutorial.uc create mode 100644 KFGameContent/Classes/KFGameInfo_VersusSurvival.uc create mode 100644 KFGameContent/Classes/KFGameInfo_WeeklySurvival.uc create mode 100644 KFGameContent/Classes/KFGameReplicationInfoVersus.uc create mode 100644 KFGameContent/Classes/KFGameReplicationInfo_Endless.uc create mode 100644 KFGameContent/Classes/KFGameReplicationInfo_Objective.uc create mode 100644 KFGameContent/Classes/KFGameReplicationInfo_WeeklySurvival.uc create mode 100644 KFGameContent/Classes/KFGoreJoint_Arm.uc create mode 100644 KFGameContent/Classes/KFGoreJoint_Chest.uc create mode 100644 KFGameContent/Classes/KFGoreJoint_Foot.uc create mode 100644 KFGameContent/Classes/KFGoreJoint_ForeArm.uc create mode 100644 KFGameContent/Classes/KFGoreJoint_Hand.uc create mode 100644 KFGameContent/Classes/KFGoreJoint_Head.uc create mode 100644 KFGameContent/Classes/KFGoreJoint_Hips.uc create mode 100644 KFGameContent/Classes/KFGoreJoint_Leg.uc create mode 100644 KFGameContent/Classes/KFGoreJoint_Neck.uc create mode 100644 KFGameContent/Classes/KFGoreJoint_Shoulder.uc create mode 100644 KFGameContent/Classes/KFGoreJoint_Spine1.uc create mode 100644 KFGameContent/Classes/KFGoreJoint_Thigh.uc create mode 100644 KFGameContent/Classes/KFInventory_Armor.uc create mode 100644 KFGameContent/Classes/KFInventory_Money.uc create mode 100644 KFGameContent/Classes/KFMGA_AnimatedTrap.uc create mode 100644 KFGameContent/Classes/KFMGA_DoshTossPit.uc create mode 100644 KFGameContent/Classes/KFMGA_Rollercoaster.uc create mode 100644 KFGameContent/Classes/KFMGA_Target.uc create mode 100644 KFGameContent/Classes/KFMGA_TargetGame.uc create mode 100644 KFGameContent/Classes/KFMGA_Target_BloatDunk.uc create mode 100644 KFGameContent/Classes/KFMGVolume_DoshToss.uc create mode 100644 KFGameContent/Classes/KFMGVolume_SwingHit.uc create mode 100644 KFGameContent/Classes/KFMG_BloatDunk.uc create mode 100644 KFGameContent/Classes/KFMG_MultilevelTargetGame.uc create mode 100644 KFGameContent/Classes/KFMG_RiggedTargetGame.uc create mode 100644 KFGameContent/Classes/KFMG_SwingRide.uc create mode 100644 KFGameContent/Classes/KFMG_TargetGame.uc create mode 100644 KFGameContent/Classes/KFMapMutator_SantasWorkshop.uc create mode 100644 KFGameContent/Classes/KFMapObjective_ActivateTrigger.uc create mode 100644 KFGameContent/Classes/KFMapObjective_AreaDefense.uc create mode 100644 KFGameContent/Classes/KFMapObjective_CollectActors.uc create mode 100644 KFGameContent/Classes/KFMapObjective_DoshHold.uc create mode 100644 KFGameContent/Classes/KFMapObjective_EscortPawns.uc create mode 100644 KFGameContent/Classes/KFMapObjective_ExterminateWave.uc create mode 100644 KFGameContent/Classes/KFMapObjective_HoldZone.uc create mode 100644 KFGameContent/Classes/KFMapObjective_RepairActors.uc create mode 100644 KFGameContent/Classes/KFMedicWeaponComponent_HRGIncision.uc create mode 100644 KFGameContent/Classes/KFObjectiveCollectActor.uc create mode 100644 KFGameContent/Classes/KFOutbreakEvent_Endless.uc create mode 100644 KFGameContent/Classes/KFOutbreakEvent_Weekly.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroupEventData_Hans.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroupEventData_Matriarch.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroupEventData_Patriarch.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroupEventData_Player.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroup_Alberts.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroup_Ana.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroup_BadAssSanta.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroup_Banner.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroup_Briar.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroup_Briar_Classic.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroup_Coleman.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroup_DAR.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroup_DJSkully.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroup_Hans.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroup_Jaeger.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroup_Masterson.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroup_Masterson_Classic.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroup_Matriarch.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroup_MrFoster.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroup_Mrs_Foster.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroup_Patriarch.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroup_Rae.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroup_Strasser.uc create mode 100644 KFGameContent/Classes/KFPawnVoiceGroup_Tanaka.uc create mode 100644 KFGameContent/Classes/KFPawn_Human_Versus.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedBloat.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedBloatKing.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedBloatKingSubspawn.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedBloatKing_SantasWorkshop.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedBloat_Versus.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedClot.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedClot_Alpha.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedClot_AlphaKing.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedClot_AlphaKing_Versus.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedClot_Alpha_Versus.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedClot_Cyst.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedClot_Slasher.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedClot_Slasher_Versus.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedCrawler.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedCrawlerKing.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedCrawler_Versus.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedDAR.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedDAR_EMP.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedDAR_Laser.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedDAR_Rocket.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedFleshPound_Versus.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedFleshpound.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedFleshpoundKing.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedFleshpoundMini.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedFleshpoundMini_Mixer.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedFleshpound_Mixer.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedGorefast.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedGorefastDualBlade.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedGorefast_Versus.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedHans.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedHansFriendlyTest.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedHans_Versus.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedHusk.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedHuskFriendlyTest.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedHusk_Versus.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedMatriarch.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedPatriarch.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedPatriarch_Versus.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedScrake.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedScrake_Mixer.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedScrake_Versus.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedSiren.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedSiren_Versus.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedStalker.uc create mode 100644 KFGameContent/Classes/KFPawn_ZedStalker_Versus.uc create mode 100644 KFGameContent/Classes/KFPhysicsVolume.uc create mode 100644 KFGameContent/Classes/KFPickupFactory_Ammo.uc create mode 100644 KFGameContent/Classes/KFPickupFactory_ItemDefault.uc create mode 100644 KFGameContent/Classes/KFPlayerCamera_Patriarch.uc create mode 100644 KFGameContent/Classes/KFPlayerCamera_Versus.uc create mode 100644 KFGameContent/Classes/KFPlayerControllerVersus.uc create mode 100644 KFGameContent/Classes/KFPlayerZedSuicideCamera.uc create mode 100644 KFGameContent/Classes/KFPlayerZedWaitingCamera.uc create mode 100644 KFGameContent/Classes/KFProj_ArcGeneratorSphereBlast.uc create mode 100644 KFGameContent/Classes/KFProj_Blade_Eviscerator.uc create mode 100644 KFGameContent/Classes/KFProj_BloatKingPukeMine.uc create mode 100644 KFGameContent/Classes/KFProj_BloatPukeMine.uc create mode 100644 KFGameContent/Classes/KFProj_Bolt_CompoundBowCryo.uc create mode 100644 KFGameContent/Classes/KFProj_Bolt_CompoundBowSharp.uc create mode 100644 KFGameContent/Classes/KFProj_Bolt_Crossbow.uc create mode 100644 KFGameContent/Classes/KFProj_BrokenFlare_HRGScorcher.uc create mode 100644 KFGameContent/Classes/KFProj_BrokenFlare_HRGScorcherSplash.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_AssaultRifle.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_DragonsBreath.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_G18.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_G18c.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_HRGIncendiaryRifle.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_HRGIncisionHeal.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_HRGIncisionHurt.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_HRGTeslauncher.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_Hemogoblin.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_IncendiaryBullet.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_LazerCutter.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_M14EBR.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_M99.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_Mac10.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_MatriarchTeslaBlast.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_MicrowaveRifle.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_Minigun.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_MosinNagant.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_Pellet.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_Pistol50AE.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_Pistol9mm.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_PistolAF2011.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_PistolColt1911.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_PistolDeagle.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_Pistol_ChiappaRhino.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_Pistol_ChiappaRhinoShrapnel.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_RailGun.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_RevolverRem1858.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_RevolverSW500.uc create mode 100644 KFGameContent/Classes/KFProj_Bullet_Winchester1894.uc create mode 100644 KFGameContent/Classes/KFProj_Cannonball_Blunderbuss.uc create mode 100644 KFGameContent/Classes/KFProj_CaulkNBurn_GroundFire.uc create mode 100644 KFGameContent/Classes/KFProj_DragonsBreathSplash.uc create mode 100644 KFGameContent/Classes/KFProj_DynamiteGrenade.uc create mode 100644 KFGameContent/Classes/KFProj_DynamiteGrenade_Mini.uc create mode 100644 KFGameContent/Classes/KFProj_EMPGrenade.uc create mode 100644 KFGameContent/Classes/KFProj_EMPGrenade_Mini.uc create mode 100644 KFGameContent/Classes/KFProj_EvilDAR_Laser.uc create mode 100644 KFGameContent/Classes/KFProj_EvilDAR_Rocket.uc create mode 100644 KFGameContent/Classes/KFProj_Explosive_HRGWinterbite.uc create mode 100644 KFGameContent/Classes/KFProj_Explosive_HRG_Kaboomstick.uc create mode 100644 KFGameContent/Classes/KFProj_Explosive_HX25.uc create mode 100644 KFGameContent/Classes/KFProj_FlameThrower_GroundFire.uc create mode 100644 KFGameContent/Classes/KFProj_Flame_HRGIncendiaryRifle.uc create mode 100644 KFGameContent/Classes/KFProj_FlareGun.uc create mode 100644 KFGameContent/Classes/KFProj_FlareGunSplash.uc create mode 100644 KFGameContent/Classes/KFProj_FlashBangGrenade.uc create mode 100644 KFGameContent/Classes/KFProj_FlashBangGrenade_Mini.uc create mode 100644 KFGameContent/Classes/KFProj_FragGrenade.uc create mode 100644 KFGameContent/Classes/KFProj_FragGrenade_Mini.uc create mode 100644 KFGameContent/Classes/KFProj_FreezeGrenade.uc create mode 100644 KFGameContent/Classes/KFProj_FreezeGrenade_Mini.uc create mode 100644 KFGameContent/Classes/KFProj_FreezeThrower_GroundIce.uc create mode 100644 KFGameContent/Classes/KFProj_FreezeThrower_IceShards.uc create mode 100644 KFGameContent/Classes/KFProj_GrenadeShard.uc create mode 100644 KFGameContent/Classes/KFProj_Grenade_HRGIncendiaryRifle.uc create mode 100644 KFGameContent/Classes/KFProj_Grenade_HRGTeslauncher.uc create mode 100644 KFGameContent/Classes/KFProj_GroundFire.uc create mode 100644 KFGameContent/Classes/KFProj_GroundIce.uc create mode 100644 KFGameContent/Classes/KFProj_HEGrenade.uc create mode 100644 KFGameContent/Classes/KFProj_HEGrenade_Mini.uc create mode 100644 KFGameContent/Classes/KFProj_HansHEGrenade.uc create mode 100644 KFGameContent/Classes/KFProj_HansHEGrenade_Halloween.uc create mode 100644 KFGameContent/Classes/KFProj_HansNerveGasGrenade.uc create mode 100644 KFGameContent/Classes/KFProj_HansNerveGasGrenade_Halloween.uc create mode 100644 KFGameContent/Classes/KFProj_HansSmokeGrenade.uc create mode 100644 KFGameContent/Classes/KFProj_HansSmokeGrenade_Halloween.uc create mode 100644 KFGameContent/Classes/KFProj_HealingDart_MedicBase.uc create mode 100644 KFGameContent/Classes/KFProj_HighExplosive_M16M203.uc create mode 100644 KFGameContent/Classes/KFProj_HighExplosive_M32.uc create mode 100644 KFGameContent/Classes/KFProj_HighExplosive_M79.uc create mode 100644 KFGameContent/Classes/KFProj_HuskCannon_Fireball.uc create mode 100644 KFGameContent/Classes/KFProj_HuskGroundFire.uc create mode 100644 KFGameContent/Classes/KFProj_Husk_Fireball.uc create mode 100644 KFGameContent/Classes/KFProj_Husk_Fireball_Versus.uc create mode 100644 KFGameContent/Classes/KFProj_LightingFlare_HRGScorcher.uc create mode 100644 KFGameContent/Classes/KFProj_Mac10Splash.uc create mode 100644 KFGameContent/Classes/KFProj_MedicGrenade.uc create mode 100644 KFGameContent/Classes/KFProj_MedicGrenade_Mini.uc create mode 100644 KFGameContent/Classes/KFProj_MicrowaveGun_GroundFire.uc create mode 100644 KFGameContent/Classes/KFProj_MicrowaveImpact.uc create mode 100644 KFGameContent/Classes/KFProj_Mine_Reconstructor.uc create mode 100644 KFGameContent/Classes/KFProj_Missile_Patriarch.uc create mode 100644 KFGameContent/Classes/KFProj_Missile_Patriarch_Versus.uc create mode 100644 KFGameContent/Classes/KFProj_MolotovFlare.uc create mode 100644 KFGameContent/Classes/KFProj_MolotovGrenade.uc create mode 100644 KFGameContent/Classes/KFProj_MolotovGrenade_Mini.uc create mode 100644 KFGameContent/Classes/KFProj_MolotovSplash.uc create mode 100644 KFGameContent/Classes/KFProj_Mortar_Patriarch.uc create mode 100644 KFGameContent/Classes/KFProj_NailBombGrenade.uc create mode 100644 KFGameContent/Classes/KFProj_NailBombGrenade_Mini.uc create mode 100644 KFGameContent/Classes/KFProj_NailShard.uc create mode 100644 KFGameContent/Classes/KFProj_Nail_Blunderbuss.uc create mode 100644 KFGameContent/Classes/KFProj_Nail_HRGNailgun.uc create mode 100644 KFGameContent/Classes/KFProj_Nail_Nailgun.uc create mode 100644 KFGameContent/Classes/KFProj_Rocket_RPG7.uc create mode 100644 KFGameContent/Classes/KFProj_Rocket_SealSqueal.uc create mode 100644 KFGameContent/Classes/KFProj_Rocket_Seeker6.uc create mode 100644 KFGameContent/Classes/KFProj_Thrown_C4.uc create mode 100644 KFGameContent/Classes/KFSM_AlphaRally.uc create mode 100644 KFGameContent/Classes/KFSM_BloatKingSubspawn_Explode.uc create mode 100644 KFGameContent/Classes/KFSM_BloatKing_Enrage.uc create mode 100644 KFGameContent/Classes/KFSM_BloatKing_Gorge.uc create mode 100644 KFGameContent/Classes/KFSM_DAR_EMPAttack.uc create mode 100644 KFGameContent/Classes/KFSM_DAR_LaserAttack.uc create mode 100644 KFGameContent/Classes/KFSM_DAR_RocketAttack.uc create mode 100644 KFGameContent/Classes/KFSM_Emerge_Crawler.uc create mode 100644 KFGameContent/Classes/KFSM_Evade_Fear.uc create mode 100644 KFGameContent/Classes/KFSM_FleshpoundKing_ChestBeam.uc create mode 100644 KFGameContent/Classes/KFSM_GorgeVictim.uc create mode 100644 KFGameContent/Classes/KFSM_GrappleAttack_Hans.uc create mode 100644 KFGameContent/Classes/KFSM_Hans_GrenadeBarrage.uc create mode 100644 KFGameContent/Classes/KFSM_Hans_GrenadeHalfBarrage.uc create mode 100644 KFGameContent/Classes/KFSM_Hans_ThrowGrenade.uc create mode 100644 KFGameContent/Classes/KFSM_Hans_WeaponSwitch.uc create mode 100644 KFGameContent/Classes/KFSM_Husk_FireBallAttack.uc create mode 100644 KFGameContent/Classes/KFSM_Husk_FlameThrowerAttack.uc create mode 100644 KFGameContent/Classes/KFSM_Husk_Suicide.uc create mode 100644 KFGameContent/Classes/KFSM_Matriarch_LightningStorm.uc create mode 100644 KFGameContent/Classes/KFSM_Matriarch_MeleeAttack.uc create mode 100644 KFGameContent/Classes/KFSM_Matriarch_PlasmaCannon.uc create mode 100644 KFGameContent/Classes/KFSM_Matriarch_ScorpionWhip.uc create mode 100644 KFGameContent/Classes/KFSM_Matriarch_SweepingClaw.uc create mode 100644 KFGameContent/Classes/KFSM_Matriarch_Taunt.uc create mode 100644 KFGameContent/Classes/KFSM_Matriarch_TeslaBlast.uc create mode 100644 KFGameContent/Classes/KFSM_Matriarch_WarningSiren.uc create mode 100644 KFGameContent/Classes/KFSM_Patriarch_Heal.uc create mode 100644 KFGameContent/Classes/KFSM_Patriarch_MinigunBarrage.uc create mode 100644 KFGameContent/Classes/KFSM_Patriarch_MissileAttack.uc create mode 100644 KFGameContent/Classes/KFSM_Patriarch_MortarAttack.uc create mode 100644 KFGameContent/Classes/KFSM_Patriarch_Taunt.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerAlpha_Grab.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerAlpha_Melee.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerAlpha_Rally.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerBloat_Block.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerBloat_Melee.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerBloat_Melee2.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerBloat_PukeMineAttack.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerCrawler_Melee.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerCrawler_Melee2.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerCrawler_Suicide.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerFleshpound_Block.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerFleshpound_Melee.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerFleshpound_Melee2.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerFleshpound_Rage.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerGorefast_Block.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerGorefast_Melee.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerGorefast_Melee2.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerGorefast_Melee3.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerHusk_FireBallAttack.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerHusk_FlameThrowerAttack.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerHusk_Melee.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerHusk_Suicide.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerPatriarch_Heal.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerPatriarch_Melee.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerPatriarch_MinigunBarrage.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerPatriarch_MissileAttack.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerPatriarch_MortarAttack.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerPatriarch_TentacleGrab.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerScrake_Block.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerScrake_Melee.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerScrake_Melee2.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerScrake_Melee3.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerSiren_Melee.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerSiren_NormalScream.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerSiren_VortexScream.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerSiren_VortexVictim.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerSlasher_Melee.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerSlasher_Melee2.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerSlasher_Roll.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerStalker_Melee.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerStalker_Melee2.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerStalker_Roll.uc create mode 100644 KFGameContent/Classes/KFSM_PlayerZedBlockBase.uc create mode 100644 KFGameContent/Classes/KFSM_ScreamBase.uc create mode 100644 KFGameContent/Classes/KFSM_Siren_Scream.uc create mode 100644 KFGameContent/Classes/KFSeasonalEventStats_Fall2019.uc create mode 100644 KFGameContent/Classes/KFSeasonalEventStats_Fall2020.uc create mode 100644 KFGameContent/Classes/KFSeasonalEventStats_Spring2019.uc create mode 100644 KFGameContent/Classes/KFSeasonalEventStats_Spring2020.uc create mode 100644 KFGameContent/Classes/KFSeasonalEventStats_Summer2019.uc create mode 100644 KFGameContent/Classes/KFSeasonalEventStats_Summer2020.uc create mode 100644 KFGameContent/Classes/KFSeasonalEventStats_Xmas2018.uc create mode 100644 KFGameContent/Classes/KFSeasonalEventStats_Xmas2019.uc create mode 100644 KFGameContent/Classes/KFSeqAct_BloodRain.uc create mode 100644 KFGameContent/Classes/KFSeqAct_DamageDestructibleActor.uc create mode 100644 KFGameContent/Classes/KFSeqAct_MinigameActivateGenerator.uc create mode 100644 KFGameContent/Classes/KFSeqAct_SetScriptedPawnSpeed.uc create mode 100644 KFGameContent/Classes/KFSeqAct_StartObjectiveWave.uc create mode 100644 KFGameContent/Classes/KFSeqAct_TriggerMapObjective.uc create mode 100644 KFGameContent/Classes/KFSeqEvent_CollectActorsProgress.uc create mode 100644 KFGameContent/Classes/KFSeqEvent_EscortPawnsCompletionPct.uc create mode 100644 KFGameContent/Classes/KFSeqEvent_EscortPawnsHealthPct.uc create mode 100644 KFGameContent/Classes/KFSeqEvent_ExterminateBossHealthPct.uc create mode 100644 KFGameContent/Classes/KFSeqEvent_ExterminateWavePct.uc create mode 100644 KFGameContent/Classes/KFSeqEvent_HoldZoneProgress.uc create mode 100644 KFGameContent/Classes/KFSeqEvent_MinigameEndCondition.uc create mode 100644 KFGameContent/Classes/KFSeqEvent_MinigameGeneratorStateChanged.uc create mode 100644 KFGameContent/Classes/KFSeqEvent_RepairActorsProgress.uc create mode 100644 KFGameContent/Classes/KFSkinTypeEffects_InvulnerabilityShield.uc create mode 100644 KFGameContent/Classes/KFSprayActor_ArcGenerator.uc create mode 100644 KFGameContent/Classes/KFStaticMeshActor_TrackLocalPC.uc create mode 100644 KFGameContent/Classes/KFTargetingWeaponComponent_HRGIncision.uc create mode 100644 KFGameContent/Classes/KFTargetingWeaponComponent_RailGun.uc create mode 100644 KFGameContent/Classes/KFTeamInfo_Zeds.uc create mode 100644 KFGameContent/Classes/KFThirdPersonCamera_Versus.uc create mode 100644 KFGameContent/Classes/KFTraderVoiceGroup_Default.uc create mode 100644 KFGameContent/Classes/KFTraderVoiceGroup_Hans.uc create mode 100644 KFGameContent/Classes/KFTraderVoiceGroup_Lockheart.uc create mode 100644 KFGameContent/Classes/KFTraderVoiceGroup_Objective.uc create mode 100644 KFGameContent/Classes/KFTraderVoiceGroup_Patriarch.uc create mode 100644 KFGameContent/Classes/KFTraderVoiceGroup_Santa.uc create mode 100644 KFGameContent/Classes/KFTrigger_BloatKingGorge.uc create mode 100644 KFGameContent/Classes/KFTrigger_MinigameGenerator.uc create mode 100644 KFGameContent/Classes/KFTrigger_ObjectiveLever.uc create mode 100644 KFGameContent/Classes/KFTrigger_SirenProjectileShield.uc create mode 100644 KFGameContent/Classes/KFTutorialSectionInfo.uc create mode 100644 KFGameContent/Classes/KFVolume_CameraFade.uc create mode 100644 KFGameContent/Classes/KFVolume_DamageAdjust.uc create mode 100644 KFGameContent/Classes/KFVolume_DisableZedJump.uc create mode 100644 KFGameContent/Classes/KFVolume_RagdollThrow.uc create mode 100644 KFGameContent/Classes/KFWeapActor_Hemogoblin_Tube.uc create mode 100644 KFGameContent/Classes/KFWeapAttach_ArcGenerator.uc create mode 100644 KFGameContent/Classes/KFWeapAttach_CompoundBow.uc create mode 100644 KFGameContent/Classes/KFWeapAttach_Dual_C4.uc create mode 100644 KFGameContent/Classes/KFWeapAttach_Eviscerator.uc create mode 100644 KFGameContent/Classes/KFWeapAttach_Flamethrower.uc create mode 100644 KFGameContent/Classes/KFWeapAttach_G18.uc create mode 100644 KFGameContent/Classes/KFWeapAttach_HuskCannon.uc create mode 100644 KFGameContent/Classes/KFWeapAttach_IonThruster.uc create mode 100644 KFGameContent/Classes/KFWeapAttach_LazerCutter.uc create mode 100644 KFGameContent/Classes/KFWeapAttach_M99.uc create mode 100644 KFGameContent/Classes/KFWeapAttach_MaceAndShield.uc create mode 100644 KFGameContent/Classes/KFWeapAttach_Mine_Reconstructor.uc create mode 100644 KFGameContent/Classes/KFWeapAttach_MultiAmmo.uc create mode 100644 KFGameContent/Classes/KFWeapAttach_PowerGloves.uc create mode 100644 KFGameContent/Classes/KFWeapAttach_Pulverizer.uc create mode 100644 KFGameContent/Classes/KFWeapAttach_Railgun.uc create mode 100644 KFGameContent/Classes/KFWeapDef_HRGTeslauncher.uc create mode 100644 KFGameContent/Classes/KFWeapDef_Medic32.uc create mode 100644 KFGameContent/Classes/KFWeap_AssaultRifle_AK12.uc create mode 100644 KFGameContent/Classes/KFWeap_AssaultRifle_AR15.uc create mode 100644 KFGameContent/Classes/KFWeap_AssaultRifle_Bullpup.uc create mode 100644 KFGameContent/Classes/KFWeap_AssaultRifle_DualMKb42_Hans.uc create mode 100644 KFGameContent/Classes/KFWeap_AssaultRifle_DualMKb42_HansFriendlyTest.uc create mode 100644 KFGameContent/Classes/KFWeap_AssaultRifle_FNFal.uc create mode 100644 KFGameContent/Classes/KFWeap_AssaultRifle_HRGIncendiaryRifle.uc create mode 100644 KFGameContent/Classes/KFWeap_AssaultRifle_HRGTeslauncher.uc create mode 100644 KFGameContent/Classes/KFWeap_AssaultRifle_LazerCutter.uc create mode 100644 KFGameContent/Classes/KFWeap_AssaultRifle_M16M203.uc create mode 100644 KFGameContent/Classes/KFWeap_AssaultRifle_MKB42.uc create mode 100644 KFGameContent/Classes/KFWeap_AssaultRifle_Medic.uc create mode 100644 KFGameContent/Classes/KFWeap_AssaultRifle_MedicRifleGrenadeLauncher.uc create mode 100644 KFGameContent/Classes/KFWeap_AssaultRifle_Microwave.uc create mode 100644 KFGameContent/Classes/KFWeap_AssaultRifle_SCAR.uc create mode 100644 KFGameContent/Classes/KFWeap_AssaultRifle_Thompson.uc create mode 100644 KFGameContent/Classes/KFWeap_AssetDummy.uc create mode 100644 KFGameContent/Classes/KFWeap_Beam_Microwave.uc create mode 100644 KFGameContent/Classes/KFWeap_Blunt_ChainBat.uc create mode 100644 KFGameContent/Classes/KFWeap_Blunt_Crovel.uc create mode 100644 KFGameContent/Classes/KFWeap_Blunt_MaceAndShield.uc create mode 100644 KFGameContent/Classes/KFWeap_Blunt_MedicBat.uc create mode 100644 KFGameContent/Classes/KFWeap_Blunt_PowerGloves.uc create mode 100644 KFGameContent/Classes/KFWeap_Blunt_Pulverizer.uc create mode 100644 KFGameContent/Classes/KFWeap_Bow_CompoundBow.uc create mode 100644 KFGameContent/Classes/KFWeap_Bow_Crossbow.uc create mode 100644 KFGameContent/Classes/KFWeap_Edged_AbominationAxe.uc create mode 100644 KFGameContent/Classes/KFWeap_Edged_FireAxe.uc create mode 100644 KFGameContent/Classes/KFWeap_Edged_IonThruster.uc create mode 100644 KFGameContent/Classes/KFWeap_Edged_Katana.uc create mode 100644 KFGameContent/Classes/KFWeap_Edged_Knife.uc create mode 100644 KFGameContent/Classes/KFWeap_Edged_Zweihander.uc create mode 100644 KFGameContent/Classes/KFWeap_Eviscerator.uc create mode 100644 KFGameContent/Classes/KFWeap_Flame_CaulkBurn.uc create mode 100644 KFGameContent/Classes/KFWeap_Flame_Flamethrower.uc create mode 100644 KFGameContent/Classes/KFWeap_GrenadeLauncher_HX25.uc create mode 100644 KFGameContent/Classes/KFWeap_GrenadeLauncher_M32.uc create mode 100644 KFGameContent/Classes/KFWeap_GrenadeLauncher_M79.uc create mode 100644 KFGameContent/Classes/KFWeap_HRG_EMP_ArcGenerator.uc create mode 100644 KFGameContent/Classes/KFWeap_HRG_Healthrower.uc create mode 100644 KFGameContent/Classes/KFWeap_HRG_Nailgun.uc create mode 100644 KFGameContent/Classes/KFWeap_HRG_Revolver_Buckshot.uc create mode 100644 KFGameContent/Classes/KFWeap_HRG_Revolver_DualBuckshot.uc create mode 100644 KFGameContent/Classes/KFWeap_Healer_Syringe.uc create mode 100644 KFGameContent/Classes/KFWeap_HuskCannon.uc create mode 100644 KFGameContent/Classes/KFWeap_Ice_FreezeThrower.uc create mode 100644 KFGameContent/Classes/KFWeap_Knife_Berserker.uc create mode 100644 KFGameContent/Classes/KFWeap_Knife_Commando.uc create mode 100644 KFGameContent/Classes/KFWeap_Knife_Demolitionist.uc create mode 100644 KFGameContent/Classes/KFWeap_Knife_FieldMedic.uc create mode 100644 KFGameContent/Classes/KFWeap_Knife_Firebug.uc create mode 100644 KFGameContent/Classes/KFWeap_Knife_Gunslinger.uc create mode 100644 KFGameContent/Classes/KFWeap_Knife_SWAT.uc create mode 100644 KFGameContent/Classes/KFWeap_Knife_Sharpshooter.uc create mode 100644 KFGameContent/Classes/KFWeap_Knife_Support.uc create mode 100644 KFGameContent/Classes/KFWeap_Knife_Survivalist.uc create mode 100644 KFGameContent/Classes/KFWeap_LMG_Stoner63A.uc create mode 100644 KFGameContent/Classes/KFWeap_Mine_Reconstructor.uc create mode 100644 KFGameContent/Classes/KFWeap_Minigun.uc create mode 100644 KFGameContent/Classes/KFWeap_Minigun_Patriarch.uc create mode 100644 KFGameContent/Classes/KFWeap_Minigun_Patriarch_Versus.uc create mode 100644 KFGameContent/Classes/KFWeap_Pistol_9mm.uc create mode 100644 KFGameContent/Classes/KFWeap_Pistol_AF2011.uc create mode 100644 KFGameContent/Classes/KFWeap_Pistol_Blunderbuss.uc create mode 100644 KFGameContent/Classes/KFWeap_Pistol_ChiappaRhino.uc create mode 100644 KFGameContent/Classes/KFWeap_Pistol_ChiappaRhinoDual.uc create mode 100644 KFGameContent/Classes/KFWeap_Pistol_Colt1911.uc create mode 100644 KFGameContent/Classes/KFWeap_Pistol_Deagle.uc create mode 100644 KFGameContent/Classes/KFWeap_Pistol_Dual9mm.uc create mode 100644 KFGameContent/Classes/KFWeap_Pistol_DualAF2011.uc create mode 100644 KFGameContent/Classes/KFWeap_Pistol_DualColt1911.uc create mode 100644 KFGameContent/Classes/KFWeap_Pistol_DualDeagle.uc create mode 100644 KFGameContent/Classes/KFWeap_Pistol_DualFlare.uc create mode 100644 KFGameContent/Classes/KFWeap_Pistol_DualG18.uc create mode 100644 KFGameContent/Classes/KFWeap_Pistol_DualHRGWinterbite.uc create mode 100644 KFGameContent/Classes/KFWeap_Pistol_Dummy.uc create mode 100644 KFGameContent/Classes/KFWeap_Pistol_Flare.uc create mode 100644 KFGameContent/Classes/KFWeap_Pistol_G18C.uc create mode 100644 KFGameContent/Classes/KFWeap_Pistol_HRGScorcher.uc create mode 100644 KFGameContent/Classes/KFWeap_Pistol_HRGWinterbite.uc create mode 100644 KFGameContent/Classes/KFWeap_Pistol_Medic.uc create mode 100644 KFGameContent/Classes/KFWeap_PowerClaw_Matriarch.uc create mode 100644 KFGameContent/Classes/KFWeap_Random.uc create mode 100644 KFGameContent/Classes/KFWeap_Revolver_DualRem1858.uc create mode 100644 KFGameContent/Classes/KFWeap_Revolver_DualSW500.uc create mode 100644 KFGameContent/Classes/KFWeap_Revolver_Rem1858.uc create mode 100644 KFGameContent/Classes/KFWeap_Revolver_SW500.uc create mode 100644 KFGameContent/Classes/KFWeap_Rifle_CenterfireMB464.uc create mode 100644 KFGameContent/Classes/KFWeap_Rifle_HRGIncision.uc create mode 100644 KFGameContent/Classes/KFWeap_Rifle_Hemogoblin.uc create mode 100644 KFGameContent/Classes/KFWeap_Rifle_M14EBR.uc create mode 100644 KFGameContent/Classes/KFWeap_Rifle_M99.uc create mode 100644 KFGameContent/Classes/KFWeap_Rifle_MosinNagant.uc create mode 100644 KFGameContent/Classes/KFWeap_Rifle_RailGun.uc create mode 100644 KFGameContent/Classes/KFWeap_Rifle_Winchester1894.uc create mode 100644 KFGameContent/Classes/KFWeap_RocketLauncher_RPG7.uc create mode 100644 KFGameContent/Classes/KFWeap_RocketLauncher_SealSqueal.uc create mode 100644 KFGameContent/Classes/KFWeap_RocketLauncher_Seeker6.uc create mode 100644 KFGameContent/Classes/KFWeap_SMG_G18.uc create mode 100644 KFGameContent/Classes/KFWeap_SMG_HK_UMP.uc create mode 100644 KFGameContent/Classes/KFWeap_SMG_Kriss.uc create mode 100644 KFGameContent/Classes/KFWeap_SMG_MP5RAS.uc create mode 100644 KFGameContent/Classes/KFWeap_SMG_MP7.uc create mode 100644 KFGameContent/Classes/KFWeap_SMG_Mac10.uc create mode 100644 KFGameContent/Classes/KFWeap_SMG_Medic.uc create mode 100644 KFGameContent/Classes/KFWeap_SMG_P90.uc create mode 100644 KFGameContent/Classes/KFWeap_Shotgun_AA12.uc create mode 100644 KFGameContent/Classes/KFWeap_Shotgun_DoubleBarrel.uc create mode 100644 KFGameContent/Classes/KFWeap_Shotgun_DragonsBreath.uc create mode 100644 KFGameContent/Classes/KFWeap_Shotgun_ElephantGun.uc create mode 100644 KFGameContent/Classes/KFWeap_Shotgun_HRG_Kaboomstick.uc create mode 100644 KFGameContent/Classes/KFWeap_Shotgun_HZ12.uc create mode 100644 KFGameContent/Classes/KFWeap_Shotgun_M4.uc create mode 100644 KFGameContent/Classes/KFWeap_Shotgun_MB500.uc create mode 100644 KFGameContent/Classes/KFWeap_Shotgun_Medic.uc create mode 100644 KFGameContent/Classes/KFWeap_Shotgun_Nailgun.uc create mode 100644 KFGameContent/Classes/KFWeap_Thrown_C4.uc create mode 100644 KFGameContent/Classes/KFWeap_Welder.uc create mode 100644 KFGameContent/Classes/KFZedArmorInfo_BloatKing.uc create mode 100644 KFGameContent/Classes/KFZedArmorInfo_ClotKing.uc create mode 100644 KFGameContent/Classes/KFZedArmorInfo_EvilDAR.uc create mode 100644 KFGameContent/Classes/KFZedArmorInfo_Matriarch.uc create mode 100644 KFGameContent/Classes/SprayActor_Flame.uc create mode 100644 KFGameContent/Classes/SprayActor_Heal.uc create mode 100644 OnlineSubsystemDingo/Classes/DownloadableContentEnumeratorDingo.uc create mode 100644 OnlineSubsystemDingo/Classes/KFOnlineLobbyDingo.uc create mode 100644 OnlineSubsystemDingo/Classes/OnlineCommunityContentInterfaceDingo.uc create mode 100644 OnlineSubsystemDingo/Classes/OnlineContentInterfaceDingo.uc create mode 100644 OnlineSubsystemDingo/Classes/OnlineGameDVRInterfaceDingo.uc create mode 100644 OnlineSubsystemDingo/Classes/OnlineGameInterfaceDingo.uc create mode 100644 OnlineSubsystemDingo/Classes/OnlineMarketplaceInterfaceDingo.uc create mode 100644 OnlineSubsystemDingo/Classes/OnlineStatsInterfaceDingo.uc create mode 100644 OnlineSubsystemDingo/Classes/OnlineSubsystemDingo.uc create mode 100644 OnlineSubsystemDingo/Classes/OnlineTitleFileInterfaceDingo.uc create mode 100644 OnlineSubsystemSteamworks/Classes/KFOnlineLobbySteamworks.uc create mode 100644 OnlineSubsystemSteamworks/Classes/KFWorkshopSteamworks.uc create mode 100644 OnlineSubsystemSteamworks/Classes/OnlineAuthInterfaceSteamworks.uc create mode 100644 OnlineSubsystemSteamworks/Classes/OnlineGameInterfaceSteamworks.uc create mode 100644 OnlineSubsystemSteamworks/Classes/OnlineLobbyInterfaceSteamworks.uc create mode 100644 OnlineSubsystemSteamworks/Classes/OnlineSubsystemSteamworks.uc create mode 100644 OnlineSubsystemSteamworks/Globals.uci create mode 100644 SubstanceAir/Classes/InterpTrackInstSubstanceInput.uc create mode 100644 SubstanceAir/Classes/InterpTrackSubstanceInput.uc create mode 100644 SubstanceAir/Classes/SeqAct_SubstanceRender.uc create mode 100644 SubstanceAir/Classes/SeqAct_SubstanceSetInputFloat.uc create mode 100644 SubstanceAir/Classes/SeqAct_SubstanceSetInputImg.uc create mode 100644 SubstanceAir/Classes/SeqAct_SubstanceSetInputInt.uc create mode 100644 SubstanceAir/Classes/SubstanceAirGraphActor.uc create mode 100644 SubstanceAir/Classes/SubstanceAirGraphInstance.uc create mode 100644 SubstanceAir/Classes/SubstanceAirImageInput.uc create mode 100644 SubstanceAir/Classes/SubstanceAirInstanceFactory.uc create mode 100644 SubstanceAir/Classes/SubstanceAirTexture2D.uc create mode 100644 SubstanceAirEd/Classes/GenericBrowserType_SubstanceAirGraphInstance.uc create mode 100644 SubstanceAirEd/Classes/GenericBrowserType_SubstanceAirImageInput.uc create mode 100644 SubstanceAirEd/Classes/GenericBrowserType_SubstanceAirInstanceFactory.uc create mode 100644 SubstanceAirEd/Classes/GenericBrowserType_SubstanceAirTexture2D.uc create mode 100644 SubstanceAirEd/Classes/ImageInputThumbnailRenderer.uc create mode 100644 UDKBase/classes/CastleGame.uc create mode 100644 UDKBase/classes/CastlePC.uc create mode 100644 UDKBase/classes/CloudGame.uc create mode 100644 UDKBase/classes/CloudHUD.uc create mode 100644 UDKBase/classes/CloudMenuMicroTrans.uc create mode 100644 UDKBase/classes/CloudPC.uc create mode 100644 UDKBase/classes/CloudSaveData.uc create mode 100644 UDKBase/classes/MobileGameCrowdAgent.uc create mode 100644 UDKBase/classes/MobileHUDExt.uc create mode 100644 UDKBase/classes/MobileMenuBase.uc create mode 100644 UDKBase/classes/MobileMenuControls.uc create mode 100644 UDKBase/classes/MobileMenuDebug.uc create mode 100644 UDKBase/classes/MobileMenuPause.uc create mode 100644 UDKBase/classes/MobileMenuSplash.uc create mode 100644 UDKBase/classes/MobilePlaceablePawn.uc create mode 100644 UDKBase/classes/MobileProjectile.uc create mode 100644 UDKBase/classes/ParticleModuleTypeDataSnow.uc create mode 100644 UDKBase/classes/SeqAct_MobileCrowdSpawner.uc create mode 100644 UDKBase/classes/SimpleGame.uc create mode 100644 UDKBase/classes/SimplePC.uc create mode 100644 UDKBase/classes/SimplePawn.uc create mode 100644 UDKBase/classes/UDKAIDecisionComponent.uc create mode 100644 UDKBase/classes/UDKAnimBlendBase.uc create mode 100644 UDKBase/classes/UDKAnimBlendByDriving.uc create mode 100644 UDKBase/classes/UDKAnimBlendByFall.uc create mode 100644 UDKBase/classes/UDKAnimBlendByFlying.uc create mode 100644 UDKBase/classes/UDKAnimBlendByHoverJump.uc create mode 100644 UDKBase/classes/UDKAnimBlendByHoverboardTilt.uc create mode 100644 UDKBase/classes/UDKAnimBlendByHoverboardTurn.uc create mode 100644 UDKBase/classes/UDKAnimBlendByHoverboarding.uc create mode 100644 UDKBase/classes/UDKAnimBlendByIdle.uc create mode 100644 UDKBase/classes/UDKAnimBlendByPhysics.uc create mode 100644 UDKBase/classes/UDKAnimBlendByPhysicsVolume.uc create mode 100644 UDKBase/classes/UDKAnimBlendByPosture.uc create mode 100644 UDKBase/classes/UDKAnimBlendBySlotActive.uc create mode 100644 UDKBase/classes/UDKAnimBlendBySpeed.uc create mode 100644 UDKBase/classes/UDKAnimBlendByTurnInPlace.uc create mode 100644 UDKBase/classes/UDKAnimBlendByVehicle.uc create mode 100644 UDKBase/classes/UDKAnimBlendByWeapType.uc create mode 100644 UDKBase/classes/UDKAnimBlendByWeapon.uc create mode 100644 UDKBase/classes/UDKAnimNodeCopyBoneTranslation.uc create mode 100644 UDKBase/classes/UDKAnimNodeFramePlayer.uc create mode 100644 UDKBase/classes/UDKAnimNodeJumpLeanOffset.uc create mode 100644 UDKBase/classes/UDKAnimNodeSeqWeap.uc create mode 100644 UDKBase/classes/UDKAnimNodeSequence.uc create mode 100644 UDKBase/classes/UDKAnimNodeSequenceByBoneRotation.uc create mode 100644 UDKBase/classes/UDKBot.uc create mode 100644 UDKBase/classes/UDKCarriedObject.uc create mode 100644 UDKBase/classes/UDKDataStore_GameSearchBase.uc create mode 100644 UDKBase/classes/UDKEmitCameraEffect.uc create mode 100644 UDKBase/classes/UDKEmitterPool.uc create mode 100644 UDKBase/classes/UDKExplosionLight.uc create mode 100644 UDKBase/classes/UDKForcedDirectionVolume.uc create mode 100644 UDKBase/classes/UDKGame.uc create mode 100644 UDKBase/classes/UDKGameInteraction.uc create mode 100644 UDKBase/classes/UDKGameObjective.uc create mode 100644 UDKBase/classes/UDKGameSettingsCommon.uc create mode 100644 UDKBase/classes/UDKGameViewportClient.uc create mode 100644 UDKBase/classes/UDKHUD.uc create mode 100644 UDKBase/classes/UDKJumpPad.uc create mode 100644 UDKBase/classes/UDKJumpPadReachspec.uc create mode 100644 UDKBase/classes/UDKKActorBreakable.uc create mode 100644 UDKBase/classes/UDKMapInfo.uc create mode 100644 UDKBase/classes/UDKMapMusicInfo.uc create mode 100644 UDKBase/classes/UDKMobileInputZone.uc create mode 100644 UDKBase/classes/UDKParticleSystemComponent.uc create mode 100644 UDKBase/classes/UDKPawn.uc create mode 100644 UDKBase/classes/UDKPickupFactory.uc create mode 100644 UDKBase/classes/UDKPlayerController.uc create mode 100644 UDKBase/classes/UDKPlayerInput.uc create mode 100644 UDKBase/classes/UDKProfileSettings.uc create mode 100644 UDKBase/classes/UDKProjectile.uc create mode 100644 UDKBase/classes/UDKScout.uc create mode 100644 UDKBase/classes/UDKScriptedNavigationPoint.uc create mode 100644 UDKBase/classes/UDKSkelControl_CantileverBeam.uc create mode 100644 UDKBase/classes/UDKSkelControl_Damage.uc create mode 100644 UDKBase/classes/UDKSkelControl_DamageHinge.uc create mode 100644 UDKBase/classes/UDKSkelControl_DamageSpring.uc create mode 100644 UDKBase/classes/UDKSkelControl_HoverboardSuspension.uc create mode 100644 UDKBase/classes/UDKSkelControl_HoverboardSwing.uc create mode 100644 UDKBase/classes/UDKSkelControl_HoverboardVibration.uc create mode 100644 UDKBase/classes/UDKSkelControl_HugGround.uc create mode 100644 UDKBase/classes/UDKSkelControl_LockRotation.uc create mode 100644 UDKBase/classes/UDKSkelControl_LookAt.uc create mode 100644 UDKBase/classes/UDKSkelControl_MassBoneScaling.uc create mode 100644 UDKBase/classes/UDKSkelControl_PropellerBlade.uc create mode 100644 UDKBase/classes/UDKSkelControl_Rotate.uc create mode 100644 UDKBase/classes/UDKSkelControl_SpinControl.uc create mode 100644 UDKBase/classes/UDKSkelControl_TurretConstrained.uc create mode 100644 UDKBase/classes/UDKSkelControl_VehicleFlap.uc create mode 100644 UDKBase/classes/UDKSkeletalMeshComponent.uc create mode 100644 UDKBase/classes/UDKSquadAI.uc create mode 100644 UDKBase/classes/UDKTeamOwnedInfo.uc create mode 100644 UDKBase/classes/UDKTeamPlayerStart.uc create mode 100644 UDKBase/classes/UDKTeleporterBase.uc create mode 100644 UDKBase/classes/UDKTrajectoryReachspec.uc create mode 100644 UDKBase/classes/UDKUIDataProvider_MapInfo.uc create mode 100644 UDKBase/classes/UDKUIDataProvider_MenuOption.uc create mode 100644 UDKBase/classes/UDKUIDataProvider_SearchResult.uc create mode 100644 UDKBase/classes/UDKUIDataProvider_ServerDetails.uc create mode 100644 UDKBase/classes/UDKUIDataProvider_SimpleElementProvider.uc create mode 100644 UDKBase/classes/UDKUIDataProvider_StringArray.uc create mode 100644 UDKBase/classes/UDKUIDataStore_MenuItems.uc create mode 100644 UDKBase/classes/UDKUIDataStore_Options.uc create mode 100644 UDKBase/classes/UDKUIDataStore_StringAliasBindingMap.uc create mode 100644 UDKBase/classes/UDKUIDataStore_StringAliasMap.uc create mode 100644 UDKBase/classes/UDKUIDataStore_StringList.uc create mode 100644 UDKBase/classes/UDKUIResourceDataProvider.uc create mode 100644 UDKBase/classes/UDKVehicle.uc create mode 100644 UDKBase/classes/UDKVehicleBase.uc create mode 100644 UDKBase/classes/UDKVehicleFactory.uc create mode 100644 UDKBase/classes/UDKVehicleMovementEffect.uc create mode 100644 UDKBase/classes/UDKVehicleSimCar.uc create mode 100644 UDKBase/classes/UDKVehicleSimChopper.uc create mode 100644 UDKBase/classes/UDKVehicleSimHover.uc create mode 100644 UDKBase/classes/UDKVehicleSimHoverboard.uc create mode 100644 UDKBase/classes/UDKVehicleWheel.uc create mode 100644 UDKBase/classes/UDKWeapon.uc create mode 100644 UDKBase/classes/UDKWeaponPawn.uc create mode 100644 UDKBase/classes/UDKWeaponShield.uc create mode 100644 UnrealEd/Classes/ASVSkelComponent.uc create mode 100644 UnrealEd/Classes/AnimNodeEditInfo.uc create mode 100644 UnrealEd/Classes/AnimNodeEditInfo_AimOffset.uc create mode 100644 UnrealEd/Classes/AnimSetLabelRenderer.uc create mode 100644 UnrealEd/Classes/AnimTreeEdSkelComponent.uc create mode 100644 UnrealEd/Classes/AnimTreeLabelRenderer.uc create mode 100644 UnrealEd/Classes/ApexClothingAssetLabelRenderer.uc create mode 100644 UnrealEd/Classes/ApexDestructibleAssetLabelRenderer.uc create mode 100644 UnrealEd/Classes/ApexDestructibleAssetThumbnailRenderer.uc create mode 100644 UnrealEd/Classes/ApexGenericAssetLabelRenderer.uc create mode 100644 UnrealEd/Classes/ArchetypeThumbnailRenderer.uc create mode 100644 UnrealEd/Classes/BasicStatsVisualizer.uc create mode 100644 UnrealEd/Classes/BrowserManager.uc create mode 100644 UnrealEd/Classes/BrushBuilder.uc create mode 100644 UnrealEd/Classes/CascadeConfiguration.uc create mode 100644 UnrealEd/Classes/CascadeOptions.uc create mode 100644 UnrealEd/Classes/CascadeParticleSystemComponent.uc create mode 100644 UnrealEd/Classes/CascadePreviewComponent.uc create mode 100644 UnrealEd/Classes/ConeBuilder.uc create mode 100644 UnrealEd/Classes/ConvertMapToNavMesh.uc create mode 100644 UnrealEd/Classes/CubeBuilder.uc create mode 100644 UnrealEd/Classes/CurveEdOptions.uc create mode 100644 UnrealEd/Classes/CurveEdPresetBase.uc create mode 100644 UnrealEd/Classes/CurveEdPreset_CosWave.uc create mode 100644 UnrealEd/Classes/CurveEdPreset_LinearDecay.uc create mode 100644 UnrealEd/Classes/CurveEdPreset_Nothing.uc create mode 100644 UnrealEd/Classes/CurveEdPreset_SineWave.uc create mode 100644 UnrealEd/Classes/CurveEdPreset_UserSet.uc create mode 100644 UnrealEd/Classes/CurvedStairBuilder.uc create mode 100644 UnrealEd/Classes/CustomPropertyItemBindings.uc create mode 100644 UnrealEd/Classes/CylinderBuilder.uc create mode 100644 UnrealEd/Classes/DEditorFontParameterValue.uc create mode 100644 UnrealEd/Classes/DEditorParameterValue.uc create mode 100644 UnrealEd/Classes/DEditorScalarParameterValue.uc create mode 100644 UnrealEd/Classes/DEditorStaticComponentMaskParameterValue.uc create mode 100644 UnrealEd/Classes/DEditorStaticSwitchParameterValue.uc create mode 100644 UnrealEd/Classes/DEditorTextureParameterValue.uc create mode 100644 UnrealEd/Classes/DEditorVectorParameterValue.uc create mode 100644 UnrealEd/Classes/DefaultSizedThumbnailRenderer.uc create mode 100644 UnrealEd/Classes/EdModeComponent.uc create mode 100644 UnrealEd/Classes/EditorComponent.uc create mode 100644 UnrealEd/Classes/EditorEngine.uc create mode 100644 UnrealEd/Classes/EditorUserSettings.uc create mode 100644 UnrealEd/Classes/EditorViewportInput.uc create mode 100644 UnrealEd/Classes/FaceFXStudioSkelComponent.uc create mode 100644 UnrealEd/Classes/FbxImportUI.uc create mode 100644 UnrealEd/Classes/FindUnreferencedFunctionsCommandlet.uc create mode 100644 UnrealEd/Classes/FontThumbnailLabelRenderer.uc create mode 100644 UnrealEd/Classes/FontThumbnailRenderer.uc create mode 100644 UnrealEd/Classes/FracturedStaticMeshLabelRenderer.uc create mode 100644 UnrealEd/Classes/GameStatsDatabase.uc create mode 100644 UnrealEd/Classes/GameStatsDatabaseVisitor.uc create mode 100644 UnrealEd/Classes/GameStatsFileReader.uc create mode 100644 UnrealEd/Classes/GameStatsReport.uc create mode 100644 UnrealEd/Classes/GameStatsVisitorImpl.uc create mode 100644 UnrealEd/Classes/GameStatsVisualizer.uc create mode 100644 UnrealEd/Classes/GenericBrowserType.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_AkBank.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_AkEvent.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_All.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_AnimTree.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_Animation.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_ApexClothingAsset.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_ApexDestructibleAsset.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_ApexDestructibleDamageParameters.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_ApexGenericAsset.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_Archetype.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_CameraAnim.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_CurveEdPresetCurve.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_Custom.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_DecalMaterial.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_FaceFXAnimSet.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_FaceFXAsset.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_FlexContainer.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_Font.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_FractureMaterial.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_FracturedStaticMesh.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_InstancedFoliageSettings.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_LandscapeLayer.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_LensFlare.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_Material.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_MaterialFunction.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_MaterialInstanceConstant.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_MaterialInstanceTimeVarying.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_MorphTargetSet.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_MorphWeightSequence.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_ParticleSystem.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_PhysXParticleSystem.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_PhysicalMaterial.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_PhysicsAsset.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_PostProcess.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_Prefab.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_ProcBuildingRuleset.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_RenderTexture.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_Sequence.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_SkeletalMesh.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_SoundClass.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_SoundCue.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_SoundMode.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_SoundWave.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_Sounds.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_SpeechRecognition.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_SpeedTree.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_StaticMesh.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_TemplateMapMetadata.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_TerrainLayer.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_TerrainMaterial.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_Texture.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_TextureCube.uc create mode 100644 UnrealEd/Classes/GenericBrowserType_TextureMovie.uc create mode 100644 UnrealEd/Classes/GenericParamListVisualizer.uc create mode 100644 UnrealEd/Classes/GenericThumbnailLabelRenderer.uc create mode 100644 UnrealEd/Classes/GeomModifier.uc create mode 100644 UnrealEd/Classes/GeomModifier_Clip.uc create mode 100644 UnrealEd/Classes/GeomModifier_Create.uc create mode 100644 UnrealEd/Classes/GeomModifier_Delete.uc create mode 100644 UnrealEd/Classes/GeomModifier_Edit.uc create mode 100644 UnrealEd/Classes/GeomModifier_Extrude.uc create mode 100644 UnrealEd/Classes/GeomModifier_Flip.uc create mode 100644 UnrealEd/Classes/GeomModifier_Lathe.uc create mode 100644 UnrealEd/Classes/GeomModifier_Optimize.uc create mode 100644 UnrealEd/Classes/GeomModifier_Pen.uc create mode 100644 UnrealEd/Classes/GeomModifier_Split.uc create mode 100644 UnrealEd/Classes/GeomModifier_Triangulate.uc create mode 100644 UnrealEd/Classes/GeomModifier_Turn.uc create mode 100644 UnrealEd/Classes/GeomModifier_Weld.uc create mode 100644 UnrealEd/Classes/GroupActor.uc create mode 100644 UnrealEd/Classes/HeatmapVisualizer.uc create mode 100644 UnrealEd/Classes/IconThumbnailRenderer.uc create mode 100644 UnrealEd/Classes/InterpEdOptions.uc create mode 100644 UnrealEd/Classes/InterpTrackAkEventHelper.uc create mode 100644 UnrealEd/Classes/InterpTrackAkRTPCHelper.uc create mode 100644 UnrealEd/Classes/InterpTrackAnimControlHelper.uc create mode 100644 UnrealEd/Classes/InterpTrackBoolPropHelper.uc create mode 100644 UnrealEd/Classes/InterpTrackColorPropHelper.uc create mode 100644 UnrealEd/Classes/InterpTrackDirectorHelper.uc create mode 100644 UnrealEd/Classes/InterpTrackEventHelper.uc create mode 100644 UnrealEd/Classes/InterpTrackFaceFXHelper.uc create mode 100644 UnrealEd/Classes/InterpTrackFloatPropHelper.uc create mode 100644 UnrealEd/Classes/InterpTrackHeadTrackingHelper.uc create mode 100644 UnrealEd/Classes/InterpTrackHelper.uc create mode 100644 UnrealEd/Classes/InterpTrackLinearColorPropHelper.uc create mode 100644 UnrealEd/Classes/InterpTrackNotifyHelper.uc create mode 100644 UnrealEd/Classes/InterpTrackParticleReplayHelper.uc create mode 100644 UnrealEd/Classes/InterpTrackSoundHelper.uc create mode 100644 UnrealEd/Classes/InterpTrackToggleHelper.uc create mode 100644 UnrealEd/Classes/InterpTrackVectorPropHelper.uc create mode 100644 UnrealEd/Classes/InterpTrackVisibilityHelper.uc create mode 100644 UnrealEd/Classes/KismetBindings.uc create mode 100644 UnrealEd/Classes/LandscapeLayerLabelRenderer.uc create mode 100644 UnrealEd/Classes/LensFlareEditorOptions.uc create mode 100644 UnrealEd/Classes/LensFlareEditorPropertyWrapper.uc create mode 100644 UnrealEd/Classes/LensFlarePreviewComponent.uc create mode 100644 UnrealEd/Classes/LensFlareThumbnailRenderer.uc create mode 100644 UnrealEd/Classes/LightingChannelsObject.uc create mode 100644 UnrealEd/Classes/LightmassOptionsObject.uc create mode 100644 UnrealEd/Classes/LinearStairBuilder.uc create mode 100644 UnrealEd/Classes/MaterialEditorInstanceConstant.uc create mode 100644 UnrealEd/Classes/MaterialEditorInstanceTimeVarying.uc create mode 100644 UnrealEd/Classes/MaterialEditorMeshComponent.uc create mode 100644 UnrealEd/Classes/MaterialEditorOptions.uc create mode 100644 UnrealEd/Classes/MaterialEditorSkeletalMeshComponent.uc create mode 100644 UnrealEd/Classes/MaterialFunctionLabelRenderer.uc create mode 100644 UnrealEd/Classes/MaterialInstanceLabelRenderer.uc create mode 100644 UnrealEd/Classes/MaterialInstanceThumbnailRenderer.uc create mode 100644 UnrealEd/Classes/MemCountThumbnailLabelRenderer.uc create mode 100644 UnrealEd/Classes/ParticleSystemLabelRenderer.uc create mode 100644 UnrealEd/Classes/ParticleSystemThumbnailRenderer.uc create mode 100644 UnrealEd/Classes/PerformanceVisualizer.uc create mode 100644 UnrealEd/Classes/PhATSimOptions.uc create mode 100644 UnrealEd/Classes/PhATSkeletalMeshComponent.uc create mode 100644 UnrealEd/Classes/PhysicsAssetLabelRenderer.uc create mode 100644 UnrealEd/Classes/PlayerMovementVisualizer.uc create mode 100644 UnrealEd/Classes/PostProcessLabelRenderer.uc create mode 100644 UnrealEd/Classes/PrefabThumbnailRenderer.uc create mode 100644 UnrealEd/Classes/PreviewMaterial.uc create mode 100644 UnrealEd/Classes/SequenceObjectHelper.uc create mode 100644 UnrealEd/Classes/SheetBuilder.uc create mode 100644 UnrealEd/Classes/SkeletalMeshLabelRenderer.uc create mode 100644 UnrealEd/Classes/SkeletalMeshThumbnailRenderer.uc create mode 100644 UnrealEd/Classes/SoundLabelRenderer.uc create mode 100644 UnrealEd/Classes/SoundNodeHelper.uc create mode 100644 UnrealEd/Classes/SpiralStairBuilder.uc create mode 100644 UnrealEd/Classes/StaticMeshLabelRenderer.uc create mode 100644 UnrealEd/Classes/StaticMeshMode_Options.uc create mode 100644 UnrealEd/Classes/StaticMeshThumbnailRenderer.uc create mode 100644 UnrealEd/Classes/TagSuboptimalTexturesCommandlet.uc create mode 100644 UnrealEd/Classes/TemplateMapMetadata.uc create mode 100644 UnrealEd/Classes/TerrainEditOptions.uc create mode 100644 UnrealEd/Classes/TetrahedronBuilder.uc create mode 100644 UnrealEd/Classes/TextureCubeThumbnailRenderer.uc create mode 100644 UnrealEd/Classes/TextureThumbnailRenderer.uc create mode 100644 UnrealEd/Classes/ThumbnailLabelRenderer.uc create mode 100644 UnrealEd/Classes/ThumbnailManager.uc create mode 100644 UnrealEd/Classes/ThumbnailRenderer.uc create mode 100644 UnrealEd/Classes/UnrealEdEngine.uc create mode 100644 UnrealEd/Classes/UnrealEdKeyBindings.uc create mode 100644 UnrealEd/Classes/UnrealEdOptions.uc create mode 100644 UnrealEd/Classes/UnrealEdTypes.uc create mode 100644 UnrealEd/Classes/VolumetricBuilder.uc create mode 100644 WebAdmin/Classes/AbstractSettingsModifier.uc create mode 100644 WebAdmin/Classes/AdminCommandHandler.uc create mode 100644 WebAdmin/Classes/BanImporter.uc create mode 100644 WebAdmin/Classes/BasicWebAdminAuth.uc create mode 100644 WebAdmin/Classes/BasicWebAdminUser.uc create mode 100644 WebAdmin/Classes/ChatLog.uc create mode 100644 WebAdmin/Classes/DCEGameInfo.uc create mode 100644 WebAdmin/Classes/DCEMapInfo.uc create mode 100644 WebAdmin/Classes/DCEMutator.uc create mode 100644 WebAdmin/Classes/DataStoreCache.uc create mode 100644 WebAdmin/Classes/DataStoreCacheEntry.uc create mode 100644 WebAdmin/Classes/DataStoreCacheKF.uc create mode 100644 WebAdmin/Classes/GeneralSettings.uc create mode 100644 WebAdmin/Classes/HashLib.uc create mode 100644 WebAdmin/Classes/IAdvWebAdminSettings.uc create mode 100644 WebAdmin/Classes/IQueryHandler.uc create mode 100644 WebAdmin/Classes/ISession.uc create mode 100644 WebAdmin/Classes/ISessionHandler.uc create mode 100644 WebAdmin/Classes/ISettingsModifier.uc create mode 100644 WebAdmin/Classes/ISettingsPrivileges.uc create mode 100644 WebAdmin/Classes/IWebAdminAuth.uc create mode 100644 WebAdmin/Classes/IWebAdminUser.uc create mode 100644 WebAdmin/Classes/KF2ImageServer.uc create mode 100644 WebAdmin/Classes/KF2ServerAdmin.uc create mode 100644 WebAdmin/Classes/KFGameInfoSettings.uc create mode 100644 WebAdmin/Classes/KFGameInfo_SurvivalSettings.uc create mode 100644 WebAdmin/Classes/MessagingSpectator.uc create mode 100644 WebAdmin/Classes/MultiAdminData.uc create mode 100644 WebAdmin/Classes/MultiWebAdminAuth.uc create mode 100644 WebAdmin/Classes/MultiWebAdminUser.uc create mode 100644 WebAdmin/Classes/NewsDesk.uc create mode 100644 WebAdmin/Classes/PCCleanUp.uc create mode 100644 WebAdmin/Classes/QHCurrent.uc create mode 100644 WebAdmin/Classes/QHCurrentKF.uc create mode 100644 WebAdmin/Classes/QHDefaults.uc create mode 100644 WebAdmin/Classes/QHDefaultsKF.uc create mode 100644 WebAdmin/Classes/QHMultiAdmin.uc create mode 100644 WebAdmin/Classes/Session.uc create mode 100644 WebAdmin/Classes/SessionHandler.uc create mode 100644 WebAdmin/Classes/SettingRendererState.uc create mode 100644 WebAdmin/Classes/SettingsMagic.uc create mode 100644 WebAdmin/Classes/SettingsRenderer.uc create mode 100644 WebAdmin/Classes/Sha1HashLib.uc create mode 100644 WebAdmin/Classes/TeamChatProxy.uc create mode 100644 WebAdmin/Classes/WebAdmin.uc create mode 100644 WebAdmin/Classes/WebAdminMenu.uc create mode 100644 WebAdmin/Classes/WebAdminMessages.uc create mode 100644 WebAdmin/Classes/WebAdminSettings.uc create mode 100644 WebAdmin/Classes/WebAdminSkin.uc create mode 100644 WebAdmin/Classes/WebAdminSystemSettings.uc create mode 100644 WebAdmin/Classes/WebAdminUtils.uc create mode 100644 WebAdmin/Classes/WebConnectionEx.uc create mode 100644 WebAdmin/Classes/WelcomeSettings.uc create mode 100644 WebAdmin/SettingsMacros.uci create mode 100644 WebAdmin/WebAdmin.uci create mode 100644 WinDrv/Classes/FacebookWindows.uc create mode 100644 WinDrv/Classes/HttpRequestWindows.uc create mode 100644 WinDrv/Classes/HttpRequestWindowsMcp.uc create mode 100644 WinDrv/Classes/HttpResponseWindows.uc diff --git a/AkAudio/Classes/ActorFactoryAKAmbientSound.uc b/AkAudio/Classes/ActorFactoryAKAmbientSound.uc new file mode 100644 index 0000000..9ac69e2 --- /dev/null +++ b/AkAudio/Classes/ActorFactoryAKAmbientSound.uc @@ -0,0 +1,21 @@ +class ActorFactoryAkAmbientSound extends ActorFactory + config(Editor) + collapsecategories + hidecategories(Object) + native; + +cpptext +{ + virtual AActor* CreateActor(const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData); + virtual UBOOL CanCreateActor(FString& OutErrorMsg, UBOOL bFromAssetOnly = FALSE); + virtual void AutoFillFields(class USelection* Selection); + virtual FString GetMenuName(); +} + +var() AKEvent AmbientEvent; + +defaultproperties +{ + MenuName="Add AkAmbientSound" + NewActorClass=class'AKAudio.AKAmbientSound' +} diff --git a/AkAudio/Classes/AkAmbientSound.uc b/AkAudio/Classes/AkAmbientSound.uc new file mode 100644 index 0000000..d0d2332 --- /dev/null +++ b/AkAudio/Classes/AkAmbientSound.uc @@ -0,0 +1,51 @@ +//============================================================================= +// Ambient sound, sits there and emits its sound. +// Copyright 1998-2007 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class AkAmbientSound extends Keypoint native; + +/** Should the audio component automatically play on load? */ +//var() bool bAutoPlay; Not showing this parameter to user since it is not working properly yet. +var bool bAutoPlay; + +/** Audio component to play */ +var() AkEvent PlayEvent; + +var() bool StopWhenOwnerIsDestroyed; + +/** Is the audio component currently playing? */ +var transient private bool bIsPlaying; + +cpptext +{ +public: + /** + * Start and stop the ambience playback + */ + virtual void StartPlayback(); + virtual void StopPlayback(); + + /** Used by the component to flag the ambient sound as not playing */ + void Playing( UBOOL in_IsPlaying ); + + virtual void FinishDestroy(); + +protected: + /** + * Starts audio playback if wanted. + */ + virtual void UpdateComponentsInternal(UBOOL bCollisionUpdate = FALSE); +} + +defaultproperties +{ + Begin Object NAME=Sprite + Sprite=Texture2D'AkResources.Wwise' + End Object + + bAutoPlay=TRUE + StopWhenOwnerIsDestroyed=TRUE + bIsPlaying=FALSE + + RemoteRole=ROLE_None +} diff --git a/AkAudio/Classes/AkComponent.uc b/AkAudio/Classes/AkComponent.uc new file mode 100644 index 0000000..4ebd9fd --- /dev/null +++ b/AkAudio/Classes/AkComponent.uc @@ -0,0 +1,96 @@ +class AkComponent extends ActorComponent + native + collapsecategories + hidecategories(Object) + hidecategories(ActorComponent) + editinlinenew; + +var() Name BoneName; +var AkEvent AutoPlayEvent; + +/** Stop sound when owner is destroyed */ +var bool bStopWhenOwnerDestroyed; + +`if(`__TW_WWISE_) +/** Whether this component is part of the audio device component pool (set to true in UAkAudioDevice::GetPooledAkComponent) */ +var transient const bool bPooled; +/** Whether this component is ready to be returned to pool. Gets set on the audio thread, while component actually gets returned on the main thread. */ +var transient const bool bWaitingToReturnToPool; +/** Whether sound should follow owner position */ +var transient const bool bFollowOwnerPosition; +/** Whether events being played are modified based on listener distance */ +var transient bool bUpdateDistanceToListener; +/** Whether events being played are modified based on relative velocity to listener (e.g. for Doppler) */ +var transient bool bUpdateRelativeVelocityToListener; + +/** Whether this component is forced to use its own OcclusionUpdateInterval (set in defaultproperties) or can adopt a posted event's interval */ +var bool bForceOcclusionUpdateInterval; // JDR: can't be transient because we set this in default properties +/** How often to update occlusion or obstruction. Zero means never update. Is set per posted event unless bForceOcclusionUpdateInterval is true. */ +var float OcclusionUpdateInterval; // JDR: can't be transient because we set this in default properties +/** last time we updated occlusion */ +var transient float LastOcclusionUpdateTime; +/** whether we were occluded the last time we checked */ +var transient bool bWasOccluded; + +/** Maximum attenuation value of all events played on this component (gets reset when/if component is returned to component pool)*/ +var transient float MaxAttenuationValue; + +/** The specific location to play this sound. Bone locations specified in BoneName will override this. If not specified plays from the attached actor's location */ +var transient vector Location; +/** The relative location to play this sound on based on the location of the actor this component is attached to. Directly setting the location will override this */ +var transient vector RelativeLocation; + +/** AK::SoundEngine::Query calls (such as GetPosition (of game object)) can take milliseconds (bad). + * Instead, just cache each game object's (AkComponent) position at the same time that it's passed off to the SoundEngine (in SetObjectPosition). + */ +var transient vector CachedObjectPosition; + +/** AkEvent to play when this AKComponent stops playing */ +var transient AkEvent StopPlayEvent; + +/** Filled by AkEvents when they're posted. Reset when/if component is returned to pool */ +var transient array CustomRTPCNames; + +/** Stops all events being played on this component */ +native function StopEvents(); + +/** Play the given event directly on this component (doesn't go through PlaySoundBase, requires custom replication if desired) */ +native function PlayEvent( AkEvent in_Event, optional bool bIsSpatialized, optional bool bIsOccluded, optional bool bDoNotCheckOcclusion ); + +/** Sets a real-time parameter control on this component */ +native function SetRTPCValue( string RTPCString, float RTPCValue ); + +/** Checks if this component is playing any event, or a specific event if one is provided */ +native function bool IsPlaying( optional AkEvent Event ); + +`endif // __TW_WWISE_ + +cpptext +{ + // Object interface. + virtual void Serialize(FArchive& Ar); + virtual void Attach(); + virtual void Detach( UBOOL bWillReattach = FALSE ); + virtual void FinishDestroy(); + virtual void ShutdownAfterError(); + + // Methods + void UnregisterGameObject(); + void Stop(); + +#if __TW_WWISE_ + // determines if this component should check occlusion + virtual bool ShouldUpdateOcclusion(); + // determines if the listener is witin the max attenuation range of the component + virtual bool ListenerWithinMaxRange( INT ListenerIndex = 0 ); + // checks occlusion (AudioComponent::CheckOcclusion) + virtual void UpdateOcclusion( INT ListenerIndex = 0); +#endif // __TW_WWISE_ +} + +defaultproperties +{ +`if(`__TW_WWISE_) + bFollowOwnerPosition=True +`endif +} diff --git a/AkAudio/Classes/InterpTrackAkEvent.uc b/AkAudio/Classes/InterpTrackAkEvent.uc new file mode 100644 index 0000000..4092935 --- /dev/null +++ b/AkAudio/Classes/InterpTrackAkEvent.uc @@ -0,0 +1,44 @@ +class InterpTrackAkEvent extends InterpTrack + native; + +cpptext +{ + // InterpTrack interface + virtual INT GetNumKeyframes() const; + virtual void GetTimeRange(FLOAT& StartTime, FLOAT& EndTime) const; + virtual FLOAT GetKeyframeTime(INT KeyIndex) const; + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual INT SetKeyframeTime(INT KeyIndex, FLOAT NewKeyTime, UBOOL bUpdateOrder=true); + virtual void RemoveKeyframe(INT KeyIndex); + virtual INT DuplicateKeyframe(INT KeyIndex, FLOAT NewKeyTime); + virtual UBOOL GetClosestSnapPosition(FLOAT InPosition, TArray &IgnoreKeys, FLOAT& OutPosition); + + virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + + /** Get the name of the class used to help out when adding tracks, keys, etc. in UnrealEd. + * @return String name of the helper class.*/ + virtual const FString GetEdHelperClassName() const; + + virtual class UMaterial* GetTrackIcon() const; + virtual void DrawTrack( FCanvas* Canvas, UInterpGroup* Group, const FInterpTrackDrawParams& Params ); + + // InterpTrackAkEvent interface + UAkEvent* GetAkEventAtPosition(FLOAT InPosition); +} + +/** Information for one sound in the track. */ +struct native AkEventTrackKey +{ + var float Time; + var() AkEvent Event; +}; + +/** Array of sounds to play at specific times. */ +var array AkEvents; + +defaultproperties +{ + TrackInstClass=class'AkAudio.InterpTrackInstAkEvent' + TrackTitle="AkEvent" +} diff --git a/AkAudio/Classes/InterpTrackAkRTPC.uc b/AkAudio/Classes/InterpTrackAkRTPC.uc new file mode 100644 index 0000000..f7b61a1 --- /dev/null +++ b/AkAudio/Classes/InterpTrackAkRTPC.uc @@ -0,0 +1,26 @@ +class InterpTrackAkRTPC extends InterpTrackFloatBase + native; + +cpptext +{ + // InterpTrack interface + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual void UpdateKeyframe(INT KeyIndex, UInterpTrackInst* TrInst); + virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + + /** Get the name of the class used to help out when adding tracks, keys, etc. in UnrealEd. + * @return String name of the helper class.*/ + virtual const FString GetEdHelperClassName() const; + + virtual class UMaterial* GetTrackIcon() const; +} + +/** Name of game parameter */ +var() string Param; + +defaultproperties +{ + TrackInstClass=class'AkAudio.InterpTrackInstAkRTPC' + TrackTitle="AkRTPC" +} diff --git a/AkAudio/Classes/InterpTrackInstAkEvent.uc b/AkAudio/Classes/InterpTrackInstAkEvent.uc new file mode 100644 index 0000000..62d9a58 --- /dev/null +++ b/AkAudio/Classes/InterpTrackInstAkEvent.uc @@ -0,0 +1,14 @@ +class InterpTrackInstAkEvent extends InterpTrackInst + native; + +cpptext +{ + virtual void InitTrackInst(UInterpTrack* Track); + virtual void TermTrackInst(UInterpTrack* Track); +} + +var float LastUpdatePosition; + +defaultproperties +{ +} diff --git a/AkAudio/Classes/InterpTrackInstAkRTPC.uc b/AkAudio/Classes/InterpTrackInstAkRTPC.uc new file mode 100644 index 0000000..1575e49 --- /dev/null +++ b/AkAudio/Classes/InterpTrackInstAkRTPC.uc @@ -0,0 +1,12 @@ +class InterpTrackInstAkRTPC extends InterpTrackInst + native; + +cpptext +{ + virtual void InitTrackInst(UInterpTrack* Track); + virtual void TermTrackInst(UInterpTrack* Track); +} + +defaultproperties +{ +} diff --git a/AkAudio/Classes/SeqAct_AkClearBanks.uc b/AkAudio/Classes/SeqAct_AkClearBanks.uc new file mode 100644 index 0000000..3b657c3 --- /dev/null +++ b/AkAudio/Classes/SeqAct_AkClearBanks.uc @@ -0,0 +1,17 @@ +class SeqAct_AkClearBanks extends SequenceAction + native; + +cpptext +{ + void Activated(); +}; + +defaultproperties +{ + ObjName="AkClearBanks" + ObjCategory="AkAudio" + + VariableLinks.Empty + + InputLinks(0)=(LinkDesc="ClearBanks") +} diff --git a/AkAudio/Classes/SeqAct_AkLoadBank.uc b/AkAudio/Classes/SeqAct_AkLoadBank.uc new file mode 100644 index 0000000..aad2868 --- /dev/null +++ b/AkAudio/Classes/SeqAct_AkLoadBank.uc @@ -0,0 +1,33 @@ +class SeqAct_AkLoadBank extends SeqAct_Latent + native; + +var() bool Async; // Asynchronous loading +var() AkBank Bank; // Bank to be loaded / unloaded +var transient int Signal; // signal (event) used during async load + +var transient bool bWaitingCallback;// true if the ojbect must cancel a cookie on destroy. + +cpptext +{ + void Activated(); + UBOOL UpdateOp(FLOAT deltaTime); + + virtual void BeginDestroy(); +}; + +defaultproperties +{ + ObjName="AkLoadBank" + ObjCategory="AkAudio" + + VariableLinks.Empty + OutputLinks.Empty + + Async = TRUE + bWaitingCallback = FALSE + + InputLinks(0)=(LinkDesc="Load") + InputLinks(1)=(LinkDesc="Unload") + + OutputLinks(0)=(LinkDesc="Finished") +} diff --git a/AkAudio/Classes/SeqAct_AkPostEvent.uc b/AkAudio/Classes/SeqAct_AkPostEvent.uc new file mode 100644 index 0000000..3ca2b87 --- /dev/null +++ b/AkAudio/Classes/SeqAct_AkPostEvent.uc @@ -0,0 +1,32 @@ +class SeqAct_AkPostEvent extends SeqAct_Latent + native; + +var transient int Signal; // signal (event) used for EndOfEvent +`if(`__TW_WWISE_) +/** If TRUE, will use PlayAkEvent() instead of the audio device to trigger the AkEvent on clients */ +var() bool bReplicateToClients; +`endif +cpptext +{ + virtual void FinishDestroy(); + + void Activated(); + UBOOL UpdateOp(FLOAT deltaTime); +private: + void PlayEventOnTargets(); +}; + +/** Event to post on the targeted actor(s) */ +var() AkEvent Event; + +defaultproperties +{ + ObjName="AkPostEvent" + ObjCategory="AkAudio" + + OutputLinks.Empty + + InputLinks(0)=(LinkDesc="Post") + + OutputLinks(0)=(LinkDesc="Finished") +} diff --git a/AkAudio/Classes/SeqAct_AkPostTrigger.uc b/AkAudio/Classes/SeqAct_AkPostTrigger.uc new file mode 100644 index 0000000..6338eb8 --- /dev/null +++ b/AkAudio/Classes/SeqAct_AkPostTrigger.uc @@ -0,0 +1,17 @@ +class SeqAct_AkPostTrigger extends SequenceAction + native; + +cpptext +{ + void Activated(); +}; + +var() string Trigger; + +defaultproperties +{ + ObjName="AkPostTrigger" + ObjCategory="AkAudio" + + InputLinks(0)=(LinkDesc="Post") +} diff --git a/AkAudio/Classes/SeqAct_AkSetRTPCValue.uc b/AkAudio/Classes/SeqAct_AkSetRTPCValue.uc new file mode 100644 index 0000000..e20cafd --- /dev/null +++ b/AkAudio/Classes/SeqAct_AkSetRTPCValue.uc @@ -0,0 +1,33 @@ +class SeqAct_AkSetRTPCValue extends SeqAct_Latent + native; + +cpptext +{ + void Activated(); + UBOOL UpdateOp(FLOAT deltaTime); +private: + void SetRTPCValue(); +}; + +/** Name of game parameter */ +var() string Param; + +/** Value of game parameter, default value used if no variable linked */ +var() float Value; + +/** True when sending RTPC signal */ +var transient bool Running; + +defaultproperties +{ + ObjName="AkSetRTPCValue" + ObjCategory="AkAudio" + + OutputLinks.Empty + + InputLinks(0)=(LinkDesc="Start") + InputLinks(1)=(LinkDesc="Stop") + VariableLinks(1)=(ExpectedType=class'SeqVar_Float',LinkDesc="Value",PropertyName=Value) + + OutputLinks(0)=(LinkDesc="Finished") +} diff --git a/AkAudio/Classes/SeqAct_AkSetState.uc b/AkAudio/Classes/SeqAct_AkSetState.uc new file mode 100644 index 0000000..0c7b1eb --- /dev/null +++ b/AkAudio/Classes/SeqAct_AkSetState.uc @@ -0,0 +1,20 @@ +class SeqAct_AkSetState extends SequenceAction + native; + +cpptext +{ + void Activated(); +}; + +var() string StateGroup; +var() string State; + +defaultproperties +{ + ObjName="AkSetState" + ObjCategory="AkAudio" + + VariableLinks.Empty + + InputLinks(0)=(LinkDesc="Set") +} diff --git a/AkAudio/Classes/SeqAct_AkSetSwitch.uc b/AkAudio/Classes/SeqAct_AkSetSwitch.uc new file mode 100644 index 0000000..852e88a --- /dev/null +++ b/AkAudio/Classes/SeqAct_AkSetSwitch.uc @@ -0,0 +1,18 @@ +class SeqAct_AkSetSwitch extends SequenceAction + native; + +cpptext +{ + void Activated(); +}; + +var() string SwitchGroup; +var() string Switch; + +defaultproperties +{ + ObjName="AkSetSwitch" + ObjCategory="AkAudio" + + InputLinks(0)=(LinkDesc="Set") +} diff --git a/AkAudio/Classes/SeqAct_AkStartAmbientSound.uc b/AkAudio/Classes/SeqAct_AkStartAmbientSound.uc new file mode 100644 index 0000000..247ef99 --- /dev/null +++ b/AkAudio/Classes/SeqAct_AkStartAmbientSound.uc @@ -0,0 +1,18 @@ +class SeqAct_AkStartAmbientSound extends SequenceAction + native; + +cpptext +{ + void Activated(); +}; + +defaultproperties +{ + ObjName="AkStartAmbientSound" + ObjCategory="AkAudio" + + InputLinks(0)=(LinkDesc="Start All") + InputLinks(1)=(LinkDesc="Stop All") + InputLinks(2)=(LinkDesc="Start Target(s)") + InputLinks(3)=(LinkDesc="Stop Targets(s)") +} diff --git a/AkAudio/Classes/SeqAct_AkStopAll.uc b/AkAudio/Classes/SeqAct_AkStopAll.uc new file mode 100644 index 0000000..a33fab4 --- /dev/null +++ b/AkAudio/Classes/SeqAct_AkStopAll.uc @@ -0,0 +1,17 @@ +class SeqAct_AkStopAll extends SequenceAction + native; + +cpptext +{ + void Activated(); +}; + +defaultproperties +{ + ObjName="AkStopAll" + ObjCategory="AkAudio" + + VariableLinks.Empty + + InputLinks(0)=(LinkDesc="StopAll") +} diff --git a/BaseAI/Classes/AIDebugTool.uc b/BaseAI/Classes/AIDebugTool.uc new file mode 100644 index 0000000..8a7d5f2 --- /dev/null +++ b/BaseAI/Classes/AIDebugTool.uc @@ -0,0 +1,244 @@ +//============================================================================= +// AIDebugTool +//============================================================================= +// +//============================================================================= +// Killing Floor 2 +// Copyright (C) 2015 Tripwire Interactive LLC +//============================================================================= +class AIDebugTool extends Object + dependson(BaseAIController) + config(AI) + native(Debug); + +var transient float GameFrameTime; + +var int BTPersonalLogSize; +var array BTPersonalLog; + +var BaseAIController DebugTarget; +var int EntryToDisplay; + +var transient init array Filters; +var array ColorCategories; + +var array UnreachableActors; + +enum ELogDrawingMode +{ + AIDH_DrawAll, + AIDH_EntryDetails, + AIDH_BlackBoard, + AIDH_Preconditions, + AIDH_SquadEnemy, + AIDH_Animation, + AIDH_Weapon +}; +var int DrawingFlags; + +struct String_Mirror +{ + var string Value; +}; + +struct native AIDebugLogLine +{ + var native String_Mirror Line{FString}; + var native Name LineCategory; + //@todo Add additional data, like position, hit info, etc + + structcpptext + { + FAIDebugLogLine(const TCHAR* PtrLine, FName inCategory = NAME_None) + { + Line = PtrLine; + LineCategory = inCategory; + } + + FAIDebugLogLine(const FString& LineIn, FName inCategory = NAME_None) + { + Line = LineIn; + LineCategory = inCategory; + } + } +}; + +struct native AIDebugLogEntry +{ + var float TimeStamp; + var vector WorldPosition; + var vector EnemyPosition; + var vector Facing; + var native String_Mirror BTStatus{FString}; + var native array BlackBoardEntries{FString}; + var native array BehaviorTrace{FString}; + var native array Preconditions{FString}; + var native array CommandStack{FString}; + var native array SquadEnemyList{FString}; + var native array LocalEnemyList{FString}; + var native array InnerState{FString}; + var native array AnimationProxy{FString}; + var native array Route; + var native init array DebugLines; + var native array WeaponInfo{FString}; + var array Lines; + + structcpptext + { + FAIDebugLogEntry() + { + appMemzero(this, sizeof(FAIDebugLogEntry)); + } + } +}; + +struct native AIDebugActorsLog +{ + var int Tail; + var array Entries; + var int NotEmptyElements; + + /** this variable is used for pooling. DO NOT CHANGE! */ + var private const int nIndex; + + structcpptext + { + + enum { LogSize = 500 }; + + FAIDebugActorsLog(UBOOL bInit = TRUE) + { + appMemzero(this, sizeof(FAIDebugLogEntry)); + if(bInit) + { + Init(); + } + } + + FORCEINLINE void Init() + { + Entries.Reserve(LogSize); + Entries.AddZeroed(LogSize); + } + + FORCEINLINE void Reset() + { + Entries.Empty(LogSize); + Entries.AddZeroed(LogSize); + NotEmptyElements = 0; + } + + /** Pooling interface Get*/ + FORCEINLINE INT GetIndex() const + { + return nIndex; + } + /** Pooling interface Set*/ + FORCEINLINE void SetIndex(INT index) + { + nIndex = index; + } + + void SaveToFile(FArchive* File); + void LoadFile(FArchive* File, UBOOL bLoadOldLogs = FALSE); + + } +}; + +struct native ETQDebugEntry +{ + var float TimeStamp; + var native init array ExecutedQueries{FString}; +}; +var transient ETQDebugEntry CurrentETQLog; +var init array ETQLogHistory; + +var bool bLoadOldLogs; + +var transient Actor LoggingContext; + +var native const Map_Mirror Logs{TMap}; + +/** + * Draws stored log for given Actor. If Actor == None than contents of loaded + * ailogex file are displayed + */ +final native function DrawLog(Canvas Canvas, Actor Actor); +final native function bool LoadLogFile(string FileName, optional bool bAppendMapName = true); +final native function FlushLogs(optional string DirName, optional BaseAIController AI); + +final native function SetDebugTarget(BaseAIController NewDebugTarget); + +final native noexport function Log(Actor Actor, string LogText, optional Name LogCategory); +final native noexport function LogSpaceLine(Actor Actor, vector Start, vector End, EDebugLineType Type, optional string Comment, optional Name Category); + +final native function SetContext(Actor Actor); + +/** + * To get previous entries send a negative number as a parameter + */ +final native function DisplayNextEntry(optional int Count = 1, optional int Direction = 1); + +final native function ToggleLogDrawingMode(ELogDrawingMode Mode); + +final native function SetHistoryFilter(Name Filter, bool bVal); +final native function ClearHistoryFilter(); + +final native function ColorHistory(Name Filter); +final native function ClearHistoryColor(); + +final native function LogUnreachableActor(Actor inActor); +final native function FlushUnreachableActors(); + +final native function AddETQLog(string QueryName, string TestName, Actor Querier); +final native function FlushETQHistory(); + +final native function AddBTLogEntry(string Entry); + +final native function Vector GetActorEntryLocation(optional Actor inActor, optional int Index=-1); + +final native function DumpNativeCallStack(Actor Actor, optional Name LogCategory = 'CallStack'); + +cpptext +{ + void Init(); + void Tick(FLOAT DeltaTime); + void CleanUp(UBOOL bShutDown); + + void FlushAILog(class AActor* Actor, UBOOL bRemoveLog = FALSE); + + enum EAILogElement + { + AILE_PrevChannel, + AILE_Command, + AILE_Timestamp, + AILE_BlackBoard, + AILE_BehaviorStack, + AILE_Preconditions, + AILE_CommandStack, + AILE_SquadEnemies, + AILE_LocalEnemies, + AILE_Route, + AILE_InnerState, + AILE_WeaponInfo + }; + + void Log(const class AActor* Actor,const FString& LogText,FName LogCategory=NAME_None); + void LogSpaceLine(const class AActor* Actor,const FVector& Start,const FVector& End,BYTE Type,const FString& Comment=TEXT(""),FName Category=NAME_None); + void ContextLog(const FString& LogText,FName LogCategory=NAME_None); + void ContextLogSpaceLine(const FVector& Start,const FVector& End,BYTE Type,const FString& Comment=TEXT(""),FName Category=NAME_None); + +protected: + void ChannelEntryHeader(const class AActor* Actor, FAIDebugLogEntry* ptrEntry); + UBOOL HasAnyLines(struct FAIDebugActorsLog* Log, INT EntryIdx, TArray& inFilters) const; + FAIDebugLogEntry* GetLogEntry(const class AActor* Actor); + +private: + static TDataBank sm_Logs; +}; + +defaultproperties +{ + BTPersonalLogSize=23 + bLoadOldLogs=false +} diff --git a/BaseAI/Classes/AIPlugin.uc b/BaseAI/Classes/AIPlugin.uc new file mode 100644 index 0000000..223ca7d --- /dev/null +++ b/BaseAI/Classes/AIPlugin.uc @@ -0,0 +1,90 @@ +//============================================================================= +// AIPlugin +//============================================================================= +// +//============================================================================= +// Killing Floor 2 +// Copyright (C) 2015 Tripwire Interactive LLC +//============================================================================= +class AIPlugin extends PluginBase within BaseAIController + native(Plugin) + abstract; + +var const protected{protected} BaseAIController MyBaseAIController; +var const protected{private} bool bCustomSetupController; + +cpptext +{ + virtual UBOOL SetupController(class ABaseAIController* Owner); + // Called if bCustomSetupController == true + virtual UBOOL SetupControllerImpl(class ABaseAIController* Owner) PURE_VIRTUAL(UPluginBase::SetupConrollerImpl, return TRUE;); + + UBOOL HasCustomControllerSetup() const + { + return bCustomSetupController; + } + + FORCEINLINE const ABaseAIController* GetController() const + { + return MyBaseAIController; + } + + FORCEINLINE ABaseAIController* GetController() + { + return MyBaseAIController; + } +}; + +event ScriptSetUp() +{ + +} + +/** + * =========== + * DEBUG STATES + * =========== + */ +state DEBUGSTATE +{ + function BeginState( Name PreviousStateName ) + { + //debug + `AILog( "BEGINSTATE"@PreviousStateName, 'State' ); + } + + function EndState( Name NextStateName ) + { + //debug + `AILog( "ENDSTATE"@NextStateName, 'State' ); + } + + function PushedState() + { + //debug + `AILog( "PUSHED", 'State' ); + } + + function PoppedState() + { + //debug + `AILog( "POPPED", 'State' ); + } + + function ContinuedState() + { + //debug + `AILog( "CONTINUED", 'State' ); + } + + function PausedState() + { + //debug + `AILog( "PAUSED", 'State' ); + } +} + +defaultproperties +{ + bCustomSetupController=false +} diff --git a/BaseAI/Classes/AIPluginLeap.uc b/BaseAI/Classes/AIPluginLeap.uc new file mode 100644 index 0000000..2c2364d --- /dev/null +++ b/BaseAI/Classes/AIPluginLeap.uc @@ -0,0 +1,413 @@ +//============================================================================= +// AIPluginLeap +//============================================================================= +// +//============================================================================= +// Killing Floor 2 +// Copyright (C) 2015 Tripwire Interactive LLC +//============================================================================= +class AIPluginLeap extends AITickablePlugin within BaseAIController + native(Plugin) + dependson(NavigationPath) + abstract + config(AI); + + +//var KFJumpDownNavPoint TheJumpDownNavPointPathObject; + +//var Actor BaseForLeaping; + +//var KFJumpDownNavPoint TheJumpDownNavPointPathObject; +//var int LandSpotIndex; + +var Actor BaseForLanding; +//var KFJumpDownLandNavPoint LandNavPoint; + +/** Start and End for the leap */ +var Vector LeapDirection; +var transient Vector LocationAtStartOfLeap; +var transient Vector ClosestLocOnEdge; + +var transient Vector ExpectedLandingLoc; + +var const public{protected} EActionPriority ActionPriority; + +var const transient bool bObserverNotified; +var const transient bool bDontNotifyObserver; +var transient bool bDontRestartByKismet; + + +var float ConfigFactorToIncreaseCalcedLeapVolBy; +var float ConfigFactorToIncreasePlottedLeapVolBy; +var float ConfigFactorToReduceLeapProjectionSizeBy; + +var float ConfigDistanceOutFromDropEdgeToCalcDropLoc; + +//var transient float DropHeight; + +var float PercentageOfLeapImmuneFromCollision; +var float ConfigPercentageOfLeapImmuneFromCollision; + +var bool bCollisionOffPhase; + +var float ConfigDesiredLeapSpeed; +var float ConfigMinSpeedAllowed; +var float ConfigMaxSpeedAllowed; +var float ConfigBaseLeapZ; +var float ConfigDesiredZPct; +var bool bConfigOnlyTraceUp; + +struct native LeapRequest +{ + //var native MoveParameters MoveParams; + var Actor TheJumpDownNavPointPathObject; + var int LandSpotIndex; + var float EdgesDropHeight; + + var EActionPriority Priority; + var const object Observer; + + var int QueryID; + + structcpptext + { + FLeapRequest() + { + appMemzero(this, sizeof(FLeapRequest)); + Reset(); + } + + FLeapRequest(FLeapRequest* pOther) + { + if(pOther != NULL) + { + appMemCopy(*this, *pOther); + } + else + { + appMemzero(this, sizeof(FLeapRequest)); + Reset(); + } + } + + FString GetDescription() const; + + void Reset() + { + Priority = AP_Invalid; + TheJumpDownNavPointPathObject = NULL; + Observer = NULL; + LandSpotIndex = -1; + } + } +}; + +var LeapRequest MyLeapRequest; + +var bool bWantTotalMovementControl; + +cpptext +{ + void ClearMoveInfo(); +} + + +/** Simple constructor that pushes a new instance of the command for the AI */ +function bool Leap( const out LeapRequest InLeapRequest ) // AIController AI, Actor InTheJumpDownNavPointPathObject, int InLandSpotIndex, float InDropHeight ) +{ + //DropHeight = InDropHeight; + //LandSpotIndex = InLandSpotIndex; + //BaseForLeaping = InTheJumpDownNavPointPathObject; + + MyLeapRequest = InLeapRequest; + + ScriptCommonMovePreparation( AP_Logic ); + + GotoState( 'Command_SpecialMove' ); + + return true; + +} + +/** Build debug string */ +event String GetDumpString() +{ + return "LeapDirection:"@LeapDirection; +} + +//function Pushed() +event bool ScriptCommonMovePreparation(EActionPriority Priority) +{ + bCollisionOffPhase = false; + + //Super.Pushed(); + + //GotoState( 'Command_SpecialMove' ); + + return true; +} + +//function Popped() +event ScriptCleanUp() +{ + //Super.Popped(); + Outer.MyBaseAIPawn.bLeaping = false; + //bReevaluatePath = TRUE; + `AILog( GetFuncName() @ " Turning me on because ScriptCleanUp: " ); + TurnMeOn(); +} + +native function protected Success(); +native function protected Failure(); + +native function bool AbortMove(bool bNewRequest); + +state Succeeding `DEBUGSTATE +{ +Begin: + `AILog("Leaping - END:"@GetStateName(), 'Leap'); + Success(); +} + +state Failing `DEBUGSTATE +{ +Begin: + `AILog("Leaping - END:"@GetStateName(), 'Leap'); + Failure(); +} + +/* this state does nothing. It's here to leave other states when move is aborted, + * and to indicate that it happened */ +state Aborting `DEBUGSTATE +{ +Begin: + `AILog("Leaping - Aborted", 'Leap'); + //AbortMove(false); + StopMovement(); +} + +/* this state does nothing. It's here to leave other states when move is aborted, +* and to indicate that it happened */ +state Idling `DEBUGSTATE +{ +Begin: + `AILog("Leaping - Idling so doing nothing", 'Leap'); + //StopMovement(); +} + + +function TestForTimeToTurnCollisionBackOn() +{ + local float timeDelta; + + if( bCollisionOffPhase ) + { + if( HasPercentOfZDiffBeenCovered() ) + { + `AILog( GetFuncName() @ " Turning me on because HasPercentOfZDiffBeenCovered: " ); + TurnMeOn(); + } + else + { + timeDelta = WorldInfo.TimeSeconds - Outer.MyBaseAIPawn.TimeStartedLeap; + + if( timeDelta > Outer.MyBaseAIPawn.TimeImmuneWhileLeaping ) + { + `AILog( GetFuncName() @ " Turning me on because of time in leap of: " @ timeDelta ); + + TurnMeOn(); + } + } + + } +} + +function bool HasPercentOfZDiffBeenCovered(); + + +function TurnMeOn() +{ + Outer.MyBaseAIPawn.SetCollision( true, true ); + + Outer.MyBaseAIPawn.bCollideWorld = true; + + Outer.MyBaseAIPawn.SetPushesRigidBodies(true); + + bCollisionOffPhase = false; +} + +function vector GetJumpVelForDropEdge( out float TimeToReachLandLoc ); + +function vector GetJumpVelForUsingJumpDownNavPointPathObject( out float TimeToReachLandLoc ); + + +state Command_SpecialMove +{ + function BeginState( Name PreviousStateName ) + { + Super.BeginState( PreviousStateName ); + + if( MyLeapRequest.TheJumpDownNavPointPathObject != none ) + { + SetDesiredDirectionForJumpDoenNavPointEdge(); + } + else + { + SetDesiredDirectionForDropEdge(); + } + + bWantTotalMovementControl = true; + } + + function Bool IfShowLeapDownDebugArtifacts() + { + return false; + } + + function vector GetCurrentJumpEdgeDirectionOfLeap() + { + return Vector(MyLeapRequest.TheJumpDownNavPointPathObject.Rotation); + } + + function float GetDistanceDownRangeToFocusForDropEdgeLeap() + { + return 500.0; + } + + //function SetDesiredDirectionForDropEdge() + //{ + // local Vector newFocalPoint; + // local float edgesDropHeight; + + // LeapDirection = MyKFNavigationHandle.GetCurrentJumpEdgeDirectionOfLeap( Outer, edgesDropHeight, ClosestLocOnEdge ); + + // Focus = none; + + // newFocalPoint = Outer.Pawn.Location + LeapDirection * Outer.DistanceDownRangeToFocusForDropEdgeLeap; + + // SetFocalPoint( newFocalPoint ); + + // if( Outer.bShowLeapDownDebugArtifacts ) + // { + // DrawDebugStar( newFocalPoint, 30, 255, 165, 0, true); + // } + + // SetDesiredRotation(rotator(LeapDirection)); + //} + + function SetDesiredDirectionForDropEdge() + { + local Vector newFocalPoint; + //local float edgesDropHeight; + + LeapDirection = GetCurrentJumpEdgeDirectionOfLeap(); + + Focus = none; + + newFocalPoint = Outer.Pawn.Location + LeapDirection * GetDistanceDownRangeToFocusForDropEdgeLeap(); + + SetFocalPoint( newFocalPoint ); + + if( IfShowLeapDownDebugArtifacts() ) // Outer.bShowLeapDownDebugArtifacts ) + { + DrawDebugStar( newFocalPoint, 300, 255, 165, 0, true); + } + + SetDesiredRotation(rotator(LeapDirection)); + } + + //function SetDesiredDirectionForJumpDoenNavPointEdge() + //{ + // local Vector newFocalPoint; + + // LeapDirection = BaseForLanding.Location - Outer.Pawn.Location; + + // Focus = none; + + // newFocalPoint = BaseForLanding.Location;// Outer.Pawn.Location + LeapDirection * Outer.DistanceDownRangeToFocusForDropEdgeLeap; + + // SetFocalPoint( newFocalPoint ); + + // if( Outer.bShowLeapDownDebugArtifacts ) + // { + // DrawDebugStar( newFocalPoint, 30, 255, 165, 0, true); + // } + + // SetDesiredRotation(rotator(LeapDirection)); + //} + + function SetDesiredDirectionForJumpDoenNavPointEdge() + { + local Vector newFocalPoint; + + if( BaseForLanding == none ) + { + return; + } + + LeapDirection = BaseForLanding.Location - Outer.Pawn.Location; + + Focus = none; + + newFocalPoint = BaseForLanding.Location;// Outer.Pawn.Location + LeapDirection * Outer.DistanceDownRangeToFocusForDropEdgeLeap; + + SetFocalPoint( newFocalPoint ); + + if( IfShowLeapDownDebugArtifacts() ) + { + DrawDebugStar( newFocalPoint, 300, 255, 165, 0, true); + } + + SetDesiredRotation(rotator(LeapDirection)); + } + + function bool DoLeap() + { + return false; + } + + function LeapLoopPreSleepDataUpdate() + { + //Outer.LeapBehavior.ProjMeshLocations.AddItem(MyKfPawn.Location); + } + +Begin: + + while( !Pawn.ReachedDesiredRotation() ) + { + Sleep(0.03); + } + + if( DoLeap() ) + { + do + { + LeapLoopPreSleepDataUpdate(); + Sleep( 0.0f ); + TestForTimeToTurnCollisionBackOn(); + + } until( Pawn.Physics != PHYS_Falling ); + + `AILog( GetFuncName() @ " Pawn.Physics != PHYS_Falling, so landed" ); + + // CGH this is where i am an trying to get the pawn told about the leap. + Outer.MyBaseAIPawn.bLeaping = false; + Outer.MyBaseAIPawn.SetCollision( true, true, true ); + +// Status = 'Success'; + Focus = Enemy; + //PopCommand( self ); + //Stop; + + NotifyLanded(); + } + bWantTotalMovementControl = false; + + GotoState( 'Succeeding' ); +} + +function NotifyLanded(); + +defaultproperties +{ +} \ No newline at end of file diff --git a/BaseAI/Classes/AIPluginMovement.uc b/BaseAI/Classes/AIPluginMovement.uc new file mode 100644 index 0000000..b8643a0 --- /dev/null +++ b/BaseAI/Classes/AIPluginMovement.uc @@ -0,0 +1,367 @@ +//============================================================================= +// AIPluginMovement +//============================================================================= +// A proxy/parent class for all specific movement implementations +//============================================================================= +// Killing Floor 2 +// Copyright (C) 2015 Tripwire Interactive LLC +//============================================================================= +class AIPluginMovement extends AITickablePlugin within BaseAIController + native(Plugin) + dependson(NavigationPath) + abstract; + +struct native MoveParameters +{ + var EBaseMoveMood MoveMood; + var EBaseMoveType MoveType; +// var EStridePose EndStridePose; + var Actor RotateAtEndToMatch; + /** When path is actually for following actor. */ + var Actor FollowingActor; + + /** Movement can be inaccurate. Useful when character ends up around < 2m away and it is not needed for it cover distance. */ + var bool bMovementCanBeInaccurate; + /** Don't stop at the end of path. Useful for charge attacks etc. when character is not expected to stop at the end of path. Doesn't apply for entering cover. */ + var bool bMoveThroughLastPoint; + /** Indicates whether movement needs to start/end with shooting animation. */ + var bool bStartPathFollowingShooting; + var bool bEndPathFollowingShooting; + /** makes sure AI will do any move even if destination is close enough */ + var bool bForceAnyMove; + var bool bAllowedToFire; + + structcpptext + { + FMoveParameters() + { + Reset(); + } + + void Reset() + { + appMemzero(this, sizeof(FMoveParameters)); + // copied from structdefaultproperties + MoveMood = BMM_Fast; + MoveType = BMT_Normal; + bStartPathFollowingShooting = TRUE; + bEndPathFollowingShooting = FALSE; + } + } + + structdefaultproperties + { +// BodyStance=NBS_Stand + MoveMood=BMM_Fast + MoveType=BMT_Normal + bStartPathFollowingShooting=true + } +}; + +enum EMoveRequestDestinationType +{ + MRDT_Invalid, + MRDT_Vector, + MRDT_Actor, +}; + +struct native MoveRequestDestination +{ + var vector VectorDest; + var Actor ActorDest; + var EMoveRequestDestinationType Type; + + structcpptext + { + FMoveRequestDestination() + { + appMemzero(this, sizeof(FMoveRequestDestination)); + } + + FMoveRequestDestination(const class FVector& vDestination) + { + VectorDest = vDestination; + Type = MRDT_Vector; + } + + FMoveRequestDestination(class AActor* Actor) : Type(MRDT_Invalid) + { + if(Actor != NULL) + { + ActorDest = Actor; + Type = MRDT_Actor; + } + } + + void Reset() + { + Type = MRDT_Invalid; + } + + void Set(const class FVector& vDestination) + { + VectorDest = vDestination; + Type = MRDT_Vector; + } + + void Set(class AActor* Actor) + { + if(Actor != NULL) + { + ActorDest = Actor; + Type = MRDT_Actor; + } + else + { + Type = MRDT_Invalid; + } + } + + //void Set(struct FCoverInfo& inCoverInfo) + //{ + // if(inCoverInfo.IsSet() == TRUE) + // { + // CoverInfoDest = inCoverInfo; + // Type = MRDT_Cover; + // } + // else + // { + // Type = MRDT_Invalid; + // } + //} + + UBOOL IsActor() const + { + return Type == MRDT_Actor; + } + + UBOOL IsVector() const + { + return Type == MRDT_Vector; + } + + //UBOOL IsCover() const + //{ + // return Type == MRDT_Cover; + //} + + class AActor* GetAsActor() + { + return Type == MRDT_Actor ? ActorDest : NULL; + } + + const class AActor* GetAsActor() const + { + return Type == MRDT_Actor ? ActorDest : NULL; + } + + //struct FCoverInfo GetAsCoverInfo() const + //{ + // return Type == MRDT_Cover ? CoverInfoDest : FCoverInfo(); + //} + + FVector GetPosition() const + { + switch(Type) + { + case MRDT_Vector: + return VectorDest; + break; + //case MRDT_Cover: + // return CoverInfoDest.Link ? CoverInfoDest.Link->GetSlotLocation(CoverInfoDest.SlotIdx) : FVector(0.f); + // break; + case MRDT_Actor: + return ActorDest ? ActorDest->Location : FVector(0.f); + break; + default: // MRDT_Invalid + break; + } + return FVector(0.0f); + } + } +}; + +struct native MovementRequest +{ + var native MoveParameters MoveParams; + var float AcceptableDistance; + var vector DestOffset; + var vector MidPointOffset; + /** a struct type with union inside representing move destination. It seems + * ok to have a native only access to it - script will only be able to modify means + * of execution, but not destination itself. + */ + var native MoveRequestDestination Destination; + var native NavigationPath PreComputedPath; + var EActionPriority Priority; + var const object Observer; + var bool bStickToNavmesh; + var bool bStickToActionArea; + var bool bDynamicDestOffset; // not used at the moment. Added for consistence + var bool bDynamicMidPoint; + var bool bPostProcessPath; + var int QueryID; + + structcpptext + { + FMovementRequest() + { + appMemzero(this, sizeof(FMovementRequest)); + Reset(); + } + + FMovementRequest(FMovementRequest* pOther) + { + if(pOther != NULL) + { + appMemCopy(*this, *pOther); + } + else + { + appMemzero(this, sizeof(FMovementRequest)); + Reset(); + } + } + + FString GetDescription() const; + + void Reset() + { + MoveParams.Reset(); + AcceptableDistance=0.0f; + Destination.Reset(); + PreComputedPath = NULL; + Priority = AP_Invalid; + bStickToNavmesh = TRUE; + bStickToActionArea = FALSE; + bPostProcessPath = FALSE; + Observer = NULL; + } + } +}; + +var MovementRequest MoveRequest; +var transient float GoalDistanceSq; + +var const public{protected} EActionPriority ActionPriority; + +var const public{private} EActionPriority MovementLock; + +var const transient bool bObserverNotified; +var const transient bool bDontNotifyObserver; +var transient bool bDontRestartByKismet; + +var float MinimumSuccessDistance; + +cpptext +{ + UBOOL IsMovementLocked(const EActionPriority Priority = AP_Logic) const // AP_Locic, i.e. AP_Invalid + 1. + { + return MovementLock >= Priority; + } + + EActionPriority GetMovementLock() const + { + return (EActionPriority)MovementLock; + } + + UBOOL CanAcceptNewMoveRequest(EActionPriority NewRequestPriority) const + { + return NewRequestPriority >= ActionPriority; + } + + FORCEINLINE EActionPriority GetActionPriority() const + { + return (EActionPriority)ActionPriority; + } + + FVector GetDestination(struct FMovementRequest& Request) const + { + return Request.Destination.GetPosition(); + } +} + +/** overrideable only in native code (no-exported as virtual) */ +native function bool MoveToRequest(out MovementRequest Request); +native function bool MoveToPointRequest(vector InDestLocation, EActionPriority CommandPriority, optional object ActionObserver, optional bool bStopAtEnd=true, optional bool bStickToNavmesh = true, optional float AcceptableDistance, optional Actor RotateAtEndToMatch); +native function bool MoveToActorRequest(Actor inPawnGoal, EActionPriority CommandPriority, optional object ActionObserver, optional bool bInAllowedToFire=true, optional float AcceptableDistance, optional vector DestOffset, optional vector MidPointOffset, optional bool bDynamicMidPoint, optional bool bStopAtEnd=true, optional bool bStickToNavmesh=true); +native function bool FollowPlugInsPath(NavigationPath InPath, EActionPriority CommandPriority, optional object ActionObserver, optional bool bStopAtEnd=true, optional Actor RotateAtEndToMatch, optional Float AcceptableDistance); + +native function bool AbortMove(bool bNewRequest); + +/** + * @param bNewRequest if set to false (default) then if there was a move + * task paused while lock was being set, then this task will be resumed. + * If true, it will not. This param makes sense only for bLock == true + */ +native function SetMovementLock(bool bLock, optional EActionPriority Priority = AP_Logic, optional bool bNewRequest); + +native function protected Success(); +native function protected Failure(); + +native function bool RePath(); + +/** Script interface to get location of destination point from given MovementRequest. + * no-exported to make inline. */ +final native noexport function vector GetDestination(out MovementRequest Request) const; + +final function EMoveRequestDestinationType GetDestinationType() +{ + return MoveRequest.Destination.Type; +} + +function StopMovement() +{ + //@todo fill it! +} + +/** Called from native code during latent movement when current move is considered unreachable */ +function bool MoveUnreachable( Vector AttemptedDest, Actor AttemptedTarget ) +{ + if( AttemptedTarget != none ) + { + `AILog( GetFuncName()$" AttemptedTarget: "$AttemptedTarget, 'PathWarning' ); + } + + return false; +} + +state Succeeding `DEBUGSTATE +{ +Begin: + `AILog("Moving - END:"@GetStateName(), 'Move'); + Success(); +} + +state Failing `DEBUGSTATE +{ +Begin: + `AILog("Moving - END:"@GetStateName(), 'Move'); + Failure(); +} + +/* this state does nothing. It's here to leave other states when move is aborted, + * and to indicate that it happened */ +state Aborting `DEBUGSTATE +{ +Begin: + `AILog("Moving - Aborted", 'Move'); + //AbortMove(false); + StopMovement(); +} + +/* this state does nothing. It's here to leave other states when move is aborted, +* and to indicate that it happened */ +state Idling `DEBUGSTATE +{ +Begin: + `AILog("Idling", 'Move'); + StopMovement(); +} + +defaultproperties +{ + // mz> this change is a little bit hacky and will need further changes. AnimSys accepts path success if destination to cover < 150.0f; + //MinimumSuccessDistance=8100.0f //90 units + MinimumSuccessDistance=160.0f //90 units +} diff --git a/BaseAI/Classes/AIPluginStuckFix.uc b/BaseAI/Classes/AIPluginStuckFix.uc new file mode 100644 index 0000000..29f6f86 --- /dev/null +++ b/BaseAI/Classes/AIPluginStuckFix.uc @@ -0,0 +1,190 @@ +//============================================================================= +// AIPluginStuckFix +//============================================================================= +// A proxy/parent class for all specific Stuck implementations +//============================================================================= +// Killing Floor 2 +// Copyright (C) 2015 Tripwire Interactive LLC +//============================================================================= +class AIPluginStuckFix extends AITickablePlugin within BaseAIController + native(Plugin) + dependson(NavigationPath, AIPluginMovement) + abstract; + +struct native FixStuckRequest +{ + var native MoveParameters MoveParams; + var float AcceptableDistance; + var vector DestOffset; + //var vector MidPointOffset; + /** a struct type with union inside representing move destination. It seems + * ok to have a native only access to it - script will only be able to modify means + * of execution, but not destination itself. + */ + var native MoveRequestDestination Destination; + //var native NavigationPath PreComputedPath; + var EActionPriority Priority; + var const object Observer; + var bool bFinalApproach; + var int QueryID; + + structcpptext + { + FFixStuckRequest() + { + appMemzero(this, sizeof(FFixStuckRequest)); + Reset(); + } + + FFixStuckRequest(FFixStuckRequest* pOther) + { + if(pOther != NULL) + { + appMemCopy(*this, *pOther); + } + else + { + appMemzero(this, sizeof(FFixStuckRequest)); + Reset(); + } + } + + FString GetDescription() const; + + void Reset() + { + MoveParams.Reset(); + AcceptableDistance=0.0f; + Destination.Reset(); + Priority = AP_Invalid; + bFinalApproach = FALSE; + Observer = NULL; + } + } +}; + + +var FixStuckRequest MoveRequest; +var const public{protected} EActionPriority ActionPriority; + +var const public{private} EActionPriority MovementLock; + +var const transient bool bObserverNotified; +var const transient bool bDontNotifyObserver; +var transient bool bDontRestartByKismet; + +cpptext +{ + UBOOL IsMovementLocked(const EActionPriority Priority = AP_Logic) const // AP_Locic, i.e. AP_Invalid + 1. + { + return MovementLock >= Priority; + } + + EActionPriority GetMovementLock() const + { + return (EActionPriority)MovementLock; + } + + UBOOL CanAcceptNewMoveRequest(EActionPriority NewRequestPriority) const + { + return NewRequestPriority >= ActionPriority; + } + + FORCEINLINE EActionPriority GetActionPriority() const + { + return (EActionPriority)ActionPriority; + } + + FVector GetDestination(struct FFixStuckRequest& Request) const + { + return Request.Destination.GetPosition(); + } +} + +/** overrideable only in native code (no-exported as virtual) */ +function bool StuckFixToPointRequest(vector InDestLocation, EActionPriority CommandPriority, optional object ActionObserver, optional bool bStopAtEnd=true, optional bool bStickToNavmesh = true, optional float AcceptableDistance, optional Actor RotateAtEndToMatch); +function bool StuckFixToActorRequest(Actor inPawnGoal, EActionPriority CommandPriority, optional object ActionObserver, optional bool bInAllowedToFire=true, optional float AcceptableDistance, optional vector DestOffset, optional vector MidPointOffset, optional bool bDynamicMidPoint, optional bool bStopAtEnd=true, optional bool bStickToNavmesh=true); + +event bool AbortMove(bool bNewRequest); + +/** + * @param bNewRequest if set to false (default) then if there was a move + * task paused while lock was being set, then this task will be resumed. + * If true, it will not. This param makes sense only for bLock == true + */ +function SetMovementLock(bool bLock, optional EActionPriority Priority = AP_Logic, optional bool bNewRequest); + +function protected Success(); +function protected Failure(); + + +/** Script interface to get location of destination point from given MovementRequest. + * no-exported to make inline. */ +final native noexport function vector GetDestination(out MovementRequest Request) const; + +final function EMoveRequestDestinationType GetDestinationType() +{ + return MoveRequest.Destination.Type; +} + +function StopMovement() +{ + //@todo fill it! +} + +/** Called from native code during latent movement when current move is considered unreachable */ +function bool MoveUnreachable( Vector AttemptedDest, Actor AttemptedTarget ) +{ + if( AttemptedTarget != none ) + { + `AILog( GetFuncName()$" AttemptedTarget: "$AttemptedTarget, 'PathWarning' ); + } + + return false; +} + +state Succeeding `DEBUGSTATE +{ +Begin: + `AILog("Moving - END:"@GetStateName(), 'Move'); + Success(); + + GotoState( 'Idling' ); +} + +state Failing `DEBUGSTATE +{ +Begin: + `AILog("Moving - END:"@GetStateName(), 'Move'); + Failure(); + + GotoState( 'Idling' ); +} + +/* this state does nothing. It's here to leave other states when move is aborted, + * and to indicate that it happened */ +state Aborting `DEBUGSTATE +{ +Begin: + `AILog("Moving - Aborted", 'Move'); + //AbortMove(false); + StopMovement(); + + GotoState( 'Idling' ); +} + +/* this state does nothing. It's here to leave other states when move is aborted, +* and to indicate that it happened */ +state Idling `DEBUGSTATE +{ +Begin: + `AILog("Idling", 'Move'); + StopMovement(); +} + +defaultproperties +{ + // mz> this change is a little bit hacky and will need further changes. AnimSys accepts path success if destination to cover < 150.0f; + //MinimumSuccessDistance=8100.0f //90 units + //MinimumSuccessDistance=160.0f //90 units +} diff --git a/BaseAI/Classes/AITickablePlugin.uc b/BaseAI/Classes/AITickablePlugin.uc new file mode 100644 index 0000000..1ac30a8 --- /dev/null +++ b/BaseAI/Classes/AITickablePlugin.uc @@ -0,0 +1,57 @@ +//============================================================================= +// AITickablePlugin +//============================================================================= +// this plugin type introduces tickable states functionality to deriving plugins +// +// NOTE: currently every plugin used is ticked directly by owner (only movement plugins +// implemented so far). If more plugins are created and need to be ticked a simple // +// registration mechanism should be implemented to store all plugins to be ticked in +// some array in owning BaseAIController (much like BaseAISubsystem.SmartObjects for example) +//============================================================================= +// Killing Floor 2 +// Copyright (C) 2015 Tripwire Interactive LLC +//============================================================================= +class AITickablePlugin extends AIPlugin within BaseAIController + native(Plugin) + abstract; + +var const float LatentTime; // Internal latent function use. +var const private{private} bool bTickingEnabled; + +cpptext +{ + void TickPlugin(FLOAT DeltaTime); + virtual void ProcessState(FLOAT DeltaSeconds); + virtual EGotoState GotoState( FName State, UBOOL bForceEvents = 0, UBOOL bKeepStack = 0 ); + + void SetEnableTicking(UBOOL bEnable) + { + bTickingEnabled = bEnable; + } + + UBOOL IsTickingEnabled() const + { + return bTickingEnabled; + } +} + +final native latent function Sleep(float Seconds); + +event ScriptTick( float DeltaTime ) +{ +} + +function bool NotifyNpcTerminallyStuck() +{ + return false; +} + +function bool NotifyNpcInGrannyMode() +{ + return false; +} + +defaultproperties +{ + bTickingEnabled=true +} \ No newline at end of file diff --git a/BaseAI/Classes/BaseAIController.uc b/BaseAI/Classes/BaseAIController.uc new file mode 100644 index 0000000..1d85594 --- /dev/null +++ b/BaseAI/Classes/BaseAIController.uc @@ -0,0 +1,318 @@ +//============================================================================= +// BaseAIController +//============================================================================= +// +//============================================================================= +// Killing Floor 2 +// Copyright (C) 2015 Tripwire Interactive LLC +//============================================================================= +class BaseAIController extends GameAIController + dependson(BaseAIPawn, PluginBase, AIPluginMovement) + implements(PlugInOwnerInterface) + native + config(AI); + +var transient BaseAIPawn MyBaseAIPawn; +var transient BaseAISquad BaseSquad; + +// ----------------------------------------------------------------------- // +// animation related vars +// ----------------------------------------------------------------------- // + +// ----------------------------------------------------------------------- // +// Plugins +// ----------------------------------------------------------------------- // +var const public{protected} array TickablePlugins; + +var instanced PluginSquad SquadPlugin; + +var instanced AIPluginMovement MovementPlugin; +var class MovementPluginClass; + +var instanced AIPluginLeap LeapPlugin; +var class LeapPluginClass; + +var instanced AIPluginStuckFix StuckFixPlugin; +var class StuckFixPluginClass; + +// base off KFAICommandHistory +var transient BaseAiPlugInHistory MyAiPlugInHistory; + +// ----------------------------------------------------------------------- // +// Movement +// ----------------------------------------------------------------------- // + +// ----------------------------------------------------------------------- // +// perception +// ----------------------------------------------------------------------- // +var bool bUsePerceptionHearing; +var bool bAlwaysAssignEnemy; + +/** When last time our enemy was visible */ +var float LastEnemySightedTime; + +// ----------------------------------------------------------------------- // +// firing +// ----------------------------------------------------------------------- // + +// ----------------------------------------------------------------------- // +// Target selection/limitation +// ----------------------------------------------------------------------- // +/** List of targets to shoot at */ +var array TargetList; +/** List of prohibited targets */ +var array ProhibitedTargetList; + +var transient BaseAIPawn SquadAssignedTarget; + +struct native LocalEnemyInfo +{ + var array PerceptionTimestamp; + var EWSPerceptionMode LatestPerception; + var EWSPerceptionMode DominantPerception; + var int VisibleCoverActions; + + var float CurrentThreat; + var vector LatestLocation; //latest location with Seen perception + var Pawn Pawn; + + var bool bSeenBefore; + var bool bIsPlayer; + + structcpptext + { + /** Constructors */ + FLocalEnemyInfo() {} + FLocalEnemyInfo(EEventParm) + { + + } + FLocalEnemyInfo(APawn* InPawn) + { + appMemzero(this, sizeof(FLocalEnemyInfo)); + Pawn = InPawn; + } + + FORCEINLINE UBOOL CanBeSeenWithAction(BYTE Action) const + { + return (VisibleCoverActions & (1 << Action)) != 0; + } + + UBOOL operator==(const FLocalEnemyInfo& InEnemyInfo) const + { + return Pawn == InEnemyInfo.Pawn; + } + + UBOOL operator==(const APawn* EnemyPawn) const + { + return Pawn == EnemyPawn; + } + } +}; +var array LocalEnemyList; + +// ----------------------------------------------------------------------- // +// Attachments and SpecialActionSttachments +// ----------------------------------------------------------------------- // + +// ----------------------------------------------------------------------- // +// Enable/Disable Navmesh and plugins +// ----------------------------------------------------------------------- // + +/** If this is on, NPC will always try to use Nav Mesh Path Finding Before Path Node */ +var bool bUseNavMesh; +/** If this is on, NPC will always try to use plugins for movement. Only works with navmesh */ +var bool bUsePluginsForMovement; + +// ----------------------------------------------------------------------- // +// debug variables +// ----------------------------------------------------------------------- // + +var(Debug) config int PlugInHistoryNum; + +cpptext +{ + virtual void Initialize(); + void OnLevelStreamedOut(ULevel* Level); + virtual UBOOL Tick(FLOAT DeltaTime, enum ELevelTick TickType); + + virtual void PreBeginPlay(); + virtual void BeginDestroy(); + virtual void GetSquadEnemies(TArray& Items, UBOOL bExcludeProhibitedTargets = FALSE, UBOOL bExcludeBeliefInfo = FALSE); + + virtual UBOOL IsFriendly(const class AController* const TestPlayer) const; + + // ----------------------------------------------------------------------- // + // Movement + // ----------------------------------------------------------------------- // + + // ----------------------------------------------------------------------- // + // perception + // ----------------------------------------------------------------------- // + void UpdateEnemyKnowledge(INT EnemyIdx, BYTE Perception); + +#if !DO_BASEAI_LOGGING +# if COMPILER_SUPPORTS_NOOP +# define BaseAILog __noop +# else +# define BaseAILog GNull->Logf +# endif + static class FOutputDeviceRedirectorBase* GLog; +#else + VARARG_DECL(void,void,{},BaseAILog,VARARG_NONE,const TCHAR*,VARARG_NONE,VARARG_NONE); + VARARG_DECL(void,void,{},BaseAILog,VARARG_NONE,const TCHAR*,VARARG_EXTRA(enum EName E),VARARG_EXTRA(E)); +#endif + + // AI debug stuff: + virtual void GetGameSpecificDebug(BYTE element, TArrayNoInit& outLogLines, TArray* Lines = NULL) const; + + static TArray InitializedAIClasses; +} + +/** Called ONCe per class for class specific initialization (e.g. ETQ queries) + */ +event InitializeAIClass() +{ +} + +event Possess(Pawn inPawn, bool bVehicleTransition) +{ + super.Possess(inPawn, bVehicleTransition); + + if (inPawn != none) + { + MyBaseAIPawn = BaseAIPawn(inPawn); +`if(`notdefined(__TW_BASEAI_LEAN_)) + InitializeDefaultBehavior(); + + // setup movement properties + SetupPathfinding(); +`endif + } +} + +function PawnDied(Pawn InPawn) +{ + CleanUp(); + super.PawnDied(InPawn); +} + +/** This function needs to stay final */ +native final function float UpdateEnemyRange(); +native final function EWSSymbolicAngle UpdateEnemyAngle(); + +native function CleanUp(optional bool bBeingDestroyed); + +// ----------------------------------------------------------------------- // +// PlugInOwner interface plimentation +// ----------------------------------------------------------------------- // + +function BaseAiPlugInHistory GetAiPlugInHistory() +{ + return MyAiPlugInHistory; +} + +function float GetTimeSince( float Time2Test ) +{ + return `TimeSince(Time2Test); +} + +// ----------------------------------------------------------------------- // +// Squad mechanics +// ----------------------------------------------------------------------- // + +native function int BroadcastEnemyKnowledge(Pawn EnemyPawn, EWSPerceptionMode Perception); +native function RemoveEnemy(Pawn EnemyPawn); +native function RemoveAllEnemies(); +native final function bool IsFriendlyPawn(Pawn TestPlayer) const; +native noexport function bool IsFriendly(Controller TestPlayer) const; + +// ----------------------------------------------------------------------- // +// Animation related +// ----------------------------------------------------------------------- // + +// ----------------------------------------------------------------------- // +// perception +// ----------------------------------------------------------------------- // +native final function UpdateEnemyPerception(optional bool bSkipResponseDelay); + +/** Selects a target from the TargetList or selects an enemy normally */ +native function bool SelectTargetInternal(bool bOnlyFromTargetList); +native event bool SetEnemy(Pawn NewEnemy); +native function bool SelectEnemy(); +native function bool SelectTarget(); + +// @todo this will be handled by squads +//function NotifyKilled(Controller Killer, Controller Killed, Pawn KilledPawn) +function NotifyKilled(Controller Killer, Controller Killed, pawn KilledPawn, class damageTyp) +{ + // remove focus from killed enemy + if (KilledPawn == Focus) + { + Focus = None; + } + + // Controller's implementation mess with Enemy, so work on this before calling parent + RemoveEnemy(KilledPawn); + + super.NotifyKilled(Killer, Killed, KilledPawn, damageTyp); +} + +// ----------------------------------------------------------------------- // +// logic flow control +// ----------------------------------------------------------------------- // + +// ----------------------------------------------------------------------- // +// Navigation +// ----------------------------------------------------------------------- // + +// ----------------------------------------------------------------------- // +// Movement +// ----------------------------------------------------------------------- // + +function StopMovement(optional EActionPriority ActionPriority = AP_Logic) +{ + if(MovementPlugin != None) + { + MovementPlugin.AbortMove(FALSE); + } + + if( LeapPlugin != none ) + { + LeapPlugin.AbortMove(FALSE); + } + + if( StuckFixPlugin != none ) + { + StuckFixPlugin.AbortMove(false); + } +} + +// ----------------------------------------------------------------------- // +// Attachments and SpecialActionSttachments +// ----------------------------------------------------------------------- // + +// ----------------------------------------------------------------------- // +// Level progress +// ----------------------------------------------------------------------- // + +// ----------------------------------------------------------------------- // +// Debug functions +// ----------------------------------------------------------------------- // +native function DrawEnemyPerception(Canvas DrawCanvas); + +function DrawDebugTextToHud( HUD HUD, String Text, optional color TextColor ); + +defaultproperties +{ + bAlwaysAssignEnemy=true + bUsePerceptionHearing=false + + // this one is a legacy thing - this needs to be true even for AI actors + // because only then PlayerReplicationInfo will be created - teams for example need that + // @todo - really needs to be refactored, but can be soooo tricky + //bIsPlayer=TRUE + + MovementPlugin=None + //MovementPluginClass="AIPluginMovement_Recast" +} diff --git a/BaseAI/Classes/BaseAIPawn.uc b/BaseAI/Classes/BaseAIPawn.uc new file mode 100644 index 0000000..ff2dca1 --- /dev/null +++ b/BaseAI/Classes/BaseAIPawn.uc @@ -0,0 +1,229 @@ +//============================================================================= +// BaseAIPawn +//============================================================================= +// +//============================================================================= +// Killing Floor 2 +// Copyright (C) 2015 Tripwire Interactive LLC +//============================================================================= +class BaseAIPawn extends GamePawn + dependson(BaseAITypes) + config(Game) + native + abstract + notplaceable + nativereplication; + +var transient BaseAIController MyBaseAI; + +/** remembers the team we were on pre-death as our PlayerReplicationInfo will be disconnected + * mz> reused as simple team number cache, moved from KFPawn.uc + */ +var byte LastTeamNum; + +// ----------------------------------------------------------------------- // +// Breadcrumbs +// ----------------------------------------------------------------------- // + +// mz> chaning this remember to change 'kBreadCrumbsMax' in BreadCrumbs struct (below) +const kBreadCrumbsMax = 10; + +struct native Breadcrumbs +{ + var transient vector Crumbs[kBreadCrumbsMax]; + var transient byte CurrentCrumb; + var float CrumbDistanceSq; + + structcpptext + { + // added this way since script consts were unsuable in this case + enum + { + kBreadCrumbsMax = 10 + }; + + FBreadcrumbs() + { + appMemzero(this, sizeof(FBreadcrumbs)); + } + + FBreadcrumbs(EEventParm) + { + appMemzero(this, sizeof(FBreadcrumbs)); + } + + void Init(const FVector& Location, FLOAT inCrumbDistanceSq=10000.f) + { + for(INT i = 0; i < kBreadCrumbsMax; ++i) + { + Crumbs[i] = Location; + } + + CrumbDistanceSq = inCrumbDistanceSq; + } + + void UpdateCrumbs(const FVector& Location) + { + if(Crumbs[CurrentCrumb].DistanceSquared(Location) >= CrumbDistanceSq) + { + const BYTE newCrumb = (CurrentCrumb + 1) % kBreadCrumbsMax; + Crumbs[newCrumb] = Location; + CurrentCrumb = newCrumb; + } + } + + FORCEINLINE FVector GetOldestCrumb() const + { + return Crumbs[(CurrentCrumb + 1) % kBreadCrumbsMax]; + } + + FVector GetNthCrumb(INT N) const + { + return N >= kBreadCrumbsMax ? GetOldestCrumb() : Crumbs[(CurrentCrumb + kBreadCrumbsMax - N) % kBreadCrumbsMax]; + } + } + + structdefaultproperties + { + CrumbDistanceSq=10000.f + } +}; + +var transient BreadCrumbs MyBreadCrumbs; + +// ----------------------------------------------------------------------- // +// Target selection/limitation +// ----------------------------------------------------------------------- // + +/** Cached value for damage config: AI type */ +var transient /*const*/ byte MyAIType; + +/** Array of all pawns attacking this controller.*/ +var const array Attackers; +var const array AttackersPerTypeCount; + +// ----------------------------------------------------------------------- // +// Animation related +// ----------------------------------------------------------------------- // + +// ----------------------------------------------------------------------- // +// members moved from GearPawn +// ----------------------------------------------------------------------- // + +// ----------------------------------------------------------------------- // +// Plugins +// ----------------------------------------------------------------------- // + +var transient bool bLeaping; +var transient float TimeStartedLeap; +var transient float TimeImmuneWhileLeaping; + +cpptext +{ + virtual void PostBeginPlay(); + virtual void PostScriptDestroyed(); + virtual UBOOL Tick(FLOAT DeltaTime, enum ELevelTick TickType); + + void AddAttacker(class ABaseAIPawn* Attacker); +}; + +// ----------------------------------------------------------------------- // +// Properties interface +// ----------------------------------------------------------------------- // + +// ----------------------------------------------------------------------- // +// Weapon handling +// ----------------------------------------------------------------------- // + +// ----------------------------------------------------------------------- // +// Pawn overrides +// ----------------------------------------------------------------------- // + +function bool Died(Controller Killer, class DamageType, vector HitLocation) +{ +`if(`notdefined(__TW_BASEAI_LEAN_)) + AbortSOUsage(); +`endif + + class'BaseAISubsystem'.static.DecreaseTeamSize(GetTeamNum()); + if(MyBaseAI != None && MyBaseAI.Enemy != None) + { + BaseAIPawn(MyBaseAI.Enemy).RemoveAttacker(self); + } + + return Super.Died(Killer,damageType,HitLocation); +} + +function PossessedBy(Controller C, bool bVehicleTransition) +{ + Super.PossessedBy(C, bVehicleTransition); + MyBaseAI = BaseAIController(C); + + // BaseAIPawn subclasses actually do get possessed by players! + if ( MyBaseAI != None ) + { + LastTeamNum = MyBaseAI.GetTeamNum(); + } +} + +function UnPossessed() +{ + MyBaseAI = None; + + super.UnPossessed(); +`if(`notdefined(__TW_BASEAI_LEAN_)) + if (AnimationProxy != None) + { + AnimationProxy.UnPossessed(); + } +`endif +} + +simulated function NotifyTeamChanged() +{ + Super.NotifyTeamChanged(); + + LastTeamNum = GetTeamNum(); +} + +// ----------------------------------------------------------------------- // +// Readabilities (Chatter too) +// ----------------------------------------------------------------------- // + +// ----------------------------------------------------------------------- // +// Target selection/limitation +// ----------------------------------------------------------------------- // +/** +* @param AIType specifies what type of attackers is of interest, -1 means all +* @return number of Pawns of given type (or all if AIType == -1) attacking this controller +*/ +native final function int GetAttackerCount(optional int AIType = -1) const; + +native final function RemoveAttacker(BaseAIPawn Attacker); + +// ----------------------------------------------------------------------- // +// level progress stuff +// ----------------------------------------------------------------------- // + +// ----------------------------------------------------------------------- // +// movement +// ----------------------------------------------------------------------- // + +// ----------------------------------------------------------------------- // +// debug +// ----------------------------------------------------------------------- // +final native function DrawCrumbs(HUD HUD) const; + +defaultproperties +{ +`if(`notdefined(__TW_BASEAI_LEAN_)) + AISelectionModifier=1.0 + AimAccuracy=Accuracy_Normal + bUseAnimationProxy=true + MovementProps=(bStartMovementShooting=true, bStartMovementShootingOnRepath=false, bEndMovementShooting=true, bCanCombatWalk=true) + bHasAISelectionModifierPerTeam=false +`endif + + bCanBeAdheredTo=TRUE + bCanBeFrictionedTo=TRUE +} diff --git a/BaseAI/Classes/BaseAISquad.uc b/BaseAI/Classes/BaseAISquad.uc new file mode 100644 index 0000000..9ad19ec --- /dev/null +++ b/BaseAI/Classes/BaseAISquad.uc @@ -0,0 +1,79 @@ +//============================================================================= +// AnimationProxy +//============================================================================= +// +//============================================================================= +// Killing Floor 2 +// Copyright (C) 2015 Tripwire Interactive LLC +//============================================================================= + +class BaseAISquad extends Info + native; + +/** Controller for leader of the squad */ +var() editconst Controller Leader; +var() editconst Actor FormationCenter; + +/** whether this squad has a human controlled player in it */ +var bool bPlayerSquad; + +var bool bIsMP; + +var transient bool bSquadInCombat; + +var transient float NextEnemySelectionTimestamp; +/** Call UpdateEnemySelection every X seconds*/ +var float EnemySelectionInterval; + +cpptext +{ + virtual void TickSpecial(FLOAT DeltaSeconds); +} + +/** Called immediately after gameplay begins. */ +event PostBeginPlay() +{ + super.PostBeginPlay(); + + class'BaseAISubsystem'.static.RegisterSquad(self); + + bIsMP = WorldInfo.GRI.IsMultiplayerGame(); +} + +event Destroyed() +{ + class'BaseAISubsystem'.static.UnRegisterSquad(self); + + super.Destroyed(); +} + +/** + * Called by BaseAISubsystem to update enemy info + * @return true if given pawn was on squad's enemy list, false otherwise + */ +native function bool NotifyKilled(Controller Killer, Controller Killed, Pawn KilledPawn, class damageType); + +/** +* Called by PluginSquad +*/ +final native function EnemyPerceivedBy(Controller Member, EWSPerceptionMode PerceptionType, Pawn Enemy); + +native function UpdateLeader(Controller inLeader); + +native function int GetSquadMemberCount() const; +native function bool GetSquadMembers(out array Members); +/** Returns FormationCenter when not in combat, and Leader pawn if in combat. + * @note could add a flag toggling this behavior. No need for it at the moment + */ +native final function BaseAIPawn GetSquadCenterPawn(); + +/** picks target/enemy for all squad members with BaseAIController.bSquadBasedEnemySelection == true + * @return TRUE if any work has been done, and there is a point in re-calling this in some time + */ +native function bool UpdateEnemySelection(); + +defaultproperties +{ + EnemySelectionInterval=0.4f + bIsMP=false +} \ No newline at end of file diff --git a/BaseAI/Classes/BaseAISubsystem.uc b/BaseAI/Classes/BaseAISubsystem.uc new file mode 100644 index 0000000..ac1794b --- /dev/null +++ b/BaseAI/Classes/BaseAISubsystem.uc @@ -0,0 +1,114 @@ +//============================================================================= +// AnimationProxy +//============================================================================= +// +//============================================================================= +// Killing Floor 2 +// Copyright (C) 2015 Tripwire Interactive LLC +//============================================================================= + +class BaseAISubsystem extends AISubsystem + config(Engine) + native + inherits(FCallbackEventDevice,FTickableObject); + +var AIDebugTool AIDebug; + +var const array Squads; + +var const array TeamSizes; + +// ----------------------------------------------------------------------- // +// @deprecated with __TW_BASEAI_LEAN_ +// ----------------------------------------------------------------------- // +`if(`notdefined(__TW_BASEAI_LEAN_)) +var ETQSystem ETQSys; +var BTManager BTMgr; +var MessageSystem MsgSys; +var NavigationSystem NavSys; +var DigitalActingManager DAM; +var SightSystem SightSys; + +var const SmartObjectReplicationActor SmartObjectReplication; +var const array SmartObjects; +var const array InitPendingSmartObjects; +var const array SpawnedCovers; +var const array AvoidanceComponents; + +native static final noexport function ETQSystem GetETQSystem(); +native static final noexport function BTManager GetBTManager(); +native static final noexport function MessageSystem GetMessageSystem(); +native static final noexport function NavigationSystem GetNavigationSystem(); +native static final noexport function DigitalActingManager GetDAM(); +native static final noexport function SightSystem GetSightSystem(); + +native static final noexport function RegisterSmartObject(SOHubComponent SO); +native static final noexport function UnRegisterSmartObject(SOHubComponent SO); + +native static final noexport function RegisterSpawnedCover(CoverLink Cover); +native static final noexport function UnRegisterSpawnedCover(CoverLink Cover); + +native static final noexport function RegisterAvoidanceComponent(AIAvoidanceComponent AvoidanceComponent); +native static final noexport function UnRegisterAvoidanceComponent(AIAvoidanceComponent AvoidanceComponent); +`endif + +// ----------------------------------------------------------------------- // +// END __TW_BASEAI_LEAN_ +// ----------------------------------------------------------------------- // + +native static final noexport function BaseAISubsystem GetInstance(); +native static final noexport function AIDebugTool GetAIDebugTool(); + +native static final noexport function RegisterSquad(BaseAISquad Squad); +native static final noexport function UnRegisterSquad(BaseAISquad Squad); + +native static final noexport function IncreaseTeamSize(BYTE TeamId); +native static final noexport function DecreaseTeamSize(BYTE TeamId); +native static final noexport function int GetTeamSize(byte TeamId); +native static final noexport function int GetEnemyTeamsSize(byte TeamId); + +//NotifyKilled(Controller Killer, Controller Killed, pawn KilledPawn, class damageType) +native static final function NotifyKilled(Controller Killer, Controller KilledController, Pawn KilledPawn, class damageType); + +cpptext +{ + virtual void Init(UBOOL bEngineStart = FALSE); + virtual void Tick(FLOAT DeltaSeconds); + virtual void CleanUp(UBOOL bShutDown = FALSE); + virtual void PrepareMapChange(); + virtual void OnLevelStreamedOut(ULevel* Level); + + static UAIDebugTool* GetAIDebugTool(void); + + static void RegisterSquad(class ABaseAISquad* Squad); + static void UnRegisterSquad(class ABaseAISquad* Squad); + static TArray* GetSquads(); + + static void ObjectDestroyed(UObject* Object); + + static void IncreaseTeamSize(BYTE TeamId); + static void DecreaseTeamSize(BYTE TeamId); + + static void OnPawnDestroyed(class ABaseAIPawn* Pawn); + void OnCheckPointLoad(); + +private: + void DecreaseTeamSizeInternal(BYTE TeamId); +public: + static int GetTeamSize(BYTE TeamId); + static int GetEnemyTeamsSize(BYTE TeamId, BYTE TeamIdLimit = 255); + + //-- editor related methods --// + void OnPIEEnd(); + void OnPIEMapSwitch(); + + virtual void Send(ECallbackEventType InType); + virtual void Send(ECallbackEventType InType, DWORD Flags); + + virtual UBOOL IsTickable() const { return TRUE; } +}; + +defaultproperties +{ + bImplementsNavMeshGeneration=true +} diff --git a/BaseAI/Classes/BaseAITypes.uc b/BaseAI/Classes/BaseAITypes.uc new file mode 100644 index 0000000..3c7f245 --- /dev/null +++ b/BaseAI/Classes/BaseAITypes.uc @@ -0,0 +1,105 @@ +//============================================================================= +// BaseAITypes +//============================================================================= +// +//============================================================================= +// Killing Floor 2 +// Copyright (C) 2015 Tripwire Interactive LLC +//============================================================================= +class BaseAITypes extends Object + native(Types) + abstract + config(AI); + +enum EActionPriority +{ + AP_Invalid, + AP_Logic, + AP_Kismet, // default GoW priority, not only for kismet + AP_Reaction, +}; + +enum EBaseMoveMood +{ + BMM_Invalid, + BMM_Static, + BMM_Slow, + BMM_Normal, + BMM_Fast, +}; + +enum EBaseMoveType +{ + BMT_Invalid, + BMT_Normal, + BMT_Combat, + BMT_Careful, + BMT_Pain, +}; + +enum EWSPerceptionMode +{ + WSPM_None, + WSPM_Memory, + WSPM_Belief, + WSPM_Hearing, + WSPM_Sight, +}; + +enum EWSSymbolicAngle +{ + WSSA_Front, + WSSA_Side, + WSSA_Back, + WSSA_Unknown, +}; + +enum EBTResult +{ + BTR_Error, + BTR_Abort, + BTR_Fail, + BTR_Success, + BTR_NotFinished, +}; + +// ----------------------------------------------------------------------- // +// Debug types +// ----------------------------------------------------------------------- // +enum EDebugLineType +{ + DLT_Generic, + DLT_InstantFire, + DLT_NoPath, + DLT_LeaderFollowing, + DLT_Failed, + DLT_Red, + DLT_Green, + DLT_Blue, +}; + +struct native SpaceLineInfo +{ + var vector Start; + var vector End; + var EDebugLineType Type; + var init string Comment; + var native Name Category; + + structcpptext + { + /** Constructors */ + FSpaceLineInfo() {} + FSpaceLineInfo(EEventParm) + { + appMemzero(this, sizeof(FSpaceLineInfo)); + } + FSpaceLineInfo(FVector inStart,FVector inEnd,BYTE inType, const FString& inComment,FName inCategory=NAME_None) + : Start(inStart), End(inEnd), Type(inType), Comment(inComment), Category(inCategory) + {} + } +}; + +defaultproperties +{ +} diff --git a/BaseAI/Classes/BaseAiPlugInHistory.uc b/BaseAI/Classes/BaseAiPlugInHistory.uc new file mode 100644 index 0000000..670c06a --- /dev/null +++ b/BaseAI/Classes/BaseAiPlugInHistory.uc @@ -0,0 +1,111 @@ +//============================================================================= +// BaseAiPlugInHistory +//============================================================================= +// +//============================================================================= +// Killing Floor 2 +// Copyright (C) 2015 Tripwire Interactive LLC +//============================================================================= +class BaseAiPlugInHistory extends Object + native(Plugin) + dependson(PluginBase); + + +struct native BaseAIPlugInHistoryItem +{ + var class PlugInClass; + var string PlugInName; + var float TimeStamp; // World time command was started + var float Duration; // Total time spent in the command + var bool bAborted; // Command was aborted (which is often fine and intentional depending on the context) (TODO:Change to bytes) + var bool bFailure; // Command failed (this is also not necessarily bad, at times it's expected) + var bool bSuccess; // Command succeeded + var string VerboseString; // Optional extra info that can be added + +}; + +var transient array PlugInHistory; +var int PlugInHistoryNum; + +var BaseAIController CtrlOwner; + +cpptext +{ + virtual void StorePlugInHistory( UPluginBase* ThePlugIn ); +} + +event Setup( int InPlugInHistoryNum, BaseAIController InCtrlOwner ) +{ + PlugInHistoryNum = InPlugInHistoryNum; + CtrlOwner = InCtrlOwner; +} + +simulated function DrawDebugToHud( HUD HUD, name Category ) +{ + //local KFHUDBase kfHUD; + local int plugInCnt; + local Canvas canToUse; + //local BaseAICommand Cmd; + local BaseAIPlugInHistoryItem plugInItem; + //local bool bDrawDebugCommandStack, bDrawDebugCommandHistory; + //local bool bDrawDebugAllPlugins, bDrawDebugPlugInHistory; + //local string AddTxt, NullTxt; + //local AICommand AC; + + //kfHUD = KFHUDBase(kfHud); + ////local float Aggression; + //bDrawDebugCommandStack = false; + //bDrawDebugCommandHistory = false; + +// if( Category == 'Default' || Category == 'All' || Category == 'OverheadNames' ) +// { +// bDrawDebugCommandStack = false; +// bDrawDebugCommandHistory = false; +// Icon = Texture2D'ENG_EditorResources_TEX.AI.S_AI'; +// DrawIconOverhead(HUD, Icon); +// return; +// } +// if( bDebug_ShowViewCone ) +// { +// if( MyKFPawn != None ) +// { +// tmp = MyKFPawn.GetPawnViewLocation(); +// rot = MyKFPawn.GetBaseAimRotation(); +// } +// DrawDebugCone(tmp ,vector( rot),Pawn .SightRadius, Acos(Pawn .PeripheralVision), Acos(Pawn .PeripheralVision),16,MakeColor(255,0,0,255)); +// } + + //return; +// NullTxt = "None"; + // Draw list of commands down the side of the screen + if( /*Pawn != None && Category == 'All'*/ true ) + { + canToUse = HUD.Canvas; + canToUse.SetOrigin(0,0); + canToUse.Font = class'Engine'.Static.GetSmallFont(); + canToUse.SetPos(canToUse.SizeX * 0.05f, canToUse.SizeY * 0.25f); + + // WRITE OUT COMMAND HISTORY + // C.SetDrawColor(255, 255, 255, 255); + CtrlOwner.DrawDebugTextToHud( HUD, "************************************************************" ); + //C.SetDrawColor(0, 0, 255, 255); + CtrlOwner.DrawDebugTextToHud( HUD, "PLUG IN HISTORY (Count:"@PlugInHistoryNum$")" ); + plugInCnt = 0; + foreach PlugInHistory( plugInItem ) + { + plugInCnt++; + // C.SetDrawColor(255, 0, 0, 255); + CtrlOwner.DrawDebugTextToHud( HUD, "PlugIn"@plugInCnt$":"@String(plugInItem.PlugInClass)@"Time:"@plugInItem.TimeStamp); + if( Len(plugInItem.VerboseString) > 0 ) + { + // C.SetDrawColor(255, 64, 64, 255); + CtrlOwner.DrawDebugTextToHud( HUD, ".............."@plugInItem.VerboseString ); + } + } + } +} + +defaultproperties +{ + PlugInHistoryNum=25 +} diff --git a/BaseAI/Classes/CodeSpeedTestCommandlet.uc b/BaseAI/Classes/CodeSpeedTestCommandlet.uc new file mode 100644 index 0000000..1621196 --- /dev/null +++ b/BaseAI/Classes/CodeSpeedTestCommandlet.uc @@ -0,0 +1,25 @@ +//============================================================================= +// AnimationProxy +//============================================================================= +// +//============================================================================= +// Killing Floor 2 +// Copyright (C) 2015 Tripwire Interactive LLC +//============================================================================= + +class CodeSpeedTestCommandlet extends Commandlet + native; + +var transient object CurrentPackage; + +cpptext +{ + /** + * Commandlet entry point + * + * @param Params the command line parameters that were passed in. + * + * @return 0 if the commandlet succeeded; otherwise, an error code defined by the commandlet. + */ + virtual INT Main(const FString& Params); +}; diff --git a/BaseAI/Classes/LatentActionObserver.uc b/BaseAI/Classes/LatentActionObserver.uc new file mode 100644 index 0000000..a85bea0 --- /dev/null +++ b/BaseAI/Classes/LatentActionObserver.uc @@ -0,0 +1,13 @@ +//============================================================================= +// AnimationProxy +//============================================================================= +// +//============================================================================= +// Killing Floor 2 +// Copyright (C) 2015 Tripwire Interactive LLC +//============================================================================= + +interface LatentActionObserver + native; + +native function OnLatentFinished(BaseAIController Observer, Object Action, byte FinishResult); diff --git a/BaseAI/Classes/NavigationPath.uc b/BaseAI/Classes/NavigationPath.uc new file mode 100644 index 0000000..a95f8c1 --- /dev/null +++ b/BaseAI/Classes/NavigationPath.uc @@ -0,0 +1,64 @@ +//============================================================================= +// NavigationPath +//============================================================================= +// deprecated stub class on 6/29/2015 (script only) +//============================================================================= +// Killing Floor 2 +// Copyright (C) 2015 Tripwire Interactive LLC +//============================================================================= +class NavigationPath extends Object; + +struct BaseTransform +{ + var const private{private} Actor Base; + var const private{private} Vector InitialLocation; + var const private{private} Rotator InitialRotation; + // used in lazy update + var const private{private} Vector UpdatedForLocation; + var const private{private} Rotator UpdatedForRotation; + // to take from initial pos into base pos + var const private{private} Matrix InitialReversedTransform; + // whole transform from initial pos (as in array) into world pos + var const private{private} Matrix IBS2WSTransform; + // reverse + var const private{private} Matrix WS2IBSTransform; +}; + +struct PathPoint +{ + var Vector Location; + var byte Flags; +}; + +// -- not to be changed from script! -- // +var init const array PathPoints; + +struct PolyArray_Mirror +{ + var init array Dummy; +}; +var private const PolyArray_Mirror PolysUsed; + +/** Base on which this path is generated. Valid if bDynamic == true. */ +var const BaseTransform Base; +/** Destination expressed in initial navmesh position. */ +var const vector LocalDestination; + +var private{private} const bool bDynamic; +/** variable auto-incremented every new path is stored in this path object */ +var public{private} const int Version; + +/** + * Returns indexed element's position offset and rotated if necessary + */ +final function vector GetElementPos(int index); + +final function SetRoute(array Route); + +/** function used to translate given location to path's generation base's space */ +final function vector WorldToLocal(vector InLocation); + +// ----------------------------------------------------------------------- // +// debug stuff +// ----------------------------------------------------------------------- // +final function DrawPath(Canvas Canvas, optional byte R=0, optional byte G=255, optional byte B=128, optional bool bPersistent); diff --git a/BaseAI/Classes/PlayerInputRecorder.uc b/BaseAI/Classes/PlayerInputRecorder.uc new file mode 100644 index 0000000..09b208d --- /dev/null +++ b/BaseAI/Classes/PlayerInputRecorder.uc @@ -0,0 +1,52 @@ +//============================================================================= +// AnimationProxy +//============================================================================= +// +//============================================================================= +// Killing Floor 2 +// Copyright (C) 2015 Tripwire Interactive LLC +//============================================================================= + +class PlayerInputRecorder extends Object + native(Tools); + +static native noexport final function StartRecording(string Filename); +static native noexport final function StopRecording(); +static native noexport final function Replay(string Filename); +static native noexport final function StopReplay(); + +cpptext +{ +#if HASEDITOR + // to be specialized in Platforms' drivers + template + static void Replay(TJoystickInfo&, TXInputState&); + + // to be specialized in Platforms' drivers + template + static void Record(TJoystickInfo&, TXInputState&); + + // to be defined in Platforms' drivers + static void FlushInputRecBuffer(UBOOL bFinalize); + + static UBOOL IsRecording(); + static UBOOL IsReplaying(); + + static void StopReplay(); + static void OnReplayingStop(); + + static UBOOL ReadInRecordedPlayerInput(UBOOL bFinishing = FALSE); + + enum + { + kInputRecordBufferSize = 128 + }; + +protected: + static FString CurrentFileName; + static UBOOL bIsInputRecording; + static UBOOL bIsInputReplaying; + static INT Version; + static INT ReplayIndex; +#endif // HASEDITOR +}; \ No newline at end of file diff --git a/BaseAI/Classes/PlugInOwnerInterface.uc b/BaseAI/Classes/PlugInOwnerInterface.uc new file mode 100644 index 0000000..ee800c0 --- /dev/null +++ b/BaseAI/Classes/PlugInOwnerInterface.uc @@ -0,0 +1,14 @@ +//============================================================================= +// PlugInOwnerInterface +//============================================================================= +// +//============================================================================= +// Killing Floor 2 +// Copyright (C) 2015 Tripwire Interactive LLC +//============================================================================= +interface PlugInOwnerInterface; + +function BaseAiPlugInHistory GetAiPlugInHistory(); + +//function float GetCurrentTime(); +function float GetTimeSince( float Time2Test ); \ No newline at end of file diff --git a/BaseAI/Classes/PluginBase.uc b/BaseAI/Classes/PluginBase.uc new file mode 100644 index 0000000..9ffc56a --- /dev/null +++ b/BaseAI/Classes/PluginBase.uc @@ -0,0 +1,122 @@ +//============================================================================= +// PluginBase +//============================================================================= +// +//============================================================================= +// Killing Floor 2 +// Copyright (C) 2015 Tripwire Interactive LLC +//============================================================================= +class PluginBase extends Object + abstract + native(Plugin); + +var PlugInOwnerInterface PlugInOwner; +var const public{private} bool bIsPluginEnabled; + +var bool bAborted; +var bool bFailure; +var bool bSuccess; + +var BaseAiPlugInHistory OwnersAiPlugInHistory; +var string HistoryString; + +/** Exiting status of this plugin */ +var() transient string StatusStr; + +cpptext +{ + FORCEINLINE UBOOL IsPluginEnabled() const + { + return bIsPluginEnabled; + } + + virtual void CleanUp(UBOOL bBeingDestroyed) {} +} + +native function DisablePlugin(); +native function EnablePlugin(); + +simulated function DrawDebugToHud( HUD HUD, name Category ); + + +event ScriptInitialize() +{ + bAborted = false; + bFailure = false; + bSuccess = false; +} + +event DrawDebug(HUD H, Name Category); + +/********************************************************************************************* +* Debugging +********************************************************************************************* */ + +/** Update command history (debugging) */ +function UpdateCommandHistory() +{ + local int i; + + if( PlugInOwner != none ) + { + if( OwnersAiPlugInHistory == none ) + { + OwnersAiPlugInHistory = PlugInOwner.GetAiPlugInHistory(); + } + + for( i = 0; i < OwnersAiPlugInHistory.PlugInHistory.Length; i++ ) + { + if( OwnersAiPlugInHistory.PlugInHistory[i].PlugInName != "" && OwnersAiPlugInHistory.PlugInHistory[i].PlugInName == string(name) ) + { + if( bAborted) + { + OwnersAiPlugInHistory.PlugInHistory[i].bAborted = true; + } + if( bFailure) + { + OwnersAiPlugInHistory.PlugInHistory[i].bFailure = true; + } + if( bSuccess ) + { + OwnersAiPlugInHistory.PlugInHistory[i].bSuccess = true; + } + + UpdateHistoryString( "Status: " $ StatusStr ); + //HistoryString = "Status: "$Status; + OwnersAiPlugInHistory.PlugInHistory[i].Duration = PlugInOwner.GetTimeSince(OwnersAiPlugInHistory.PlugInHistory[i].TimeStamp); + OwnersAiPlugInHistory.PlugInHistory[i].VerboseString = HistoryString; + } + } + } +} + +/** Update the command's HistoryString, which is output when DumpCommandHistory() is called */ +function UpdateHistoryString( string AddString ) +{ + + if( PlugInOwner != none ) + { + if( OwnersAiPlugInHistory == none ) + { + OwnersAiPlugInHistory = PlugInOwner.GetAiPlugInHistory(); + } + + if( OwnersAiPlugInHistory.PlugInHistoryNum > 0 ) + { + HistoryString = HistoryString$" "$AddString; + } + } + +} + +/** Used when dumping command history to log file */ +event string GetDebugVerboseText() +{ + return HistoryString; +} + +defaultproperties +{ + bIsPluginEnabled=true + HistoryString="[I]" +} \ No newline at end of file diff --git a/BaseAI/Classes/PluginSquad.uc b/BaseAI/Classes/PluginSquad.uc new file mode 100644 index 0000000..979d49c --- /dev/null +++ b/BaseAI/Classes/PluginSquad.uc @@ -0,0 +1,26 @@ +//============================================================================= +// AnimationProxy +//============================================================================= +// +//============================================================================= +// Killing Floor 2 +// Copyright (C) 2015 Tripwire Interactive LLC +//============================================================================= +/** + * + * + * This plugin introduces squad mechanics to owning BaseAIController. This class is not the same as a squad itself, + * it introduces actions that can be performed on a squad. Advantage of this approach is that any given BaseAIController + * can easily change squads just by changing 'Squad' variable of its 'CoveringPlugin'. + */ + +class PluginSquad extends AIPlugin within BaseAIController + native(Plugin); + +var const BaseAISquad Squad; + +final native function EnemyPerceived(EWSPerceptionMode PerceptionType, Pawn PerceivedEnemy); + +defaultproperties +{ +} \ No newline at end of file diff --git a/BaseAI/Globals.uci b/BaseAI/Globals.uci new file mode 100644 index 0000000..f9140bc --- /dev/null +++ b/BaseAI/Globals.uci @@ -0,0 +1,66 @@ +//============================================================================= +// Globals +//============================================================================= +// /* MessageSystem macros */ +//============================================================================= +// Killing Floor 2 +// Copyright (C) 2015 Tripwire Interactive LLC +//============================================================================= + +`define MsgSystem class'MessageSystem'.static.GetInstance() + + +/* Behavior tree macros */ + +`if(`isdefined(FINAL_RELEASE)) + +`define BTLog(msg) +`define BTLog_Ext(msg, object) + +`define AILog(text) +`define AILog(text, category) +`define AILog(text, category, bForce) +`define AILog_Ext(text, category, object) + +`define AILogNativeCallStack() +`define AILogScriptCallStack() +`define AILogNativeCallStack_Ext(actor) +`define AILogScriptCallStack_Ext(actor) +`define AILogSpaceLine(Owner, Start, End) +`define AILogSpaceLine(Owner, Start, End, Type) +`define AILogSpaceLine(Owner, Start, End, Type, Comment) +`define AILogSpaceLine(Owner, Start, End, Type, Comment, Category) + +`define AILogSetContext(Owner) + +`define DEBUGSTATE + +`else + +`define BTLog(msg) AILog_Internal(`msg, 'BehaviorTree') +`define BTLog_Ext(msg, object) if (`object != none) { `object.AILog_Internal(`msg, 'BehaviorTree' ); } + +`define StaticEngineContext class'Engine'.static.GetEngine() +`define AILog(text) if( ! `StaticEngineContext.bDisableAILogging) {AILog_Internal(`text);} +`define AILog(text, category) if( ! `StaticEngineContext.bDisableAILogging) {AILog_Internal(`text,`category);} +`define AILog(text, category, bForce) if( ! `StaticEngineContext.bDisableAILogging) {AILog_Internal(`text,`category,`bForce);} +`define AILog_Ext(text, category, object) if( !`StaticEngineContext.bDIsableAILogging && `object != None ) { `object.AILog_Internal(`text,`category); } + +`define AILogNativeCallStack() class'BaseAISubsystem'.static.GetAIDebugTool().DumpNativeCallStack(self) +`define AILogScriptCallStack() AILog_Internal(GetScriptTrace(),'CallStack') + +`define AILogNativeCallStack_Ext(actor) class'BaseAISubsystem'.static.GetAIDebugTool().DumpNativeCallStack(`actor) +`define AILogScriptCallStack_Ext(actor) `actor.AILog_Internal(GetScriptTrace(),'CallStack') + +`define AILogSpaceLine(Owner, Start, End) class'BaseAISubsystem'.static.GetAIDebugTool().LogSpaceLine(`Owner, `Start, `End, DLT_Generic) +`define AILogSpaceLine(Owner, Start, End, Type) class'BaseAISubsystem'.static.GetAIDebugTool().LogSpaceLine(`Owner, `Start, `End, `Type) +`define AILogSpaceLine(Owner, Start, End, Type, Comment) class'BaseAISubsystem'.static.GetAIDebugTool().LogSpaceLine(`Owner, `Start, `End, `Type, `Comment) +`define AILogSpaceLine(Owner, Start, End, Type, Comment, Category) class'BaseAISubsystem'.static.GetAIDebugTool().LogSpaceLine(`Owner, `Start, `End, `Type, `Comment, `Category) + + +`define AILogSetContext(Owner) class'BaseAISubsystem'.static.GetAIDebugTool().SetContext(`Owner) + +`define DEBUGSTATE extends DEBUGSTATE + +`endif + diff --git a/Core/Classes/Commandlet.uc b/Core/Classes/Commandlet.uc new file mode 100644 index 0000000..86379ba --- /dev/null +++ b/Core/Classes/Commandlet.uc @@ -0,0 +1,120 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * UnrealScript Commandlet (command-line applet) class. + * + * Commandlets are executed from the ucc.exe command line utility, using the + * following syntax: + * + * yourgame.exe package_name.commandlet_class_name [parm=value]... + * + * for example: + * + * yourgame.exe Core.HelloWorldCommandlet + * yourgame.exe UnrealEd.MakeCommandlet + * + * As a convenience, if a user tries to run a commandlet and the exact + * name he types isn't found, then ucc.exe appends the text "commandlet" + * onto the name and tries again. Therefore, the following shortcuts + * perform identically to the above: + * + * yourgame.exe Core.HelloWorld + * yourgame.exe UnrealEd.Make + * + * Commandlets are executed in a "raw" UnrealScript environment, in which + * the game isn't loaded, the client code isn't loaded, no levels are + * loaded, and no actors exist. + */ +class Commandlet + extends Object + abstract + transient + native; + +/** Description of the commandlet's purpose */ +var localized string HelpDescription; + +/** Usage template to show for "ucc help" */ +var localized string HelpUsage; + +/** Hyperlink for more info */ +var localized string HelpWebLink; + +/** The name of the parameter the commandlet takes */ +var localized array HelpParamNames; + +/** The description of the parameter */ +var localized array HelpParamDescriptions; + +/** + * Whether to load objects required in server, client, and editor context. If IsEditor is set to false, then a + * UGameEngine (or whatever the value of Engine.Engine.GameEngine is) will be created for the commandlet instead + * of a UEditorEngine (or Engine.Engine.EditorEngine), unless the commandlet overrides the CreateCustomEngine method. + */ +var bool IsServer, IsClient, IsEditor; + +/** Whether to redirect standard log to the console */ +var bool LogToConsole; + +/** Whether to show standard error and warning count on exit */ +var bool ShowErrorCount; + +cpptext +{ + virtual INT Main(const FString& Params); + + /** + * Parses a string into tokens, separating switches (beginning with - or /) from + * other parameters + * + * @param CmdLine the string to parse + * @param Tokens [out] filled with all parameters found in the string + * @param Switches [out] filled with all switches found in the string + * + * @return @todo + */ + static void ParseCommandLine( const TCHAR* CmdLine, TArray& Tokens, TArray& Switches ) + { + FString NextToken; + while ( ParseToken(CmdLine, NextToken, FALSE) ) + { + if ( **NextToken == TCHAR('-') || **NextToken == TCHAR('/') ) + { + new(Switches) FString(NextToken.Mid(1)); + } + else + { + new(Tokens) FString(NextToken); + } + } + } + + /** + * This is where you put any custom code that needs to be executed from InitializeIntrinsicPropertyValues() in + * your commandlet + */ + void StaticInitialize() {} + + /** + * Allows commandlets to override the default behavior and create a custom engine class for the commandlet. If + * the commandlet implements this function, it should fully initialize the UEngine object as well. Commandlets + * should indicate that they have implemented this function by assigning the custom UEngine to GEngine. + */ + virtual void CreateCustomEngine() {} +} + +/** + * Entry point for your commandlet + * + * @param Params the string containing the parameters for the commandlet + */ +event int Main(string Params); + +defaultproperties +{ + IsServer=true + IsClient=true + IsEditor=true + LogToConsole=false + ShowErrorCount=true +} diff --git a/Core/Classes/Component.uc b/Core/Classes/Component.uc new file mode 100644 index 0000000..f462467 --- /dev/null +++ b/Core/Classes/Component.uc @@ -0,0 +1,89 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * This class is the base class for any kind of object that wants the following features: + * - be a subobject inside a class definition (called the owner class) + * - values of the component can be overridden in a subclass of the owner class, by + * defining a component in the subclass with the same name as the component in the base class + * definition. Note, you CANNOT GIVE IT A CLASS= DEFINITION! (See UDN page for more info) + * - Changes to the default values to the component will be propagated to components that are + * created inside a map, unless the value was changed away from the default value in the editor. + */ +class Component extends Object + native + abstract; + +var const native Class TemplateOwnerClass; +var const native name TemplateName; + +cpptext +{ + /** + * Given a subobject and an owner class, save a refernce to it for retrieveing defaults on load + * @param OriginalSubObject The original template for this subobject (or another instance for a duplication?) + * @param OwnerClass The class that contains the original template + * @param SubObjectName If the OriginalSubObject is NULL, manually set the name of the subobject to this + */ + void LinkToSourceDefaultObject(UComponent* OriginalComponent, UClass* OwnerClass, FName ComponentName = NAME_None); + + /** + * Copies the SourceDefaultObject onto our own memory to propagate any modified defaults + * @param Ar The archive used to serialize the pointer to the subobject template + */ + void PreSerialize(FArchive& Ar); + + /** + * Copies the Source DefaultObject onto our own memory to propagate any modified defaults + * @return The object pointed to by the SourceDefaultActorClass and SourceDefaultSubObjectName + */ + UComponent* ResolveSourceDefaultObject(); + + /** + * Returns name to use for this component in component instancing maps. + * + * @return a name for this component which is unique within a single object graph. + */ + FName GetInstanceMapName() const; + + /** + * Returns whether this component was instanced from a component template. + * + * @return TRUE if this component was instanced from a template. FALSE if this component was created manually at runtime. + */ + UBOOL IsInstanced() const; + + /** + * Returns whether native properties are identical to the one of the passed in component. + * + * @param Other Other component to compare against + * + * @return TRUE if native properties are identical, FALSE otherwise + */ + virtual UBOOL AreNativePropertiesIdenticalTo( UComponent* Other ) const; + + /** + * Callback for retrieving a textual representation of natively serialized properties. Child classes should implement this method if they wish + * to have natively serialized property values included in things like diffcommandlet output. + * + * @param out_PropertyValues receives the property names and values which should be reported for this object. The map's key should be the name of + * the property and the map's value should be the textual representation of the property's value. The property value should + * be formatted the same way that UProperty::ExportText formats property values (i.e. for arrays, wrap in quotes and use a comma + * as the delimiter between elements, etc.) + * @param ExportFlags bitmask of EPropertyPortFlags used for modifying the format of the property values + * + * @return return TRUE if property values were added to the map. + */ + virtual UBOOL GetNativePropertyValues( TMap& out_PropertyValues, DWORD ExportFlags=0 ) const; + + // UObject interface. + + virtual UBOOL IsPendingKill() const; + + /** + * @return if this object is a UComponent or subclass + */ + virtual UBOOL IsAComponent() const + { + return TRUE; + } +} diff --git a/Core/Classes/DistributionFloat.uc b/Core/Classes/DistributionFloat.uc new file mode 100644 index 0000000..7893b69 --- /dev/null +++ b/Core/Classes/DistributionFloat.uc @@ -0,0 +1,131 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DistributionFloat extends Component + inherits(FCurveEdInterface) + native + collapsecategories + hidecategories(Object) + editinlinenew + abstract; + +struct native RawDistributionFloat extends RawDistribution +{ + structcpptext + { + #if !CONSOLE + /** + * Initialize a raw distribution from the original Unreal distribution + */ + void Initialize(); + #endif + + /** + * Gets a pointer to the raw distribution if you can just call FRawDistribution::GetValue1 on it, otherwise NULL + */ + const FRawDistribution* GetFastRawDistribution(); + + /** + * Get the value at the specified F + */ + FLOAT GetValue(FLOAT F=0.0f, UObject* Data=NULL, class FRandomStream* InRandomStream = NULL); + + /** + * Get the min and max values + */ + void GetOutRange(FLOAT& MinOut, FLOAT& MaxOut); + + /** + * Is this distribution a uniform type? (ie, does it have two values per entry?) + */ + inline UBOOL IsUniform() { return LookupTableNumElements == 2; } + } + + var() export noclear DistributionFloat Distribution; +}; + +struct native MatineeRawDistributionFloat extends RawDistributionFloat +{ + structcpptext + { + /** + * Get the value at the specified F + */ + FLOAT GetValue(FLOAT F=0.0f, UObject* Data=NULL, class FRandomStream* InRandomStream = NULL); + } + + /** The value that will be modified by Matinee. */ + var float MatineeValue; + + /** TRUE when the value returned is controlled by matinee. */ + var bool bInMatinee; + +}; + +cpptext +{ + +#if !CONSOLE + /** + * Return the operation used at runtime to calculate the final value + */ + virtual ERawDistributionOperation GetOperation() { return RDO_None; } + + /** + * Return the lock flags used at runtime to calculate the final value + */ + virtual ERawDistributionLockFlags GetLockFlags(INT InIndex) { return RDL_None; } + + /** + * Fill out an array of floats and return the number of elements in the entry + * + * @param Time The time to evaluate the distribution + * @param Values An array of values to be filled out, guaranteed to be big enough for 4 values + * @return The number of elements (values) set in the array + */ + virtual DWORD InitializeRawEntry(FLOAT Time, FLOAT* Values); +#endif + + virtual FLOAT GetValue( FLOAT F = 0.f, UObject* Data = NULL, class FRandomStream* InRandomStream = NULL ); + + virtual void GetInRange(FLOAT& MinIn, FLOAT& MaxIn); + virtual void GetOutRange(FLOAT& MinOut, FLOAT& MaxOut); + + /** + * Return whether or not this distribution can be baked into a FRawDistribution lookup table + */ + virtual UBOOL CanBeBaked() const + { + return bCanBeBaked; + } + + /** UObject interface */ + virtual void Serialize(FArchive& Ar); + + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + /** + * If the distribution can be baked, then we don't need it on the client or server + */ + virtual UBOOL NeedsLoadForClient() const; + virtual UBOOL NeedsLoadForServer() const; +} + + + +/** Can this variable be baked out to a FRawDistribution? Should be TRUE 99% of the time*/ +var(Baked) bool bCanBeBaked; + +/** Set internally when the distribution is updated so that that FRawDistribution can know to update itself*/ +var bool bIsDirty; + +/** Script-accessible way to query a float distribution */ +native function float GetFloatValue(optional float F = 0.0); + + +defaultproperties +{ + bCanBeBaked=true + // make sure the FRawDistribution is initialized + bIsDirty=true +} diff --git a/Core/Classes/DistributionVector.uc b/Core/Classes/DistributionVector.uc new file mode 100644 index 0000000..f34d492 --- /dev/null +++ b/Core/Classes/DistributionVector.uc @@ -0,0 +1,133 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DistributionVector extends Component + inherits(FCurveEdInterface) + native + collapsecategories + hidecategories(Object) + editinlinenew + abstract; + +enum EDistributionVectorLockFlags +{ + EDVLF_None, + EDVLF_XY, + EDVLF_XZ, + EDVLF_YZ, + EDVLF_XYZ +}; + +enum EDistributionVectorMirrorFlags +{ + EDVMF_Same, + EDVMF_Different, + EDVMF_Mirror +}; + +struct native RawDistributionVector extends RawDistribution +{ + structcpptext + { + #if !CONSOLE + /** + * Initialize a raw distribution from the original Unreal distribution + */ + void Initialize(); + #endif + + /** + * Gets a pointer to the raw distribution if you can just call FRawDistribution::GetValue3 on it, otherwise NULL + */ + const FRawDistribution *GetFastRawDistribution(); + + /** + * Get the value at the specified F + */ + FVector GetValue(FLOAT F=0.0f, UObject* Data=NULL, INT LastExtreme=0, class FRandomStream* InRandomStream = NULL); + + /** + * Get the min and max values + */ + void GetOutRange(FLOAT& MinOut, FLOAT& MaxOut); + + /** + * Is this distribution a uniform type? (ie, does it have two values per entry?) + */ + inline UBOOL IsUniform() { return LookupTableNumElements == 2; } + } + + var() export noclear DistributionVector Distribution; +}; + +cpptext +{ + +#if !CONSOLE + /** + * Return the operation used at runtime to calculate the final value + */ + virtual ERawDistributionOperation GetOperation() { return RDO_None; } + + /** + * Return the lock flags used at runtime to calculate the final value + */ + virtual ERawDistributionLockFlags GetLockFlags(INT InIndex) { return RDL_None; } + + /** + * Return true if the distribution is a uniform curve + */ + virtual UBOOL IsUniformCurve() { return FALSE; } + + /** + * Fill out an array of vectors and return the number of elements in the entry + * + * @param Time The time to evaluate the distribution + * @param Values An array of values to be filled out, guaranteed to be big enough for 2 vectors + * @return The number of elements (values) set in the array + */ + virtual DWORD InitializeRawEntry(FLOAT Time, FVector* Values); +#endif + + virtual FVector GetValue( FLOAT F = 0.f, UObject* Data = NULL, INT LastExtreme = 0, class FRandomStream* InRandomStream = NULL ); + + virtual void GetInRange(FLOAT& MinIn, FLOAT& MaxIn); + virtual void GetOutRange(FLOAT& MinOut, FLOAT& MaxOut); + virtual void GetRange(FVector& OutMin, FVector& OutMax); + + /** + * Return whether or not this distribution can be baked into a FRawDistribution lookup table + */ + virtual UBOOL CanBeBaked() const + { + return bCanBeBaked; + } + + /** UObject interface */ + virtual void Serialize(FArchive& Ar); + + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + /** + * If the distribution can be baked, then we don't need it on the client or server + */ + virtual UBOOL NeedsLoadForClient() const; + virtual UBOOL NeedsLoadForServer() const; +} + + +/** Can this variable be baked out to a FRawDistribution? Should be TRUE 99% of the time*/ +var(Baked) bool bCanBeBaked; + +/** Set internally when the distribution is updated so that that FRawDistribution can know to update itself*/ +var bool bIsDirty; + +/** Script-accessible way to query a vector distribution */ +native function vector GetVectorValue(optional float F = 0.0, optional INT LastExtreme = 0); + +defaultproperties +{ + bCanBeBaked=true + // make sure the FRawDistribution is initialized + bIsDirty=true +} \ No newline at end of file diff --git a/Core/Classes/Factory.uc b/Core/Classes/Factory.uc new file mode 100644 index 0000000..42cd113 --- /dev/null +++ b/Core/Classes/Factory.uc @@ -0,0 +1,28 @@ +/** + * Base class for all factories + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class Factory extends Object + abstract + noexport + native; + +var class SupportedClass; +var class ContextClass; +var string Description; +var array Formats; +var bool bCreateNew; +var bool bEditAfterNew; +var bool bEditorImport; +var bool bText; +var int AutoPriority; + + /** List of game names that this factory can be used for (if empty, all games valid) */ +var array ValidGameNames; + +defaultproperties +{ + Description = ""; +} + diff --git a/Core/Classes/HelpCommandlet.uc b/Core/Classes/HelpCommandlet.uc new file mode 100644 index 0000000..f4b9582 --- /dev/null +++ b/Core/Classes/HelpCommandlet.uc @@ -0,0 +1,20 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +/** This commandlet finds and displays help information on other commandlets */ +class HelpCommandlet extends Commandlet + native; + +cpptext +{ + virtual INT Main(const FString& Params); +} + +/** + * Looks at the parameters and displays help based upon those parameters + * + * @param Params the string containing the parameters for the commandlet + */ +event int Main(string Params); + diff --git a/Core/Classes/Interface.uc b/Core/Classes/Interface.uc new file mode 100644 index 0000000..210343c --- /dev/null +++ b/Core/Classes/Interface.uc @@ -0,0 +1,9 @@ +/** + * Base class for all interfaces + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +interface Interface + native; + + diff --git a/Core/Classes/Object.uc b/Core/Classes/Object.uc new file mode 100644 index 0000000..1abed4c --- /dev/null +++ b/Core/Classes/Object.uc @@ -0,0 +1,2232 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +//============================================================================= +// Object: The base class all objects. +// This is a built-in Unreal class and it shouldn't be modified by mod authors +//============================================================================= +class Object + abstract + native + noexport; + +//============================================================================= +// Unreal base structures. + +// Temporary UnrealScript->C++ mirrors. + +struct pointer +{ + var native const int Dummy; +}; + +//@HSL_BEGIN_XBOX +struct hatpointer +{ + var native const int Dummy; +}; +//@HSL_END_XBOX + +struct {QWORD} qword +{ + var() native int A, B; +}; + +struct {DWORD} dword +{ + var() native int A; +}; + + +//============================================================================= +// UObject variables. + +// Internal variables. +var native private const editconst noexport pointer VfTableObject; +var native private const editconst pointer HashNext; +var native private const editconst qword ObjectFlags; // This needs to be 8-byte aligned in 32-bit! +var native private const editconst pointer HashOuterNext; +var native private const editconst pointer StateFrame; +var native private const editconst noexport Object Linker; +var native private const editconst noexport pointer LinkerIndex; +var native private const editconst noexport int ObjectInternalInteger; +var native private const editconst noexport int NetIndex; +var native const editconst Object Outer; +var() native const editconst name Name; +var native const editconst class Class; +var() native const editconst Object ObjectArchetype; +//////////////////////////////////////////////////////////////////////////////////////////////// +// IMPORTANT: DO NOT ADD _ANY_ MEMBERS AFTER ObjectArchetype! Add ALL members before it, as the +// C++ code expects it to be the final member of UObject! (see UObject::InitProperties) +//////////////////////////////////////////////////////////////////////////////////////////////// + + +//============================================================================= +// Unreal base structures continued. + +//@HSL_BEGIN_XBOX +// An IP address. +// @igs(jtl) IPv6 compatible version of FIpAddr. If native uses IPv6, AddrA-D are the IN6_ADDR struct. +// Otherwise, the IPv4 address is in AddrD. +struct {FIpAddr} IpAddr +{ + var int AddrA; + var int AddrB; + var int AddrC; + var int AddrD; + var int Port; +}; +//@HSL_END_XBOX + +struct {DOUBLE} double +{ + var native const int A; + var native const int B; +}; + +struct ThreadSafeCounter +{ + var native const int Value; +}; + +struct BitArray_Mirror +{ + var native const pointer IndirectData; + var native const int InlineData[4]; + var native const int NumBits; + var native const int MaxBits; +}; + +struct SparseArray_Mirror +{ + var native const array Elements; + var native const BitArray_Mirror AllocationFlags; + var native const int FirstFreeIndex; + var native const int NumFreeIndices; +}; + +struct Set_Mirror +{ + var native const SparseArray_Mirror Elements; + var native const int InlineHash; + var native const pointer Hash; + var native const int HashSize; +}; + +struct Map_Mirror +{ + var native const Set_Mirror Pairs; +}; + +struct MultiMap_Mirror +{ + var native const Set_Mirror Pairs; +}; + +struct UntypedBulkData_Mirror +{ + var native const pointer VfTable; + var native const int BulkDataFlags; + var native const int ElementCount; + var native const int BulkDataOffsetInFile; + var native const int BulkDataSizeOnDisk; + var native const int SavedBulkDataFlags; + var native const int SavedElementCount; + var native const int SavedBulkDataOffsetInFile; + var native const int SavedBulkDataSizeOnDisk; + var native const pointer BulkData; + var native const int LockStatus; + var native const pointer AttachedAr; + var native const int bShouldFreeOnEmpty; +}; + +struct RenderCommandFence_Mirror +{ + var native const transient int NumPendingFences; +}; + +// needs to match FColorVertexBuffer in C++ +struct FColorVertexBuffer_Mirror +{ + var native const pointer VfTable; + var native const pointer VertexData; + var private const int Data; + var private const int Stride; + var private const int NumVertices; +}; + +struct IndirectArray_Mirror +{ + // FScriptArray + var native const pointer Data; + var native const int ArrayNum; + var native const int ArrayMax; +}; + +struct Array_Mirror +{ + // FScriptArray + var native const pointer Data; + var native const int ArrayNum; + var native const int ArrayMax; +}; + +/** + * Structure mirroring an array of pointers using an inline allocator. + */ +struct InlinePointerArray_Mirror +{ + var private const pointer InlineData; + var private const Array_Mirror SecondaryData; +}; + +// A globally unique identifier. +struct immutable Guid +{ + var int A, B, C, D; +}; + +// A point or direction vector in 3d space. +struct immutable Vector +{ + var() float X, Y, Z; +}; + +struct immutable Vector4 +{ + var() float X, Y, Z, W; +}; + +struct immutable Vector2D +{ + var() float X, Y; +}; + +struct immutable TwoVectors +{ + var() Vector v1, v2; +}; + +// A plane definition in 3d space. +struct immutable Plane extends Vector +{ + var() float W; +}; + +// An orthogonal rotation in 3d space. +struct immutable Rotator +{ + var() int Pitch, Yaw, Roll; +}; + +// Quaternion +struct immutable Quat +{ + var() float X, Y, Z, W; +}; + +// A packed normal. +struct immutable PackedNormal +{ + var() byte X, Y, Z, W; +}; + +/** + * Screen coordinates + */ +struct immutable IntPoint +{ + var() int X, Y; +}; + +/** + * A vector of spherical harmonic coefficients. + */ +struct SHVector +{ + // Note: The number of SH coefficients must match NUM_SH_BASIS in SHMath.h! + // The struct must also be padded to be 16-byte aligned. + var() float V[9]; + var float Padding[3]; +}; + +/** + * A vector of spherical harmonic coefficients for each color component. + */ +struct SHVectorRGB +{ + var() SHVector R; + var() SHVector G; + var() SHVector B; +}; + +/** + * Point Of View type. + */ +struct TPOV +{ + /** Location */ + var() Vector Location; + /** Rotation */ + var() Rotator Rotation; + /** FOV angle */ + var() float FOV; + + structdefaultproperties + { + FOV=90.f + } +}; + +/** Various ways to interpolate TAlphaBlend. */ +enum AlphaBlendType +{ + ABT_Linear, + ABT_Cubic, + ABT_Sinusoidal, + ABT_EaseInOutExponent2, + ABT_EaseInOutExponent3, + ABT_EaseInOutExponent4, + ABT_EaseInOutExponent5, +}; + +/** Structure to encompass Alpha Interpolation. */ +struct TAlphaBlend +{ + /** Internal Lerped value for Alpha */ + var const FLOAT AlphaIn; + /** Resulting Alpha value, between 0.f and 1.f */ + var const FLOAT AlphaOut; + /** Target to reach */ + var() FLOAT AlphaTarget; + /** Default blend time */ + var() FLOAT BlendTime; + /** Time left to reach target */ + var const FLOAT BlendTimeToGo; + /** Type of blending used (Linear, Cubic, etc.) */ + var() AlphaBlendType BlendType; + + structdefaultproperties + { + BlendTime=0.67f + BlendType=ABT_Linear + } +}; + +// Generic axis enum. +enum EAxis +{ + AXIS_NONE, // = 0 + AXIS_X, // = 1 + AXIS_Y, // = 2 + AXIS_BLANK, // = 3. Need this because AXIS enum is used as bitfield in C++... + AXIS_Z // 4 +}; + +enum EInputEvent +{ + IE_Pressed, + IE_Released, + IE_Repeat, + IE_DoubleClick, + IE_Axis +}; + +enum EAspectRatioAxisConstraint +{ + AspectRatio_MaintainYFOV, + AspectRatio_MaintainXFOV, + AspectRatio_MajorAxisFOV +}; + +// A color. +struct immutable Color +{ + var() byte B, G, R, A; +}; + +// A linear color. +struct immutable LinearColor +{ + var() float R, G, B, A; + + structdefaultproperties + { + A=1.f + } +}; + +// A bounding box. +struct immutable Box +{ + var() vector Min, Max; + var byte IsValid; +}; + +// A bounding box and bounding sphere with the same origin. +struct BoxSphereBounds +{ + var() vector Origin; + var() vector BoxExtent; + var() float SphereRadius; +}; + +// a 4x4 matrix +struct immutable Matrix +{ + var() Plane XPlane; + var() Plane YPlane; + var() Plane ZPlane; + var() Plane WPlane; +}; + +struct Cylinder +{ + var float Radius, Height; +}; + +// Interpolation data types. +enum EInterpCurveMode +{ + CIM_Linear, + CIM_CurveAuto, + CIM_Constant, + CIM_CurveUser, + CIM_CurveBreak, + CIM_CurveAutoClamped +}; + +// Interpolation data types. +enum EInterpMethodType +{ + IMT_UseFixedTangentEvalAndNewAutoTangents, + IMT_UseFixedTangentEval, + IMT_UseBrokenTangentEval +}; + +struct InterpCurvePointFloat +{ + var() float InVal; + var() float OutVal; + var() float ArriveTangent; + var() float LeaveTangent; + var() EInterpCurveMode InterpMode; +}; +struct InterpCurveFloat +{ + var() array Points; + var EInterpMethodType InterpMethod; +}; + +struct InterpCurvePointVector2D +{ + var() float InVal; + var() vector2d OutVal; + var() vector2d ArriveTangent; + var() vector2d LeaveTangent; + var() EInterpCurveMode InterpMode; +}; +struct InterpCurveVector2D +{ + var() array Points; + var EInterpMethodType InterpMethod; +}; + +struct InterpCurvePointVector +{ + var() float InVal; + var() vector OutVal; + var() vector ArriveTangent; + var() vector LeaveTangent; + var() EInterpCurveMode InterpMode; +}; +struct InterpCurveVector +{ + var() array Points; + var EInterpMethodType InterpMethod; +}; + +struct InterpCurvePointTwoVectors +{ + var() float InVal; + var() twovectors OutVal; + var() twovectors ArriveTangent; + var() twovectors LeaveTangent; + var() EInterpCurveMode InterpMode; +}; +struct InterpCurveTwoVectors +{ + var() array Points; + var EInterpMethodType InterpMethod; +}; + +struct InterpCurvePointQuat +{ + var() float InVal; + var() quat OutVal; + var() quat ArriveTangent; + var() quat LeaveTangent; + var() EInterpCurveMode InterpMode; +}; +struct InterpCurveQuat +{ + var() array Points; + var EInterpMethodType InterpMethod; +}; + +struct InterpCurvePointLinearColor +{ + var() float InVal; + var() linearcolor OutVal; + var() linearcolor ArriveTangent; + var() linearcolor LeaveTangent; + var() EInterpCurveMode InterpMode; +}; +struct InterpCurveLinearColor +{ + var() array Points; + var EInterpMethodType InterpMethod; +}; + +// Base class for raw (baked out) Distribution type +struct RawDistribution +{ + var byte Type; + var byte Op; + var byte LookupTableNumElements; + var byte LookupTableChunkSize; + var array LookupTable; + var float LookupTableTimeScale; + var float LookupTableStartTime; +}; + +/** A fence used to track rendering thread command execution. */ +struct RenderCommandFence +{ + var private native const int NumPendingFences; +}; + +/** Mirror for FElementId used in generic Octree */ +struct OctreeElementId +{ + var private native const pointer Node; + var private native const int ElementIndex; +}; + +/** Bone Atom definition */ +struct BoneAtom +{ + var quat Rotation; + var vector Translation; + var float Scale; +}; + +//============================================================================= +// Constants. + +const MaxInt = 0x7fffffff; +const Pi = 3.1415926535897932; +const RadToDeg = 57.295779513082321600; // 180 / Pi +const DegToRad = 0.017453292519943296; // Pi / 180 +const UnrRotToRad = 0.00009587379924285; // Pi / 32768 +const RadToUnrRot = 10430.3783504704527; // 32768 / Pi +const DegToUnrRot = 182.0444; +const UnrRotToDeg = 0.00549316540360483; +const INDEX_NONE = -1; + +// Aspect ratio constants +const AspectRatio4x3 = 1.33333; +const AspectRatio5x4 = 1.25; +const AspectRatio16x9 = 1.77778; +const InvAspectRatio4x3 = 0.75; +const InvAspectRatio5x4 = 0.8; +const InvAspectRatio16x9 = 0.56249; + +//============================================================================= +// Logging Severity Levels. + +/** + * Determines which ticking group an Actor/Component belongs to + */ +enum ETickingGroup +{ + /** + * Any item that needs to be updated before asynchronous work is done + */ + TG_PreAsyncWork, + /** + * Any item that can be run in parallel of our async work + */ + TG_DuringAsyncWork, + /** + * Any item that needs the async work to be done before being updated + */ + TG_PostAsyncWork, + // NVCHANGE_BEGIN: JCAO - Add second scene for clothing + /** + * Any item that needs being updated after physcis scene was done and before the cloth work started + */ + TG_PostPhysicsPreClothWork, + // NVCHANGE_END: JCAO - Add second scene for clothing + /** + * Any item that needs the update work to be done before being ticked + */ + TG_PostUpdateWork, + /** Special effects that need to be updated last */ + TG_EffectsUpdateWork +}; + + +/** + * These are the types of PerfMem RunResults you the system understands and can achieve. They are stored in the table as we + * will get "valid" numbers but we ran OOM. We want to list the numbers in the OOM case because there is probably something that + * jumped up to cause the OOM (e.g. vertex lighting). + **/ +enum EAutomatedRunResult +{ + ARR_Unknown, + ARR_OOM, + ARR_Passed, +}; + + +/** + * Different modes for the DebugBreak() method. + */ +enum EDebugBreakType +{ + DEBUGGER_NativeOnly, + + /** not yet implemented */ + DEBUGGER_ScriptOnly, + /** not yet implemented */ + DEBUGGER_Both, +}; + +//============================================================================= +// Basic native operators and functions. + + +// +// Bool operators. +// + +native(129) static final preoperator bool ! ( bool A ); +native(242) static final operator(24) bool == ( bool A, bool B ); +native(243) static final operator(26) bool != ( bool A, bool B ); +native(130) static final operator(30) bool && ( bool A, skip bool B ); +native(131) static final operator(30) bool ^^ ( bool A, bool B ); +native(132) static final operator(32) bool || ( bool A, skip bool B ); + + +// +// Byte operators. +// + +native(133) static final operator(34) byte *= ( out byte A, byte B ); +native(198) static final operator(34) byte *= ( out byte A, float B ); +native(134) static final operator(34) byte /= ( out byte A, byte B ); +native(135) static final operator(34) byte += ( out byte A, byte B ); +native(136) static final operator(34) byte -= ( out byte A, byte B ); +native(137) static final preoperator byte ++ ( out byte A ); +native(138) static final preoperator byte -- ( out byte A ); +native(139) static final postoperator byte ++ ( out byte A ); +native(140) static final postoperator byte -- ( out byte A ); + + +// +// Integer operators. +// + +native(141) static final preoperator int ~ ( int A ); +native(143) static final preoperator int - ( int A ); +native(144) static final operator(16) int * ( int A, int B ); +native(145) static final operator(16) int / ( int A, int B ); +native(253) static final operator(18) int % ( int A, int B ); +native(146) static final operator(20) int + ( int A, int B ); +native(147) static final operator(20) int - ( int A, int B ); +native(148) static final operator(22) int << ( int A, int B ); +native(149) static final operator(22) int >> ( int A, int B ); +native(196) static final operator(22) int >>>( int A, int B ); +native(150) static final operator(24) bool < ( int A, int B ); +native(151) static final operator(24) bool > ( int A, int B ); +native(152) static final operator(24) bool <= ( int A, int B ); +native(153) static final operator(24) bool >= ( int A, int B ); +native(154) static final operator(24) bool == ( int A, int B ); +native(155) static final operator(26) bool != ( int A, int B ); +native(156) static final operator(28) int & ( int A, int B ); +native(157) static final operator(28) int ^ ( int A, int B ); +native(158) static final operator(28) int | ( int A, int B ); +native(159) static final operator(34) int *= ( out int A, float B ); +native(160) static final operator(34) int /= ( out int A, float B ); +native(161) static final operator(34) int += ( out int A, int B ); +native(162) static final operator(34) int -= ( out int A, int B ); +native(163) static final preoperator int ++ ( out int A ); +native(164) static final preoperator int -- ( out int A ); +native(165) static final postoperator int ++ ( out int A ); +native(166) static final postoperator int -- ( out int A ); + + +// +// Integer functions. +// + +/** Rand will give you a value between 0 and Max -1 **/ +native(167) static final Function int Rand ( int Max ); +native(249) static final function int Min ( int A, int B ); +native(250) static final function int Max ( int A, int B ); +native(251) static final function int Clamp ( int V, int A, int B ); +native static final function string ToHex ( int A ); + + +// +// Float operators. +// + +native(169) static final preoperator float - ( float A ); +native(170) static final operator(12) float ** ( float Base, float Exp ); +native(171) static final operator(16) float * ( float A, float B ); +native(172) static final operator(16) float / ( float A, float B ); +native(173) static final operator(18) float % ( float A, float B ); +native(174) static final operator(20) float + ( float A, float B ); +native(175) static final operator(20) float - ( float A, float B ); +native(176) static final operator(24) bool < ( float A, float B ); +native(177) static final operator(24) bool > ( float A, float B ); +native(178) static final operator(24) bool <= ( float A, float B ); +native(179) static final operator(24) bool >= ( float A, float B ); +native(180) static final operator(24) bool == ( float A, float B ); +native(210) static final operator(24) bool ~= ( float A, float B ); +native(181) static final operator(26) bool != ( float A, float B ); +native(182) static final operator(34) float *= ( out float A, float B ); +native(183) static final operator(34) float /= ( out float A, float B ); +native(184) static final operator(34) float += ( out float A, float B ); +native(185) static final operator(34) float -= ( out float A, float B ); + +// +// Float functions. +// + +native(186) static final function float Abs ( float A ); +native(187) static final function float Sin ( float A ); +native static final function float Asin ( float A ); +native(188) static final function float Cos ( float A ); +native static final function float Acos ( float A ); +native(189) static final function float Tan ( float A ); +native(190) static final function float Atan ( float A ); +native static final function float Atan2 ( float A, float B ); +native(191) static final function float Exp ( float A ); +native(192) static final function float Loge ( float A ); +native(193) static final function float Sqrt ( float A ); +native(194) static final function float Square( float A ); +native(195) static final function float FRand (); +native(244) static final function float FMin ( float A, float B ); +native(245) static final function float FMax ( float A, float B ); +native(246) static final function float FClamp( float V, float A, float B ); +native(247) static final function float Lerp ( float A, float B, float Alpha ); +native(199) static final function int Round ( float A ); +native static final function int FFloor ( float A ); +native static final function int FCeil(float A); + +/** + * Cubic Spline interpolation. + * @param P end points + * @param T tangent directions at end points + * @param Alpha distance along spline + * @return evaluated value. + */ +native static final function float FCubicInterp(float P0, float T0, float P1, float T1, float A); + +/** + * Interpolates with ease-in (smoothly approaches B). + * @param A Value to interpolate from. + * @param B Value to interpolate to. + * @param Alpha Interpolant. + * @param Exp Exponent. Higher values result in more rapid deceleration. + * @return Interpolated value. + */ +static final function float FInterpEaseIn(float A, float B, float Alpha, float Exp) +{ + return Lerp(A, B, Alpha**Exp); +} + +/** + * Interpolates with ease-out (smoothly departs A). + * @param A Value to interpolate from. + * @param B Value to interpolate to. + * @param Alpha Interpolant. + * @param Exp Exponent. Higher values result in more rapid acceleration. + * @return Interpolated value. + */ +static final function float FInterpEaseOut(float A, float B, float Alpha, float Exp) +{ + return Lerp(A, B, Alpha**(1/Exp)); +} + +/** + * Interpolates with both ease-in and ease-out (smoothly departs A, smoothly approaches B). + * @param A Value to interpolate from. + * @param B Value to interpolate to. + * @param Alpha Interpolant. + * @param Exp Exponent. Higher values result in more rapid acceleration adn deceleration. + * @return Interpolated value. + */ +native static final function float FInterpEaseInOut(float A, float B, float Alpha, float Exp); + + +/** Return a random number within the given range. */ +static final simulated function float RandRange( float InMin, float InMax ) +{ + return InMin + (InMax - InMin) * FRand(); +} + + +/** + * Returns the relative percentage position Value is in the range [Min,Max]. + * Examples: + * - GetRangeValueByPct( 2, 4, 2 ) == 0 + * - GetRangeValueByPct( 2, 4, 4 ) == 1 + * - GetRangeValueByPct( 2, 4, 3 ) == 0.5 + * + * @param Min Min limit + * @param Max Max limit + * @param Value Value between Range. + * + * @return relative percentage position Value is in the range [Min,Max]. + */ + +static final simulated function float FPctByRange( float Value, float InMin, float InMax ) +{ + return (Value - InMin) / (InMax - InMin); +} + + +/** + * Tries to reach Target based on distance from Current position, + * giving a nice smooth feeling when tracking a position. + * (Doesn't work well when target teleports) + * + * @param Current Actual position + * @param Target Target position + * @param DeltaTime time since last tick + * @param InterpSpeed Interpolation speed + * @return new interpolated position + */ +native static final function float FInterpTo( float Current, float Target, float DeltaTime, float InterpSpeed ); +/** Same as above, but using a constant step */ +native static final function float FInterpConstantTo( float Current, float Target, float DeltaTime, float InterpSpeed ); + + +// +// Vector operators. +// + +native(211) static final preoperator vector - ( vector A ); +native(212) static final operator(16) vector * ( vector A, float B ); +native(213) static final operator(16) vector * ( float A, vector B ); +native(296) static final operator(16) vector * ( vector A, vector B ); +native(214) static final operator(16) vector / ( vector A, float B ); +native(215) static final operator(20) vector + ( vector A, vector B ); +native(216) static final operator(20) vector - ( vector A, vector B ); +native(275) static final operator(22) vector << ( vector A, rotator B ); +native(276) static final operator(22) vector >> ( vector A, rotator B ); +native(217) static final operator(24) bool == ( vector A, vector B ); +native(218) static final operator(26) bool != ( vector A, vector B ); +native(219) static final operator(16) float Dot ( vector A, vector B ); +native(220) static final operator(16) vector Cross ( vector A, vector B ); +native(221) static final operator(34) vector *= ( out vector A, float B ); +native(297) static final operator(34) vector *= ( out vector A, vector B ); +native(222) static final operator(34) vector /= ( out vector A, float B ); +native(223) static final operator(34) vector += ( out vector A, vector B ); +native(224) static final operator(34) vector -= ( out vector A, vector B ); + +// +// Vector functions. +// + +native(225) static final function float VSize ( vector A ); +native static final function float VSize2D ( vector A ); +native(228) static final function float VSizeSq ( vector A ); +native static final function float VSizeSq2D ( vector A ); +native(226) static final function vector Normal ( vector A ); +native(227) static final function vector Normal2D(vector A); +native static final function vector VLerp ( vector A, vector B, float Alpha ); +native(252) static final function vector VRand ( ); +native static final function vector VRandCone ( vector Dir, float ConeHalfAngleRadians ); +native static final function vector VRandCone2 ( vector Dir, float HorizontalConeHalfAngleRadians, float VerticalConeHalfAngleRadians ); +native(300) static final function vector MirrorVectorByNormal( vector InVect, vector InNormal ); +native(1500) static final function Vector ProjectOnTo( Vector x, Vector y ); +native(1501) static final function bool IsZero( Vector A ); + +/** + * Tries to reach Target based on distance from Current position, + * giving a nice smooth feeling when tracking a location. + * (Doesn't work well when target teleports) + * + * @param Current Actual location + * @param Target Target location + * @param DeltaTime time since last tick + * @param InterpSpeed Interpolation speed + * @return new interpolated position + */ + +native static final function vector VInterpTo( vector Current, vector Target, float DeltaTime, float InterpSpeed ); + +/** Clamps a vector to not be longer than MaxLength. */ +native static final function vector ClampLength( vector V, float MaxLength ); + +/** Returns dot product of two vectors while ignoring the Z component. */ +native static final function float NoZDot( vector A, vector B ); + +simulated final function bool InCylinder( Vector Origin, Rotator Dir, float Width, Vector A, optional bool bIgnoreZ ) +{ + local Vector B; + local Vector VDir; + + if( bIgnoreZ ) + { + Origin.Z = 0; + Dir.Pitch = 0; + A.Z = 0; + } + + VDir = Vector(Dir); + B = (((A - Origin) DOT VDir) * VDir) + Origin; + + if( VSizeSq(B-A) <= Width * Width ) + { + return TRUE; + } + + return FALSE; +} + +// +// Rotator operators and functions. +// + +native(142) static final operator(24) bool == ( rotator A, rotator B ); +native(203) static final operator(26) bool != ( rotator A, rotator B ); +native(287) static final operator(16) rotator * ( rotator A, float B ); +native(288) static final operator(16) rotator * ( float A, rotator B ); +native(289) static final operator(16) rotator / ( rotator A, float B ); +native(290) static final operator(34) rotator *= ( out rotator A, float B ); +native(291) static final operator(34) rotator /= ( out rotator A, float B ); +native(316) static final operator(20) rotator + ( rotator A, rotator B ); +native(317) static final operator(20) rotator - ( rotator A, rotator B ); +native(318) static final operator(34) rotator += ( out rotator A, rotator B ); +native(319) static final operator(34) rotator -= ( out rotator A, rotator B ); +native static final operator(24) bool ClockwiseFrom( int A, int B ); + +native(229) static final function GetAxes( rotator A, out vector X, out vector Y, out vector Z ); +native(230) static final function GetUnAxes( rotator A, out vector X, out vector Y, out vector Z ); +native static final function vector GetRotatorAxis( rotator A, int Axis ); +native(320) static final function Rotator RotRand( optional bool bRoll ); +native static final function Rotator OrthoRotation( vector X, vector Y, vector Z ); +native static final function Rotator Normalize( rotator Rot ); +native static final function Rotator RLerp( Rotator A, Rotator B, float Alpha, optional bool bShortestPath ); +/** Given rotation R in the space defined by RBasis, return R in "world" space */ +native static final function Rotator RTransform(rotator R, rotator RBasis); + + +/** + * Tries to reach Target based on distance from Current position, + * giving a nice smooth feeling when tracking a position. + * (Doesn't work well when target teleports) + * + * @param Current Actual position + * @param Target Target position + * @param DeltaTime time since last tick + * @param InterpSpeed Interpolation speed, if !bConstantInterpSpeed will perform a continuous lerp, otherwise will interp at constant speed + * @return new interpolated position + */ + +native static final function Rotator RInterpTo( rotator Current, rotator Target, float DeltaTime, float InterpSpeed, optional bool bConstantInterpSpeed ); + + +/** + * Returns a Rotator axis within the [-32768,+32767] range in float + * + * @param RotAxis, axis of the rotator + * @return Normalized axis value, within the [-32768,+32767] range. + */ +native static final function int NormalizeRotAxis(int Angle); + + +/** Gives the rotation difference between two Rotators, taking the shortest route between them (in degrees). */ +native static final function float RDiff( Rotator A, Rotator B ); + +/** + * returns Rotator Size (vector definition applied to rotators) + * @param Rotator R + * @returns mathematical vector length: Sqrt(Pitch^2 + Yaw^2 + Roll^2) + */ + +native static final function float RSize(rotator R); + + + +/** + * Clamp a rotation Axis. + * The ViewAxis rotation component must be normalized (within the [-32768,+32767] range). + * This function will set out_DeltaViewAxis to the delta needed to bring ViewAxis within the [MinLimit,MaxLimit] range. + * + * @param ViewAxis Rotation Axis to clamp + * @input out_DeltaViewAxis Delta Rotation Axis to be added to ViewAxis rotation (from ProcessViewRotation). + * Set to be the Delta to bring ViewAxis within the [MinLimit,MaxLimit] range. + * @param MaxLimit Maximum for Clamp. ViewAxis will not exceed this. + * @param MinLimit Minimum for Clamp. ViewAxis will not go below this. + */ + +static final simulated function ClampRotAxis +( + int ViewAxis, + out int out_DeltaViewAxis, + int MaxLimit, + int MinLimit +) +{ + local int DesiredViewAxis; + + ViewAxis = NormalizeRotAxis( ViewAxis ); + DesiredViewAxis = ViewAxis + out_DeltaViewAxis; + + if( DesiredViewAxis > MaxLimit ) + { + DesiredViewAxis = MaxLimit; + } + + if( DesiredViewAxis < MinLimit ) + { + DesiredViewAxis = MinLimit; + } + + out_DeltaViewAxis = DesiredViewAxis - ViewAxis; +} + +/** + * Clamp Rotator Axis. + * + * @param Current Input axis angle. + * @param Center Center of allowed angle. + * @param MaxDelta Maximum delta allowed. + * @return axis angle clamped between [Center-MaxDelta, Center+MaxDelta] + */ +static final simulated function int ClampRotAxisFromBase(int Current, int Center, int MaxDelta) +{ + local int DeltaFromCenter; + + DeltaFromCenter = NormalizeRotAxis(Current - Center); + + if( DeltaFromCenter > MaxDelta ) + { + Current = Center + MaxDelta; + } + else if( DeltaFromCenter < -MaxDelta ) + { + Current = Center - MaxDelta; + } + + return Current; +}; + + +/** + * Clamp Rotator Axis. + * + * @param Current Input axis angle. + * @param Min Min allowed angle. + * @param Max Max allowed angle. + * @return axis angle clamped between [Min, Max] + */ +static final simulated function int ClampRotAxisFromRange(int Current, int Min, int Max) +{ + local int Delta, Center; + + Delta = NormalizeRotAxis(Max - Min) / 2; + Center = NormalizeRotAxis(Max + Min) / 2; + + return ClampRotAxisFromBase(Current, Center, Delta); +}; + + +/** + * Smooth clamp a rotator axis. + * This is mainly used to bring smoothly a rotator component within a certain range [MinLimit,MaxLimit]. + * For example to limit smoothly the player's ViewRotation Pitch or Yaw component. + * + * @param fDeltaTime Elapsed time since this function was last called, for interpolation. + * @param ViewAxis Rotator's Axis' current angle. + * @input out_DeltaViewAxis Delta Value of Axis to be added to ViewAxis (through PlayerController::ProcessViewRotation(). + * This value gets modified. + * @param MaxLimit Up angle limit. + * @param MinLimit Negative angle limit (value must be negative) + * @param InterpolationSpeed Interpolation Speed to bring ViewAxis within the [MinLimit,MaxLimit] range. + */ + +static final simulated function bool SClampRotAxis +( + float DeltaTime, + int ViewAxis, + out int out_DeltaViewAxis, + int MaxLimit, + int MinLimit, + float InterpolationSpeed +) +{ + local bool bClamped; + + // make sure rotation components are normalized + out_DeltaViewAxis = NormalizeRotAxis( out_DeltaViewAxis ); + ViewAxis = NormalizeRotAxis( ViewAxis ); + + // forbid player from going beyond limits through fDeltaViewAxis + if( ViewAxis <= MaxLimit && (ViewAxis + out_DeltaViewAxis) >= MaxLimit ) + { + out_DeltaViewAxis = MaxLimit - ViewAxis; + bClamped = TRUE; + } + else if( ViewAxis > MaxLimit ) + { + // if players goes counter interpolation, ignore input + if( out_DeltaViewAxis > 0 ) + { + out_DeltaViewAxis = 0.f; + } + // if above limit, interpolate back to within limits + if( (ViewAxis + out_DeltaViewAxis) > MaxLimit ) + { + out_DeltaViewAxis = FInterpTo(ViewAxis, MaxLimit, DeltaTime, InterpolationSpeed ) - ViewAxis - 1; + } + } + // forbid player from going beyond limits through fDeltaViewAxis + else if( ViewAxis >= MinLimit && (ViewAxis + out_DeltaViewAxis) <= MinLimit ) + { + out_DeltaViewAxis = MinLimit - ViewAxis; + bClamped = TRUE; + } + else if( ViewAxis < MinLimit ) + { + // if players goes counter interpolation, ignore input + if( out_DeltaViewAxis < 0 ) + { + out_DeltaViewAxis = 0.f; + } + // if above limit, interpolate back to within limits + if( (ViewAxis + out_DeltaViewAxis) < MinLimit ) + { + out_DeltaViewAxis += FInterpTo(ViewAxis, MinLimit, DeltaTime, InterpolationSpeed ) - ViewAxis + 1; + } + } + return bClamped; +} + +/** Create a Rotation from independant Pitch, Yaw, Roll */ +static final function Rotator MakeRotator(int Pitch, int Yaw, int Roll) +{ + local rotator R; + + R.Pitch = Pitch; + R.Yaw = Yaw; + R.Roll = Roll; + return R; +} + +// +// String operators. +// + +native(112) static final operator(40) string $ ( coerce string A, coerce string B ); +native(168) static final operator(40) string @ ( coerce string A, coerce string B ); +native(115) static final operator(24) bool < ( string A, string B ); +native(116) static final operator(24) bool > ( string A, string B ); +native(120) static final operator(24) bool <= ( string A, string B ); +native(121) static final operator(24) bool >= ( string A, string B ); +native(122) static final operator(24) bool == ( string A, string B ); +native(123) static final operator(26) bool != ( string A, string B ); +native(124) static final operator(24) bool ~= ( string A, string B ); +native(322) static final operator(44) string $= ( out string A, coerce string B ); +native(323) static final operator(44) string @= ( out string A, coerce string B ); +native(324) static final operator(45) string -= ( out string A, coerce string B ); + + +// +// String functions. +// + +native(125) static final function int Len ( coerce string S ); +native(126) static final function int InStr ( coerce string S, coerce string t, optional bool bSearchFromRight, optional bool bIgnoreCase, optional int StartPos ); +native(127) static final function string Mid ( coerce string S, int i, optional int j ); +native(128) static final function string Left ( coerce string S, int i ); +native(234) static final function string Right ( coerce string S, int i ); +native(235) static final function string Caps ( coerce string S ); +native(238) static final function string Locs ( coerce string S); +native(236) static final function string Chr ( int i ); +native(237) static final function int Asc ( string S ); +native(201) static final function string Repl ( coerce string Src, coerce string Match, coerce string With, optional bool bCaseSensitive ); + +/** + * Splits Text on the first Occurrence of Split and returns the remaining + * part of Text. + */ +static final function string Split(coerce string Text, coerce string SplitStr, optional bool bOmitSplitStr) +{ + local int pos; + pos = InStr(Text,SplitStr); + if (pos != -1) + { + if (bOmitSplitStr) + { + return Mid(Text,pos+Len(SplitStr)); + } + return Mid(Text,pos); + } + else + { + return Text; + } +} + +/** Get right most number from an actor name (ie Text == "CoverLink_45" returns "45") */ +static final function string GetRightMost( coerce string Text ) +{ + local int Idx; + Idx = InStr(Text,"_"); + while (Idx != -1) + { + Text = Mid(Text,Idx+1,Len(Text)); + Idx = InStr(Text,"_"); + } + return Text; +} + +/** + * Create a single string from an array of strings, using the delimiter specified, optionally ignoring blank members + * + * @param StringArray the array of strings to join into the single string + * @param out_Result [out] will contain a single string containing all elements of the array, separated by the delimiter specified + * @param Delim the delimiter to insert where array elements are concatenated + * @param bIgnoreBlanks TRUE to skip elements which contain emtpy strings + */ +static final function JoinArray(array StringArray, out string out_Result, optional string delim = ",", optional bool bIgnoreBlanks = true) +{ + local int i; + + out_Result = ""; + for (i = 0; i < StringArray.Length; i++) + { + if ( (StringArray[i] != "") || (!bIgnoreBlanks) ) + { + if (out_Result != "" || (!bIgnoreBlanks && i > 0) ) + out_Result $= delim; + + out_Result $= StringArray[i]; + } + } +} + +/** + * Breaks up a delimited string into elements of a string array. + * + * @param BaseString - The string to break up + * @param Pieces - The array to fill with the string pieces + * @param Delim - The string to delimit on + * @param bCullEmpty - If true, empty strings are not added to the array + */ +native static final function ParseStringIntoArray(string BaseString, out array Pieces, string Delim, bool bCullEmpty); + +/** + * Wrapper for splitting a string into an array of strings using a single expression. + */ +static final function array SplitString( string Source, optional string Delimiter=",", optional bool bCullEmpty ) +{ + local array Result; + ParseStringIntoArray(Source, Result, Delimiter, bCullEmpty); + return Result; +} + +/** + * Returns the full path name of the specified object (including package and groups), ie CheckObject::GetPathName(). + */ +native static final function string PathName(Object CheckObject); + + +// +// Object operators and functions. +// + +native(114) static final operator(24) bool == ( Object A, Object B ); +native(119) static final operator(26) bool != ( Object A, Object B ); + +native static final operator(24) bool == ( Interface A, Interface B ); +native static final operator(26) bool != ( Interface A, Interface B ); + +/** + * Determine if a class is a child of another class. + * + * @return TRUE if TestClass == ParentClass, or if TestClass is a child of ParentClass; FALSE otherwise, or if either + * the value for either parameter is 'None'. + */ +native(258) static final function bool ClassIsChildOf( class TestClass, class ParentClass ); +native(197) final function bool IsA( name ClassName ); + + +// +// Name operators. +// + +native(254) static final operator(24) bool == ( name A, name B ); +native(255) static final operator(26) bool != ( name A, name B ); + +// +// Matrix operators and functions +// +native static final operator(34) matrix * (Matrix A, Matrix B); + +native static final function vector TransformVector(Matrix TM, vector A); +native static final function vector InverseTransformVector(Matrix TM, vector A); +native static final function vector TransformNormal(Matrix TM, vector A); +native static final function vector InverseTransformNormal(Matrix TM, vector A); +native static final function matrix MakeRotationTranslationMatrix(vector Translation, Rotator Rotation); +native static final function matrix MakeRotationMatrix(Rotator Rotation); +native static final function rotator MatrixGetRotator(Matrix TM); +native static final function vector MatrixGetOrigin(Matrix TM); +native static final function vector MatrixGetAxis(Matrix TM, EAxis Axis); + +// +// Quaternion functions +// + +native static final function Quat QuatProduct( Quat A, Quat B ); +native static final function float QuatDot( Quat A, Quat B ); +native static final function Quat QuatInvert( Quat A ); +native static final function vector QuatRotateVector( Quat A, vector B ); +native static final function Quat QuatFindBetween( Vector A, Vector B ); +native static final function Quat QuatFromAxisAndAngle( Vector Axis, Float Angle ); +native static final function Quat QuatFromRotator( rotator A ); +native static final function rotator QuatToRotator( Quat A ); +native static final function Quat QuatSlerp( Quat A, Quat B, float Alpha, optional bool bShortestPath ); + +native(270) static final operator(16) Quat + (Quat A, Quat B); +native(271) static final operator(16) Quat - (Quat A, Quat B); + +// +// Vector2D functions +// + +native static final operator(16) vector2d + (vector2d A, vector2d B); +native static final operator(16) vector2d - (vector2d A, vector2d B); +native static final operator(16) vector2d * (vector2d A, float B); +native static final operator(16) vector2d / (vector2d A, float B ); +native static final operator(34) vector2d *= (out vector2d A, float B); +native static final operator(34) vector2d /= (out vector2d A, float B); +native static final operator(34) vector2d += (out vector2d A, vector2d B); +native static final operator(34) vector2d -= (out vector2d A, vector2d B); + + +/** + * Returns the value in the Range, relative to Pct. + * Examples: + * - GetRangeValueByPct( Range, 0.f ) == Range.X + * - GetRangeValueByPct( Range, 1.f ) == Range.Y + * - GetRangeValueByPct( Range, 0.5 ) == (Range.X+Range.Y)/2 + * + * @param Range Range of values. [Range.X,Range.Y] + * @param Pct Relative position in range in percentage. [0,1] + * + * @return the value in the Range, relative to Pct. + */ +static final simulated function float GetRangeValueByPct( Vector2D Range, float Pct ) +{ + return ( Range.X + (Range.Y-Range.X) * Pct ); +} + + +/** + * Returns the relative percentage position Value is in the Range. + * Examples: + * - GetRangeValueByPct( Range, Range.X ) == 0 + * - GetRangeValueByPct( Range, Range.Y ) == 1 + * - GetRangeValueByPct( Range, (Range.X+Range.Y)/2 ) == 0.5 + * + * @param Range Range of values. [Range.X,Range.Y] + * @param Value Value between Range. + * + * @return relative percentage position Value is in the Range. + */ +static final simulated function float GetRangePctByValue( Vector2D Range, float Value ) +{ + return (Range.Y == Range.X) ? Range.X : (Value - Range.X) / (Range.Y - Range.X); +} + +/** + * Useful for mapping a value in one value range to a different value range. Output is clamped to the OutputRange. + * e.g. given that velocities [50..100] correspond to a sound volume of [0.2..1.4], find the + * volume for a velocity of 77. + */ +static final simulated native function float GetMappedRangeValue(vector2d InputRange, vector2d OutputRange, float Value); + + +/** Construct a vector2d variable */ +static final function vector2d vect2d( float InX, float InY ) +{ + local vector2d NewVect2d; + + NewVect2d.X = InX; + NewVect2d.Y = InY; + return NewVect2d; +} + +/** Evaluate a float curve for an input of InVal */ +native static final function float EvalInterpCurveFloat(const out InterpCurveFloat FloatCurve, float InVal); +/** Evaluate a vector curve for an input of InVal */ +native static final function vector EvalInterpCurveVector(const out InterpCurveVector VectorCurve, float InVal); +/** Evaluate a vector2D curve for an input of InVal */ +native static final function vector2D EvalInterpCurveVector2D(const out InterpCurveVector2D Vector2DCurve, float InVal); + +// +// Color functions +// + +static final operator(20) color - (color A, color B) +{ + A.R -= B.R; + A.G -= B.G; + A.B -= B.B; + return A; +} + +static final operator(16) color * (float A, color B) +{ + B.R *= A; + B.G *= A; + B.B *= A; + return B; +} + +static final operator(16) color * (color A, float B) +{ + A.R *= B; + A.G *= B; + A.B *= B; + return A; +} + +static final operator(20) color + (color A, color B) +{ + A.R += B.R; + A.G += B.G; + A.B += B.B; + return A; +} + +/** Create a Color from independant RGBA components */ +static final function Color MakeColor(byte R, byte G, byte B, optional byte A) +{ + local Color C; + + C.R = R; + C.G = G; + C.B = B; + C.A = A; + return C; +} + +/** Util to interpolate between two colors */ +static final function Color LerpColor(Color A, Color B, float Alpha) +{ + local vector FloatA, FloatB, FloatResult; + local float AlphaA, AlphaB, FloatResultAlpha; + local color Result; + + FloatA.X = A.R; + FloatA.Y = A.G; + FloatA.Z = A.B; + AlphaA = A.A; + + FloatB.X = B.R; + FloatB.Y = B.G; + FloatB.Z = B.B; + AlphaB = B.A; + + FloatResult = FloatA + ((FloatB - FloatA) * FClamp(Alpha, 0.0, 1.0)); + FloatResultAlpha = AlphaA + ((AlphaB - AlphaA) * FClamp(Alpha, 0.0, 1.0)); + + Result.R = FloatResult.X; + Result.G = FloatResult.Y; + Result.B = FloatResult.Z; + Result.A = FloatResultAlpha; + + return Result; +} + +// +// Linear Color Functions +// + +/** Create a LinearColor from independant RGBA components. */ +static final function LinearColor MakeLinearColor( float R, float G, float B, float A ) +{ + local LinearColor LC; + + LC.R = R; + LC.G = G; + LC.B = B; + LC.A = A; + return LC; +} + +/** converts a color to a LinearColor + * @param OldColor the color to convert + * @return the matching LinearColor + */ +static final function LinearColor ColorToLinearColor(color OldColor) +{ + return MakeLinearColor(float(OldColor.R) / 255.0, float(OldColor.G) / 255.0, float(OldColor.B) / 255.0, float(OldColor.A) / 255.0); +} + +/** multiply the RGB components of a LinearColor by a float */ +static final operator(16) LinearColor * (LinearColor LC, float Mult) +{ + LC.R *= Mult; + LC.G *= Mult; + LC.B *= Mult; + return LC; +} + +/** subtract the RGB components of B from the RGB components of A */ +static final operator(20) LinearColor - (LinearColor A, LinearColor B) +{ + A.R -= B.R; + A.G -= B.G; + A.B -= B.B; + return A; +} + +//============================================================================= +// General functions. + + +// this define allows us to detect code that is directly calling functions that should only be called through a macro, such as +// LogInternal & WarnInternal +`if(`isdefined(FINAL_RELEASE)) + `if(`isdefined(FINAL_RELEASE_DEBUGCONSOLE)) + `define prevent_direct_calls + `else + `define prevent_direct_calls private + `endif +`else + `define prevent_direct_calls +`endif + +// +// Logging. +// +/** + * Writes a message to the log. This function should never be called directly - use the `log macro instead, which has the following signature: + * + * log( coerce string Msg, optional bool bCondition=true, optional name LogTag='ScriptLog' ); + * + * @param Msg the string to print to the log + * @param bCondition if specified, the message is only printed to the log if this condition is satisfied. + * @param LogTag if specified, the message will be prepended with this tag in the log file + * + */ +native(231) final static `{prevent_direct_calls} function LogInternal( coerce string S, optional name Tag ); + +/** + * Same as calling LogInternal(SomeMsg, 'Warning'); This function should never be called directly - use the `warn macro instead, which has the following signature: + * + * warn( coerce string Msg, optional bool bCondition=true ); + */ +native(232) final static `{prevent_direct_calls} function WarnInternal( coerce string S ); + +native static function string Localize( string SectionName, string KeyName, string PackageName ); + +/** given a path to a localized key of the form "Package.Section.Name", + * return the appropriate value from the localization file for the current language + */ +static final function string ParseLocalizedPropertyPath(string PathName) +{ + local array Pieces; + + ParseStringIntoArray(PathName, Pieces, ".", false); + if (Pieces.length >= 3) + { + return Localize(Pieces[1], Pieces[2], Pieces[0]); + } + else + { + return ""; + } +} + +/** + * Dumps the current script function stack to the log file, useful + * for debugging. + */ +native static final function ScriptTrace(); + + +/** + * Gets the current script function stack back so you can log it to a specific log location (e.g. AILog). + */ +native static final function String GetScriptTrace(); + + +/** + * Script-induced breakpoint. Useful for examining state with the debugger at a particular point in script. + * + * @param UserFlags user-defined flags to be used for e.g. indentifying different calls to DebugBreak in the same session + * @param DebuggerType C++ debugger, UScript debugger, or both + */ +native static final function DebugBreak( optional int UserFlags, optional EDebugBreakType DebuggerType=DEBUGGER_NativeOnly ); + +/** + * Returns the current calling function's name, useful for + * debugging. + */ + +native static final function Name GetFuncName(); + +/** + * Enables/disables script function call trace logging. + */ +native static final function SetUTracing( bool bShouldUTrace ); + +/** + * Returns whether script function call trace logging is currently enabled. + */ +native static final function bool IsUTracing(); + + +// +// Goto state and label. +// + +/** + * Transitions to the desired state and label if specified, + * generating the EndState event in the current state if applicable + * and BeginState in the new state, unless transitioning to the same + * state. + * + * @param NewState - new state to transition to + * + * @param Label - optional Label to jump to + * + * @param bForceEvents - optionally force EndState/BeginState to be + * called even if transitioning to the same state. + * + * @param bKeepStack - prevents state stack from being cleared + */ + +native(113) final function GotoState( optional name NewState, optional name Label, optional bool bForceEvents, optional bool bKeepStack ); + + +/** + * Checks the current state and determines whether or not this object + * is actively in the specified state. Note: This does work with + * inherited states. + * + * @param TestState - state to check for + * @param bTestStateStack - check the state stack? (does *NOT* work with inherited states in the stack) + * + * @return True if currently in TestState + */ + +native(281) final function bool IsInState( name TestState, optional bool bTestStateStack ); + + +/** + * Returns true if TestState derives from TestParentState. + */ + +native final function bool IsChildState(Name TestState, Name TestParentState); + + +/** + * Returns the current state name, useful for determining current + * state similar to IsInState. Note: This *doesn't* work with + * inherited states, in that it will only compare at the lowest + * state level. + * + * @return Name of the current state + */ + +native(284) final function name GetStateName(); + + +/** + * Pushes the new state onto the state stack, setting it as the + * current state until a matching PopState() is called. Note that + * multiple states may be pushed on top of each other. + * You may not push the same state multiple times. + * + * This will call PushedState when entering the state that was just + * pushed on the state stack. It will not call BeginState. + * @see event PushedState + * @see event ContinuedState + * + * @param NewState - name of the state to push on the stack + * + * @param NewLabel - optional name of the state label to jump to + */ + +native final function PushState(Name NewState, optional Name NewLabel); + + +/** + * Pops the current pushed state, returning execution to the previous + * state at the same code point. Note: PopState() will have no effect + * if no state has been pushed onto the stack. + * + * This will call PoppedState when entering the state that was just + * pushed on the state stack. It will not call EndState. + * @see event PoppedState + * @see event PausedState + * + * @param bPopAll - optionally pop all states on the stack to the + * originally executing one + */ + +native final function PopState(optional bool bPopAll); + + +/** + * Logs the current state stack for debugging purposes. + */ + +native final function DumpStateStack(); + + + +// +// State notification events +// + +/** + * Called immediately when entering a state, while within the + * GotoState() call that caused the state change (before any + * state code is executed). + */ +event BeginState(Name PreviousStateName); + +/** + * Called immediately before going out of the current state, while + * within the GotoState() call that caused the state change, and + * before BeginState() is called within the new state. + */ +event EndState(Name NextStateName); + +/** + * Called immediately in the new state that was pushed onto the + * state stack, before any state code is executed. + */ +event PushedState(); + +/** + * Called immediately in the current state that is being popped off + * of the state stack, before the new state is activated. + */ +event PoppedState(); + +/** + * Called on the state that is being paused because of a PushState(). + */ +event PausedState(); + +/** + * Called on the state that is no longer paused because of a PopState(). + */ +event ContinuedState(); + + + +// +// Probe messages. +// + +native(117) final function Enable( name ProbeFunc ); +native(118) final function Disable( name ProbeFunc ); + + +// +// Object handling. +// + +native static final function name GetEnum( object E, coerce int i ); +native static final function object DynamicLoadObject( string ObjectName, class ObjectClass, optional bool MayFail ); +native static final function object FindObject( string ObjectName, class ObjectClass ); + + +// +// Configuration. +// + +native(536) final function SaveConfig(); +native static final function StaticSaveConfig(); + +/** + * Import property values from JSON formatted string + * + * @param PropertyName name of the property owned by this object + * @param JSON string that contains JSON format property values + */ +native static final function ImportJSON(string PropertyName, const out string JSON); + +/* +/** + * Saves the current value for all configurable properties in this object to the .ini file. The values for any global config + * properties will be propagated to all child classes. + * + * @param bRefreshInstances if TRUE, all instances of this class will re-load the values for their configurable properties + * from the .ini. THIS WILL CLOBBER ANY EXISTING VALUES! + * @param PropertyName if specified, only this property's value will be saved. + */ +native(536) final function SaveConfig( optional bool bRefreshInstances, optional string PropertyName ); + +/** + * Saves the default values for all configurable properties in this object's class to the .ini file. The values for any global config + * properties will be propagated to all child classes. + * + * @param bRefreshInstances if TRUE, all instances of this class will re-load the values for their configurable properties + * from the .ini. THIS WILL CLOBBER ANY EXISTING VALUES! + * @param PropertyName if specified, only this property's value will be saved. + */ +native static final function StaticSaveConfig( optional bool bRefreshInstances, optional string PropertyName ); + +/** + * Resets the values for configurable properties in this object's class back to the values in the corresponding Default*.ini file. + * + * @param bRefreshInstances if TRUE, all instances of this class will re-load the values for their configurable properties + * from the .ini. THIS WILL CLOBBER ANY EXISTING VALUES! + * @param PropertyName if specified, only this property's value will be reset. + */ +native static final function ResetConfig( optional bool bRefreshInstances, optional string PropertyName ); + +/** + * Removes the values for all configurable properties in this object's class from the .ini file. + * + * @param PropertyName if specified, only this property's value will be removed. + */ +native(537) final function ClearConfig( optional string PropertyName ); + +/** + * Removes the values for all configurable properties in this object's class from the .ini file. + * + * @param PropertyName if specified, only this property's value will be removed. + */ +native static final function StaticClearConfig( optional string PropertyName ); +*/ + +/** + * Retrieve the names of sections which contain data for the specified PerObjectConfig class. + * + * @param SearchClass the PerObjectConfig class to retrieve sections for. + * @param out_SectionNames will receive the list of section names that correspond to PerObjectConfig sections of the specified class + * @param ObjectOuter the Outer to use for determining which file to look in. Specify the same object that is used when creating the PerObjectConfig + * objects that sections are being retrieved for. (PerObjectConfig data is generally stored in a file named after the Outer used when + * creating those objects, unless the PerObjectConfig class specifies a config file in its class declaration); + * specify None to use the transient package as the Outer. + * @param MaxResults the maximum number of section names to retrieve + * + * @return TRUE if the file specified was found and it contained at least 1 section for the specified class + */ +native static final function bool GetPerObjectConfigSections( class SearchClass, out array out_SectionNames, optional Object ObjectOuter, optional int MaxResults=1024 ); + + +// +// Maths +// + +/** + * Calculates the distance of a given Point in world space to a given line, + * defined by the vector couple (Origin, Direction). + * + * @param Point point to check distance to Axis + * @param Line unit vector indicating the direction to check against + * @param Origin point of reference used to calculate distance + * @param OutClosestPoint optional point that represents the closest point projected onto Axis + * + * @return distance of Point from line defined by (Origin, Direction) + */ +native final function float PointDistToLine(vector Point, vector Line, vector Origin, optional out vector OutClosestPoint); + +/** + * Returns closest distance from a point to a segment. + * + * @param Point point to check distance for + * @param StartPoint StartPoint of segment + * @param EndPoint EndPoint of segment + * @param OutClosestPoint Closest point on segment. + * + * @return closest distance from Point to segment defined by (StartPoint, EndPoint). + */ +native final function float PointDistToSegment(Vector Point, Vector StartPoint, Vector EndPoint, optional out Vector OutClosestPoint); + +/** + * Calculates the distance of a given point to the given plane. (defined by a combination of vector and rotator) + * Rotator.AxisX = U, Rotator.AxisY = Normal, Rotator.AxisZ = V + * + * @param Point Point to check distance to Orientation + * @param Orientation Rotator indicating the direction to check against + * @param Origin Point of reference used to calculate distance + * @param out_ClosestPoint Optional point that represents the closest point projected onto Plane defined by the couple (Origin, Orientation) + * + * @return distance of Point to plane + */ + +simulated final function float PointDistToPlane( Vector Point, Rotator Orientation, Vector Origin, optional out vector out_ClosestPoint ) +{ + local vector AxisX, AxisY, AxisZ, PointNoZ, OriginNoZ; + local float fPointZ, fProjDistToAxis; + + // Get orientation axis' + GetAxes(Orientation, AxisX, AxisY, AxisZ); + + // Remove Z component of Point Location + fPointZ = Point dot AxisZ; + PointNoZ = Point - fPointZ * AxisZ; + + // Remove Z component of Origin + OriginNoZ = Origin - (Origin dot AxisZ) * AxisZ; + + // Projected distance of Point onto AxisX. + fProjDistToAxis = (PointNoZ - OriginNoZ) Dot AxisX; + out_ClosestPoint = OriginNoZ + fProjDistToAxis * AxisX + fPointZ * AxisZ; + + // return distance to closest point + return VSize(out_ClosestPoint-Point); +} + + +/** +* Calculates a point's projection onto a plane +* @param Point point to project onto the plane +* @param A point on plane +* @param B point on plane +* @param C point on plane +* @return projection of point onto the plane defined by ABC +*/ +native static final function Vector PointProjectToPlane(Vector Point, Vector A, Vector B, Vector C); + +/** + * Calculates the dotted distance of vector 'Direction' to coordinate system O(AxisX,AxisY,AxisZ). + * + * Orientation: (consider 'O' the first person view of the player, and 'Direction' a vector pointing to an enemy) + * - positive azimuth means enemy is on the right of crosshair. (negative means left). + * - positive elevation means enemy is on top of crosshair, negative means below. + * + * @Note: 'Azimuth' (.X) sign is changed to represent left/right and not front/behind. front/behind is the funtion's return value. + * + * @param OutDotDist .X = 'Direction' dot AxisX relative to plane (AxisX,AxisZ). (== Cos(Azimuth)) + * .Y = 'Direction' dot AxisX relative to plane (AxisX,AxisY). (== Sin(Elevation)) + * @param Direction direction of target. + * @param AxisX X component of reference system. + * @param AxisY Y component of reference system. + * @param AxisZ Z component of reference system. + * + * @return true if 'Direction' is facing AxisX (Direction dot AxisX >= 0.f) + */ + +native static final function bool GetDotDistance +( + out Vector2D OutDotDist, + Vector Direction, + Vector AxisX, + Vector AxisY, + Vector AxisZ +); + +/** + * Calculates the angular distance of vector 'Direction' to coordinate system O(AxisX,AxisY,AxisZ). + * + * Orientation: (consider 'O' the first person view of the player, and 'Direction' a vector pointing to an enemy) + * - positive azimuth means enemy is on the right of crosshair. (negative means left). + * - positive elevation means enemy is on top of crosshair, negative means below. + * + * @param out_AngularDist .X = Azimuth angle (in radians) of 'Direction' vector compared to plane (AxisX,AxisZ). + * .Y = Elevation angle (in radians) of 'Direction' vector compared to plane (AxisX,AxisY). + * @param Direction Direction of target. + * @param AxisX X component of reference system. + * @param AxisY Y component of reference system. + * @param AxisZ Z component of reference system. + * + * @output true if 'Direction' is facing AxisX (Direction dot AxisX >= 0.f) + */ +native static final function bool GetAngularDistance +( + out Vector2D OutAngularDist, + Vector Direction, + Vector AxisX, + Vector AxisY, + Vector AxisZ +); + +/** + * Converts Dot distance to angular distance. + * @see GetAngularDistance() and GetDotDistance(). + * + * @param OutAngDist Angular distance in radians. + * @param DotDist Dot distance. + */ +native static final function GetAngularFromDotDist( out Vector2D OutAngDist, Vector2D DotDist ); + + +/* transforms angular distance in radians to degrees */ +static final simulated function GetAngularDegreesFromRadians( out Vector2D OutFOV ) +{ + OutFOV.X = OutFOV.X*RadToDeg; + OutFOV.Y = OutFOV.Y*RadToDeg; +} + +/** + * Returns world space angle (in radians) of given vector + * + * @param Dir Vector to be converted into heading angle + */ +static final simulated function float GetHeadingAngle( Vector Dir ) +{ + local float Angle; + + Angle = Acos( FClamp( Dir.X, -1.f, 1.f ) ); + if( Dir.Y < 0.f ) + { + Angle *= -1.f; + } + + return Angle; +} + +/** + * Gets the difference in world space angles in [-PI,PI] range + * + * @param A1 First angle + * @param A2 Second angle + */ +static final simulated function float FindDeltaAngle( float A1, float A2 ) +{ + local float Delta; + + // Find the difference + Delta = A2 - A1; + // If change is larger than PI + if( Delta > PI ) + { + // Flip to negative equivalent + Delta = Delta - (PI * 2.f); + } + else if( delta < -PI ) + { + // Otherwise, if change is smaller than -PI + // Flip to positive equivalent + Delta = Delta + (PI * 2.f); + } + + // Return delta in [-PI,PI] range + return Delta; +} + +static final simulated function float UnwindHeading( float a ) +{ + while( a > PI ) + { + a -= (PI * 2.0f); + } + + while( a < -PI ) + { + a += (PI * 2.0f); + } + + return a; +} + + +/** + * Converts a float value to a 0-255 byte, assuming a range of + * 0.f to 1.f. + * + * @param inputFloat - float to convert + * + * @param bSigned - optional, assume a range of -1.f to 1.f + * + * @return byte value 0-255 + */ + +simulated final function byte FloatToByte(float inputFloat, optional bool bSigned) +{ + if (bSigned) + { + // handle a 0.02f threshold so we can guarantee valid 0/255 values + if (inputFloat > 0.98f) + { + return 255; + } + else if (inputFloat < -0.98f) + { + return 0; + } + else + { + return byte((inputFloat+1.f)*128.f); + } + } + else + { + if (inputFloat > 0.9961f) + { + return 255; + } + else if (inputFloat < 0.004f) + { + return 0; + } + else + { + return byte(inputFloat*255.f); + } + } +} + + +/** + * Converts a 0-255 byte to a float value, to a range of 0.f + * to 1.f. + * + * @param inputByte - byte to convert + * + * @param bSigned - optional, spit out -1.f to 1.f instead + * + * @return newly converted value + */ + +simulated final function float ByteToFloat(byte inputByte, optional bool bSigned) +{ + if( bSigned ) + { + return ((float(inputByte)/128.f)-1.f); + } + else + { + return (float(inputByte)/255.f); + } +} + +/** + * Returns whether the object is pending kill and about to have references to it NULLed by + * the garbage collector. + * + * @return TRUE if object is pending kill, FALSE otherwise + */ +native final function bool IsPendingKill(); + +/** @return the name of the package this object resides in */ +final function name GetPackageName() +{ + local Object O; + + O = self; + while (O.Outer != None) + { + O = O.Outer; + } + return O.Name; +} + +/** + * Script hook to FRotationMatrix::TransformFVector(). + */ +native final function vector TransformVectorByRotation(rotator SourceRotation, vector SourceVector, optional bool bInverse); + + +/** + * Returns a string containing a system timestamp + */ +native final function string TimeStamp(); + +/** + * Return the system time components. + */ +native final function GetSystemTime( out int Year, out int Month, out int DayOfWeek, out int Day, out int Hour, out int Min, out int Sec, out int MSec ); + +/** @return the current engine version number for this build */ +native final function int GetEngineVersion(); + +/** @return the changelist number that was used when generating this build */ +native final function int GetBuildChangelistNumber(); + +final function int GetRandomOptionSumFrequency( const out array FreqList ) +{ + local float FreqSum, RandVal; + local int Idx; + + for( Idx = 0; Idx < FreqList.Length; Idx++ ) + { + FreqSum += FreqList[Idx]; + } + + RandVal = FRand() * FreqSum; + FreqSum = 0; + for( Idx = 0; Idx < FreqList.Length; Idx++ ) + { + FreqSum += FreqList[Idx]; + if( RandVal < FreqSum ) + { + return Idx; + } + } + + return -1; +} + +/** @return the three character language identifier currently in use */ +native static final function string GetLanguage(); + + +/** + * Invalidate the specified Guid (sets all values to zero) + * + * @param InGuid Guid to invalidate + */ +native static final function InvalidateGuid( out Guid InGuid ); + +/** + * Determine if the specified Guid is valid or not + * + * @param InGuid Guid to check the validity of + * + * @return True if the specified Guid is valid, false if it is not + */ +native static final function bool IsGuidValid( const out Guid InGuid ); + +/** Create a new Guid */ +native static final function Guid CreateGuid(); + +/** + * Construct a Guid from the specified string, if possible + * + * @param InGuidString String to construct the Guid from (should be in a format matching the output of GetStringFromGuid) + * + * @return A Guid constructed from the specified string, if possible; Otherwise, an invalid Guid (all zeroes) + */ +native static final function Guid GetGuidFromString( const out string InGuidString ); + +/** + * Get the string representation of the specified Guid + * + * @param InGuid Guid to get the string representation of + * + * @return The string representation of the specified Guid + */ +native static final function string GetStringFromGuid( const out guid InGuid ); + + +native static final function int ProfNodeStart(string TimerName); +native static final function ProfNodeStop(optional int AssumedTimerIndex = -1); +native static final function ProfNodeSetTimeThresholdSeconds(float Threshold); +native static final function ProfNodeSetDepthThreshold(int Depth); +native static final function ProfNodeEvent(string EventName); + +defaultproperties +{ +} diff --git a/Core/Classes/Subsystem.uc b/Core/Classes/Subsystem.uc new file mode 100644 index 0000000..b8fa5ec --- /dev/null +++ b/Core/Classes/Subsystem.uc @@ -0,0 +1,33 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +//============================================================================= +// Subsystem: The base class all subsystems. Subsystems usually +// correspond to large C++ classes. The benefit of defining a C++ class as +// a subsystem is that you can make some of its variables script-accessible, +// and you can make some of its properties automatically saveable as part +// of the configuration. +// +// This is a built-in Unreal class and it shouldn't be modified. +//============================================================================= +class Subsystem extends Object + abstract + native + transient + inherits(FExec); + +cpptext +{ + + // USubsystem interface. + virtual void Tick( FLOAT DeltaTime ) + {} + + // FExec interface. + virtual UBOOL Exec( const TCHAR* Cmd, FOutputDevice& Ar ) { return 0; } + +} + +defaultproperties +{ +} diff --git a/Core/Globals.uci b/Core/Globals.uci new file mode 100644 index 0000000..6e1b3ca --- /dev/null +++ b/Core/Globals.uci @@ -0,0 +1,144 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +/** + * Globals.uci - Unreal Engine global include file for UnrealScript. + * Never include this file before the class definition. + */ + + +/** + * Macro for including the current function name in a string. + */ +`define Location "("$Name$") `{ClassName}::"$GetStateName()$":"$GetFuncName() +`define StaticLocation "`{ClassName}::"$GetStateName()$":"$GetFuncName() + +/** + * Expands to an in-line if statement with a log if debug is defined; + * it expands to nothing if debug is not defined. The debug macro takes + * its value from the -debug flag on the script compilation command line. + * + * Also demonstrates how to use backslashes to declare a multi-line macro. + * + * @param msg the string that should be logged + * @param cond [opt] the condition that is used to evaluate whether the message should be written + * @param tag [opt] the tag for the log statement + */ + +/* + this macro is now added to the hardcoded symbol table, so don't try adding it again +`if(`isdefined(debug)) +`define Logd(msg,cond,tag)\ + `if(`cond)\ + if (`cond)\ + `{endif}\ + log(`msg`if(`tag),`tag`endif) +`else +`define Logd +`endif +*/ + +/** + * Expands to an in-line if statement with a log unless FINAL_RELEASE is defined; + * + * + * @param msg the string that should be logged + * @param cond [opt] the condition that is used to evaluate whether the message should be written + * @param tag [opt] the tag for the log statement + */ +/* + this macro is now added to the hardcoded symbol table, so don't try adding it again +`if( `isdefined(FINAL_RELEASE) ) + `if(`isdefined(FINAL_RELEASE_DEBUGCONSOLE)) + `define Log(msg,cond,tag) `if(`cond)if(`cond)`{endif}log(`msg`if(`tag),`tag`endif) + `else + `define Log(msg,cond,tag) + `endif +`else +`define Log(msg,cond,tag) `if(`cond)if(`cond)`{endif}log(`msg`if(`tag),`tag`endif) +`endif +*/ + +/** + * Macro for easily logging a property or function return value. Expands into a string + * containing the name of the expression and value of the expression. + * Useful for writing self-documenting log statements. + * + * @param expr the expression that you want to log + * @param name [opt] the text that will immediately preceed the expression's value + * in the log statement. if not specified, uses expr. + */ +`define ShowVar(expr,name) "`if(`name)`name`else`expr`endif:'"$`expr$"'" + +/** + * Macro for easily logging a property or function return value. Expands into a string + * containing the name of the expression and value of the expression. + * Useful for writing self-documenting log statements. + * + * @param expr the expression that you want to log + * @param name [opt] the text that will immediately preceed the expression's value + * in the log statement. if not specified, uses expr. + */ +`define ShowEnum(enum,expr,name) "`if(`name)`name`else`expr`endif:'"$GetEnum(Enum'`enum',`expr)$"'" + +/** + * Macro for easily logging the name of an object. Useful for logging objects without extraneous + * checks against None. + * + * @param obj the object that you want to log + * @param name [opt] the text that will immediately preceed the object's name + * in the log statement. if not specified, uses obj. + */ +`define ShowObj(Obj,name) "`if(`name)`name`else`Obj`endif:"$(`Obj != None ? string(`Obj.Name) : "None") + +/** + * Macro for logging the entry into a function. + * + * @param msg [opt] any additional text you'd like included in the log message + * @param cond [opt] the condition that is used to evaluate whether the message should be written + */ +`define Entry(msg,cond,tag) `log(">> "$ `Location `if(`msg)@`msg`endif, `if(`cond), `cond`{endif}`if(`tag), `tag`{endif}) + +/** + * Macro for logging the exit from a function. + * + * @param msg [opt] any additional text you'd like included in the log message + * @param cond [opt] the condition that is used to evaluate whether the message should be written + */ +`define Exit(msg,cond,tag) `log("<< "$ `Location `if(`msg)@`msg`endif, `if(`cond), `cond`{endif}`if(`tag), `tag`{endif}) + +/** + * Macro for logging an IP address + * + * @param addr the IP address you want to log + */ +// `define ShowAddr(addr) " Addr:'"$IpAddrToString(`addr)$"'" + + +`define LogFatal(cat,msg) `log("FATAL:" @ `msg,,`cat) +`define LogError(cat,msg) `log("ERROR:" @ `msg,,`cat) +`define LogWarn(cat,msg) `log("WARN:" @ `msg,,`cat) +`define LogInfo(cat,msg) `log("INFO:" @ `msg,,`cat) +`define LogDebug(cat,msg) `log("DEBUG:" @ `msg,,`cat) +`define LogTrace(cat,msg) `log("TRACE:" @ `msg,,`cat) + +/** Convenience macro for inventory debugging */ +`define LogInv(msg) `log(WorldInfo.TimeSeconds @ "Self:" @ Self @ "Instigator:" @ Instigator @ GetStateName() $ "::" $ GetFuncName() @ `msg,,'Inventory') +`define DLog(msg) `Log(WorldInfo.TimeSeconds @ Self @ GetStateName() $ "::" $ GetFuncName() @ `msg) + +/** This is a slick way to to do thing like: TimeSince(LastFoo) < Delta where the macro makes it a lot easier to read what the code is doing **/ +`define TimeSince(Time) (WorldInfo.TimeSeconds - `Time) +/** This is used for classes which are object derived and do not have access to WorldInfo so we need to pass in the Actor to get a worldinfo **/ +`define TimeSinceEx(Actor,Time) (`Actor.WorldInfo.TimeSeconds - `Time) + +//@HSL_BEGIN_XBOX +`define AddUniqueItemToArray(Array,Item) if (`Array.Find(`Item) == INDEX_NONE) { `Array.AddItem(`Item); } + +//@igs(jc): Make players and controllers 16 globally for our purposes. If you change these +// numbers, make sure you also adjust the ones in UnDingo.h +`define MAX_NUM_PLAYERS 24 +`define MAX_NUM_CONTROLLERS 24 +//@HSL_END_XBOX + +/** To use WITH_PHYSX directive in uc files. Comment this out when using WITH_NOVODEX **/ +`define WITH_PHYSX diff --git a/Core/nFringeGlobals.uci b/Core/nFringeGlobals.uci new file mode 100644 index 0000000..562b524 --- /dev/null +++ b/Core/nFringeGlobals.uci @@ -0,0 +1,49 @@ +/** + * Expands to an in-line if statement with a log if debug is defined; + * it expands to nothing if debug is not defined. The debug macro takes + * its value from the -debug flag on the script compilation command line. + * + * Also demonstrates how to use backslashes to declare a multi-line macro. + * + * @param msg the string that should be logged + * @param cond [opt] the condition that is used to evaluate whether the message should be written + * @param tag [opt] the tag for the log statement + */ +`if(`isdefined(debug)) +`define logd(msg,cond,tag)\ + `if(`cond)\ + if (`cond)\ + `{endif}\ + log(`msg`if(`tag),`tag`endif) +`else +`define logd +`endif + +/** + * Expands to an in-line if statement with a log unless FINAL_RELEASE is defined; + * + * + * @param msg the string that should be logged + * @param cond [opt] the condition that is used to evaluate whether the message should be written + * @param tag [opt] the tag for the log statement + */ +`if(`isdefined(FINAL_RELEASE)) +`define log(msg,cond,tag) +`else +`define log(msg,cond,tag) `if(`cond)if(`cond)`{endif}log(`msg`if(`tag),`tag`endif) +`endif + +`if(`isdefined(FINAL_RELEASE)) +`define warn(msg,cond) +`else +`define warn(msg,cond) `if(`cond)if(`cond)`{endif}warn(`msg) +`endif + +`if(`isdefined(FINAL_RELEASE)) +`define assert(cond) +`else +`define assert(cond) Assert(`cond) +`endif + +`define ConditionalExtends(x) + diff --git a/Engine/Classes/AICommandBase.uc b/Engine/Classes/AICommandBase.uc new file mode 100644 index 0000000..eafec51 --- /dev/null +++ b/Engine/Classes/AICommandBase.uc @@ -0,0 +1,48 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AICommandBase extends Object within AIController + native(AI) + abstract; + +/** + * When determining the utility value one can think of it in these terms: + * + * -how important is doing this action compared to other actions + * -how exciting is doing this action compared to other actions + * + * e.g. I have 2 idle actions; reading a newspaper and picking on a pedestrian. Picking on the pedestrian is more existing + * so it should be higher rated than reading the newspaper + * + * e.g. I have an action am drinking ambrosia and responding to a threat. In this case drinking ambrosia is really + * important. At the same importance as "EngageThreat" classification. So we will add EngageThreat.UtilityStartVal + * to our utilty score to represent that. + * + * + * Utility functions should be checking for the data that says whether or not something occured. They should NOT be + * checking for things like: If you were in an Idle Action and/or if your current Action has some property set. + * That is bad as that is causing undue coupling between Actions. + * + * Additionally, the Utilty Function rules all. Period. + * + * If things are not correctly occurring then the utility function is broken in some way. + * One should not try to set special bools on blackboard/controller/active state and then look for them + * + * If the current set of stimuli is not "valid" / "able to have data for the utility" then we need to + * more than likely add some generalized functionality to it. + * + * If that can not be done then we need to start along the "bool cloud" path in the stimulus struct But that should be the last option. + * + * + * + **/ +static event int GetUtility( AIController InAI ) +{ + `warn( "AICommandBase Base Class GetUtility was called. Please have your Parent Type or your indiv AICmd implement this function" ); + ScriptTrace(); + return -1; +} + +defaultproperties +{ +} \ No newline at end of file diff --git a/Engine/Classes/AIController.uc b/Engine/Classes/AIController.uc new file mode 100644 index 0000000..a7c67fd --- /dev/null +++ b/Engine/Classes/AIController.uc @@ -0,0 +1,358 @@ +//============================================================================= +// AIController, the base class of AI. +// +// Controllers are non-physical actors that can be attached to a pawn to control +// its actions. AIControllers implement the artificial intelligence for the pawns they control. +// +//Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class AIController extends Controller + native(AI); + +`if(`notdefined(__TW_)) +/** auto-adjust around corners, with no hitwall notification for controller or pawn + if wall is hit during a MoveTo() or MoveToward() latent execution. */ +var bool bAdjustFromWalls; +`endif + +/** skill, scaled by game difficulty (add difficulty to this value) */ +var float Skill; + +/** Move target from last scripted action */ +var Actor ScriptedMoveTarget; + +/** Route from last scripted action; if valid, sets ScriptedMoveTarget with the points along the route */ +var Route ScriptedRoute; + +/** if true, we're following the scripted route in reverse */ +var bool bReverseScriptedRoute; + +/** if ScriptedRoute is valid, the index of the current point we're moving to */ +var int ScriptedRouteIndex; + +/** view focus from last scripted action */ +var Actor ScriptedFocus; + +cpptext +{ + INT AcceptNearbyPath(AActor *goal); +#if __TW_PATHFINDING_ + virtual void AdjustFromWall(FVector HitNormal, AActor* HitActor); +#else + void AdjustFromWall(FVector HitNormal, AActor* HitActor); +#endif + virtual void SetAdjustLocation(FVector NewLoc,UBOOL bAdjust,UBOOL bOffsetFromBase=FALSE); + virtual FVector DesiredDirection(); + + /** Called when the AIController is destroyed via script */ + virtual void PostScriptDestroyed(); +} + +event PreBeginPlay() +{ + Super.PreBeginPlay(); + if ( bDeleteMe ) + return; + + if ( WorldInfo.Game != None ) + Skill += WorldInfo.Game.GetModifiedGameDifficulty(); + Skill = FClamp(Skill, 0, 3); +} + +`if(`__TW_PATHFINDING_) +// Adding declaration here for easier ability to call this event from native code in Engine +event AILog_Internal( coerce string LogText, optional Name LogCategory, optional bool bForce, optional bool BugIt, optional bool bSkipExtraInfo ); +`endif + +/* Reset() +reset actor to initial state - used when restarting level without reloading. +*/ +function Reset() +{ + Super.Reset(); +} + +/** + * list important AIController variables on canvas. HUD will call DisplayDebug() on the current ViewTarget when + * the ShowDebug exec is used + * + * @param HUD - HUD with canvas to draw on + * @input out_YL - Height of the current font + * @input out_YPos - Y position on Canvas. out_YPos += out_YL, gives position to draw text for next debug line. + */ +simulated function DisplayDebug(HUD HUD, out float out_YL, out float out_YPos) +{ + local int i; + local string T; + local Canvas Canvas; + + Canvas = HUD.Canvas; + + super.DisplayDebug(HUD, out_YL, out_YPos); + + if (HUD.ShouldDisplayDebug('AI')) + { + Canvas.DrawColor.B = 255; + if ( (Pawn != None) && (MoveTarget != None) && Pawn.ReachedDestination(MoveTarget) ) + Canvas.DrawText(" Skill "$Skill$" NAVIGATION MoveTarget "$GetItemName(String(MoveTarget))$"(REACHED) MoveTimer "$MoveTimer, false); + else + Canvas.DrawText(" Skill "$Skill$" NAVIGATION MoveTarget "$GetItemName(String(MoveTarget))$" MoveTimer "$MoveTimer, false); + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + + Canvas.DrawText(" Destination "$GetDestinationPosition()$" Focus "$GetItemName(string(Focus))$" Preparing Move "$bPreparingMove, false); + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + + Canvas.DrawText(" RouteGoal "$GetItemName(string(RouteGoal))$" RouteDist "$RouteDist, false); + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + + for ( i=0; i 5 ) + T = T$"--"$GetItemName(string(RouteCache[i-1])); + break; + } + else if ( i < 5 ) + T = T$GetItemName(string(RouteCache[i]))$"-"; + } + + Canvas.DrawText(" RouteCache: "$T, false); + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + } +} + +event SetTeam(int inTeamIdx) +{ + WorldInfo.Game.ChangeTeam(self,inTeamIdx,true); +} + +simulated event GetPlayerViewPoint(out vector out_Location, out Rotator out_Rotation) +{ + // AI does things from the Pawn + if (Pawn != None) + { + out_Location = Pawn.Location; + out_Rotation = Pawn.Rotation; + } + else + { + Super.GetPlayerViewPoint(out_Location, out_Rotation); + } +} + +/** + * Scripting hook to move this AI to a specific actor. + */ +function OnAIMoveToActor(SeqAct_AIMoveToActor Action) +{ + local Actor DestActor; + local SeqVar_Object ObjVar; + + // abort any previous latent moves + ClearLatentAction(class'SeqAct_AIMoveToActor',true,Action); + // pick a destination + DestActor = Action.PickDestination(Pawn); + // if we found a valid destination + if (DestActor != None) + { + // set the target and push our movement state + ScriptedRoute = Route(DestActor); + if (ScriptedRoute != None) + { + if (ScriptedRoute.RouteList.length == 0) + { + `warn("Invalid route with empty MoveList for scripted move"); + } + else + { + ScriptedRouteIndex = 0; + if (!IsInState('ScriptedRouteMove')) + { + PushState('ScriptedRouteMove'); + } + } + } + else + { + ScriptedMoveTarget = DestActor; + if (!IsInState('ScriptedMove')) + { + PushState('ScriptedMove'); + } + } + // set AI focus, if one was specified + ScriptedFocus = None; + foreach Action.LinkedVariables(class'SeqVar_Object', ObjVar, "Look At") + { + ScriptedFocus = Actor(ObjVar.GetObjectValue()); + if (ScriptedFocus != None) + { + break; + } + } + } + else + { + `warn("Invalid destination for scripted move"); + } +} + +/** + * Simple scripted movement state, attempts to pathfind to ScriptedMoveTarget and + * returns execution to previous state upon either success/failure. + */ +state ScriptedMove +{ + event PoppedState() + { + if (ScriptedRoute == None) + { + // if we still have the move target, then finish the latent move + // otherwise consider it aborted + ClearLatentAction(class'SeqAct_AIMoveToActor', (ScriptedMoveTarget == None)); + } + // and clear the scripted move target + ScriptedMoveTarget = None; + } + + event PushedState() + { + if (Pawn != None) + { + // make sure the pawn physics are initialized + Pawn.SetMovementPhysics(); + } + } + +Begin: + // while we have a valid pawn and move target, and + // we haven't reached the target yet + while (Pawn != None && + ScriptedMoveTarget != None && + !Pawn.ReachedDestination(ScriptedMoveTarget)) + { + // check to see if it is directly reachable + if (ActorReachable(ScriptedMoveTarget)) + { + // then move directly to the actor + MoveToward(ScriptedMoveTarget, ScriptedFocus); + } + else + { + // attempt to find a path to the target + MoveTarget = FindPathToward(ScriptedMoveTarget); + if (MoveTarget != None) + { + // move to the first node on the path + MoveToward(MoveTarget, ScriptedFocus); + } + else + { + // abort the move + `warn("Failed to find path to"@ScriptedMoveTarget); + ScriptedMoveTarget = None; + } + } + } + // return to the previous state + PopState(); +} + +/** scripted route movement state, pushes ScriptedMove for each point along the route */ +state ScriptedRouteMove +{ + event PoppedState() + { + // if we still have the move target, then finish the latent move + // otherwise consider it aborted + ClearLatentAction(class'SeqAct_AIMoveToActor', (ScriptedRoute == None)); + ScriptedRoute = None; + } + +Begin: + while (Pawn != None && ScriptedRoute != None && ScriptedRouteIndex < ScriptedRoute.RouteList.length && ScriptedRouteIndex >= 0) + { + ScriptedMoveTarget = ScriptedRoute.RouteList[ScriptedRouteIndex].Actor; + if (ScriptedMoveTarget != None) + { + PushState('ScriptedMove'); + } + if (Pawn != None && Pawn.ReachedDestination(ScriptedRoute.RouteList[ScriptedRouteIndex].Actor)) + { + if (bReverseScriptedRoute) + { + ScriptedRouteIndex--; + } + else + { + ScriptedRouteIndex++; + } + } + else + { + `warn("Aborting scripted route"); + ScriptedRoute = None; + PopState(); + } + } + + if (Pawn != None && ScriptedRoute != None && ScriptedRoute.RouteList.length > 0) + { + switch (ScriptedRoute.RouteType) + { + case ERT_Linear: + PopState(); + break; + case ERT_Loop: + bReverseScriptedRoute = !bReverseScriptedRoute; + // advance index by one to get back into valid range + if (bReverseScriptedRoute) + { + ScriptedRouteIndex--; + } + else + { + ScriptedRouteIndex++; + } + Goto('Begin'); + break; + case ERT_Circle: + ScriptedRouteIndex = 0; + Goto('Begin'); + break; + default: + `warn("Unknown route type"); + ScriptedRoute = None; + PopState(); + break; + } + } + else + { + ScriptedRoute = None; + PopState(); + } + + // should never get here + `warn("Reached end of state execution"); + ScriptedRoute = None; + PopState(); +} + +function NotifyWeaponFired(Weapon W, byte FireMode); +function NotifyWeaponFinishedFiring(Weapon W, byte FireMode); + +function bool CanFireWeapon( Weapon Wpn, byte FireModeNum ) { return TRUE; } + + +defaultproperties +{ + bAdjustFromWalls=true + bCanDoSpecial=true + MinHitWall=-0.5f +} diff --git a/Engine/Classes/AISubsystem.uc b/Engine/Classes/AISubsystem.uc new file mode 100644 index 0000000..226370d --- /dev/null +++ b/Engine/Classes/AISubsystem.uc @@ -0,0 +1,51 @@ +/** + * Copyright 2008 PCF, All Rights Reserved. + * This class is here because Engine needs to hold a pointer to an instance of it. + */ + class AISubsystem extends Subsystem + abstract + native; + +var bool bImplementsNavMeshGeneration; + +cpptext +{ + virtual void Init(UBOOL bEngineStart = FALSE) PURE_VIRTUAL(UAISubsystem::Init,); + virtual void CleanUp(UBOOL bShutDown = FALSE) PURE_VIRTUAL(UAISubsystem::CleanUp,); + + /** to be called on new level loading */ + virtual void Reset() PURE_VIRTUAL(UAISubsystem::Reset,); + + virtual void PrepareMapChange() PURE_VIRTUAL(UAISubsystem::PrepareMapChange,); + /** GC started, after all CALLBACK_PreGarbageCollection */ + virtual void OnLevelStreamedOut(ULevel* Level) PURE_VIRTUAL(UAISubsystem::OnLevelStreamedOut,); + + /** interface for triggering nav mesh generation */ + virtual UBOOL GenerateNavMesh() { return FALSE; } + + virtual void OnPIEStart() PURE_VIRTUAL(UAISubsystem::OnPIEStart,); + virtual void OnPIEFinished() PURE_VIRTUAL(UAISubsystem::OnPIEFinished,); + + virtual void ToggleNavBy(AActor* Referencer, UBOOL bEnable, BYTE NavFlag=0) PURE_VIRTUAL(UAISubsystem::ToggleNavBy,); + virtual void ToggleNavBy(UComponent* Referencer, UBOOL bEnable, BYTE NavFlag=0) PURE_VIRTUAL(UAISubsystem::ToggleNavBy,); + virtual void ToggleNavBy(ACoverLink* Referencer, INT SlotIdx, UBOOL bEnable, BYTE NavFlag=0) PURE_VIRTUAL(UAISubsystem::ToggleNavBy,); + + virtual void UpdateActionAreas() PURE_VIRTUAL(UAISubsystem::UpdateActionAreas,); +} + +final native static noexport function ToggleNavByActor(Actor Referencer, bool bEnable); +final native static noexport function ToggleNavByComponent(Component Referencer, bool bEnable); +final native static noexport function ToggleNavByCover(CoverLink Referencer, int SlotIdx, bool bEnable); + +`if(`__TW_) +/** Used to access the difficulty values from KFGame for BaseAI */ +event float GetDifficultyValue(int Index) +{ + return -1; +} +`endif + +defaultproperties +{ + bImplementsNavMeshGeneration=false +} diff --git a/Engine/Classes/AISwitchablePylon.uc b/Engine/Classes/AISwitchablePylon.uc new file mode 100644 index 0000000..725a704 --- /dev/null +++ b/Engine/Classes/AISwitchablePylon.uc @@ -0,0 +1,56 @@ +//============================================================================= +// AISwitchablePylon +// +// represents a mesh which is turned on/off via an AI triggerable switch at runtime.. e.g. an electronic gate, or a laser fence +// +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class AISwitchablePylon extends Pylon + placeable + native(inherit); +cpptext +{ + /** returns TRUE if the path from Poly back to start has an edge which is linked to a switch which is linked to this + * pylon + * @param Edge - the edge linking Poly to the next neighbor in question + * @param Poly - the source poly (the current end-of-line poly in the chain) + * @return - TRUE if the previousPath chain of Poly has a switch linked to this pylon in it + */ + UBOOL HasSwitchLinkedToMeInPath(struct FNavMeshEdgeBase* Edge, struct FNavMeshPolyBase* Poly); + + // overidden to deny access to edges when we're disabled and the path doesn't incorporate a switch linked to this pylon + virtual UBOOL CostFor( const FNavMeshPathParams& PathParams, + const FVector& PreviousPoint, + FVector& out_PathEdgePoint, + struct FNavMeshEdgeBase* Edge, + struct FNavMeshPolyBase* SourcePoly, + INT& out_Cost); + +} + + +var() bool bOpen; + +function PostBeginPlay() +{ + Super.PostBeginPlay(); + SetEnabled(bOpen); +} + +event SetEnabled(bool bEnabled) +{ + bOpen = bEnabled; + bForceObstacleMeshCollision = !bOpen; +} + +event bool IsEnabled() +{ + return bOpen; +} + + +defaultproperties +{ + bNeedsCostCheck=true + bRouteBeginPlayEvenIfStatic=true +} diff --git a/Engine/Classes/AccessControl.uc b/Engine/Classes/AccessControl.uc new file mode 100644 index 0000000..b1f650c --- /dev/null +++ b/Engine/Classes/AccessControl.uc @@ -0,0 +1,1687 @@ +//============================================================================= +// AccessControl. +// +// AccessControl is a helper class for GameInfo. +// The AccessControl class determines whether or not the player is allowed to +// login in the PreLogin() function, controls whether or not a player can enter +// as a spectator or a game administrator, and handles authentication of +// clients with the online subsystem (including the listen server host). +// +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class AccessControl extends Info + dependson(OnlineAuthInterface) + config(Game); + +/** Contains policies for allowing/denying IP addresses */ +var globalconfig array IPPolicies; + +/** Contains the list of banned UIDs */ +var globalconfig array BannedIDs; + + +/** Various localized strings */ +var localized string IPBanned; +var localized string WrongPassword; +var localized string NeedPassword; +var localized string SessionBanned; +var localized string KickedMsg; +var localized string DefaultKickReason; +var localized string IdleKickReason; + + +var class AdminClass; + +/** Password required for admin privileges */ +var private globalconfig string AdminPassword; + +/** Password required to enter the game */ +var private globalconfig string GamePassword; + +var localized string ACDisplayText[3]; +var localized string ACDescText[3]; + +var bool bDontAddDefaultAdmin; + +/** Whether or not to authenticate clients (specifically their UID's) when they join; client UID's can't be trusted until they are authenticated */ +var globalconfig bool bAuthenticateClients; + +/** Whether or not to authenticate the game server with clients; a client must be fully authenticated before it can authenticate the server */ +var globalconfig bool bAuthenticateServer; + +/** Whether or not to authenticate the listen host, on lists servers */ +var globalconfig bool bAuthenticateListenHost; + +/** The maximum number of times to retry authentication */ +var globalconfig int MaxAuthRetryCount; + +/** The delay between authentication attempts */ +var globalconfig int AuthRetryDelay; + +/** Caches a local reference to the online subsystem */ +var OnlineSubsystem OnlineSub; + +/** Caches a local reference to the online subsystems auth interface, if it has one set */ +var OnlineAuthInterface CachedAuthInt; + +/** Whether or not this classes auth delegates have been registered with the auth interface */ +var bool bAuthDelegatesRegistered; + +/** Struct used for tracking clients pending authentication */ +struct PendingClientAuth +{ + var Player ClientConnection; // The NetConnection of the client pending auth + var UniqueNetId ClientUID; // The UID of the client + + var float AuthTimestamp; // The timestamp for when authentication was started + var int AuthRetryCount; // The number of times authentication has been retried for this client +}; + +/** Tracks clients who are currently pending authentication */ +var array ClientsPendingAuth; + +/** Struct used for tracking server auth retry counts */ +struct ServerAuthRetry +{ + var UniqueNetId ClientUID; // The UID of the client requesting retries + var int AuthRetryCount; // The number of times server authentication has been retried for this client +}; + +/** Tracks server auth retry requests for clients */ +var array ServerAuthRetries; + +/** Whether or not the listen host is pending authentication */ +var bool bPendingListenAuth; + +/** Stores the UID of the listen server auth ticket */ +var int ListenAuthTicketUID; + +/** The number of times listen host auth has been retried */ +var int ListenAuthRetryCount; + +function PostBeginPlay() +{ + OnlineSub = Class'GameEngine'.static.GetOnlineSubsystem(); + InitAuthHooks(); +} + +function Destroyed() +{ + Cleanup(); +} + +/** + * Checks whether or not the specified PlayerController is an admin + * + * @param P The PlayerController to check + * @return TRUE if the specified player has admin privileges. + */ +function bool IsAdmin(PlayerController P) +{ + if ( P != None ) + { + if ( Admin(P) != None ) + { + return true; + } + + if ( P.PlayerReplicationInfo != None && P.PlayerReplicationInfo.bAdmin ) + { + return true; + } + } + + return false; +} + +function bool SetAdminPassword(string P) +{ + AdminPassword = P; + return true; +} + +function SetGamePassword(string P) +{ + GamePassword = P; + WorldInfo.Game.UpdateGameSettings(); +} + +function bool RequiresPassword() +{ + return GamePassword != "" || GameEngine(class'Engine'.static.GetEngine()).bPrivateServer; +} + +/** + * Takes a string and tries to find the matching controller associated with it. First it searches as if the string is the + * player's name. If it doesn't find a match, it attempts to resolve itself using the target as the player id. + * + * @Params Target The search key + * + * @returns the controller associated with the key. NONE is a valid return and means not found. + */ +function Controller GetControllerFromString(string Target) +{ + local Controller C,FinalC; + local int i; + + FinalC = none; + foreach WorldInfo.AllControllers(class'Controller', C) + { + if (C.PlayerReplicationInfo != None && (C.PlayerReplicationInfo.PlayerName ~= Target || C.PlayerReplicationInfo.PlayerName ~= Target)) + { + FinalC = C; + break; + } + } + + // if we didn't find it by name, attempt to convert the target to a player index and look him up if possible. + if ( C == none && WorldInfo != none && WorldInfo.GRI != none ) + { + for (i=0;i"; +`else + OutError = PathName(WorldInfo.Game.GameMessageClass)$".MaxedOutMessage"; +`endif + } + // BWJ - 8-11-16 - Require bJoinViaInvite in join URL for private servers + else if ( (GamePassword != "" && !(InPassword == GamePassword) && (AdminPassword == "" || !(InPassword == AdminPassword))) || + ( Engine.bPrivateServer && !bHasPrivateServerOption ) ) + { +`if(`__TW_NETWORKING_) + OutError = "" : "Engine.AccessControl.WrongPassword>"; +`else + OutError = (InPassword == "") ? "Engine.AccessControl.NeedPassword" : "Engine.AccessControl.WrongPassword"; +`endif + } + + // Check server IP bans (UID bans are checked in GameInfo::PreLogin) + if (!CheckIPPolicy(Address)) + { +`if(`__TW_) + OutError = ""; +`else + OutError = "Engine.AccessControl.IPBanned"; +`endif + } + + // If the client was not already rejected, handle authentication of the clients UID + if (bAuthenticateClients && OutError == "" && CachedAuthInt != None && bAuthDelegatesRegistered) + { + if (OnlineSub != None && OnlineSub.GameInterface != None) + { + GameSettings = OnlineSub.GameInterface.GetGameSettings(WorldInfo.Game.PlayerReplicationInfoClass.default.SessionName); +`if(`__TW_NETWORKING_) + //If we're connecting locally, don't even bother with the authentication stuff in the rest of the function + if (Address == "127.0.0.1") + { + `log("Skipping online subsystem authentication because it's a local connection from address:" $ Address); + return; + } +`endif + + // If 'bIsLanMatch' is set, do not enable any authentication + if ((WorldInfo.NetMode == NM_DedicatedServer || WorldInfo.NetMode == NM_ListenServer) && GameSettings != None && !GameSettings.bIsLanMatch) + { + // If the client does not support authentication, reject him immediately + if (!bSupportsAuth) + { + if (OnlineSub.Class.Name == 'OnlineSubsystemSteamworks') + { +`if(`__TW_) + OutError = ""; +`else + OutError = "Engine.Errors.SteamClientRequired"; +`endif + } + else + { +`if(`__TW_) + OutError = ""; +`else + OutError = "Server requires authentication"; +`endif + } + } + + // Pause the login process for the client + if (OutError == "") + { + ClientConn = WorldInfo.Game.PauseLogin(); + } + + if (ClientConn != none) + { + // If there are any other client connections from the same UID and IP, kick them (fixes an auth issue, + // preventing players from rejoining if they were disconnected, and the old connection still lingers) + + // First find the joining clients IP + foreach WorldInfo.AllClientConnections(CurConn, CurIP, CurPort) + { + if (CurConn == ClientConn) + { + ClientIP = CurIP; + break; + } + } + + // See if there is an active auth session matching the same IP and UID + LingeringPort = 0; + + foreach CachedAuthInt.AllClientAuthSessions(CurClientSession) + { + if (CurClientSession.EndPointIP == ClientIP && CurClientSession.EndPointUID == UniqueId) + { + LingeringPort = CurClientSession.EndPointPort; + break; + } + } + + + // If there was an existing active auth session, match it up to the lingering connection and disconnect it + if (LingeringPort != 0) + { + foreach WorldInfo.AllClientConnections(CurConn, CurIP, CurPort) + { + if (CurConn != ClientConn && CurIP == ClientIP && CurPort == LingeringPort) + { + `log("Closing old connection with duplicate IP ("$Address$") and SteamId ("$ + Class'OnlineSubsystem'.static.UniqueNetIdToString(UniqueId)$")",, 'DevNet'); + + WorldInfo.Game.RejectLogin(CurConn, ""); + + break; + } + } + } + + + // If there are other client connections from the same UID, but not the same IP, reject the new player + // NOTE: The above code shouldn't affect this, as OnClientConnectionClose (which cleans up lists) + // is called during RejectLogin + for (i=0; i= AuthRetryDelay) + { + if (CachedAuthInt.FindClientAuthSession(ClientsPendingAuth[i].ClientConnection, CurClientSession)) + { + if (ClientsPendingAuth[i].AuthRetryCount < MaxAuthRetryCount) + { + // End the auth session first before retrying + CachedAuthInt.EndRemoteClientAuthSession(CurClientSession.EndPointUID, CurClientSession.EndPointIP); + + // Get the client to end it on his end too (this should execute on client before the new auth request below) + CachedAuthInt.SendClientAuthEndSessionRequest(ClientsPendingAuth[i].ClientConnection); + + // Start the new auth session + if (CachedAuthInt.SendClientAuthRequest(ClientsPendingAuth[i].ClientConnection, CurClientSession.EndPointUID)) + { + ClientsPendingAuth[i].AuthTimestamp = WorldInfo.RealTimeSeconds; + ClientsPendingAuth[i].AuthRetryCount++; + } + else + { + bFailed = True; + } + } + else + { + bFailed = True; + } + + if (bFailed) + { + `log("Client authentication timed out after"@MaxAuthRetryCount@"tries",, 'DevOnline'); + + OldLength = ClientsPendingAuth.Length; + + WorldInfo.Game.RejectLogin(ClientsPendingAuth[i].ClientConnection, "Authentication failed"); + + // If OnClientConnectionClose did not alter ClientsPendingAuth, remove the entry now + if (OldLength == ClientsPendingAuth.Length) + { + ClientsPendingAuth.Remove(i, 1); + } + + i--; + } + } + } + } + + if (ClientsPendingAuth.Length == 0) + { + ClearTimer('PendingAuthTimer'); + } +} + +/** + * Called when the auth interface is ready to perform authentication (may not be called, if the auth interface was already ready) + * NOTE: Listen host authentication may be kicked off here + */ +function OnAuthReady() +{ + local int i, OldLength; + + if (bAuthDelegatesRegistered) + { + // If there are any pending client auth's queued, kickoff authentication + for (i=0; i 0) + { + `log("OnAuthReady: Kicking off delayed auth for clients"); + + SetTimer(3.0, True, nameof(PendingAuthTimer)); + } + + if (bAuthenticateListenHost && WorldInfo.NetMode == NM_ListenServer && bPendingListenAuth) + { + BeginListenHostAuth(); + } + } +} + +/** + * Called when the server receives auth data from a client, needed for authentication + * + * @param ClientUID The UID of the client + * @param ClientIP The IP of the client + * @param AuthTicketUID The UID used to reference the auth data + */ +//@HSL_BEGIN_XBOX +function ProcessClientAuthResponse(UniqueNetId ClientUID, IpAddr ClientIP, int AuthTicketUID) +{ +//@HSL_END_XBOX + local bool bSuccess; + local int i, PendingIdx, OldLength; + + // Check that we are expecting auth data from this client + PendingIdx = INDEX_None; + + for (i=0; inot< pause at login, the UID needs to be stored in the PRI from here + P.PlayerReplicationInfo.SetUniqueId(ClientUID); + + `log("Client '"$PRI.PlayerName$"'passed authentication, UID:"@ + Class'OnlineSubsystem'.static.UniqueNetIdToString(ClientUID)); + } + else + { + `log("Client passed authentication, UID:"@Class'OnlineSubsystem'.static.UniqueNetIdToString(ClientUID)); + } + + bResumeLogin = True; + + // Kick off server auth + if (bAuthenticateServer) + { + if (CachedAuthInt.FindClientAuthSession(ClientConnection, CurClientSession)) + { + ProcessServerAuthRequest(ClientConnection, ClientUID, CurClientSession.EndPointIP, + CurClientSession.EndPointPort); + } + else + { + `log("Failed to kickoff server auth; could not find matching client session"); + } + } + } + else + { + `log("Client failed authentication (unauthenticated UID:"@ + Class'OnlineSubsystem'.static.UniqueNetIdToString(ClientUID)$"), kicking"); + + // Kick the client + WorldInfo.Game.RejectLogin(ClientConnection, "Authentication failed"); + } + } + + // Remove the tracking entry, if it was not removed above + if (ClientsPendingAuth.Length == PendingLen) + { + ClientsPendingAuth.Remove(PendingIdx, 1); + } + } + else + { + `log("AccessControl::OnClientAuthComplete: Received unexpected auth result for client",, 'DevOnline'); + } + + if (bResumeLogin) + { + WorldInfo.Game.ResumeLogin(ClientConnection); + } +} + + +/** + * Server authentication + */ + +/** + * Called when the server receives a message from a client, requesting a server auth session + * + * @param ClientConnection The NetConnection of the client the request came from + * @param ClientUID The UID of the client making the request + * @param ClientIP The IP of the client making the request + * @param ClientPort The port the client is on + */ +//@HSL_BEGIN_XBOX +function ProcessServerAuthRequest(Player ClientConnection, UniqueNetId ClientUID, IpAddr ClientIP, int ClientPort) +{ +//@HSL_END_XBOX + local int AuthTicketUID; + local LocalAuthSession CurServerSession; + local bool bFound; + + // NOTE: Native code handles checking of whether or not client is authenticated + if (bAuthenticateServer) + { + // Make sure there is not already a server auth session for this client + foreach CachedAuthInt.AllLocalServerAuthSessions(CurServerSession) + { + if (CurServerSession.EndPointUID == ClientUID && CurServerSession.EndPointIP == ClientIP) + { + bFound = true; + } + } + + if (!bFound) + { + // Kickoff server auth + if (CachedAuthInt.CreateServerAuthSession(ClientUID, ClientIP, ClientPort, AuthTicketUID)) + { + if (!CachedAuthInt.SendServerAuthResponse(ClientConnection, AuthTicketUID)) + { + `log("WARNING!!! Failed to send auth ticket to client"); + } + } + else + { + `log("Failed to kickoff server auth",, 'DevOnline'); + } + } + } +} + +/** + * Called when the server receives a server auth retry request from a client + * + * @param ClientConnection The client NetConnection + */ +function ProcessServerAuthRetryRequest(Player ClientConnection) +{ + local bool bFoundAndAuthenticated; +//@HSL_BEGIN_XBOX + local IpAddr ClientIP; +//@HSL_END_XBOX + local int ClientPort, i, CurRetryIdx; + local UniqueNetId ClientUID; + local AuthSession CurClientSession; + local LocalAuthSession CurServerSession; + + if (bAuthenticateServer && ClientConnection != none) + { + bFoundAndAuthenticated = CachedAuthInt.FindClientAuthSession(ClientConnection, CurClientSession) && + CurClientSession.AuthStatus == AUS_Authenticated; + + // Only execute a server auth retry, if the client is fully authenticated + if (bFoundAndAuthenticated) + { + ClientUID = CurClientSession.EndPointUID; + ClientIP = CurClientSession.EndPointIP; + ClientPort = CurClientSession.EndPointPort; + + CurRetryIdx = INDEX_None; + + for (i=0; i Max(30, MaxAuthRetryCount + 20)) + { + WorldInfo.Game.RejectLogin(ClientConnection, "Spamming server auth"); + } + else + { + // Update the retry count + ServerAuthRetries[CurRetryIdx].AuthRetryCount++; + } + } + } +} + + +/** + * Listen host authentication + */ + +/** + * Kicks off authentication of the listen host + */ +function BeginListenHostAuth(optional bool bRetry) +{ + local UniqueNetId ServerUID, HostUID; +//@HSL_BEGIN_XBOX + local IpAddr ServerIP; + local int ServerPort; +//@HSL_END_XBOX + local OnlineGameSettings GameSettings; + local bool bGotHostInfo, bFound, bSecure; + local AuthSession CurClientSession, ListenSession; + + bPendingListenAuth = false; + + if (CachedAuthInt.IsReady()) + { + bGotHostInfo = CachedAuthInt.GetServerUniqueId(ServerUID) && + CachedAuthInt.GetServerAddr(ServerIP, ServerPort) && + OnlineSub.PlayerInterface.GetUniquePlayerId(0, HostUID); + } + + if (bGotHostInfo) + { + // Search for an existing listen host auth session first + foreach CachedAuthInt.AllClientAuthSessions(CurClientSession) + { + if (CurClientSession.EndPointUID == HostUID && CurClientSession.EndPointIP == ServerIP) + { + ListenSession = CurClientSession; + bFound = true; + + break; + } + } + + // If there is not an existing session, kick one off + if (!bFound || bRetry) + { + `log("Kicking off listen auth session"); + + if (OnlineSub.GameInterface != none) + { + GameSettings = OnlineSub.GameInterface.GetGameSettings(WorldInfo.Game.PlayerReplicationInfoClass.default.SessionName); + } + + if (GameSettings != none) + { + bSecure = GameSettings.bAntiCheatProtected; + } + + // Kickoff authentication + if (CachedAuthInt.CreateClientAuthSession(ServerUID, ServerIP, ServerPort, bSecure, ListenAuthTicketUID)) + { + // Give the auth interface a moment to setup the auth session, before verifying + SetTimer(1.0, false, nameof(ContinueListenHostAuth)); + } + + SetTimer(AuthRetryDelay, false, nameof(ListenHostAuthTimeout)); + } + // If there is an existing session, do nothing if already authenticated, or enable timeout if not + else if (ListenSession.AuthStatus != AUS_Authenticated && !IsTimerActive('ListenHostAuthTimeout')) + { + `log("BeginListenHostAuth was called when there is already a listen auth session, but the timeout is not active"); + + SetTimer(AuthRetryDelay, false, nameof(ListenHostAuthTimeout)); + } + } + else + { + `log("Failed to kickoff listen host authentication"); + // Go straight to failed auth + OnlineSub.PlayerInterface.GetUniquePlayerId(0, HostUID); + OnClientAuthComplete(false, HostUID, None, "Failed to kickoff listen host authentication"); + } +} + +/** + * After listen host authentication kicks off, this is called after a short delay, to continue authentication + */ +function ContinueListenHostAuth() +{ + local bool bGotHostInfo; + local UniqueNetId HostUID; +//@HSL_BEGIN_XBOX + local IpAddr ServerIP; + local int ServerPort; +//@HSL_END_XBOX + + if (OnlineSub.PlayerInterface != none) + { + bGotHostInfo = OnlineSub.PlayerInterface.GetUniquePlayerId(0, HostUID) && + CachedAuthInt.GetServerAddr(ServerIP, ServerPort); + } + + if (!bGotHostInfo || !CachedAuthInt.VerifyClientAuthSession(HostUID, ServerIP, ServerPort, ListenAuthTicketUID)) + { + `log("VerifyClientAuthSession failed for listen host"); + OnlineSub.PlayerInterface.GetUniquePlayerId(0, HostUID); + OnClientAuthComplete(false, HostUID, None, "VerifyClientAuthSession failed for listen host"); + } +} + +/** + * Ends any active listen host auth sessions + */ +function EndListenHostAuth() +{ + local bool bGotHostInfo; + local UniqueNetId ServerUID, HostUID; +//@HSL_BEGIN_XBOX + local IpAddr ServerIP; + local int ServerPort; +//@HSL_END_XBOX + + if (OnlineSub.PlayerInterface != none) + { + bGotHostInfo = CachedAuthInt.GetServerUniqueId(ServerUID) && + CachedAuthInt.GetServerAddr(ServerIP, ServerPort) && + OnlineSub.PlayerInterface.GetUniquePlayerId(0, HostUID); + } + + if (bGotHostInfo) + { + CachedAuthInt.EndLocalClientAuthSession(ServerUID, ServerIP, ServerPort); + CachedAuthInt.EndRemoteClientAuthSession(HostUID, ServerIP); + } + else + { + `log("Failed to end listen host auth session"); + } +} + +/** + * Triggered upon listen host authentication failure, or timeout + */ +function ListenHostAuthTimeout() +{ + local UniqueNetId HostUID; + + ClearTimer('ListenHostAuthTimeout'); + ClearTimer('ContinueListenHostAuth'); + + if (ListenAuthRetryCount < MaxAuthRetryCount) + { + ListenAuthRetryCount++; + + // Retry auth again + BeginListenHostAuth(true); + } + else + { + `log("Listen host authentication failed after"@MaxAuthRetryCount@"attempts"); + OnlineSub.PlayerInterface.GetUniquePlayerId(0, HostUID); + OnClientAuthComplete(false, HostUID, None, "VerifyClientAuthSession failed for listen host"); + EndListenHostAuth(); + } +} + + +/** + * Client disconnect cleanup + */ + +/** + * Called on the server when a clients net connection is closing (so auth sessions can be ended) + * + * @param ClientConnection The client NetConnection that is closing + */ +function OnClientConnectionClose(Player ClientConnection) +{ + local int i; + + if (ClientConnection != none) + { + // End the auth session for the exiting client (done in the static function to keep it in one place) + StaticOnClientConnectionClose(ClientConnection); + + // Remove from tracking + for (i=0; i Components; + +/** All actor components which are directly or indirectly attached to the actor. */ +var private transient const array AllComponents; + +// The actor's position and rotation. +/** Actor's location; use Move or SetLocation to change. */ +var(Movement) const vector Location; + +/** The actor's rotation; use SetRotation to change. */ +var(Movement) const rotator Rotation; + +/** Scaling factor, 1.0=normal size. */ +var(Display) const repnotify interp float DrawScale ; + +/** Scaling vector, (1.0,1.0,1.0)=normal size. */ +var(Display) const interp vector DrawScale3D; + +/** Offset from box center for drawing. */ +var(Display) const vector PrePivot; + +/** Color to tint the icon for this actor */ +var(Display) editoronly Color EditorIconColor; + +/** A fence to track when the primitive is detached from the scene in the rendering thread. */ +var private native const RenderCommandFence DetachFence; + +/** Allow each actor to run at a different time speed */ +var float CustomTimeDilation; + +// Priority Parameters +// Actor's current physics mode. +var(Movement) const enum EPhysics +{ + PHYS_None, + PHYS_Walking, + PHYS_Falling, + PHYS_Swimming, + PHYS_Flying, + PHYS_Rotating, + PHYS_Projectile, + PHYS_Interpolating, + PHYS_Spider, + PHYS_Ladder, + PHYS_RigidBody, + PHYS_SoftBody, /** update bounding boxes and killzone test, otherwise like PHYS_None */ + PHYS_NavMeshWalking, /** slide along navmesh, "fake" phys_walking */ + PHYS_Unused, + PHYS_Custom, /** user-defined custom physics */ +} Physics; + +/** The set of Directions an actor can be moving **/ +enum EMoveDir +{ + MD_Stationary, + MD_Forward, + MD_Backward, + MD_Left, + MD_Right, + MD_Up, + MD_Down +}; + +/** The type of metric we want about the actor **/ +enum EActorMetricsType +{ + METRICS_VERTS, + METRICS_TRIS, + METRICS_SECTIONS, +}; + + +// Owner. +var const Actor Owner; // Owner actor. +var(Attachment) const Actor Base; // Actor we're standing on. + +struct native TimerData +{ + var bool bLoop; + var bool bPaused; + var Name FuncName; + var float Rate, Count; + var float TimerTimeDilation; + var Object TimerObj; + /** This is going to scale this timer's values by this amount**/ + + + structcpptext + { + FTimerData(EEventParm) + { + appMemzero(this, sizeof(FTimerData)); + TimerTimeDilation = 1.0f; + } + } + + //default TimerTimeDilation to 1.0f + structdefaultproperties + { + TimerTimeDilation=1.0f + } +}; +var const array Timers; // list of currently active timers + +// Flags. +var const public{private} bool bStatic; // Does not move or change over time. It is only safe to change this property in defaultproperties. + +/** If this is True, all PrimitiveComponents of the actor are hidden. If this is false, only PrimitiveComponents with HiddenGame=True are hidden. */ +var(Display) const bool bHidden; + +var const bool bNoDelete; // Cannot be deleted during play. +var const bool bDeleteMe; // About to be deleted. +var transient const bool bTicked; // Actor has been updated. +var const bool bOnlyOwnerSee; // Only owner can see this actor. + +/** if set, this Actor and all of its components are not ticked. Modify via SetTickIsDisabled() + * this flag has no effect on bStatic Actors + */ +var const public{private} bool bTickIsDisabled; + +var bool bWorldGeometry; // Collision and Physics treats this actor as static world geometry + +/** Ignore Unreal collisions between PHYS_RigidBody pawns (vehicles/ragdolls) and this actor (only relevant if bIgnoreEncroachers is false) */ +var bool bIgnoreRigidBodyPawns; +var bool bOrientOnSlope; // when landing, orient base on slope of floor +var const bool bIgnoreEncroachers; // Ignore collisions between movers and this actor +/** whether encroachers can push this Actor (only relevant if bIgnoreEncroachers is false and not an encroacher ourselves) + * if false, the encroacher gets EncroachingOn() called immediately instead of trying to safely move this actor first + */ +var bool bPushedByEncroachers; +/** If TRUE, when an InterpActor (Mover) encroaches or runs into this Actor, it is destroyed, and will not stop the mover. */ +var bool bDestroyedByInterpActor; + +/** Whether to route BeginPlay even if the actor is static. */ +var const bool bRouteBeginPlayEvenIfStatic; +/** Used to determine when we stop moving, so we can update PreviousLocalToWorld to stop motion blurring. */ +var const bool bIsMoving; +/** + * If true (and is an encroacher) will do the encroachment check inside MoveActor even if there is no movement. + * This is useful for objects that may change bounding box but not actually move. + */ +var bool bAlwaysEncroachCheck; +/** whether this Actor may return an alternate location from GetTargetLocation() when bRequestAlternateLoc is true + * (used as an early out when tracing to those locations, etc) + */ +var bool bHasAlternateTargetLocation; + +/** If TRUE, PHYS_Walking will attempt to step up onto this object when it hits it */ +var(Collision) bool bCanStepUpOn; + +// Networking flags +var const bool bNetTemporary; // Tear-off simulation in network play. +var const bool bOnlyRelevantToOwner; // this actor is only relevant to its owner. If this flag is changed during play, all non-owner channels would need to be explicitly closed. +var transient bool bNetDirty; // set when any attribute is assigned a value in unrealscript, reset when the actor is replicated +var bool bAlwaysRelevant; // Always relevant for network. +var bool bReplicateInstigator; // Replicate instigator to client (used by bNetTemporary projectiles). +var bool bReplicateMovement; // if true, replicate movement/location related properties +var bool bSkipActorPropertyReplication; // if true, don't replicate actor class variables for this actor +var bool bUpdateSimulatedPosition; // if true, update velocity/location after initialization for simulated proxies +var bool bTearOff; // if true, this actor is no longer replicated to new clients, and + // is "torn off" (becomes a ROLE_Authority) on clients to which it was being replicated. +var bool bOnlyDirtyReplication; // if true, only replicate actor if bNetDirty is true - useful if no C++ changed attributes (such as physics) + // bOnlyDirtyReplication only used with bAlwaysRelevant actors + +/** Whether this actor will interact with fluid surfaces or not. */ +var(Physics) bool bAllowFluidSurfaceInteraction; + + +/** Demo recording variables */ +/** Set when we are currently replicating this Actor into a demo */ +var transient bool bDemoRecording; +/** Demo recording driver owns this actor. */ +var bool bDemoOwner; + +/** force Actor to be relevant for demos (only works on dynamic actors) */ +var bool bForceDemoRelevant; + +/** Should replicate initial rotation. This property should never be changed during execution, as the client and server rely on the default value of this property always being the same. */ +var const bool bNetInitialRotation; + +var bool bReplicateRigidBodyLocation; // replicate Location property even when in PHYS_RigidBody +var bool bKillDuringLevelTransition; // If set, actor and its components are marked as pending kill during seamless map transitions +/** whether we already exchanged Role/RemoteRole on the client, as removing then readding a streaming level + * causes all initialization to be performed again even though the actor may not have actually been reloaded + */ +var const bool bExchangedRoles; + +/** If true, texture streaming code iterates over all StaticMeshComponents found on this actor when building texture streaming information. */ +var(Advanced) bool bConsiderAllStaticMeshComponentsForStreaming; + +//debug +var(Debug) bool bDebug; // Used to toggle debug logging + +// HUD +/** IF true, may call PostRenderFor() even when this actor is not visible */ +var bool bPostRenderIfNotVisible; + +/** Used by SkeletalMeshComponent Ticking optimization. */ +var const transient int SkelMeshCompTickTag; + +// Net variables. +enum ENetRole +{ + ROLE_None, // No role at all. + ROLE_SimulatedProxy, // Locally simulated proxy of this actor. + ROLE_AutonomousProxy, // Locally autonomous proxy of this actor. + ROLE_Authority, // Authoritative control over the actor. +}; +var ENetRole RemoteRole, Role; + +/** Internal - used by UWorld::ServerTickClients() */ +var const transient int NetTag; + +/** Next time this actor will be considered for replication, set by SetNetUpdateTime() */ +var const float NetUpdateTime; + +/** How often (per second) this actor will be considered for replication, used to determine NetUpdateTime */ +var float NetUpdateFrequency; + +/** Priority for this actor when checking for replication in a low bandwidth or saturated situation, higher priority means it is more likely to replicate */ +var float NetPriority; + +/** When set to TRUE will force this actor to immediately be considered for replication, instead of waiting for NetUpdateTime */ +var transient bool bForceNetUpdate; + +/** Last time this actor was updated for replication via NetUpdateTime or bForceNetUpdate + * @warning: internal net driver time, not related to WorldInfo.TimeSeconds + */ +var const transient float LastNetUpdateTime; + +/** Is this actor still pending a full net update due to clients that weren't able to replicate the actor at the time of LastNetUpdateTime */ +var const transient bool bPendingNetUpdate; + +/** How long has it been since the last tick? */ +var float TimeSinceLastTick; + +var Pawn Instigator; // Pawn responsible for damage caused by this actor. + +var const transient WorldInfo WorldInfo; +var float LifeSpan; // How old the object lives before dying, 0=forever. +var const float CreationTime; // The time this actor was created, relative to WorldInfo.TimeSeconds + +//----------------------------------------------------------------------------- +// Structures. + +struct native transient TraceHitInfo +{ + var Material Material; // Material we hit. + var PhysicalMaterial PhysMaterial; // The Physical Material that was hit + var int Item; // Extra info about thing we hit. + var int LevelIndex; // Level index, if we hit BSP. + var name BoneName; // Name of bone if we hit a skeletal mesh. + var PrimitiveComponent HitComponent; // Component of the actor that we hit. +}; + + +/** Hit definition struct. Mainly used by Instant Hit Weapons. */ +struct native transient ImpactInfo +{ + /** Actor Hit */ + var Actor HitActor; + /** world location of hit impact */ + var vector HitLocation; + /** Hit normal of impact */ + var vector HitNormal; + /** Direction of ray when hitting actor */ + var vector RayDir; + /** Start location of trace */ + var vector StartTrace; + /** Trace Hit Info (material, bonename...) */ + var TraceHitInfo HitInfo; + + structcpptext + { + FImpactInfo() + : HitActor(NULL) + , HitLocation(0,0,0) + , HitNormal(0,0,0) + , RayDir(0,0,0) + , StartTrace(0,0,0) + {} + + FImpactInfo(EEventParm) + { + appMemzero(this, sizeof(FImpactInfo)); + } + } +}; + +/** Struct used for passing information from Matinee to an Actor for blending animations during a sequence. */ +struct native transient AnimSlotInfo +{ + /** Name of slot that we want to play the animtion in. */ + var name SlotName; + + /** Strength of each Channel within this Slot. Channel indexs are determined by track order in Matinee. */ + var array ChannelWeights; +}; + +/** Used to indicate each slot name and how many channels they have. */ +struct native transient AnimSlotDesc +{ + /** Name of the slot. */ + var name SlotName; + + /** Number of channels that are available in this slot. */ + var int NumChannels; +}; + +//----------------------------------------------------------------------------- +// Major actor properties. + +/** + * The value of WorldInfo->TimeSeconds for the frame when this actor was last rendered. This is written + * from the render thread, which is up to a frame behind the game thread, so you should allow this time to + * be at least a frame behind the game thread's world time before you consider the actor non-visible. + * There's an equivalent variable in PrimitiveComponent. + */ +var transient float LastRenderTime; + +// Actor's tag name. +var(Object) name Tag; +var name InitialState; +// Actor's layer name. +var(Object) name Layer; +var deprecated name Group; + +/** Bitflag to represent which views this actor is hidden in, via per-view layer visibilty */ +var transient qword HiddenEditorViews; + +// Internal. +var transient const array Touching; // List of touching actors. +var transient const array Children; // array of actors owned by this actor +var const float LatentFloat; // Internal latent function use. +var const AnimNodeSequence LatentSeqNode; // Internal latent function use. + +// physics volume this actor is currently in +var transient const PhysicsVolume PhysicsVolume; +// Velocity. +var vector Velocity; +// Acceleration. +var vector Acceleration; +// Angular velocity, in radians/sec. Read-only, see RotationRate to set rotation. +var transient const vector AngularVelocity; + +// Attachment related variables +var(Attachment) SkeletalMeshComponent BaseSkelComponent; +var(Attachment) name BaseBoneName; + +/** array of actors attached to this actor. */ +var const array Attached; +/** location relative to base/bone (valid if base exists) */ +var const vector RelativeLocation; +/** rotation relative to base/bone (valid if base exists) */ +var const rotator RelativeRotation; + +/** Uses 'hard' attachment code. bBlockActor must also be false. + This actor cannot then move relative to base (setlocation etc.). + Dont set while currently based on something! */ +var(Attachment) const bool bHardAttach; + +/** If TRUE, this actor ignores the effects of changes in its base's rotation on its location and rotation. */ +var(Attachment) bool bIgnoreBaseRotation; + +/** If TRUE, BaseSkelComponent is used as the shadow parent for this actor.*/ +var(Attachment) bool bShadowParented; + +/** If TRUE, Skip moveactor collision check for this actor moving as a result of its base, to which it is hard attached moving + - only if this actor doesn't block actors.*/ +var(Attachment) bool bSkipAttachedMoves; + +/** Determines whether or not adhesion code should attempt to adhere to this actor. **/ +var bool bCanBeAdheredTo; + +/** Determines whether or not friction code should attempt to friction to this actor. **/ +var bool bCanBeFrictionedTo; + + +//----------------------------------------------------------------------------- +// Display properties. + +// Advanced. +var bool bHurtEntry; // keep HurtRadius from being reentrant +var bool bGameRelevant; // Always relevant for game +var const bool bMovable; // Actor can be moved. +var bool bDestroyInPainVolume; // destroy this actor if it enters a pain volume +var bool bCanBeDamaged; // can take damage +var bool bShouldBaseAtStartup; // if true, find base for this actor at level startup, if collides with world and PHYS_None or PHYS_Rotating +var bool bPendingDelete; // set when actor is about to be deleted (since endstate and other functions called + // during deletion process before bDeleteMe is set). +var bool bCanTeleport; // This actor can be teleported. +var const bool bAlwaysTick; // Update even when paused +/** indicates that this Actor can dynamically block AI paths */ +var(Navigation) bool bBlocksNavigation; + +//----------------------------------------------------------------------------- +// Collision. + +// Collision primitive. +var(Collision) editconst PrimitiveComponent CollisionComponent; + +var native int OverlapTag; + +/** enum for LDs to select collision options - sets Actor flags and that of our CollisionComponent via PostEditChange() */ +var(Collision) const transient enum ECollisionType +{ + COLLIDE_CustomDefault, // custom programmer set collison (PostEditChange() will restore collision to defaults when this is selected) + COLLIDE_NoCollision, // doesn't collide + COLLIDE_BlockAll, // blocks everything + COLLIDE_BlockWeapons, // only blocks zero extent things (usually weapons) + COLLIDE_TouchAll, // touches (doesn't block) everything + COLLIDE_TouchWeapons, // touches (doesn't block) only zero extent things + COLLIDE_BlockAllButWeapons, // only blocks non-zero extent things (Pawns, etc) + COLLIDE_TouchAllButWeapons, // touches (doesn't block) only non-zero extent things + COLLIDE_BlockWeaponsKickable // Same as BlockWeapons, but enables flags to be kicked by player physics +} CollisionType; +/** used when collision is changed via Kismet "Change Collision" action to set component flags on the CollisionComponent + * will not modify replicated Actor flags regardless of setting + */ +var transient ECollisionType ReplicatedCollisionType; +/** mirrored copy of CollisionComponent's BlockRigidBody for the Actor property window for LDs (so it's next to CollisionType) + * purely for editing convenience and not used at all by the physics code + */ +var(Collision) const transient bool BlockRigidBody; + +// Collision flags. +var bool bCollideWhenPlacing; // This actor collides with the world when placing. +var const bool bCollideActors; // Collides with other actors. +var bool bCollideWorld; // Collides with the world. +var(Collision) bool bCollideComplex; // Ignore Simple Collision on Static Meshes, and collide per Poly. +var bool bBlockActors; // Blocks other nonplayer actors. +var bool bProjTarget; // Projectiles should potentially target this actor. +var bool bBlocksTeleport; +/** Controls whether move operations should collide with destructible pieces or not. */ +var bool bMoveIgnoresDestruction; +/** When in PHYS_Projectile, this actor will move with the MOVE_SingleBlocking flag */ +var bool bProjectileMoveSingleBlocking; + +/** + * For encroachers, don't do the overlap check when they move. You will not get touch events for this actor moving, but it is much faster. + * So if you want touch events from volumes or triggers you need to set this to be FALSE. + * This is an optimisation for large numbers of PHYS_RigidBody actors for example. + */ +var(Collision) bool bNoEncroachCheck; + +/** If true, this actor collides as an encroacher, even if its physics is not PHYS_RigidBody or PHYS_Interpolating */ +var bool bCollideAsEncroacher; + +/** If true, do a zero-extent trace each frame from old to new Location when in PHYS_RigidBody. If it hits the world (ie might be tunneling), call FellOutOfWorld. */ +var(Collision) bool bPhysRigidBodyOutOfWorldCheck; + +/** Set TRUE if a component is ever attached which is outside the world. OutsideWorldBounds will be called in Tick in this case. */ +var const transient bool bComponentOutsideWorld; + +/** If TRUE, components of this Actor will only ever be placed into one node of the octree. This makes insertion faster, but may impact runtime performance */ +var bool bForceOctreeSNFilter; +/** If TRUE, components of this actor will always be added using multinodefilter, even if game is up and the actor is dynamic */ +var bool bForceOctreeMNFilter; + +/** RigidBody of CollisionComponent was awake last frame -- used to call OnWakeRBPhysics/OnSleepRBPhysics events */ +var const transient bool bRigidBodyWasAwake; +/** Should call OnWakeRBPhysics/OnSleepRBPhysics events */ +var bool bCallRigidBodyWakeEvents; + +//----------------------------------------------------------------------------- +// Physics. + +// Options. +var bool bBounce; // Bounces when hits ground fast. +var const bool bJustTeleported; // Used by engine physics - not valid for scripts. + +// Physics properties. +var(Movement) rotator RotationRate; // Change in rotation per second. +/** + * PLEASE NOTE DesiredRotation is removed + * This DesiredRotation is moved to Pawn to remove redundant variables usage. (i.e. between Pawn and Controller) + * Pawn now handles all DesiredRotation and it is only one place. + * All Actor's DesiredRotation won't work anymore - Use RotationRate to control Actor's rotation + **/ +var Actor PendingTouch; // Actor touched during move which wants to add an effect after the movement completes + +//@note: Pawns have properties that override these values +const MINFLOORZ = 0.7; // minimum z value for floor normal (if less, not a walkable floor) + // 0.7 ~= 45 degree angle for floor +const ACTORMAXSTEPHEIGHT = 35.0; // max height floor walking actor can step up to + +const RBSTATE_LINVELSCALE = 10.0; +const RBSTATE_ANGVELSCALE = 1000.0; + +/** describes the physical state of a rigid body + * @warning: C++ mirroring is in UnPhysPublic.h + */ +struct RigidBodyState +{ + var vector Position; + var Quat Quaternion; + var vector LinVel; // RBSTATE_LINVELSCALE times actual (precision reasons) + var vector AngVel; // RBSTATE_ANGVELSCALE times actual (precision reasons) + var byte bNewData; +}; + +const RB_None=0x00; // Not set, empty +const RB_NeedsUpdate=0x01; // If bNewData & RB_NeedsUpdate != 0 then an update is needed +const RB_Sleeping=0x02; // if bNewData & RB_Sleeping != 0 then this RigidBody needs to sleep + +/** Information about one contact between a pair of rigid bodies + * @warning: C++ mirroring is in UnPhysPublic.h + */ +struct RigidBodyContactInfo +{ + var vector ContactPosition; + var vector ContactNormal; + var float ContactPenetration; + var vector ContactVelocity[2]; + var PhysicalMaterial PhysMaterial[2]; +}; + +/** Information about an overall collision, including contacts + * @warning: C++ mirroring is in UnPhysPublic.h + */ +struct CollisionImpactData +{ + /** all the contact points in the collision*/ + var array ContactInfos; + + /** the total force applied as the two objects push against each other*/ + var vector TotalNormalForceVector; + /** the total counterforce applied of the two objects sliding against each other*/ + var vector TotalFrictionForceVector; +}; + +/** Struct used to pass back information for physical impact effect */ +struct native PhysEffectInfo +{ + var() float Threshold; + var() float ReFireDelay; + var() ParticleSystem Effect; + var() AkBaseSoundObject Sound; +}; + +// endif + +//----------------------------------------------------------------------------- +// Mobile device properties + +/** Enable this actor to receive the OnMobileTouch event when a player touches this actor when using a touch screen device */ +var(Mobile) bool bEnableMobileTouch; + +//----------------------------------------------------------------------------- +// Networking. + +// Symmetric network flags, valid during replication only. +var const bool bNetInitial; // Initial network update. +var const bool bNetOwner; // Player owns this actor. + +//Editing flags +var const bool bHiddenEd; // Is hidden within the editor at its startup. +var const bool bEditable; // Whether the actor can be manipulated by editor operations. +var deprecated const bool bHiddenEdGroup;// Is hidden by the group browser. +var const bool bHiddenEdLayer; // Is hidden by the layer browser. +var const bool bHiddenEdCustom; // custom visibility flag for game-specific editor modes; not used by base editor functionality +var transient editoronly bool bHiddenEdTemporary; // Is temporarily hidden within the editor; used for show/hide/etc. functionality w/o dirtying the actor +var transient editoronly bool bHiddenEdLevel; // Is hidden by the level browser. +var transient editoronly bool bHiddenEdScene; // Is hidden by the scene browser. +var(Advanced) bool bEdShouldSnap; // Snap to grid in editor. +var transient const bool bTempEditor; // Internal UnrealEd. +var(Collision) bool bPathColliding;// this actor should collide (if bWorldGeometry && bBlockActors is true) during path building (ignored if bStatic is true, as actor will always collide during path building) +var transient bool bPathTemp; // Internal/path building +var bool bScriptInitialized; // set to prevent re-initializing of actors spawned during level startup +var(Advanced) bool bLockLocation; // Prevent the actor from being moved in the editor. +/** always allow Kismet to modify this Actor, even if it's static and not networked (e.g. for server side only stuff) */ +var const bool bForceAllowKismetModification; + +var class MessageClass; + +//----------------------------------------------------------------------------- +// Enums. + +// Traveling from server to server. +enum ETravelType +{ + TRAVEL_Absolute, // Absolute URL. + TRAVEL_Partial, // Partial (carry name, reset server). + TRAVEL_Relative, // Relative URL. +}; + + +// double click move direction. +enum EDoubleClickDir +{ + DCLICK_None, + DCLICK_Left, + DCLICK_Right, + DCLICK_Forward, + DCLICK_Back, + DCLICK_Active, + DCLICK_Done +}; + +/** The ticking group this actor belongs to */ +var const ETickingGroup TickGroup; + +//----------------------------------------------------------------------------- +// Kismet + +/** List of all events that this actor can support, for use by the editor */ +var const array > SupportedEvents; + +/** List of all events currently associated with this actor */ +var const array GeneratedEvents; + +/** List of all latent actions currently active on this actor */ +var array LatentActions; + +/** + * Struct used for cross level actor references + */ +struct immutablewhencooked native ActorReference +{ + var() Actor Actor; + var() editconst const guid Guid; + + structcpptext + { + FActorReference() + { + Actor = NULL; + } + FActorReference(EEventParm) + { + appMemzero(this, sizeof(FActorReference)); + } + explicit FActorReference(class AActor *InActor, FGuid &InGuid) + { + Actor = InActor; + Guid = InGuid; + } + // overload various operators to make the reference struct as transparent as possible + FORCEINLINE AActor* operator*() + { + return Actor; + } + FORCEINLINE AActor* operator->() + { + return Actor; + } + /** Slow version of deref that will use GUID if Actor is NULL */ + AActor* operator~(); + FORCEINLINE FActorReference* operator=(AActor* TargetActor) + { + Actor = TargetActor; + return this; + } + FORCEINLINE UBOOL operator==(const FActorReference &Ref) const + { + return (Ref != NULL && (Ref.Actor == Actor)); + } + FORCEINLINE UBOOL operator!=(const FActorReference &Ref) const + { + return (Ref == NULL || (Ref.Actor != Actor)); + } + FORCEINLINE UBOOL operator==(AActor *TestActor) const + { + return (Actor == TestActor); + } + FORCEINLINE UBOOL operator!=(AActor *TestActor) const + { + return (Actor != TestActor); + } + FORCEINLINE operator AActor*() + { + return Actor; + } + FORCEINLINE operator UBOOL() + { + return (Actor != NULL); + } + FORCEINLINE UBOOL operator!() + { + return (Actor == NULL); + } + FORCEINLINE class ANavigationPoint* Nav() + { + return ((class ANavigationPoint*)Actor); + } + + friend FArchive& operator<<( FArchive& Ar, FActorReference& T ); + } +}; + +struct immutablewhencooked native NavReference +{ + var() NavigationPoint Nav; + var() editconst const guid Guid; +}; + +/** + * Struct for handling positions relative to a base actor, which is potentially moving + */ +struct native BasedPosition +{ + var() Actor Base; + var() Vector Position; + + var Vector CachedBaseLocation; + var Rotator CachedBaseRotation; + var Vector CachedTransPosition; + + structcpptext + { + FBasedPosition(); + FBasedPosition(EEventParm); + explicit FBasedPosition( class AActor *InBase, FVector& InPosition ); + // Retrieve world location of this position + FVector operator*(); + void Set( class AActor* InBase, FVector& InPosition ); + void Clear(); + + friend FArchive& operator<<( FArchive& Ar, FBasedPosition& T ); + } +}; + +var(Debug) bool bDebugEffectIsRelevant; +`define debugEffectIsRelevant(msg,cond) if(bDebugEffectIsRelevant && `cond) { DebugMessagePlayer(`msg); } + +// NVCHANGE_BEGIN_TURB: Multiple PhysX levels +/** Load this actor if PhysXLevel is 0 (PhysX hardware acceleration off) */ +var(Advanced) bool bLoadIfPhysXLevel0; +/** Load this actor if PhysXLevel is 1 (Low PhysX hardware acceleration) */ +var(Advanced) bool bLoadIfPhysXLevel1; +/** Load this actor if PhysXLevel is 2 (High PhysX hardware acceleration) */ +var(Advanced) bool bLoadIfPhysXLevel2; +// NVCHANGE_END_TURB: Multiple PhysX levels + +`if(`__TW_) +//----------------------------------------------------------------------------- +// game specific + +/** Indicates PHYS_Spider Pawns can have their base set to this (set automatically during editor path build) */ +var(Collision) bool bCrawlable; + +/** Don't check collision against this actor for audio occlusion */ +var const bool bIgnoreAudioOcclusion; +/** Don't check collision against this actor for network relevancy */ +var const bool bIgnoreNetRelevancyCollision; +/** If set, bIgnoreNetRelevancyCollision & bIgnoreAudioOcclusion are set manually */ +var const bool bOverride_OcclusionFlags; + +/** Controls how this actor is affected by zed time */ +enum EZedTimeType +{ + /** If bIsLocalPlayerInZedTime==TRUE, also in zed time */ + ZTT_ClientEffect, + /** Always affected actors (e.g. GameInfo) */ + ZTT_Always, + /** Never affected actors (e.g. Controller) */ + ZTT_Never, + /** Manually controlled by subclass */ + ZTT_Manual +}; + +/** Total tick time passed (adjusted by TimeDilation) since this actor was spawned */ +var private transient float ActorTimeSeconds; + +/** If set, do not process conditional/deferred component updates during post tick */ +var const transient bool bSkipPostTickComponentUpdate; +`endif + +//----------------------------------------------------------------------------- +// cpptext. + +cpptext +{ + // Used to adjust box used for collision in overlap checks which are performed at a location other than the actor's current location. + static FVector OverlapAdjust; + + // Constructors. + virtual void BeginDestroy(); + virtual UBOOL IsReadyForFinishDestroy(); + + // UObject interface. + virtual INT* GetOptimizedRepList( BYTE* InDefault, FPropertyRetirement* Retire, INT* Ptr, UPackageMap* Map, UActorChannel* Channel ); + void ProcessEvent( UFunction* Function, void* Parms, void* Result=NULL ); + void ProcessState( FLOAT DeltaSeconds ); + UBOOL ProcessRemoteFunction( UFunction* Function, void* Parms, FFrame* Stack ); + void ProcessDemoRecFunction( UFunction* Function, void* Parms, FFrame* Stack ); + void InitExecution(); + virtual void PreEditChange(UProperty* PropertyThatWillChange); + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual void PreSave(); + virtual void PostLoad(); + void NetDirty(UProperty* property); + + // AActor interface. + virtual APawn* GetPlayerPawn() const {return NULL;} + virtual UBOOL IsPlayerPawn() const {return false;} + virtual UBOOL IgnoreBlockingBy( const AActor *Other) const; + UBOOL IsOwnedBy( const AActor *TestOwner ) const; + UBOOL IsBlockedBy( const AActor* Other, const UPrimitiveComponent* Primitive ) const; + UBOOL IsBasedOn( const AActor *Other ) const; + + /** If returns TRUE, can fracture a FSMA, if it has bBreakChunksOnActorTouch set. */ + virtual UBOOL CanCauseFractureOnTouch() + { + return FALSE; + } + + /** Creates offsets for locations based on the editor grid size and active viewport. **/ + virtual FVector CreateLocationOffset(UBOOL bDuplicate, UBOOL bOffsetLocations, INT ViewportType, FLOAT GridSize) const; + + /** + * Utility for finding the PrefabInstance that 'owns' this actor. + * If the actor is not part of a prefab instance, returns NULL. + * If the actor _is_ a PrefabInstance, return itself. + */ + class APrefabInstance* FindOwningPrefabInstance() const; + + AActor* GetBase() const; + +#if WITH_EDITOR + // Editor specific + + /** + * @return TRUE if the actor is in the named layer, FALSE otherwise. + */ + UBOOL IsInLayer(const TCHAR* LayerName) const; + + /** + * Parses the actor's layer string into a list of layer names (strings). + * @param OutLayers [out] Receives the list of layer names. + */ + void GetLayers(TArray& OutLayers) const; + + /** + * Called by ApplyDeltaToActor to perform an actor class-specific operation based on widget manipulation. + * The default implementation is simply to translate the actor's location. + */ + virtual void EditorApplyTranslation(const FVector& DeltaTranslation, UBOOL bAltDown, UBOOL bShiftDown, UBOOL bCtrlDown); + + /** + * Called by ApplyDeltaToActor to perform an actor class-specific operation based on widget manipulation. + * The default implementation is simply to modify the actor's rotation. + */ + virtual void EditorApplyRotation(const FRotator& DeltaRotation, UBOOL bAltDown, UBOOL bShiftDown, UBOOL bCtrlDown); + + /** + * Called by ApplyDeltaToActor to perform an actor class-specific operation based on widget manipulation. + * The default implementation is simply to modify the actor's draw scale. + */ + virtual void EditorApplyScale(const FVector& DeltaScale, const FMatrix& ScaleMatrix, const FVector* PivotLocation, UBOOL bAltDown, UBOOL bShiftDown, UBOOL bCtrlDown); + + /** + * Called by MirrorActors to perform a mirroring operation on the actor + */ + virtual void EditorApplyMirror(const FVector& MirrorScale, const FVector& PivotLocation); + + /** + * Simple accessor to check if the actor is hidden upon editor startup + * + * @return TRUE if the actor is hidden upon editor startup; FALSE if it is not + */ + UBOOL IsHiddenEdAtStartup() const + { + return bHiddenEd; + } + + // Called before editor copy, TRUE allow export + virtual UBOOL ShouldExport() { return TRUE; } + // Called before editor paste, TRUE allow import + virtual UBOOL ShouldImport(FString* ActorPropString, UBOOL IsMovingLevel) { return TRUE; } + // For UUnrealEdEngine::UpdatePropertyWindows() + virtual UBOOL GetSelectedComponents(TArray& SelectedObjects) { return FALSE; } + + /** Notifications that a key was pressed in the editor */ + virtual void OnEditorKeyPressed(FName Key, EInputEvent Event) {}; + + /** + * Called by ReplaceSelectedActors to allow a new actor to copy properties from an old actor when it is replaced + * + * @param OldActor the actor that is being replaced. + */ + virtual void EditorReplacedActor (AActor* OldActor) {} +#endif + + void EditorUpdateBase(); + void EditorUpdateAttachedActors(const TArray& IgnoreActors); + + + UBOOL IsHiddenEd() const; + virtual UBOOL IsSelected() const + { + return (UObject::IsSelected() && !bDeleteMe); + } + +#if __TW_ + /** + * Called when this actor is selected or unselected in the editor. + * + * @param bSelected whether the actor is selected or unselected + */ + virtual void EditorSelectionChange( UBOOL bSelected ) {}; +#endif + + virtual FLOAT GetNetPriority(const FVector& ViewPos, const FVector& ViewDir, APlayerController* Viewer, UActorChannel* InChannel, FLOAT Time, UBOOL bLowBandwidth); + /** ticks the actor + * @return TRUE if the actor was ticked, FALSE if it was aborted (e.g. because it's in stasis) + */ + virtual UBOOL Tick( FLOAT DeltaTime, enum ELevelTick TickType ); + /** + * bFinished is FALSE while the actor is being continually moved, and becomes TRUE on the last call. + * This can be used to defer computationally intensive calculations to the final PostEditMove call of + * eg a drag operation. + */ + virtual void PostEditMove(UBOOL bFinished); + virtual void PostRename(); + virtual void Spawned(); + /** sets CollisionType to a default value based on the current collision settings of this Actor and its CollisionComponent */ + void SetDefaultCollisionType(); + /** sets collision flags based on the current CollisionType */ + void SetCollisionFromCollisionType(); + virtual void PreNetReceive(); + virtual void PostNetReceive(); + virtual void PostNetReceiveLocation(); + virtual void PostNetReceiveBase(AActor* NewBase); + + // Rendering info. + + FMatrix LocalToWorld() const + { +#if 0 + FTranslationMatrix LToW ( -PrePivot ); + FScaleMatrix TempScale ( DrawScale3D * DrawScale ); + FRotationMatrix TempRot ( Rotation ); + FTranslationMatrix TempTrans ( Location ); + LToW *= TempScale; + LToW *= TempRot; + LToW *= TempTrans; + return LToW; +#else + FMatrix Result; + + const FLOAT SR = GMath.SinTab(Rotation.Roll), + SP = GMath.SinTab(Rotation.Pitch), + SY = GMath.SinTab(Rotation.Yaw), + CR = GMath.CosTab(Rotation.Roll), + CP = GMath.CosTab(Rotation.Pitch), + CY = GMath.CosTab(Rotation.Yaw); + + const FLOAT LX = Location.X, + LY = Location.Y, + LZ = Location.Z, + PX = PrePivot.X, + PY = PrePivot.Y, + PZ = PrePivot.Z; + + const FLOAT DX = DrawScale3D.X * DrawScale, + DY = DrawScale3D.Y * DrawScale, + DZ = DrawScale3D.Z * DrawScale; + + Result.M[0][0] = CP * CY * DX; + Result.M[0][1] = CP * DX * SY; + Result.M[0][2] = DX * SP; + Result.M[0][3] = 0.f; + + Result.M[1][0] = DY * ( CY * SP * SR - CR * SY ); + Result.M[1][1] = DY * ( CR * CY + SP * SR * SY ); + Result.M[1][2] = -CP * DY * SR; + Result.M[1][3] = 0.f; + + Result.M[2][0] = -DZ * ( CR * CY * SP + SR * SY ); + Result.M[2][1] = DZ * ( CY * SR - CR * SP * SY ); + Result.M[2][2] = CP * CR * DZ; + Result.M[2][3] = 0.f; + + Result.M[3][0] = LX - CP * CY * DX * PX + CR * CY * DZ * PZ * SP - CY * DY * PY * SP * SR + CR * DY * PY * SY + DZ * PZ * SR * SY; + Result.M[3][1] = LY - (CR * CY * DY * PY + CY * DZ * PZ * SR + CP * DX * PX * SY - CR * DZ * PZ * SP * SY + DY * PY * SP * SR * SY); + Result.M[3][2] = LZ - (CP * CR * DZ * PZ + DX * PX * SP - CP * DY * PY * SR); + Result.M[3][3] = 1.f; + + return Result; +#endif + } + FMatrix WorldToLocal() const + { + return FTranslationMatrix(-Location) * + FInverseRotationMatrix(Rotation) * + FScaleMatrix(FVector( 1.f / DrawScale3D.X, 1.f / DrawScale3D.Y, 1.f / DrawScale3D.Z) / DrawScale) * + FTranslationMatrix(PrePivot); + } + + /** Returns the size of the extent to use when moving the object through the world */ + FVector GetCylinderExtent() const; + + AActor* GetTopOwner(); + virtual UBOOL IsPendingKill() const + { + return bDeleteMe || HasAnyFlags(RF_PendingKill); + } + /** Fast check to see if an actor is alive by not being virtual */ + FORCEINLINE UBOOL ActorIsPendingKill(void) const + { + return bDeleteMe || HasAnyFlags(RF_PendingKill); + } + virtual void PostScriptDestroyed() {} // C++ notification that the script Destroyed() function has been called. + + // AActor collision functions. + virtual UBOOL ShouldTrace(UPrimitiveComponent* Primitive,AActor *SourceActor, DWORD TraceFlags); + virtual UBOOL IsOverlapping( AActor *Other, FCheckResult* Hit=NULL, UPrimitiveComponent* OtherPrimitiveComponent=NULL, UPrimitiveComponent* MyPrimitiveComponent=NULL ); + + virtual FBox GetComponentsBoundingBox(UBOOL bNonColliding=0) const; + + /** + * This will check to see if the Actor is still in the world. It will check things like + * the KillZ, SoftKillZ, outside world bounds, etc. and handle the situation. + **/ + void CheckStillInWorld(); + + // AActor general functions. + void UnTouchActors(); + void FindTouchingActors(); +#if __TW_ + virtual void BeginTouch(AActor *Other, UPrimitiveComponent* OtherComp, const FVector &HitLocation, const FVector &HitNormal, UPrimitiveComponent* MyComp=NULL); +#else + void BeginTouch(AActor *Other, UPrimitiveComponent* OtherComp, const FVector &HitLocation, const FVector &HitNormal, UPrimitiveComponent* MyComp=NULL); +#endif + void EndTouch(AActor *Other, UBOOL NoNotifySelf); + UBOOL IsBrush() const; + UBOOL IsStaticBrush() const; + UBOOL IsVolumeBrush() const; + UBOOL IsBrushShape() const; + UBOOL IsEncroacher() const; + + virtual UBOOL FindInterpMoveTrack(class UInterpTrackMove** MoveTrack, class UInterpTrackInstMove** MoveTrackInst, class USeqAct_Interp** OutSeq); + + /** whether this Actor wants to be ticked */ + FORCEINLINE UBOOL WantsTick() const { return !bStatic && !bTickIsDisabled; } + /** accessor for the value of bStatic */ + FORCEINLINE UBOOL IsStatic() const { return bStatic; } + /** + * Returns True if an actor cannot move or be destroyed during gameplay, and can thus cast and receive static shadowing. + */ + UBOOL HasStaticShadowing() const { return bStatic || (bNoDelete && !bMovable); } + + /** + * Sets the hard attach flag by first handling the case of already being + * based upon another actor + * + * @param bNewHardAttach the new hard attach setting + */ + virtual void SetHardAttach(UBOOL bNewHardAttach); + + virtual void NotifyBump(AActor *Other, UPrimitiveComponent* OtherComp, const FVector &HitNormal); +#if __TW_PATHFINDING_ + /** Overridden to return what was bumped into */ + virtual void NotifyBumpLevel(AActor *Wall, const FVector &HitLocation, const FVector &HitNormal); +#else + /** notification when actor has bumped against the level */ + virtual void NotifyBumpLevel(const FVector &HitLocation, const FVector &HitNormal); +#endif + void SetCollision( UBOOL bNewCollideActors, UBOOL bNewBlockActors, UBOOL bNewIgnoreEncroachers ); + virtual void SetBase(AActor *NewBase, FVector NewFloor = FVector(0,0,1), INT bNotifyActor=1, USkeletalMeshComponent* SkelComp=NULL, FName AttachName=NAME_None ); + void UpdateTimers(FLOAT DeltaSeconds); + virtual void TickAuthoritative( FLOAT DeltaSeconds ); + virtual void TickSimulated( FLOAT DeltaSeconds ); + virtual void TickSpecial( FLOAT DeltaSeconds ); + virtual UBOOL PlayerControlled(); + virtual UBOOL IsNetRelevantFor(APlayerController* RealViewer, AActor* Viewer, const FVector& SrcLocation); + + /** + * Check if this actor is the owner when doing relevancy checks for actors marked bOnlyRelevantToOwner + * + * @param ReplicatedActor - the actor we're doing a relevancy test on + * + * @param ActorOwner - the owner of ReplicatedActor + * + * @param ConnectionActor - the controller of the connection that we're doing relevancy checks for + * + * @return TRUE if this actor should be considered the owner + */ + virtual UBOOL IsRelevancyOwnerFor(AActor* ReplicatedActor, AActor* ActorOwner, AActor* ConnectionActor); + + /** returns whether this Actor should be considered relevant because it is visible through + * the other side of any portals RealViewer can see + */ + UBOOL IsRelevantThroughPortals(APlayerController* RealViewer); + + // Level functions + virtual void SetZone( UBOOL bTest, UBOOL bForceRefresh ); + virtual void SetVolumes(); + virtual void SetVolumes(const TArray& Volumes); + virtual void PreBeginPlay(); + virtual void PostBeginPlay(); + + /* + * Play a sound. Creates an AudioComponent only if the sound is determined to be audible, and replicates the sound to clients based on optional flags + * + * @param SoundLocation the location to play the sound; if not specified, uses the actor's location. + */ + void PlaySound(class USoundCue* InSoundCue, UBOOL bNotReplicated = FALSE, UBOOL bNoRepToOwner = FALSE, UBOOL bStopWhenOwnerDestroyed = FALSE, FVector* SoundLocation = NULL, UBOOL bNoRepToRelevant = FALSE); +// WWISEMODIF_START + void PlayAkEvent(class UAkEvent* InSoundCue, UBOOL bNotReplicated = FALSE, UBOOL bNoRepToOwner = FALSE, UBOOL bStopWhenOwnerDestroyed = FALSE, FVector* SoundLocation = NULL, UBOOL bNoRepToRelevant = FALSE); + void PlaySoundBase(class UAkBaseSoundObject* InSoundCue, UBOOL bNotReplicated = FALSE, UBOOL bNoRepToOwner = FALSE, UBOOL bStopWhenOwnerDestroyed = FALSE, FVector* SoundLocation = NULL, UBOOL bNoRepToRelevant = FALSE +#ifdef __TW_WWISE_ + ,FRotator* SoundRotation = NULL // used for echoes +#endif // __TW_WWISE_ + ); +// WWISEMODIF_END + + // Physics functions. + virtual void setPhysics(BYTE NewPhysics, AActor *NewFloor = NULL, FVector NewFloorV = FVector(0,0,1) ); + virtual void performPhysics(FLOAT DeltaSeconds); + virtual void physProjectile(FLOAT deltaTime, INT Iterations); + virtual void BoundProjectileVelocity(); + virtual void processHitWall(FCheckResult const& Hit, FLOAT TimeSlice=0.f); + virtual void processLanded(FVector const& HitNormal, AActor *HitActor, FLOAT remainingTime, INT Iterations); + virtual void physFalling(FLOAT deltaTime, INT Iterations); + virtual void physWalking(FLOAT deltaTime, INT Iterations); + virtual void physNavMeshWalking(FLOAT deltaTime){} + virtual void physCustom(FLOAT deltaTime, INT Iterations) {}; + virtual void physicsRotation(FLOAT deltaTime, FVector OldVelocity); + inline void TwoWallAdjust(const FVector &DesiredDir, FVector &Delta, const FVector &HitNormal, const FVector &OldHitNormal, FLOAT HitTime) + { + if ((OldHitNormal | HitNormal) <= 0.f) //90 or less corner, so use cross product for dir + { + FVector NewDir = (HitNormal ^ OldHitNormal); + NewDir = NewDir.SafeNormal(); + Delta = (Delta | NewDir) * (1.f - HitTime) * NewDir; + if ((DesiredDir | Delta) < 0.f) + Delta = -1.f * Delta; + } + else //adjust to new wall + { + Delta = (Delta - HitNormal * (Delta | HitNormal)) * (1.f - HitTime); + if ((Delta | DesiredDir) <= 0.f) + Delta = FVector(0.f,0.f,0.f); + else if ( Abs((HitNormal | OldHitNormal) - 1.f) < KINDA_SMALL_NUMBER ) + { + // we hit the same wall again even after adjusting to move along it the first time + // nudge away from it (this can happen due to precision issues) + Delta += HitNormal * 0.1f; + } + } + } + UBOOL moveSmooth(FVector const& Delta); + virtual FRotator FindSlopeRotation(const FVector& FloorNormal, const FRotator& NewRotation); + void UpdateRelativeRotation(); + virtual void GetNetBuoyancy(FLOAT &NetBuoyancy, FLOAT &NetFluidFriction); + virtual void SmoothHitWall(FVector const& HitNormal, AActor *HitActor); + virtual void stepUp(const FVector& GravDir, const FVector& DesiredDir, const FVector& Delta, FCheckResult &Hit); + virtual UBOOL ShrinkCollision(AActor *HitActor, UPrimitiveComponent* HitComponent, const FVector &StartLocation); + virtual void GrowCollision() {}; + virtual UBOOL MoveWithInterpMoveTrack(UInterpTrackMove* MoveTrack, UInterpTrackInstMove* MoveInst, FLOAT CurTime, FLOAT DeltaTime); + virtual void AdjustInterpTrackMove(FVector& Pos, FRotator& Rot, FLOAT DeltaTime, UBOOL bIgnoreRotation = FALSE) {} + virtual void physInterpolating(FLOAT DeltaTime); + virtual void PushedBy(AActor* Other) {}; + virtual void UpdateBasedRotation(FRotator &FinalRotation, const FRotator& ReducedRotation) {}; + virtual void ReverseBasedRotation() {}; + + /** Utility to add extra forces necessary for rigid-body gravity and damping to the collision component. */ + void AddRBGravAndDamping(); + + virtual void physRigidBody(FLOAT DeltaTime); + virtual void physSoftBody(FLOAT DeltaTime); + + virtual void InitRBPhys(); + virtual void InitRBPhysEditor() {} + virtual void TermRBPhys(FRBPhysScene* Scene); + + /** + * Used by the cooker to pre cache the convex data for static meshes within a given actor. + * This data is stored with the level. + * @param Level - The level the cache is in + * @param TriByteCount - running total of memory usage for per-tri collision cache + * @param TriMeshCount - running count of per-tri collision cache + * @param HullByteCount - running total of memory usage for hull cache + * @param HullCount - running count of hull cache + */ + virtual void BuildPhysStaticMeshCache(ULevel* Level, + INT& TriByteCount, INT& TriMeshCount, INT& HullByteCount, INT& HullCount); + + void ApplyNewRBState(const FRigidBodyState& NewState, FLOAT* AngErrorAccumulator, FVector& OutDeltaPos); + UBOOL GetCurrentRBState(FRigidBodyState& OutState); + + /** + * Event called when this Actor is involved in a rigid body collision. + * bNotifyRigidBodyCollision must be true on the physics PrimitiveComponent within this Actor for this event to be called. + * This base class implementation fires off the RigidBodyCollision Kismet event if attached. + */ + virtual void OnRigidBodyCollision(const FRigidBodyCollisionInfo& MyInfo, const FRigidBodyCollisionInfo& OtherInfo, const FCollisionImpactData& RigidCollisionData); + + /** Update information used to detect overlaps between this actor and physics objects, used for 'pushing' things */ + virtual void UpdatePushBody() {}; + +#if WITH_NOVODEX + virtual void ModifyNxActorDesc(NxActorDesc& ActorDesc,UPrimitiveComponent* PrimComp, const class NxGroupsMask& GroupsMask, UINT MatIndex) {} + virtual void PostInitRigidBody(NxActor* nActor, NxActorDesc& ActorDesc, UPrimitiveComponent* PrimComp) {} + virtual void PreTermRigidBody(NxActor* nActor) {} + virtual void SyncActorToRBPhysics(); + void SyncActorToClothPhysics(); +#endif // WITH_NOVODEX +#if WITH_PHYSX + virtual void ModifyPxActor(PxActor* nActor, UPrimitiveComponent* PrimComp, UPhysicalMaterial* PhysMat) {} + virtual void PostInitRigidBody(PxActor* nActor, UPrimitiveComponent* PrimComp) {} + virtual void PreTermRigidBody(PxActor* nActor) {} + virtual void SyncActorToRBPhysics(); +#endif // WITH_PHYSX + + // AnimControl Matinee Track support + + /** Used to provide information on the slots that this Actor provides for animation to Matinee. */ + virtual void GetAnimControlSlotDesc(TArray& OutSlotDescs) {} + + /** + * Called by Matinee when we open it to start controlling animation on this Actor. + * Is also called again when the GroupAnimSets array changes in Matinee, so must support multiple calls. + */ + virtual void PreviewBeginAnimControl(class UInterpGroup* InInterpGroup) {} + + /** Called each frame by Matinee to update the desired sequence by name and position within it. */ + virtual void PreviewSetAnimPosition(FName SlotName, INT ChannelIndex, FName InAnimSeqName, FLOAT InPosition, UBOOL bLooping, UBOOL bFireNotifies, UBOOL bEnableRootMotion, FLOAT DeltaTime) {} + + /** Called each frame by Matinee to update the desired animation channel weights for this Actor. */ + virtual void PreviewSetAnimWeights(TArray& SlotInfos) {} + + /** Called by Matinee when we close it after we have been controlling animation on this Actor. */ + virtual void PreviewFinishAnimControl(class UInterpGroup* InInterpGroup) {} + + /** Function used to control FaceFX animation in the editor (Matinee). */ + virtual void PreviewUpdateFaceFX(UBOOL bForceAnim, const FString& GroupName, const FString& SeqName, FLOAT InPosition) {} + + /** Used by Matinee playback to start a FaceFX animation playing. */ +// WWISEMODIF_START + virtual void PreviewActorPlayFaceFX(const FString& GroupName, const FString& SeqName, UAkBaseSoundObject* InSoundCue) {} +// WWISEMODIF_END + + /** Used by Matinee to stop current FaceFX animation playing. */ + virtual void PreviewActorStopFaceFX() {} + + /** Used in Matinee to get the AudioComponent we should play facial animation audio on. */ + virtual UAudioComponent* PreviewGetFaceFXAudioComponent() { return NULL; } + + /** Get the UFaceFXAsset that is currently being used by this Actor when playing facial animations. */ + virtual class UFaceFXAsset* PreviewGetActorFaceFXAsset() { return NULL; } + + /** Called each frame by Matinee to update the weight of a particular MorphNodeWeight. */ + virtual void PreviewSetMorphWeight(FName MorphNodeName, FLOAT MorphWeight) {} + + /** Called each frame by Matinee to update the scaling on a SkelControl. */ + virtual void PreviewSetSkelControlScale(FName SkelControlName, FLOAT Scale) {} + + /** Called each frame by Matinee to update the controlstrength on a SkelControl. */ + virtual void SetSkelControlStrength(FName SkelControlName, FLOAT ControlStrength) {} + + // AI functions. + int TestCanSeeMe(class APlayerController *Viewer); + virtual AActor* AssociatedLevelGeometry(); + virtual UBOOL HasAssociatedLevelGeometry(AActor *Other); + UBOOL SuggestTossVelocity(FVector* TossVelocity, const FVector& Dest, const FVector& Start, FLOAT TossSpeed, FLOAT BaseTossZ, FLOAT DesiredZPct, const FVector& CollisionSize, FLOAT TerminalVelocity, FLOAT OverrideGravityZ = 0.f, UBOOL bOnlyTraceUp = FALSE); + virtual UBOOL ReachedBy(APawn* P, const FVector& TestPosition, const FVector& Dest); + virtual UBOOL TouchReachSucceeded(APawn *P, const FVector &TestPosition); + virtual UBOOL BlockedByVehicle(); + + // Special editor behavior + AActor* GetHitActor(); + /** + * Function that gets called from within Map_Check to allow this actor to check itself + * for any potential errors and register them with map check dialog. + */ +#if WITH_EDITOR + virtual INT AddMyMarker(AActor *S) { return 0; }; + virtual void ClearMarker() {}; + + virtual void CheckForErrors(); + virtual void CheckForDeprecated(); + + + /** tells this Actor to set its collision for the path building state + * for normally colliding Actors that AI should path through (e.g. doors) or vice versa + * @param bNowPathBuilding - whether we are now building paths + */ + virtual void SetCollisionForPathBuilding(UBOOL bNowPathBuilding); + +#endif + + // path creation + virtual void PrePath() {}; + virtual void PostPath() {}; + + /** + * Return whether this actor is a builder brush or not. + * + * @return TRUE if this actor is a builder brush, FALSE otherwise + */ + virtual UBOOL IsABuilderBrush() const { return FALSE; } + + /** + * Return whether this actor is the current builder brush or not + * + * @return TRUE if htis actor is the current builder brush, FALSE otherwise + */ + virtual UBOOL IsCurrentBuilderBrush() const { return FALSE; } + + virtual UBOOL IsABrush() const {return FALSE;} + virtual UBOOL IsAVolume() const {return FALSE;} + virtual UBOOL IsABrushShape() const {return FALSE;} + virtual UBOOL IsAFluidSurface() const {return FALSE;} + + virtual APlayerController* GetAPlayerController() { return NULL; } + virtual AController* GetAController() { return NULL; } + virtual APawn* GetAPawn() { return NULL; } + virtual const APawn* GetAPawn() const { return NULL; } + virtual class AVehicle* GetAVehicle() { return NULL; } + virtual AVolume* GetAVolume() { return NULL; } + virtual class AFluidSurfaceActor* GetAFluidSurface() { return NULL; } + virtual class AProjectile* GetAProjectile() { return NULL; } + virtual const class AProjectile* GetAProjectile() const { return NULL; } + virtual class APortalTeleporter* GetAPortalTeleporter() { return NULL; }; +#if __TW_PATHFINDING_ + virtual ANavigationPoint* GetANavigationPoint() { return NULL; } + virtual const ANavigationPoint* GetANavigationPoint() const { return NULL; } +#endif + virtual APlayerController* GetTopPlayerController() + { + AActor* TopActor = GetTopOwner(); + return (TopActor ? TopActor->GetAPlayerController() : NULL); + } + + /** + * Verifies that neither this actor nor any of its components are RF_Unreachable and therefore pending + * deletion via the GC. + * + * @return TRUE if no unreachable actors are referenced, FALSE otherwise + */ + virtual UBOOL VerifyNoUnreachableReferences(); + + virtual void ClearComponents(); + void ConditionalUpdateComponents(UBOOL bCollisionUpdate = FALSE); + + /** Used by octree RestrictedOverlapCheck to determine whether an actor should be considered + * + * @return TRUE is actor should be considered + */ + virtual UBOOL WantsOverlapCheckWith(AActor* TestActor) { return TRUE; }; + + /** + * Used by Octree ActorRadius check to determine whether to return a component even if the actor owning the component has already been returned. + * @RETURN True if component should be returned + */ + virtual UBOOL ForceReturnComponent(UPrimitiveComponent* TestPrimitive) { return FALSE; }; + +protected: + virtual void UpdateComponentsInternal(UBOOL bCollisionUpdate = FALSE); +public: + + /** + * Flags all components as dirty if in the editor, and then calls UpdateComponents(). + * + * @param bCollisionUpdate [opt] As per UpdateComponents; defaults to FALSE. + * @param bTransformOnly [opt] TRUE to update only the component transforms, FALSE to update the entire component. + */ + virtual void ConditionalForceUpdateComponents(UBOOL bCollisionUpdate = FALSE,UBOOL bTransformOnly = TRUE); + + /** + * Flags all components as dirty so that they will be guaranteed an update from + * AActor::Tick(), and also be conditionally reattached by AActor::ConditionalUpdateComponents(). + * @param bTransformOnly - True if only the transform has changed. + */ + void MarkComponentsAsDirty(UBOOL bTransformOnly = TRUE); + + /** + * Works through the component arrays marking entries as pending kill so references to them + * will be NULL'ed. + * + * @param bAllowComponentOverride Whether to allow component to override marking the setting + */ + virtual void MarkComponentsAsPendingKill( UBOOL bAllowComponentOverride = FALSE ); + + /** + * Called by the static lighting system, allows this actor to generate static lighting primitives. + * The individual component's GetStaticLightingInfo functions will not be called if this returns TRUE. + */ + virtual UBOOL GetActorStaticLightingInfo(TArray& PrimitiveInfos, const TArray& InRelevantLights, const FLightingBuildOptions& Options) + { + return FALSE; + } + + /** Called by the lighting system to allow actors to order their components for deterministic lighting */ + virtual void OrderComponentsForDeterministicLighting() {} + + virtual void InvalidateLightingCache(); + +#if __TW_PRECOMPUTED_VISIBILITY_ + virtual void InvalidatePrecomputedVisibility(); +#endif + + /** Called by the static lighting system after lighting has been built. */ + virtual void FinalizeStaticLighting() {}; + + virtual UBOOL ActorLineCheck(FCheckResult& Result,const FVector& End,const FVector& Start,const FVector& Extent,DWORD TraceFlags); + + // Natives. + DECLARE_FUNCTION(execPollSleep); + DECLARE_FUNCTION(execPollFinishAnim); + + // Matinee + void GetInterpFloatPropertyNames(TArray &outNames); + void GetInterpVectorPropertyNames(TArray &outNames); + void GetInterpColorPropertyNames(TArray &outNames); + void GetInterpLinearColorPropertyNames(TArray &outNames); + FLOAT* GetInterpFloatPropertyRef(FName inName, FPointer &outContainer); + FVector* GetInterpVectorPropertyRef(FName inName); + FColor* GetInterpColorPropertyRef(FName inName); + FLinearColor* GetInterpLinearColorPropertyRef(FName inName); + + /** + * Get the names of any boolean properties of this Actor which are marked as 'interp'. + * Will also look in components of this Actor, and makes the name in the form 'componentname.propertyname'. + * + * @param OutNames The names of all the boolean properties marked as 'interp'. + */ + void GetInterpBoolPropertyNames( TArray& OutNames ); + + /** + * Looks up the matching boolean property and returns a reference to the actual value. + * + * @param InName The name of boolean property to retrieve a reference. + * @return A pointer to the actual value; NULL if the property was not found. + */ + BITFIELD* GetInterpBoolPropertyRef( FName InName, BITFIELD& Mask ); + + /** + * Returns TRUE if this actor is contained by TestLevel. + * @todo seamless: update once Actor->Outer != Level + */ + UBOOL IsInLevel(const ULevel *TestLevel) const; + /** Return the ULevel that this Actor is part of. */ + ULevel* GetLevel() const; + + /** + * Determine whether this actor is referenced by its level's GameSequence. + * + * @param pReferencer if specified, will be set to the SequenceObject that is referencing this actor. + * + * @return TRUE if this actor is referenced by kismet. + */ + UBOOL IsReferencedByKismet( class USequenceObject** pReferencer=NULL ) const; + + /** + * Do anything needed to clear out cross level references; Called from ULevel::PreSave + */ + virtual void ClearCrossLevelReferences(); + + /** + * Called when a level is loaded/unloaded, to get a list of all the crosslevel + * paths that need to be fixed up. + */ + virtual void GetActorReferences(TArray &ActorRefs, UBOOL bIsRemovingLevel) {} + + /** Returns ptr to GUID object for this actor. Override in child classes that actually have a GUID */ + virtual FGuid* GetGuid() { return NULL; } + + /* + * Route finding notifications (sent to target) + */ + virtual class ANavigationPoint* SpecifyEndAnchor(APawn* RouteFinder) { return NULL; } + virtual UBOOL AnchorNeedNotBeReachable(); + virtual void NotifyAnchorFindingResult(ANavigationPoint* EndAnchor, APawn* RouteFinder) {} + virtual UBOOL ShouldHideActor(FVector const& CameraLocation) { return FALSE; } + /** @return whether this Actor has exactly one attached colliding component (directly or indirectly) + * and that component is its CollisionComponent + */ + UBOOL HasSingleCollidingComponent(); + /** Called each from while the Matinee action is running, to set the animation weights for the actor. */ + virtual void SetAnimWeights( const TArray& SlotInfos ); + /** called when this Actor was moved because its Base moved, but after that move the Actor was + * encroaching on its Base + * @param EncroachedBase - the Actor we encroached (Base will be temporarily NULL when this function is called) + * @param OverlapHit - result from the overlap check that determined this Actor was encroaching + * @return whether the encroachment was resolved (i.e, this Actor is no longer encroaching its base) + */ + virtual UBOOL ResolveAttachedMoveEncroachment(AActor* EncroachedBase, const FCheckResult& OverlapHit) + { + return FALSE; + } + + virtual void OnEditorAnimEnd( UAnimNodeSequence* SeqNode, FLOAT PlayedTime, FLOAT ExcessTime ) {} + + virtual UBOOL Get_bDebug() { return bDebug; } + + /** + * Called when this actor is in a level which is being removed from the world (e.g. my level is getting UWorld::RemoveFromWorld called on it) + */ + virtual void OnRemoveFromWorld(); + + /** + * allows actors to override path collision, but only during cover builds + * allows them to be ignored at path generation time but not ignored during cover build + */ + virtual UBOOL NeedsCollisionOverrideDuringCoverBuild() {return FALSE;} +} + +//----------------------------------------------------------------------------- +// Network replication. + +replication +{ + // Location + if ( (!bSkipActorPropertyReplication || bNetInitial) && bReplicateMovement + && (((RemoteRole == ROLE_AutonomousProxy) && bNetInitial) + || ((RemoteRole == ROLE_SimulatedProxy) && (bNetInitial || bUpdateSimulatedPosition) && ((Base == None) || Base.bWorldGeometry))) ) + Location, Rotation; + + if ( (!bSkipActorPropertyReplication || bNetInitial) && bReplicateMovement + && RemoteRole==ROLE_SimulatedProxy ) + Base; + + if( (!bSkipActorPropertyReplication || bNetInitial) && bReplicateMovement && (bNetInitial || bUpdateSimulatedPosition) + && RemoteRole==ROLE_SimulatedProxy && (Base != None) && !Base.bWorldGeometry) + RelativeRotation, RelativeLocation; + + // Physics + if( (!bSkipActorPropertyReplication || bNetInitial) && bReplicateMovement + && ((RemoteRole == ROLE_SimulatedProxy) && (bNetInitial || bUpdateSimulatedPosition)) ) + Velocity, Physics; + + // Animation. + if ( (!bSkipActorPropertyReplication || bNetInitial) && (Role==ROLE_Authority) ) + bHardAttach; + + // Properties changed using accessor functions + if ( (!bSkipActorPropertyReplication || bNetInitial) && (Role==ROLE_Authority) && bNetDirty ) + bHidden; + + if ( (!bSkipActorPropertyReplication || bNetInitial) && (Role==ROLE_Authority) && bNetDirty + && (bCollideActors || bCollideWorld) ) + bProjTarget, bBlockActors; + + // Properties changed only when spawning or in script (relationships, rendering, lighting) + if ( (!bSkipActorPropertyReplication || bNetInitial) && (Role==ROLE_Authority) ) + Role,RemoteRole,bNetOwner,bTearOff; + + if ( (!bSkipActorPropertyReplication || bNetInitial) && (Role==ROLE_Authority) + && bNetDirty && bReplicateInstigator ) + Instigator; + + // Infrequently changed mesh properties + if ( (!bSkipActorPropertyReplication || bNetInitial) && (Role==ROLE_Authority) && bNetDirty ) + DrawScale, bCollideActors, bCollideWorld, ReplicatedCollisionType; + + // Properties changed using accessor functions + if ( bNetOwner && (!bSkipActorPropertyReplication || bNetInitial) && (Role==ROLE_Authority) && bNetDirty ) + Owner; +} + +//----------------------------------------------------------------------------- +// natives. + +/** + * Flags all components as dirty and then calls UpdateComponents(). + * + * @param bCollisionUpdate [opt] As per UpdateComponents; defaults to FALSE. + * @param bTransformOnly [opt] TRUE to update only the component transforms, FALSE to update the entire component. + */ +native function ForceUpdateComponents(optional bool bCollisionUpdate = FALSE, optional bool bTransformOnly = TRUE); + +// Execute a console command in the context of the current level and game engine. +native function string ConsoleCommand(string Command, optional bool bWriteToLog = true); + +//============================================================================= +// General functions. + +// Latent functions. +native(256) final latent function Sleep( float Seconds ); +native(261) final latent function FinishAnim( AnimNodeSequence SeqNode, optional bool bFinishOnBlendOut ); + +// Collision. +native(262) final noexport function SetCollision( optional bool bNewColActors, optional bool bNewBlockActors, optional bool bNewIgnoreEncroachers ); +native(283) final function SetCollisionSize( float NewRadius, float NewHeight ); +native final function SetCollisionType(ECollisionType NewCollisionType); +native final function SetDrawScale(float NewScale); +native final function SetDrawScale3D(vector NewScale3D); + +// Movement. +native(266) final function bool Move( vector Delta ); +native(267) final function bool SetLocation( vector NewLocation ); +native(299) final function bool SetRotation( rotator NewRotation ); +/** This will return the direction in LocalSpace that that actor is moving. This is useful for firing off effects based on which way the actor is moving. **/ +native function EMoveDir MovingWhichWay( out float Amount ); + +/** updates the zone/PhysicsVolume of this Actor + * @param bForceRefresh - forces the code to do a full collision check instead of exiting early if the current info is valid + */ +native final noexport function SetZone(bool bForceRefresh); + +// SetRelativeRotation() sets the rotation relative to the actor's base +native final function bool SetRelativeRotation( rotator NewRotation ); +native final function bool SetRelativeLocation( vector NewLocation ); +native final function noexport SetHardAttach(optional bool bNewHardAttach); + +/** + * This will look over the set of all attached of components that are SetBased on this Actor + * and then ShadowParent them to our MyPrimComp and use MyLightEnv. + **/ +native simulated function SetShadowParentOnAllAttachedComponents(PrimitiveComponent MyPrimComp, LightEnvironmentComponent MyLightEnv); + +/** Returns a new rotation component value + * @PARAM Current is the current rotation value + * @PARAM Desired is the desired rotation value + * @PARAM DeltaRate is the rotation amount to apply + */ +native final function int fixedTurn(int Current, int Desired, int DeltaRate); + +native(3969) noexport final function bool MoveSmooth( vector Delta ); +native(3971) final function AutonomousPhysics(float DeltaSeconds); + +/** returns terminal velocity (max speed while falling) for this actor. Unless overridden, it returns the TerminalVelocity of the PhysicsVolume in which this actor is located. +*/ +native function float GetTerminalVelocity(); + +// Relations. +native(298) noexport final function SetBase( actor NewBase, optional vector NewFloor, optional SkeletalMeshComponent SkelComp, optional name AttachName ); +native(272) final function SetOwner( actor NewOwner ); + +/** Attempts to find a valid base for this actor and sets it as the current base if found */ +native function FindBase(); + +/** Attempts to find a base for this actor; does not modify the actor's base. HeightBelow is the number of units below center to trace (FindBase uses 8) */ +native function SearchForBaseBelow(float HeightBelow, out Actor NewBase, out vector HitNormal); + +/** iterates up the Base chain to see whether or not this Actor is based on the given Actor + * @param TestActor the Actor to test for + * @return whether or not this Actor is based on TestActor + */ +native noexport final function bool IsBasedOn(Actor TestActor); + +/** Walks up the Base chain from this Actor and returns the Actor at the top (the eventual Base). this->Base is NULL, returns this. */ +native function Actor GetBaseMost(); + +/** iterates up the Owner chain to see whether or not this Actor is owned by the given Actor + * @param TestActor the Actor to test for + * @return whether or not this Actor is owned by TestActor + */ +native noexport final function bool IsOwnedBy(Actor TestActor); + +/** This will compute the aggregate velocity all the way up the Base chain */ +native final function Vector GetAggregateBaseVelocity( optional Actor TestBase ); + +simulated event ReplicatedEvent(name VarName); // Called when a variable with the property flag "RepNotify" is replicated + +/** adds/removes a property from a list of properties that will always be replicated when this Actor is bNetInitial, even if the code thinks + * the client has the same value the server already does + * This is a workaround to the problem where an LD places an Actor in the level, changes a replicated variable away from the defaults, + * then at runtime the variable is changed back to the default but it doesn't replicate because initial replication is based on class defaults + * Only has an effect when called on bStatic or bNoDelete Actors + * Only properties already in the owning class's replication block may be specified + * @param PropToReplicate the property to add or remove to the list + * @param bAdd true to add the property, false to remove the property + */ +native final function SetForcedInitialReplicatedProperty(Property PropToReplicate, bool bAdd); + + +/** This will calculate and then set the passed in BasedPosition. This is just modifying the passed in BasedPosition. */ +native static final function Vect2BP( out BasedPosition BP, Vector Pos, optional Actor ForcedBase ) const; +/** This will take the BasedPosition passed and return a Vector for it **/ +native static final function Vector BP2Vect( BasedPosition BP ) const; + +// legacy versions of the above +/** This will calculate and then set the passed in BasedPosition. This is just modifying the passed in BasedPosition. */ +native static final function SetBasedPosition( out BasedPosition BP, Vector Pos, optional Actor ForcedBase ) const; +/** This will take the BasedPosition passed and return a Vector for it **/ +native static final function Vector GetBasedPosition( BasedPosition BP ) const; + + +//========================================================================= +// Rendering. + +/** Flush persistent lines */ +native static final function FlushPersistentDebugLines() const; + +/** Draw a debug line */ +native static final function DrawDebugLine(vector LineStart, vector LineEnd, byte R, byte G, byte B, optional bool bPersistentLines) const; // SLOW! Use for debugging only! + +/** Draw a debug point */ +native static final function DrawDebugPoint(vector Position, float Size, LinearColor PointColor, optional bool bPersistentLines) const; // SLOW! Use for debugging only! + +/** Draw a debug box */ +native static final function DrawDebugBox(vector Center, vector Extent, byte R, byte G, byte B, optional bool bPersistentLines) const; // SLOW! Use for debugging only! + +/** Draw a debug star */ +native static final function DrawDebugStar(vector Position, float Size, byte R, byte G, byte B, optional bool bPersistentLines) const; // SLOW! Use for debugging only! + +/** Draw Debug coordinate system */ +native static final function DrawDebugCoordinateSystem(vector AxisLoc, Rotator AxisRot, float Scale, optional bool bPersistentLines) const; // SLOW! Use for debugging only! + +/** Draw a debug sphere */ +native static final function DrawDebugSphere(vector Center, float Radius, INT Segments, byte R, byte G, byte B, optional bool bPersistentLines) const; // SLOW! Use for debugging only! + +/** Draw a debug cylinder */ +native static final function DrawDebugCylinder(vector Start, vector End, float Radius, INT Segments, byte R, byte G, byte B, optional bool bPersistentLines) const; // SLOW! Use for debugging only! + +/** Draw a debug cone */ +native static final function DrawDebugCone(Vector Origin, Vector Direction, FLOAT Length, FLOAT AngleWidth, FLOAT AngleHeight, INT NumSides, Color DrawColor, optional bool bPersistentLines) const; + +/** Draw Debug string in the world (SLOW, use only in debug) + * @param TextLocation - location the string should be drawn (NOTE: if base actor is non-null this will be treated as an offset from that actor) + * @param Text - text to draw + * @param TestBaseActor (optional) - actor the string should be attached to (none if it should be static) + * @param Color (optional) - the color of the text to draw + * @param Duration (optional) - the duration the text should stick around; defauls to forever + */ +native static final function DrawDebugString(vector TextLocation, coerce string Text, optional Actor TestBaseActor, optional color TextColor, optional float Duration=-1.f) const; + +native static final function DrawDebugFrustrum( const out Matrix FrustumToWorld, byte R, byte G, byte B, optional bool bPersistentLines ) const; + +/** clear all debug strings */ +native static final function exec FlushDebugStrings() const; + +/** Draw some value over time onto the StatChart. Toggle on and off with */ +native final function ChartData(string DataName, float DataValue); + +/** + * Changes the value of bHidden. + * + * @param bNewHidden - The value to assign to bHidden. + */ +native final function SetHidden(bool bNewHidden); + +/** changes the value of bOnlyOwnerSee + * @param bNewOnlyOwnerSee the new value to assign to bOnlyOwnerSee + */ +native final function SetOnlyOwnerSee(bool bNewOnlyOwnerSee); + +//========================================================================= +// Physics. + +native(3970) noexport final function SetPhysics( EPhysics newPhysics ); + +// Timing +native final function Clock(out float time); +native final function UnClock(out float time); + +// Components + +/** + * Adds a component to the actor's components array, attaching it to the actor. + * @param NewComponent - The component to attach. + */ +native final function AttachComponent(ActorComponent NewComponent); + +/** + * Removes a component from the actor's components array, detaching it from the actor. + * @param ExComponent - The component to detach. + */ +native final function DetachComponent(ActorComponent ExComponent); + +/** + * Detaches and immediately reattaches specified component. Handles bWillReattach properly. + */ +native final function ReattachComponent(ActorComponent ComponentToReattach); + +/** Changes the ticking group for this actor */ +native final function SetTickGroup(ETickingGroup NewTickGroup); + +/** turns on or off this Actor's desire to be ticked (bTickIsDisabled) + * because this is implemented as a separate tickable list, calls to this function + * to disable ticking will not take effect until the end of the current list to avoid shuffling + * elements around while they are being iterated over + */ +native final function SetTickIsDisabled(bool bInDisabled); + +//========================================================================= +// Engine notification functions. + +// +// Major notifications. +// +event Destroyed(); +event GainedChild( Actor Other ); +event LostChild( Actor Other ); +event Tick( float DeltaTime ); + +// +// Physics & world interaction. +// +event Timer(); +event HitWall( vector HitNormal, actor Wall, PrimitiveComponent WallComp ) +{ + TriggerEventClass(class'SeqEvent_HitWall', Wall); +} + +event Falling(); +event Landed( vector HitNormal, actor FloorActor ); +event PhysicsVolumeChange( PhysicsVolume NewVolume ); +event Touch( Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal ); +event PostTouch( Actor Other ); // called for PendingTouch actor after physics completes +event UnTouch( Actor Other ); +event Bump( Actor Other, PrimitiveComponent OtherComp, Vector HitNormal ); +event BaseChange(); +event Attach( Actor Other ); +event Detach( Actor Other ); +event Actor SpecialHandling(Pawn Other); +/** + * Called when collision values change for this actor (via SetCollision/SetCollisionSize). + */ +event CollisionChanged(); +/** called when this Actor is encroaching on Other and we couldn't find an appropriate place to push Other to + * @return true to abort the move, false to allow it + * @warning do not abort moves of PHYS_RigidBody actors as that will cause the Unreal location and physics engine location to mismatch + */ +event bool EncroachingOn(Actor Other); +event EncroachedBy( actor Other ); +event RanInto( Actor Other ); // called for encroaching actors which successfully moved the other actor out of the way + +/** RigidBody woke up after being stationary - only valid if bCallRigidBodyWakeEvents==TRUE */ +event OnWakeRBPhysics(); +/** RigidBody went to sleep after being awake - only valid if bCallRigidBodyWakeEvents==TRUE */ +event OnSleepRBPhysics(); + +/** Clamps out_Rot between the upper and lower limits offset from the base */ +simulated final native function bool ClampRotation( out Rotator out_Rot, Rotator rBase, Rotator rUpperLimits, Rotator rLowerLimits ); +/** Called by ClampRotation if the rotator was outside of the limits */ +simulated event bool OverRotated( out Rotator out_Desired, out Rotator out_Actual ); + +/** + * Called when being activated by the specified pawn. Default + * implementation searches for any SeqEvent_Used and activates + * them. + * + * @return true to indicate this actor was activated + */ +function bool UsedBy(Pawn User) +{ + return TriggerEventClass(class'SeqEvent_Used', User, -1); +} + +/** called when the actor falls out of the world 'safely' (below KillZ and such) */ +simulated event FellOutOfWorld(class dmgType) +{ + SetPhysics(PHYS_None); + SetHidden(True); + SetCollision(false,false); + Destroy(); +} + +/** called when the Actor is outside the hard limit on world bounds + * @note physics and collision are automatically turned off after calling this function + */ +simulated event OutsideWorldBounds() +{ + Destroy(); +} + +/** Called when an Actor should be destroyed by a pain volume. */ +simulated function VolumeBasedDestroy(PhysicsVolume PV) +{ + Destroy(); +} + +/** + * Trace a line and see what it collides with first. + * Takes this actor's collision properties into account. + * Returns first hit actor, Level if hit level, or None if hit nothing. + */ +native(277) noexport final function Actor Trace +( + out vector HitLocation, + out vector HitNormal, + vector TraceEnd, + optional vector TraceStart, + optional bool bTraceActors, + optional vector Extent, + optional out TraceHitInfo HitInfo, + optional int ExtraTraceFlags +); + +/** + * Run a line check against just this PrimitiveComponent. Return TRUE if we hit. + * NOTE: the actual Actor we call this on is irrelevant! + */ +native noexport final function bool TraceComponent +( + out vector HitLocation, + out vector HitNormal, + PrimitiveComponent InComponent, + vector TraceEnd, + optional vector TraceStart, + optional vector Extent, + optional out TraceHitInfo HitInfo, + optional bool bComplexCollision +); + +/** + * Run a point check against just this PrimitiveComponent. Return TRUE if we hit. + * NOTE: the actual Actor we call this on is irrelevant! + */ +native noexport final function bool PointCheckComponent +( + PrimitiveComponent InComponent, + vector PointLocation, + vector PointExtent +); + +// returns true if did not hit world geometry +native(548) noexport final function bool FastTrace +( + vector TraceEnd, + optional vector TraceStart, + optional vector BoxExtent, + optional bool bTraceBullet +); + +native noexport final function bool TraceAllPhysicsAssetInteractions +( + SkeletalMeshComponent SkelMeshComp, + Vector EndTrace, + Vector StartTrace, + out Array out_Hits, + optional Vector Extent +`if(`__TW_HITZONE_DETECTION_) + , + optional bool bTraceHitZones +`endif +); + +/* + * Tries to position a box to avoid overlapping world geometry. + * If no overlap, the box is placed at SpotLocation, otherwise the position is adjusted + * @Parameter BoxExtent is the collision extent (X and Y=CollisionRadius, Z=CollisionHeight) + * @Parameter SpotLocation is the position where the box should be placed. Contains the adjusted location if it is adjusted. + * @Return true if successful in finding a valid non-world geometry overlapping location + */ +native final function bool FindSpot(vector BoxExtent, out vector SpotLocation); + +native final function bool ContainsPoint(vector Spot); +native noexport final function bool IsOverlapping(Actor A); +native final function GetComponentsBoundingBox(out box ActorBox) const; +native function GetBoundingCylinder(out float CollisionRadius, out float CollisionHeight) const; + +/** @return whether this Actor may be blocked by any primitive of Other */ +native final noexport function bool IsBlockedBy(const Actor Other) const; + +/** Spawn an actor. Returns an actor of the specified class, not + * of class Actor (this is hardcoded in the compiler). Returns None + * if the actor could not be spawned (if that happens, there will be a log warning indicating why) + * Defaults to spawning at the spawner's location. + * + * @note: ActorTemplate is sent for replicated actors and therefore its properties will also be applied + * at initial creation on the client. However, because of this, ActorTemplate must be a static resource + * (an actor archetype, default object, or a bStatic/bNoDelete actor in a level package) + * or the spawned Actor cannot be replicated + */ +native noexport final function coerce actor Spawn +( + class SpawnClass, + optional actor SpawnOwner, + optional name SpawnTag, + optional vector SpawnLocation, + optional rotator SpawnRotation, + optional Actor ActorTemplate, + optional bool bNoCollisionFail +); + +// +// Destroy this actor. Returns true if destroyed, false if indestructible. +// Destruction is latent. It occurs at the end of the tick. +// +native(279) final noexport function bool Destroy(); + +// Networking - called on client when actor is torn off (bTearOff==true) +event TornOff(); + +//============================================================================= +// Timing. + +/** + * Sets a timer to call the given function at a set + * interval. Defaults to calling the 'Timer' event if + * no function is specified. If InRate is set to + * 0.f it will effectively disable the previous timer. + * + * NOTE: Functions with parameters are not supported! + * + * @param InRate the amount of time to pass between firing + * @param inbLoop whether to keep firing or only fire once + * @param inTimerFunc the name of the function to call when the timer fires + */ +native(280) final function SetTimer(float InRate, optional bool inbLoop, optional Name inTimerFunc='Timer', optional Object inObj); + +/** + * Clears a previously set timer, identical to calling + * SetTimer() with a <= 0.f rate. + * + * @param inTimerFunc the name of the timer to remove or the default one if not specified + */ +native final function ClearTimer(optional Name inTimerFunc='Timer', optional Object inObj); + +/** + * Clears all previously set timers + */ +native final function ClearAllTimers(optional Object inObj); + +/** + * Pauses/Unpauses a previously set timer + * + * @param bPause whether to pause/unpause the timer + * @param inTimerFunc the name of the timer to pause or the default one if not specified + * @param inObj object timer is attached to + */ +native final function PauseTimer( bool bPause, optional Name inTimerFunc='Timer', optional Object inObj ); + +/** + * Returns true if the specified timer is active, defaults + * to 'Timer' if no function is specified. + * + * @param inTimerFunc the name of the timer to remove or the default one if not specified + */ +native final function bool IsTimerActive(optional Name inTimerFunc='Timer', optional Object inObj); + +/** + * Gets the current count for the specified timer, defaults + * to 'Timer' if no function is specified. Returns -1.f + * if the timer is not currently active. + * + * @param inTimerFunc the name of the timer to remove or the default one if not specified + */ +native final function float GetTimerCount(optional Name inTimerFunc='Timer', optional Object inObj); + +/** + * Gets the current rate for the specified timer. + * + * @note: GetTimerRate('SomeTimer') - GetTimerCount('SomeTimer') is the time remaining before 'SomeTimer' is called + * + * @param: TimerFuncName the name of the function to check for a timer for; 'Timer' is the default + * + * @return the rate for the given timer, or -1.f if that timer is not active + */ +native final function float GetTimerRate(optional name TimerFuncName = 'Timer', optional Object inObj); + +simulated final function float GetRemainingTimeForTimer(optional name TimerFuncName = 'Timer', optional Object inObj) +{ + local float Count, Rate; + Rate = GetTimerRate(TimerFuncName,inObj); + if (Rate != -1.f) + { + Count = GetTimerCount(TimerFuncName,inObj); + return Rate - Count; + } + return -1.f; +} + +/** This will search the Timers on this actor and set the passed in TimerTimeDilation **/ +native final function ModifyTimerTimeDilation( const name TimerName, const float InTimerTimeDilation, optional Object inObj ); + +/** This will search the Timers on this actor and reset the TimerTimeDilation to 1.0f **/ +native final function ResetTimerTimeDilation( const name TimerName, optional Object inObj ); + + +//============================================================================= +// Sound functions. + +/* Create an audio component. + * may fail and return None if sound is disabled, there are too many sounds playing, or if the Location is out of range of all listeners + */ +native final function AudioComponent CreateAudioComponent(SoundCue InSoundCue, optional bool bPlay, optional bool bStopWhenOwnerDestroyed, optional bool bUseLocation, optional vector SourceLocation, optional bool bAttachToSelf = true); + +/* + * Play a sound. Creates an AudioComponent only if the sound is determined to be audible, and replicates the sound to clients based on optional flags + * @param InSoundCue - the sound to play + * @param bNotReplicated (opt) - sound is considered only for players on this machine (supercedes other flags) + * @param bNoRepToOwner (opt) - sound is not replicated to the Owner of this Actor (typically for Inventory sounds) + * @param bStopWhenOwnerDestroyed (opt) - whether the sound should cut out early if the playing Actor is destroyed + * @param SoundLocation (opt) - alternate location to play the sound instead of this Actor's Location + * @param bNoRepToRelevant (opt) - sound is not replicated to clients for which this Actor is relevant (for important sounds that are locally simulated when possible) + */ +native noexport final function PlaySound(SoundCue InSoundCue, optional bool bNotReplicated, optional bool bNoRepToOwner, optional bool bStopWhenOwnerDestroyed, optional vector SoundLocation, optional bool bNoRepToRelevant); + +// WWISEMODIF_START + +/* + * Play an AkEvent, SoundCue style. Creates an AudioComponent only if the sound is determined to be audible, and replicates the sound to clients based on optional flags + * @param InAkEvent - the sound to play + * @param bNotReplicated (opt) - sound is considered only for players on this machine (supercedes other flags) + * @param bNoRepToOwner (opt) - sound is not replicated to the Owner of this Actor (typically for Inventory sounds) + * @param bStopWhenOwnerDestroyed (opt) - whether the sound should cut out early if the playing Actor is destroyed + * @param SoundLocation (opt) - alternate location to play the sound instead of this Actor's Location + * @param bNoRepToRelevant (opt) - sound is not replicated to clients for which this Actor is relevant (for important sounds that are locally simulated when possible) + */ +native noexport final function PlayAkEvent(AkEvent InSoundCue, optional bool bNotReplicated, optional bool bNoRepToOwner, optional bool bStopWhenOwnerDestroyed, optional vector SoundLocation, optional bool bNoRepToRelevant); + +/* + * Play an AkEvent or a SoundCue. Creates an AudioComponent only if the sound is determined to be audible, and replicates the sound to clients based on optional flags + * @param InAkEvent - the sound to play + * @param bNotReplicated (opt) - sound is considered only for players on this machine (supercedes other flags) + * @param bNoRepToOwner (opt) - sound is not replicated to the Owner of this Actor (typically for Inventory sounds) + * @param bStopWhenOwnerDestroyed (opt) - whether the sound should cut out early if the playing Actor is destroyed + * @param SoundLocation (opt) - alternate location to play the sound instead of this Actor's Location + * @param bNoRepToRelevant (opt) - sound is not replicated to clients for which this Actor is relevant (for important sounds that are locally simulated when possible) + * @param SoundRotation (opt) - rotation to use for playing advanced echo effects when using an AKEventAdvanced for the InSoundCue + */ +native noexport final function PlaySoundBase( AkBaseSoundObject InSoundCue, optional bool bNotReplicated, optional bool bNoRepToOwner, optional bool bStopWhenOwnerDestroyed, optional vector SoundLocation, optional bool bNoRepToRelevant +`if(`__TW_WWISE_) + , optional rotator SoundRotation // used for echoes +`endif //__TW_WWISE_ + ); + +/* + * Post an AkEvent. + * @param InAkEvent - AkEvent to play on the current actor + * @param bIsOccluded (opt) - whether event has been determined to be occluded + * @param bIsSpatialized (opt) - whether event should be spatialized or not + */ +native final function PostAkEvent( AkEvent InAkEvent +`if(`__TW_WWISE_) + , optional bool bIsOccluded + , optional bool bIsSpatialized + , optional bool bStopWhenOwnerDestroyed +`endif //__TW_WWISE_ +); + +`if(`__TW_WWISE_) +/* + * Post an AkEvent. + * @param InAkEvent - AkEvent to play on the current actor + * @param bIsOccluded (opt) - whether event has been determined to be occluded + */ +native final function PostAkEventAtLocation(AkEvent InAkEvent, vector SoundLocation, optional bool bIsOccluded); + +/* +* Post an AkEvent to play on a specified bone of the actor. +* @param InAkEvent - AkEvent to play on the current actor +* @param BoneName - Bone to attach the event to +* @param bIsOccluded (opt) - whether event has been determined to be occluded +* @param bIsSpatialized (opt) - whether event should be spatialized or not +* */ +native final function PostAkEventOnBone(AkEvent InAkEvent, name BoneName, optional bool bIsOccluded, optional bool bIsSpatialized); + +/* + * Stop all AkEvents that are currently playing on the given bone + */ +native final function StopAkEventsOnBone( name BoneName ); + +/* + * Set an RTPC value. + * @param InRTPC - Name of the RTPC value to be modified + * @param targetvalue - Target value of the RTPC for the current actor + * @param bGlobal - Set this RPC with Global scope rather than Actor scope + */ +native final function SetRTPCValue( Name InRTPC, float targetvalue, optional bool bGlobal ); + +/** returns the rotation to use when playing AKEvent sounds that + * require a rotation + */ +native simulated function rotator GetAKRotation(); +`else +/* + * Set an RTPC value. + * @param InRTPC - Name of the RTPC value to be modified + * @param targetvalue - Target value of the RTPC for the current actor + */ +native final function SetRTPCValue( Name InRTPC, float targetvalue ); +`endif // __TW_WWISE_ + +/* + * Set State for AkAudio. + * @param InStateGroup - Name of the State Group to be modified + * @param InState - Target value of the state ( Not Specific to this actor ) + */ +native final function SetState( Name InStateGroup, Name InState ); + +/* + * Set Switch for AkAudio. + * @param InStateGroup - Name of the Switch Group to be modified + * @param InState - Target value of the switch ( Will apply on this specific actor ) + */ +native final function SetSwitch( Name InSwitchGroup, Name InSwitch ); + +/* + * Post Trigger for AkAudio. + * @param InTrigger - Name of the Trigger to be posted + */ +native final function PostTrigger( Name InTrigger ); + +/* + * Post Trigger for AkAudio. + * @param InTrigger - Name of the Trigger to be posted + */ +native final function ActivateOcclusion( bool bInActivate ); + +// WWISEMODIF_END +//============================================================================= +// AI functions. + +/* Inform other creatures that you've made a noise + they might hear (they are sent a HearNoise message) + Senders of MakeNoise should have an instigator if they are not pawns. +*/ +native(512) final function MakeNoise( float Loudness, optional Name NoiseType ); + +/* PlayerCanSeeMe returns true if any player (server) or the local player (standalone + * or client) has a line of sight to actor's location. + * @param bForceLOSCheck (opt) - If set, force a line of sight check instead of relying on the occlusion checks + */ +native(532) final function bool PlayerCanSeeMe(optional bool bForceLOSCheck); + +/* epic =============================================== +* ::SuggestTossVelocity() +* +* returns a recommended Toss velocity vector, given a destination and a Toss speed magnitude +* @param TossVelocity - out param stuffed with the computed velocity to use +* @param End - desired end point of arc +* @param Start - desired start point of arc +* @param TossSpeed - in the magnitude of the toss - assumed to only change due to gravity for the entire lifetime of the projectile +* @param BaseTossZ - is an additional Z direction force added to the toss (which will not be included in the returned TossVelocity) - (defaults to 0) +* @param DesiredZPct (optional) - is the requested pct of the toss in the z direction (0=toss horizontally, 0.5 = toss at 45 degrees). This is the starting point for finding a toss. (Defaults to 0.05). +* the purpose of this is to bias the test in cases where there is more than one solution +* @param CollisionSize (optional) - is the size of bunding box of the tossed actor (defaults to (0,0,0) +* @param TerminalVelocity (optional) - terminal velocity of the projectile +* @param OverrideGravityZ (optional) - gravity inflicted upon the projectile in the z direction +* @param bOnlyTraceUp (optional) - when TRUE collision checks verifying the arc will only be done along the upward portion of the arc +* @return - TRUE/FALSE depending on whether a valid arc was computed +*/ +native noexport final function bool SuggestTossVelocity(out vector TossVelocity, + vector Destination, + vector Start, + float TossSpeed, + optional float BaseTossZ, + optional float DesiredZPct, + optional vector CollisionSize, + optional float TerminalVelocity, + optional float OverrideGravityZ /* = GetGravityZ() */, + optional bool bOnlyTraceUp); + +/** CalculateMinSpeedTrajectory() + * returns a velocity that will result in a trajectory that minimizes the speed of the projectile within the given range + * @param out_Velocity - out param stuffed with the computed velocity to use + * @param End - desired end point of arc + * @param Start - desired start point of arc + * @param MaxTossSpeed - Max acceptable speed of projectile + * @param MinTossSpeed - Min Acceptable speed of projectile + * @param CollisionSize (optional) - is the size of bunding box of the tossed actor (defaults to (0,0,0) + * @param TerminalVelocity (optional) - terminal velocity of the projectile + * @param GravityZ (optional) - gravity inflicted upon the projectile in the z direction + * @param bOnlyTraceUp (optional) - when TRUE collision checks verifying the arc will only be done along the upward portion of the arc + * @return - TRUE/FALSE depending on whether a valid arc was computed +*/ +native final function bool CalculateMinSpeedTrajectory(out vector out_Velocity, + vector End, + vector Start, + float MaxTossSpeed, + float MinTossSpeed, + optional vector CollisionSize, + optional float TerminalVelocity, + optional float GravityZ = GetGravityZ(), + optional bool bOnlyTraceUp); + +/** returns the position the AI should move toward to reach this actor + * accounts for AI using path lanes, cutting corners, and other special adjustments + */ +native final virtual function vector GetDestination(Controller C); + +//============================================================================= +// Regular engine functions. + +// Teleportation. +function bool PreTeleport(Teleporter InTeleporter); +function PostTeleport(Teleporter OutTeleporter); + +//======================================================================== +// Disk access. + +// Find files. +native(547) final function string GetURLMap(); + +//============================================================================= +// Iterator functions. + +// Iterator functions for dealing with sets of actors. + +/* AllActors() - avoid using AllActors() too often as it iterates through the whole actor list and is therefore slow +*/ +native(304) final iterator function AllActors ( class BaseClass, out actor Actor, optional class InterfaceClass ); + +/* DynamicActors() only iterates through the non-static actors on the list (still relatively slow, but + much better than AllActors). This should be used in most cases and replaces AllActors in most of + Epic's game code. +*/ +native(313) final iterator function DynamicActors ( class BaseClass, out actor Actor, optional class InterfaceClass ); + +/* ChildActors() returns all actors owned by this actor. Slow like AllActors() +*/ +native(305) final iterator function ChildActors ( class BaseClass, out actor Actor ); + +/* BasedActors() returns all actors based on the current actor (fast) +*/ +native(306) final iterator function BasedActors ( class BaseClass, out actor Actor ); + +/* TouchingActors() returns all actors touching the current actor (fast) +*/ +native(307) final iterator function TouchingActors( class BaseClass, out actor Actor ); + +/* TraceActors() return all actors along a traced line. Reasonably fast (like any trace) +*/ +native(309) final iterator function TraceActors ( class BaseClass, out actor Actor, out vector HitLoc, out vector HitNorm, vector End, optional vector Start, optional vector Extent, optional out TraceHitInfo HitInfo, optional int ExtraTraceFlags ); + +/* VisibleActors() returns all visible (not bHidden) actors within a radius +for which a trace from Loc (which defaults to caller's Location) to that actor's Location does not hit the world. +Slow like AllActors(). Use VisibleCollidingActors() instead if desired actor types are in the collision hash (bCollideActors is true) +*/ +native(311) final iterator function VisibleActors ( class BaseClass, out actor Actor, optional float Radius, optional vector Loc ); + +/* VisibleCollidingActors() returns all colliding (bCollideActors==true) actors within a certain radius +for which a trace from Loc (which defaults to caller's Location) to that actor's Location does not hit the world. +Much faster than AllActors() since it uses the collision octree +bUseOverlapCheck uses a sphere vs. box check instead of checking to see if the center of an object lies within a sphere +*/ +native(312) final iterator function VisibleCollidingActors ( class BaseClass, out actor Actor, float Radius, optional vector Loc, optional bool bIgnoreHidden, optional vector Extent, optional bool bTraceActors, optional class InterfaceClass, optional out TraceHitInfo HitInfo ); + +/* CollidingActors() returns colliding (bCollideActors==true) actors within a certain radius. +Much faster than AllActors() for reasonably small radii since it uses the collision octree +bUseOverlapCheck uses a sphere vs. box check instead of checking to see if the center of an object lies within a sphere +*/ +native(321) final iterator function CollidingActors ( class BaseClass, out actor Actor, float Radius, optional vector Loc, optional bool bUseOverlapCheck, optional class InterfaceClass, optional out TraceHitInfo HitInfo ); + +/** + * Returns colliding (bCollideActors==true) which overlap a Sphere from location 'Loc' and 'Radius' radius. + * + * @param BaseClass The Actor returns must be a subclass of this. + * @param out_Actor returned Actor at each iteration. + * @param Radius Radius of sphere for overlapping check. + * @param Loc Center of sphere for overlapping check. (Optional, caller's location is used otherwise). + * @param bIgnoreHidden if true, ignore bHidden actors. + */ +native final iterator function OverlappingActors( class BaseClass, out Actor out_Actor, float Radius, optional vector Loc, optional bool bIgnoreHidden ); + +/** returns each component in the Components list */ +native final iterator function ComponentList(class BaseClass, out ActorComponent out_Component); + +/** + * Iterates over all components directly or indirectly attached to this actor. + * @param BaseClass - Only components deriving from BaseClass will be iterated upon. + * @param OutComponent - The iteration variable. + */ +native final iterator function AllOwnedComponents(class BaseClass, out ActorComponent OutComponent); + +/** + iterator LocalPlayerControllers() + returns all locally rendered/controlled player controllers (typically 1 per client, unless split screen) +*/ +native final iterator function LocalPlayerControllers(class BaseClass, out PlayerController PC); +/** Return first found LocalPlayerController. Fine for single player, in split screen, one will be picked. */ +native final function PlayerController GetALocalPlayerController(); + +//============================================================================= +// Scripted Actor functions. + +// +// Called immediately before gameplay begins. +// +event PreBeginPlay() +{ + // Handle autodestruction if desired. + if (!bGameRelevant && !bStatic && WorldInfo.NetMode != NM_Client && !WorldInfo.Game.CheckRelevance(self)) + { + if (bNoDelete) + { + ShutDown(); + } + else + { + Destroy(); + } + } +} + +// +// Broadcast a localized message to all players. +// Most message deal with 0 to 2 related PRIs. +// The LocalMessage class defines how the PRI's and optional actor are used. +// +event BroadcastLocalizedMessage( class InMessageClass, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ) +{ + WorldInfo.Game.BroadcastLocalized( self, InMessageClass, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject ); +} + +// +// Broadcast a localized message to all players on a team. +// Most message deal with 0 to 2 related PRIs. +// The LocalMessage class defines how the PRI's and optional actor are used. +// +event BroadcastLocalizedTeamMessage( int TeamIndex, class InMessageClass, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ) +{ + WorldInfo.Game.BroadcastLocalizedTeam( TeamIndex, self, InMessageClass, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject ); +} + +// Called immediately after gameplay begins. +// +event PostBeginPlay(); + +// Called after PostBeginPlay. +// +simulated event SetInitialState() +{ + bScriptInitialized = true; + if( InitialState!='' ) + GotoState( InitialState ); + else + GotoState( 'Auto' ); +} + + +/** + * When a constraint is broken we will get this event from c++ land. + **/ +simulated event ConstraintBrokenNotify( Actor ConOwner, RB_ConstraintSetup ConSetup, RB_ConstraintInstance ConInstance ) +{ + +} + +simulated event NotifySkelControlBeyondLimit( SkelControlLookAt LookAt ); + +/* epic =============================================== +* ::StopsProjectile() +* +* returns true if Projectiles should call ProcessTouch() when they touch this actor +*/ +simulated function bool StopsProjectile(Projectile P) +{ + return bProjTarget || bBlockActors; +} + +/* HurtRadius() + Hurt locally authoritative actors within the radius. +*/ +simulated function bool HurtRadius +( + float BaseDamage, + float DamageRadius, + class DamageType, + float Momentum, + vector HurtOrigin, + optional Actor IgnoredActor, + optional Controller InstigatedByController = Instigator != None ? Instigator.Controller : None, + optional bool bDoFullDamage +) +{ + local Actor Victim; + local bool bCausedDamage; + local TraceHitInfo HitInfo; + local StaticMeshComponent HitComponent; + local KActorFromStatic NewKActor; + + // Prevent HurtRadius() from being reentrant. + if ( bHurtEntry ) + return false; + + bHurtEntry = true; + bCausedDamage = false; + foreach VisibleCollidingActors( class'Actor', Victim, DamageRadius, HurtOrigin,,,,, HitInfo ) + { + if ( Victim.bWorldGeometry ) + { + // check if it can become dynamic + // @TODO note that if using StaticMeshCollectionActor (e.g. on Consoles), only one component is returned. Would need to do additional octree radius check to find more components, if desired + HitComponent = StaticMeshComponent(HitInfo.HitComponent); + if ( (HitComponent != None) && HitComponent.CanBecomeDynamic() ) + { + NewKActor = class'KActorFromStatic'.Static.MakeDynamic(HitComponent); + if ( NewKActor != None ) + { + Victim = NewKActor; + } + } + } + if ( !Victim.bWorldGeometry && (Victim != self) && (Victim != IgnoredActor) && (Victim.bCanBeDamaged || Victim.bProjTarget) ) + { + Victim.TakeRadiusDamage(InstigatedByController, BaseDamage, DamageRadius, DamageType, Momentum, HurtOrigin, bDoFullDamage, self); + bCausedDamage = bCausedDamage || Victim.bProjTarget; + } + } + bHurtEntry = false; + return bCausedDamage; +} + +// +// Damage and kills. +// +function KilledBy( pawn EventInstigator ); + +/** apply some amount of damage to this actor + * @param DamageAmount the base damage to apply + * @param EventInstigator the Controller responsible for the damage + * @param HitLocation world location where the hit occurred + * @param Momentum force caused by this hit + * @param DamageType class describing the damage that was done + * @param HitInfo additional info about where the hit occurred + * @param DamageCauser the Actor that directly caused the damage (i.e. the Projectile that exploded, the Weapon that fired, etc) + */ +event TakeDamage(int DamageAmount, Controller EventInstigator, vector HitLocation, vector Momentum, class DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser) +{ + local int idx; + local SeqEvent_TakeDamage dmgEvent; + // search for any damage events + for (idx = 0; idx < GeneratedEvents.Length; idx++) + { + dmgEvent = SeqEvent_TakeDamage(GeneratedEvents[idx]); + if (dmgEvent != None) + { + // notify the event of the damage received + dmgEvent.HandleDamage(self, EventInstigator, DamageType, DamageAmount); + } + } +} + +`if(`__TW_) +/** + * the reverse of TakeDamage(); heals the specified amount + * + * @param Amount The amount of damage to heal + * @param Healer Who is doing the healing + * @param DamageType What type of healing is it + * @param bRepairArmor Should this fix armor? + */ +event bool HealDamage(int Amount, Controller Healer, class DamageType, optional bool bCanRepairArmor=true, optional bool bMessageHealer=true); +`else +/** + * the reverse of TakeDamage(); heals the specified amount + * + * @param Amount The amount of damage to heal + * @param Healer Who is doing the healing + * @param DamageType What type of healing is it + */ +event bool HealDamage(int Amount, Controller Healer, class DamageType); +`endif + +/** + * Take Radius Damage + * by default scales damage based on distance from HurtOrigin to Actor's location. + * This can be overridden by the actor receiving the damage for special conditions (see KAsset.uc). + * This then calls TakeDamage() to go through the same damage pipeline. + * + * @param InstigatedBy, instigator of the damage + * @param BaseDamage + * @param DamageRadius (from Origin) + * @param DamageType class + * @param Momentum (float) + * @param HurtOrigin, origin of the damage radius. + * @param bFullDamage, if true, damage not scaled based on distance HurtOrigin + * @param DamageCauser the Actor that directly caused the damage (i.e. the Projectile that exploded, the Weapon that fired, etc) + * @param DamageFalloff allows for nonlinear damage falloff from the point. Default is linera. + * + * @return Returns amount of damage applied. + */ +simulated function TakeRadiusDamage +( + Controller InstigatedBy, + float BaseDamage, + float DamageRadius, + class DamageType, + float Momentum, + vector HurtOrigin, + bool bFullDamage, + Actor DamageCauser, + optional float DamageFalloffExponent=1.f +) +{ + local float ColRadius, ColHeight; + local float DamageScale, Dist, ScaledDamage; + local vector Dir; + + GetBoundingCylinder(ColRadius, ColHeight); + + Dir = Location - HurtOrigin; + Dist = VSize(Dir); + Dir = Normal(Dir); + + if ( bFullDamage ) + { + DamageScale = 1.f; + } + else + { + Dist = FMax(Dist - ColRadius,0.f); + DamageScale = FClamp(1.f - Dist/DamageRadius, 0.f, 1.f); + DamageScale = DamageScale ** DamageFalloffExponent; + } + + if (DamageScale > 0.f) + { +`if(`__TW_) + AdjustRadiusDamage(BaseDamage, DamageScale, HurtOrigin); +`endif + ScaledDamage = DamageScale * BaseDamage; + TakeDamage + ( + ScaledDamage, + InstigatedBy, + Location - 0.5f * (ColHeight + ColRadius) * Dir, + (DamageScale * Momentum * Dir), + DamageType,, + DamageCauser + ); + } +} + +/** + * Make sure we pass along a valid HitInfo struct for damage. + * The main reason behind this is that SkeletalMeshes do require a BoneName to receive and process an impulse... + * So if we don't have access to it (through touch() or for any non trace damage results), we need to perform an extra trace call(). + * + * @param HitInfo, initial structure to check + * @param FallBackComponent, PrimitiveComponent to use if HitInfo.HitComponent is none + * @param Dir, Direction to use if a Trace needs to be performed to find BoneName on skeletalmesh. Trace from HitLocation. + * @param out_HitLocation, HitLocation to use for potential Trace, will get updated by Trace. + */ +final simulated function CheckHitInfo +( + out TraceHitInfo HitInfo, + PrimitiveComponent FallBackComponent, + Vector Dir, + out Vector out_HitLocation +) +{ + local vector out_NewHitLocation, out_HitNormal, TraceEnd, TraceStart; + local TraceHitInfo newHitInfo; + + //`log("Actor::CheckHitInfo - HitInfo.HitComponent:" @ HitInfo.HitComponent @ "FallBackComponent:" @ FallBackComponent ); + + // we're good, return! + if( SkeletalMeshComponent(HitInfo.HitComponent) != None && HitInfo.BoneName != '' ) + { + return; + } + + // Use FallBack PrimitiveComponent if possible + if( HitInfo.HitComponent == None || + (SkeletalMeshComponent(HitInfo.HitComponent) == None && SkeletalMeshComponent(FallBackComponent) != None) ) + { + HitInfo.HitComponent = FallBackComponent; + } + + // if we do not have a valid BoneName, perform a trace against component to try to find one. + if( SkeletalMeshComponent(HitInfo.HitComponent) != None && HitInfo.BoneName == '' ) + { + if( IsZero(Dir) ) + { + //`warn("passed zero dir for trace"); + Dir = Vector(Rotation); + } + + if( IsZero(out_HitLocation) ) + { + //`warn("IsZero(out_HitLocation)"); + //assert(false); + out_HitLocation = Location; + } + + TraceStart = out_HitLocation - 128 * Normal(Dir); + TraceEnd = out_HitLocation + 128 * Normal(Dir); + + if( TraceComponent( out_NewHitLocation, out_HitNormal, HitInfo.HitComponent, TraceEnd, TraceStart, vect(0,0,0), newHitInfo ) ) + { // Update HitLocation + HitInfo.BoneName = newHitInfo.BoneName; + HitInfo.PhysMaterial = newHitInfo.PhysMaterial; + out_HitLocation = out_NewHitLocation; + } + /* + else + { + // FIXME LAURENT -- The test fails when a just spawned projectile triggers a touch() event, the trace performed will be slightly off and fail. + `log("Actor::CheckHitInfo non successful TraceComponent!!"); + `log("HitInfo.HitComponent:" @ HitInfo.HitComponent ); + `log("TraceEnd:" @ TraceEnd ); + `log("TraceStart:" @ TraceStart ); + `log("out_HitLocation:" @ out_HitLocation ); + + ScriptTrace(); + //DrawDebugLine(TraceEnd, TraceStart, 255, 0, 0, TRUE); + //DebugFreezeGame(); + } + */ + } +} + +/** + * Get gravity currently affecting this actor + */ +native function float GetGravityZ(); + +/** + * Debug Freeze Game + * dumps the current script function stack and pauses the game with PlayersOnly (still allowing the player to move around). + */ +event DebugFreezeGame(optional Actor ActorToLookAt) +{ +`if(`notdefined(FINAL_RELEASE)) + local PlayerController PC; + ScriptTrace(); + PC = GetALocalPlayerController(); + + if (PC!=none) + { + PC.ConsoleCommand("PlayersOnly"); + + if( ActorToLookAt != None ) + { + PC.SetViewTarget(ActorToLookAt); + } + } +`endif +} + +function bool CheckForErrors(); + +/* BecomeViewTarget + Called by Camera when this actor becomes its ViewTarget */ +event BecomeViewTarget( PlayerController PC ); + +/* EndViewTarget + Called by Camera when this actor no longer its ViewTarget */ +event EndViewTarget( PlayerController PC ); + +/** + * Calculate camera view point, when viewing this actor. + * + * @param fDeltaTime delta time seconds since last update + * @param out_CamLoc Camera Location + * @param out_CamRot Camera Rotation + * @param out_FOV Field of View + * + * @return true if Actor should provide the camera point of view. + */ +simulated function bool CalcCamera( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV ) +{ + local vector HitNormal; + local float Radius, Height; + + GetBoundingCylinder(Radius, Height); + + if (Trace(out_CamLoc, HitNormal, Location - vector(out_CamRot) * Radius * 20, Location, false) == None) + { + out_CamLoc = Location - vector(out_CamRot) * Radius * 20; + } + else + { + out_CamLoc = Location + Height * vector(Rotation); + } + + return false; +} + +// Returns the string representation of the name of an object without the package +// prefixes. +// +simulated function String GetItemName( string FullName ) +{ + local int pos; + + pos = InStr(FullName, "."); + While ( pos != -1 ) + { + FullName = Right(FullName, Len(FullName) - pos - 1); + pos = InStr(FullName, "."); + } + + return FullName; +} + +// Returns the human readable string representation of an object. +// +simulated function String GetHumanReadableName() +{ + return GetItemName(string(class)); +} + +static function ReplaceText(out string Text, string Replace, string With) +{ + local int i; + local string Input; + + Input = Text; + Text = ""; + i = InStr(Input, Replace); + while(i != -1) + { + Text = Text $ Left(Input, i) $ With; + Input = Mid(Input, i + Len(Replace)); + i = InStr(Input, Replace); + } + Text = Text $ Input; +} + +// Get localized message string associated with this actor +static function string GetLocalString( + optional int Switch, + optional PlayerReplicationInfo RelatedPRI_1, + optional PlayerReplicationInfo RelatedPRI_2 + ) +{ + return ""; +} + +function MatchStarting(); // called when gameplay actually starts + +function String GetDebugName() +{ + return GetItemName(string(self)); +} + +/** + * list important Actor variables on canvas. HUD will call DisplayDebug() on the current ViewTarget when + * the ShowDebug exec is used + * + * @param HUD - HUD with canvas to draw on + * @input out_YL - Height of the current font + * @input out_YPos - Y position on Canvas. out_YPos += out_YL, gives position to draw text for next debug line. + */ +simulated function DisplayDebug(HUD HUD, out float out_YL, out float out_YPos) +{ + local string T; + local Actor A; + local float MyRadius, MyHeight; + local Canvas Canvas; + + Canvas = HUD.Canvas; + + Canvas.SetPos(4, out_YPos); + Canvas.SetDrawColor(255,0,0); + + T = GetDebugName(); + if( bDeleteMe ) + { + T = T$" DELETED (bDeleteMe == true)"; + } + + if( T != "" ) + { + Canvas.DrawText(T, FALSE); + out_YPos += out_YL; + Canvas.SetPos(4, out_YPos); + } + + Canvas.SetDrawColor(255,255,255); + + if( HUD.ShouldDisplayDebug('net') ) + { + if( WorldInfo.NetMode != NM_Standalone ) + { + // networking attributes + T = "ROLE:" @ Role @ "RemoteRole:" @ RemoteRole @ "NetMode:" @ WorldInfo.NetMode; + + if( bTearOff ) + { + T = T @ "Tear Off"; + } + Canvas.DrawText(T, FALSE); + out_YPos += out_YL; + Canvas.SetPos(4, out_YPos); + } + } + + Canvas.DrawText("Location:" @ Location @ "Rotation:" @ Rotation, FALSE); + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + + if( HUD.ShouldDisplayDebug('physics') ) + { + T = "Physics" @ GetPhysicsName() @ "in physicsvolume" @ GetItemName(string(PhysicsVolume)) @ "on base" @ GetItemName(string(Base)) @ "gravity" @ GetGravityZ(); + if( bBounce ) + { + T = T$" - will bounce"; + } + Canvas.DrawText(T, FALSE); + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + + Canvas.DrawText("bHardAttach:" @ bHardAttach @ "RelativeLoc:" @ RelativeLocation @ "RelativeRot:" @ RelativeRotation @ "SkelComp:" @ BaseSkelComponent @ "Bone:" @ string(BaseBoneName), FALSE); + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + + Canvas.DrawText("Velocity:" @ Velocity @ "Speed:" @ VSize(Velocity) @ "Speed2D:" @ VSize2D(Velocity), FALSE); + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + + Canvas.DrawText("Acceleration:" @ Acceleration, FALSE); + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + } + + if( HUD.ShouldDisplayDebug('collision') ) + { + Canvas.DrawColor.B = 0; + GetBoundingCylinder(MyRadius, MyHeight); + Canvas.DrawText("Collision Radius:" @ MyRadius @ "Height:" @ MyHeight); + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + + Canvas.DrawText("Collides with Actors:" @ bCollideActors @ " world:" @ bCollideWorld @ "proj. target:" @ bProjTarget); + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + Canvas.DrawText("Blocks Actors:" @ bBlockActors); + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + + T = "Touching "; + ForEach TouchingActors(class'Actor', A) + T = T$GetItemName(string(A))$" "; + if ( T == "Touching ") + T = "Touching nothing"; + Canvas.DrawText(T, FALSE); + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + } + + Canvas.DrawColor.B = 255; + Canvas.DrawText(" STATE:" @ GetStateName(), FALSE); + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + + Canvas.DrawText( " Instigator:" @ GetItemName(string(Instigator)) @ "Owner:" @ GetItemName(string(Owner)) ); + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); +} + +simulated function String GetPhysicsName() +{ + Switch( PHYSICS ) + { + case PHYS_None: return "None"; break; + case PHYS_Walking: return "Walking"; break; + case PHYS_Falling: return "Falling"; break; + case PHYS_Swimming: return "Swimming"; break; + case PHYS_Flying: return "Flying"; break; + case PHYS_Rotating: return "Rotating"; break; + case PHYS_Projectile: return "Projectile"; break; + case PHYS_Interpolating: return "Interpolating"; break; + case PHYS_Spider: return "Spider"; break; + case PHYS_Ladder: return "Ladder"; break; + case PHYS_RigidBody: return "RigidBody"; break; + case PHYS_Unused: return "Unused"; break; + case PHYS_Custom: return "Custom"; break; + } + return "Unknown"; +} + +/** called when a sound is going to be played on this Actor via PlayerController::ClientHearSound() + * gives it a chance to modify the component that will be used (add parameter values, etc) + */ +simulated event ModifyHearSoundComponent(AudioComponent AC); + +/** + * Function for allowing you to tell FaceFX which AudioComponent it should use for playing audio + * for corresponding facial animation. + */ +simulated event AudioComponent GetFaceFXAudioComponent() +{ + return None; +} + +/** + * Reset actor to initial state - used when restarting level without reloading. + */ +event Reset(); + +/** + * @RETURN true if this actor is touching a pain causing volume + */ +function bool IsInPain() +{ + local PhysicsVolume V; + + ForEach TouchingActors(class'PhysicsVolume',V) + if ( V.bPainCausing && (V.DamagePerSec > 0) ) + return true; + return false; +} + +function PlayTeleportEffect(bool bOut, bool bSound); + +simulated function bool CanSplash() +{ + return false; +} + +/** Called when this actor touches a fluid surface */ +simulated function ApplyFluidSurfaceImpact( FluidSurfaceActor Fluid, vector HitLocation) +{ + local float Radius, Height, AdjustedVelocity; + + if (bAllowFluidSurfaceInteraction) + { + AdjustedVelocity = 0.01 * Abs(Velocity.Z); + GetBoundingCylinder(Radius, Height); + Fluid.FluidComponent.ApplyForce( HitLocation, AdjustedVelocity * Fluid.FluidComponent.ForceImpact, Radius*0.3, True ); + } +} + +/** OBSOLETE, replaced by ActorEffectIsRelevant and ImpactEffectIsRelevant */ +simulated function bool EffectIsRelevant(vector SpawnLocation, bool bForceDedicated, optional float VisibleCullDistance=5000.0, optional float HiddenCullDistance=350.0 ) +{ + if ( SpawnLocation == Location ) + return ActorEffectIsRelevant(Instigator, bForceDedicated, VisibleCullDistance, HiddenCullDistance); + else + return ImpactEffectIsRelevant(Instigator, SpawnLocation, bForceDedicated, VisibleCullDistance, HiddenCullDistance); +} + +/** + * Determine whether an effect being spawned on this actor + * is relevant to the local client (to determine whether it really needs to be spawned). + * Intended for use only with short lived effects + * NOTE: Use ImpactEffectIsRelevant if the actor is not rendered! + * + * @PARAM EffectInstigator: Instigator os this effect - always relevant if instigated by local player + * @PARAM SpawnLocation: Location where effect is being spawned. If being spawned attached to this actor, use this actor's location to take advantage of check for whether actor is being rendered. + * @PARAM bForceDedicated: Whether effect should always be spawned on dedicated server (if effect is replicated to clients) + * @PARAM CullDistance: Max distance to spawn this effect if SpawnLocation is visible to the local player + * @PARAM HiddenCullDistance: Max distance to spawn this effect if SpawnLocation is not visible to the local player + */ +simulated function bool ActorEffectIsRelevant(Pawn EffectInstigator, bool bForceDedicated, optional float VisibleCullDistance=5000.0, optional float HiddenCullDistance=350.0 ) +{ + local PlayerController P; + local float DistSq; + local vector CameraLoc; + local rotator CameraRot; + + // No local player, so only spawn on dedicated server if bForceDedicated + if ( WorldInfo.NetMode == NM_DedicatedServer ) + { + `debugEffectIsRelevant( "EffectIsRelevant FAILED - dedicated server", bForceDedicated ); + + return bForceDedicated; + } + + if ( bForceDedicated && (WorldInfo.NetMode == NM_ListenServer) && (WorldInfo.Game.NumPlayers > 1) ) + { + // Is acting as server, so spawn effect if bForceDedicated + return TRUE; + } + + // spawn all effects instigated by the local player (not a server) + if ( (EffectInstigator != None) && EffectInstigator.IsHumanControlled() && EffectInstigator.IsLocallyControlled() ) + { + return TRUE; + } + + // Determine how far to the nearest local viewer + DistSq = 10000000000.0; + ForEach LocalPlayerControllers(class'PlayerController', P) + { + if ( P.GetViewTarget() == self ) + { + return true; + } + P.GetPlayerViewPoint(CameraLoc, CameraRot); + DistSq = FMin(DistSq, VSizeSq(Location - CameraLoc)*Square(P.LODDistanceFactor)); + } + + if ( DistSq > VisibleCullDistance*VisibleCullDistance ) + { + `debugEffectIsRelevant( "EffectIsRelevant FAILED - VisibleCullDistance", TRUE ); + + // never spawn beyond cull distance + return FALSE; + } + else if ( DistSq < HiddenCullDistance*HiddenCullDistance ) + { + // If close enough, always spawn even if hidden + return TRUE; + } + + // If beyond HiddenCullDistance, only spawn if actor is visible to local player + return ( `TimeSince( LastRenderTime ) < 0.3 ); +} + +/** + * Determine whether an effect being spawned at some spot in the world + * is relevant to the local client (to determine whether it really needs to be spawned). + * Intended for use only with short lived effects + * + * @PARAM EffectInstigator: Instigator os this effect - always relevant if instigated by local player + * @PARAM SpawnLocation: Location where effect is being spawned. If being spawned attached to this actor, use this actor's location to take advantage of check for whether actor is being rendered. + * @PARAM bForceDedicated: Whether effect should always be spawned on dedicated server (if effect is replicated to clients) + * @PARAM CullDistance: Max distance to spawn this effect if SpawnLocation is visible to the local player + * @PARAM HiddenCullDistance: Max distance to spawn this effect if SpawnLocation is not visible to the local player + * @PARAM bSkipLOSCheck: If true, don't perform a LOS trace, as the object is "big" like an explosion and a LOS would be inaccurate + */ +simulated function bool ImpactEffectIsRelevant(Pawn EffectInstigator, vector SpawnLocation, bool bForceDedicated, optional float VisibleCullDistance=5000.0, optional float HiddenCullDistance=350.0, optional bool bSkipLOSCheck ) +{ + local PlayerController P; + local float DistSq, InViewThreshold; + local bool bIsInViewFrustrum; + local vector CameraLoc; + local rotator CameraRot; + + // No local player, so only spawn on dedicated server if bForceDedicated + if ( WorldInfo.NetMode == NM_DedicatedServer ) + { + `debugEffectIsRelevant( "EffectIsRelevant FAILED - dedicated server", bForceDedicated ); + + return bForceDedicated; + } + + if ( bForceDedicated && (WorldInfo.NetMode == NM_ListenServer) && (WorldInfo.Game.NumPlayers > 1) ) + { + // Is acting as server, so spawn effect if bForceDedicated + return TRUE; + } + + // spawn all effects instigated by the local player (not a server) + if ( (EffectInstigator != None) && EffectInstigator.IsHumanControlled() && EffectInstigator.IsLocallyControlled() ) + { + return TRUE; + } + + // Determine how far to the nearest local viewer + DistSq = 10000000000.0; + ForEach LocalPlayerControllers(class'PlayerController', P) + { + P.GetPlayerViewPoint(CameraLoc, CameraRot); + DistSq = FMin(DistSq, VSizeSq(SpawnLocation - CameraLoc)*Square(P.LODDistanceFactor)); + } + + if ( DistSq > VisibleCullDistance*VisibleCullDistance ) + { + `debugEffectIsRelevant( "EffectIsRelevant FAILED - VisibleCullDistance", TRUE ); + + // never spawn beyond cull distance + return FALSE; + } + else if ( DistSq < HiddenCullDistance*HiddenCullDistance ) + { + // If close enough, always spawn even if hidden + return TRUE; + } + + // Don't spawn if spawnlocation not in a local player's view frustrum and visible + bIsInViewFrustrum = FALSE; + ForEach LocalPlayerControllers(class'PlayerController', P) + { + P.GetPlayerViewPoint(CameraLoc, CameraRot); + InViewThreshold = (Cos(P.GetFOVAngle()) - 0.1f); + + // Check the spawn location + if( (Normal(SpawnLocation - CameraLoc) Dot vector(CameraRot)) > InViewThreshold ) + { + if( bSkipLOSCheck || FastTrace(SpawnLocation, CameraLoc) ) + { + bIsInViewFrustrum = TRUE; + break; + } + } + } + + `debugEffectIsRelevant( "EffectIsRelevant FAILED - Outside View Frustrum", bIsInViewFrustrum ); + return bIsInViewFrustrum; +} + +final event DebugMessagePlayer( coerce String Msg ) +{ +`if(`notdefined(FINAL_RELEASE)) + local PlayerController PC; + + `log( "!!!!"@Msg@"!!!!" ); + ScriptTrace(); + + foreach LocalPlayerControllers(class'PlayerController', PC) + { + PC.ClientMessage( Msg ); + } +`endif +} + +//----------------------------------------------------------------------------- +// Scripting support + + +/** Convenience function for triggering events in the GeneratedEvents list + * If you need more options (activating multiple outputs, etc), call ActivateEventClass() directly + */ +simulated function bool TriggerEventClass(class InEventClass, Actor InInstigator, optional int ActivateIndex = -1, optional bool bTest, optional out array ActivatedEvents) +{ + local array ActivateIndices; + + if (ActivateIndex >= 0) + { + ActivateIndices[0] = ActivateIndex; + } + return ActivateEventClass(InEventClass, InInstigator, GeneratedEvents, ActivateIndices, bTest, ActivatedEvents); +} + +/** Called by SeqAct_AttachToEvent when a duplicate event is added to this actor at run-time */ +simulated event ReceivedNewEvent(SequenceEvent Evt) +{ +} + +/** trigger a "global" Kismet event (one that doesn't have an Originator, generally because it's triggered by a game-time object) */ +simulated function bool TriggerGlobalEventClass(class InEventClass, Actor InInstigator, optional int ActivateIndex = -1) +{ + local array EventsToActivate; + local array ActivateIndices; + local Sequence GameSeq; + local bool bResult; + local int i; + + if (ActivateIndex >= 0) + { + ActivateIndices[0] = ActivateIndex; + } + + GameSeq = WorldInfo.GetGameSequence(); + if (GameSeq != None) + { + GameSeq.FindSeqObjectsByClass(InEventClass, true, EventsToActivate); + for (i = 0; i < EventsToActivate.length; i++) + { + if (SequenceEvent(EventsToActivate[i]).CheckActivate(self, InInstigator,, ActivateIndices)) + { + bResult = true; + } + } + } + + return bResult; +} + +/** + * Iterates through the given list of events and looks for all + * matching events, activating them as found. + * + * @return true if an event was found and activated + */ +simulated final function bool ActivateEventClass( class InClass, Actor InInstigator, const out array EventList, + optional const out array ActivateIndices, optional bool bTest, optional out array ActivatedEvents ) +{ + local SequenceEvent Evt; + ActivatedEvents.Length = 0; + foreach EventList(Evt) + { + if (ClassIsChildOf(Evt.Class,InClass) && + Evt.CheckActivate(self,InInstigator,bTest,ActivateIndices)) + { + ActivatedEvents.AddItem(Evt); + } + } + return (ActivatedEvents.Length > 0); +} + +/** + * Builds a list of all events of the specified class. + * + * @param eventClass - type of event to search for + * @param out_EventList - list of found events + * @param bIncludeDisabled - will not filter out the events with bEnabled = FALSE + * + * @return true if any events were found + */ +simulated final function bool FindEventsOfClass(class EventClass, optional out array out_EventList, optional bool bIncludeDisabled) +{ + local SequenceEvent Evt; + local bool bFoundEvent; + foreach GeneratedEvents(Evt) + { + if (Evt != None && (Evt.bEnabled || bIncludeDisabled) && ClassIsChildOf(Evt.Class,EventClass) && (Evt.MaxTriggerCount == 0 || Evt.MaxTriggerCount > Evt.TriggerCount)) + { + out_EventList.AddItem(Evt); + bFoundEvent = TRUE; + } + } + return bFoundEvent; +} + +/** + * Clears all latent actions of the specified class. + * + * @param actionClass - type of latent action to clear + * @param bAborted - was this latent action aborted? + * @param exceptionAction - action to skip + */ +simulated final function ClearLatentAction(class actionClass,optional bool bAborted,optional SeqAct_Latent exceptionAction) +{ + local int idx; + for (idx = 0; idx < LatentActions.Length; idx++) + { + if (LatentActions[idx] == None) + { + // remove dead entry + LatentActions.Remove(idx--,1); + } + else + if (ClassIsChildOf(LatentActions[idx].class,actionClass) && + LatentActions[idx] != exceptionAction) + { + // if aborted, + if (bAborted) + { + // then notify the action + LatentActions[idx].AbortFor(self); + } + // remove action from list + LatentActions.Remove(idx--,1); + } + } +} + +/** + * If this actor is not already scheduled for destruction, + * destroy it now. + */ +simulated function OnDestroy(SeqAct_Destroy Action) +{ + local int AttachIdx, IgnoreIdx; + local Actor A; + + // Iterate through based actors and destroy them as well + if( Action.bDestroyBasedActors ) + { + for( AttachIdx = 0; AttachIdx < Attached.Length; AttachIdx++ ) + { + A = Attached[AttachIdx]; + for( IgnoreIdx = 0; IgnoreIdx < Action.IgnoreBasedClasses.Length; IgnoreIdx++ ) + { + if( ClassIsChildOf( A.Class, Action.IgnoreBasedClasses[IgnoreIdx]) ) + { + A = None; + break; + } + } + if( A == None ) + continue; + + A.OnDestroy( Action ); + } + } + + if (bNoDelete || Role < ROLE_Authority) + { + // bNoDelete actors cannot be destroyed, and are shut down instead. + ShutDown(); + } + else if( !bDeleteMe ) + { + Destroy(); + } +} + +/** forces this actor to be net relevant if it is not already + * by default, only works on level placed actors (bNoDelete) + */ +event ForceNetRelevant() +{ + if (RemoteRole == ROLE_None && bNoDelete && !bStatic) + { + RemoteRole = ROLE_SimulatedProxy; + bAlwaysRelevant = true; + NetUpdateFrequency = 0.1; + } + bForceNetUpdate = TRUE; +} + +/** Updates NetUpdateTime to the new value for future net relevancy checks */ +final native function SetNetUpdateTime(float NewUpdateTime); + +/** + * ShutDown an actor. + */ + +simulated event ShutDown() +{ + // Shut down physics + SetPhysics(PHYS_None); + // shut down collision + SetCollision(false, false); + if (CollisionComponent != None) + { + CollisionComponent.SetBlockRigidBody(false); + } + + // shut down rendering + SetHidden(true); + // and ticking + SetTickIsDisabled(true); + + ForceNetRelevant(); + + if (RemoteRole != ROLE_None) + { + // force replicate flags if necessary + SetForcedInitialReplicatedProperty(Property'Engine.Actor.bCollideActors', (bCollideActors == default.bCollideActors)); + SetForcedInitialReplicatedProperty(Property'Engine.Actor.bBlockActors', (bBlockActors == default.bBlockActors)); + SetForcedInitialReplicatedProperty(Property'Engine.Actor.bHidden', (bHidden == default.bHidden)); + SetForcedInitialReplicatedProperty(Property'Engine.Actor.Physics', (Physics == default.Physics)); + } + + // we can't set bTearOff here as that will prevent newly joining clients from receiving the state changes + // so we just set a really low NetUpdateFrequency + NetUpdateFrequency = 0.1; + // force immediate network update of these changes + bForceNetUpdate = TRUE; +} + +/** + * Calls PrestreamTextures() for all the actor's meshcomponents. + * @param Seconds Number of seconds to force all mip-levels to be resident + * @param bEnableStreaming Whether to start (TRUE) or stop (FALSE) streaming + * @param CinematicTextureGroups Bitfield indicating which texture groups that use extra high-resolution mips + */ +native function PrestreamTextures( float Seconds, bool bEnableStreaming, optional int CinematicTextureGroups = 0 ); + +simulated function OnModifyHealth(SeqAct_ModifyHealth Action) +{ + local Controller InstigatorController; + local Pawn InstigatorPawn; + + InstigatorController = Controller(Action.Instigator); + if( InstigatorController == None ) + { + InstigatorPawn = Pawn(Action.Instigator); + if( InstigatorPawn != None ) + { + InstigatorController = InstigatorPawn.Controller; + } + } + + if( Action.bHeal ) + { + HealDamage(Action.Amount, InstigatorController, Action.DamageType); + } + else + { + TakeDamage(Action.Amount, InstigatorController, Location, vector(Rotation) * -Action.Momentum, Action.DamageType); + } +} + +/** + * Called upon receiving a SeqAct_Teleport action. Grabs + * the first destination available and attempts to teleport + * this actor. + * + * @param Action - teleport action that was activated + */ +simulated function OnTeleport(SeqAct_Teleport Action) +{ + local array objVars; + local int idx; + local Actor destActor, tempActor, A; + local Controller C; + local bool bOccupiedDest, bColliding; + local float ColRadius, ColHeight; + local Vector Extent; + + GetBoundingCylinder( ColRadius, ColHeight); + Extent.X = ColRadius; + Extent.Y = ColRadius; + Extent.Z = ColHeight; + + bOccupiedDest = FALSE; + + // find the first supplied actor + Action.GetObjectVars(objVars,"Destination"); + for (idx = 0; idx < objVars.Length; idx++) + { + tempActor = Actor(objVars[idx]); + if( tempActor == None ) + { + continue; + } + + // If its a player variable, teleport to the Pawn not the Controller. + C = Controller(tempActor); + if(C != None && C.Pawn != None) + { + tempActor = C.Pawn; + } + + if( Action.bCheckOverlap ) + { + bColliding = FALSE; + foreach VisibleCollidingActors ( class'Actor', A, ColRadius * 2.f, tempActor.Location, FALSE, Extent, TRUE ) + { + if( IsBlockedBy( A ) ) + { + bColliding = TRUE; + break; + } + } + + bOccupiedDest = bColliding; + } + + destActor = tempActor; + if( (!Action.bCheckOverlap || !bOccupiedDest) && destActor != None ) + { + break; + } + } + // and set to that actor's location + if (destActor != None && Action.ShouldTeleport(self, destActor.Location,Action.TeleportDistance,Action.TeleportVolumes)) + { + if (SetLocation(destActor.Location)) + { + PlayTeleportEffect(false, true); + if (Action.bUpdateRotation) + { + SetRotation(destActor.Rotation); + } + + // make sure the changes get replicated + ForceNetRelevant(); + bUpdateSimulatedPosition = true; + bNetDirty = true; + } + else + { + `warn("Unable to teleport to"@destActor); + } + } + else if (destActor != None) + { + `warn("Unable to teleport to"@destActor); + } +} + +/** + * Handler for the SeqAct_SetVelocity action. Allows level designer to impart a velocity on the actor. + */ +simulated function OnSetVelocity( SeqAct_SetVelocity Action ) +{ + local Vector V; + local float Mag; + + Mag = Action.VelocityMag; + if( Mag <= 0.f ) + { + Mag = VSize( Action.VelocityDir); + } + V = Normal(Action.VelocityDir) * Mag; + if( Action.bVelocityRelativeToActorRotation ) + { + V = V >> Rotation; + } + Velocity = V; + + if( Physics == PHYS_RigidBody && CollisionComponent != None ) + { + CollisionComponent.SetRBLinearVelocity( Velocity ); + } +} + +/** + * Handler for the SeqAct_SetBlockRigidBody action. Allows level designer to toggle the rigid-body blocking + * flag on an Actor, and will handle updating the physics engine etc. + */ +simulated function OnSetBlockRigidBody(SeqAct_SetBlockRigidBody Action) +{ + if(CollisionComponent != None) + { + // Turn on + if(Action.InputLinks[0].bHasImpulse) + { + CollisionComponent.SetBlockRigidBody(true); + } + // Turn off + else if(Action.InputLinks[1].bHasImpulse) + { + CollisionComponent.SetBlockRigidBody(false); + } + } +} + +/** Handler for the SeqAct_SetPhysics action, allowing designer to change the Physics mode of an Actor. */ +simulated function OnSetPhysics(SeqAct_SetPhysics Action) +{ + ForceNetRelevant(); + SetPhysics( Action.NewPhysics ); + if (RemoteRole != ROLE_None) + { + if (Physics != PHYS_None) + { + bUpdateSimulatedPosition = true; + if (bOnlyDirtyReplication) + { + // SetPhysics() doesn't set bNetDirty, but we need it in this case + bNetDirty = true; + } + } + SetForcedInitialReplicatedProperty(Property'Engine.Actor.Physics', (Physics == default.Physics)); + } +} + +/** Handler for collision action, allow designer to toggle collide/block actors */ +function OnChangeCollision(SeqAct_ChangeCollision Action) +{ + // if the action is out of date then use the previous properties + if (Action.ObjInstanceVersion < Action.GetObjClassVersion()) + { + SetCollision( Action.bCollideActors, Action.bBlockActors, Action.bIgnoreEncroachers ); + } + else + { + // otherwise use the new collision type + SetCollisionType(Action.CollisionType); + } + ForceNetRelevant(); + if (RemoteRole != ROLE_None) + { + // force replicate flags if necessary + SetForcedInitialReplicatedProperty(Property'Engine.Actor.bCollideActors', (bCollideActors == default.bCollideActors)); + SetForcedInitialReplicatedProperty(Property'Engine.Actor.bBlockActors', (bBlockActors == default.bBlockActors)); + // don't bother with bIgnoreEncroachers as it isn't editable + } +} + +/** Handler for SeqAct_ToggleHidden, just sets bHidden. */ +simulated function OnToggleHidden(SeqAct_ToggleHidden Action) +{ + local int AttachIdx, IgnoreIdx; + local Actor A; + + // Iterate through based actors and toggle them as well + if( Action.bToggleBasedActors ) + { + for( AttachIdx = 0; AttachIdx < Attached.Length; AttachIdx++ ) + { + A = Attached[AttachIdx]; + for( IgnoreIdx = 0; IgnoreIdx < Action.IgnoreBasedClasses.Length; IgnoreIdx++ ) + { + if( ClassIsChildOf( A.Class, Action.IgnoreBasedClasses[IgnoreIdx]) ) + { + A = None; + break; + } + } + if( A == None ) + continue; + + A.OnToggleHidden( Action ); + } + } + + if (Action.InputLinks[0].bHasImpulse) + { + SetHidden(True); + } + else if (Action.InputLinks[1].bHasImpulse) + { + SetHidden(False); + } + else + { + SetHidden(!bHidden); + } + + ForceNetRelevant(); + if (RemoteRole != ROLE_None) + { + SetForcedInitialReplicatedProperty(Property'Engine.Actor.bHidden', (bHidden == default.bHidden)); + } +} + +/** Attach an actor to another one. Kismet action. */ +function OnAttachToActor(SeqAct_AttachToActor Action) +{ + local int idx; + local Actor Attachment; + local Controller C; + local Array ObjVars; + + Action.GetObjectVars(ObjVars,"Attachment"); + for( idx=0; idxSkelComponent + * @param PlayedTime - Time played on this animation. (play rate independant). + * @param ExcessTime - how much time overlapped beyond end of animation. (play rate independant). + */ +event OnAnimEnd(AnimNodeSequence SeqNode, float PlayedTime, float ExcessTime); + +/** + * Event called when a PlayAnim is called AnimNodeSequence in the animation tree of one of this Actor's SkeletalMeshComponents. + * bCauseActorAnimPlay must be set 'true' on the AnimNodeSequence for this event to get generated. + * + * @param SeqNode - Node had PlayAnim called. You can get to the SkeletalMeshComponent by looking at SeqNode->SkelComponent + */ +event OnAnimPlay(AnimNodeSequence SeqNode); + +// AnimControl Matinee Track Support + +/** Called when we start an AnimControl track operating on this Actor. Supplied is the set of AnimSets we are going to want to play from. */ +event BeginAnimControl(InterpGroup InInterpGroup); + +/** Called each from while the Matinee action is running, with the desired sequence name and position we want to be at. */ +event SetAnimPosition(name SlotName, int ChannelIndex, name InAnimSeqName, float InPosition, bool bFireNotifies, bool bLooping, bool bEnableRootMotion); + + +/** Called when we are done with the AnimControl track. */ +event FinishAnimControl(InterpGroup InInterpGroup); + +/** + * Play FaceFX animations on this Actor. + * Returns TRUE if succeeded, if failed, a log warning will be issued. + */ +// WWISEMODIF_START, alessard, nov-28-2008, WwiseAudioIntegration +event bool PlayActorFaceFXAnim(FaceFXAnimSet AnimSet, String GroupName, String SeqName, SoundCue SoundCueToPlay, AkEvent AkEventToPlay); +// WWISEMODIF_END + +/** Stop any matinee FaceFX animations on this Actor. */ +event StopActorFaceFXAnim(); + +/** Called each frame by Matinee to update the weight of a particular MorphNodeWeight. */ +event SetMorphWeight(name MorphNodeName, float MorphWeight); + +/** Called each frame by Matinee to update the scaling on a SkelControl. */ +event SetSkelControlScale(name SkelControlName, float Scale); + +/** + * Called every tick if bShouldTickOwner is true + */ +event TickSkelControl(float DeltaTime, SkeletalMeshComponent SkelComp, SkelControlBase SkelCtrl); + +/** + * Returns TRUE if Actor is playing a FaceFX anim. + * Implement in sub-class. + */ +simulated function bool IsActorPlayingFaceFXAnim() +{ + return FALSE; +} + +/** +* Returns FALSE if Actor can play facefx +* Implement in sub-class. +*/ +simulated function bool CanActorPlayFaceFXAnim() +{ + return TRUE; +} + +/** Used by Matinee in-game to mount FaceFXAnimSets before playing animations. */ +event FaceFXAsset GetActorFaceFXAsset(); + +// for AI... bots have perfect aim shooting non-pawn stationary targets +function bool IsStationary() +{ + return true; +} + +/** + * returns the point of view of the actor. + * note that this doesn't mean the camera, but the 'eyes' of the actor. + * For example, for a Pawn, this would define the eye height location, + * and view rotation (which is different from the pawn rotation which has a zeroed pitch component). + * A camera first person view will typically use this view point. Most traces (weapon, AI) will be done from this view point. + * + * @param out_Location - location of view point + * @param out_Rotation - view rotation of actor. + */ +simulated event GetActorEyesViewPoint( out vector out_Location, out Rotator out_Rotation ) +{ + out_Location = Location; + out_Rotation = Rotation; +} + +/** + * Searches the owner chain looking for a player. + */ +native simulated function bool IsPlayerOwned(); + +/* PawnBaseDied() +The pawn on which this actor is based has just died +*/ +function PawnBaseDied(); + +/* + * default implementation calls eventScriptGetTeamNum() + */ +simulated native function byte GetTeamNum(); + +simulated event byte ScriptGetTeamNum() +{ + return 255; +} + +simulated function NotifyLocalPlayerTeamReceived(); + +/** Used by PlayerController.FindGoodView() in RoundEnded State */ +simulated function FindGoodEndView(PlayerController PC, out Rotator GoodRotation) +{ + GoodRotation = PC.Rotation; +} + +/** + * @param RequestedBy - the Actor requesting the target location + * @param bRequestAlternateLoc (optional) - return a secondary target location if there are multiple + * @return the optimal location to fire weapons at this actor + */ +simulated native function vector GetTargetLocation(optional actor RequestedBy, optional bool bRequestAlternateLoc) const; + +/** called when this Actor was spawned by a Kismet actor factory (SeqAct_ActorFactory) + * after all other spawn events (PostBeginPlay(), etc) have been called + */ +event SpawnedByKismet(); + +/** called when a SeqAct_Interp action starts interpolating this Actor via matinee + * @note this function is called on clients for actors that are interpolated clientside via MatineeActor + * @param InterpAction the SeqAct_Interp that is affecting the Actor + */ +simulated event InterpolationStarted(SeqAct_Interp InterpAction, InterpGroupInst GroupInst); + +/** called when a SeqAct_Interp action finished interpolating this Actor + * @note this function is called on clients for actors that are interpolated clientside via MatineeActor + * @param InterpAction the SeqAct_Interp that was affecting the Actor + */ +simulated event InterpolationFinished(SeqAct_Interp InterpAction); + +/** called when a SeqAct_Interp action affecting this Actor received an event that changed its properties + * (paused, reversed direction, etc) + * @note this function is called on clients for actors that are interpolated clientside via MatineeActor + * @param InterpAction the SeqAct_Interp that is affecting the Actor + */ +simulated event InterpolationChanged(SeqAct_Interp InterpAction); + +/** Called when a PrimitiveComponent this Actor owns has: + * -bNotifyRigidBodyCollision set to true + * -ScriptRigidBodyCollisionThreshold > 0 + * -it is involved in a physics collision where the relative velocity exceeds ScriptRigidBodyCollisionThreshold + * + * @param HitComponent the component of this Actor that collided + * @param OtherComponent the other component that collided + * @param RigidCollisionData information on the collision itslef, including contact points + * @param ContactIndex the element in each ContactInfos' ContactVelocity and PhysMaterial arrays that corresponds + * to this Actor/HitComponent + */ +event RigidBodyCollision( PrimitiveComponent HitComponent, PrimitiveComponent OtherComponent, + const out CollisionImpactData RigidCollisionData, int ContactIndex ); + +/** + * Called each frame (for each wheel) when an SVehicle has a wheel in contact with this Actor. + * Not called on Actors that have bWorldGeometry or bStatic set to TRUE. + */ +event OnRanOver(SVehicle Vehicle, PrimitiveComponent RunOverComponent, int WheelIndex); + +/** function used to update where icon for this actor should be rendered on the HUD + * @param NewHUDLocation is a vector whose X and Y components are the X and Y components of this actor's icon's 2D position on the HUD + */ +simulated native function SetHUDLocation(vector NewHUDLocation); + +/** +Hook to allow actors to render HUD overlays for themselves. +Assumes that appropriate font has already been set +*/ +simulated native function NativePostRenderFor(PlayerController PC, Canvas Canvas, vector CameraPosition, vector CameraDir); + +/** +Script function called by NativePostRenderFor(). +*/ +simulated event PostRenderFor(PlayerController PC, Canvas Canvas, vector CameraPosition, vector CameraDir); + +/** + * Notification that root motion mode changed. + * Called only from SkelMeshComponents that have bRootMotionModeChangeNotify set. + * This is useful for synchronizing movements. + * For intance, when using RMM_Translate, and the event is called, we know that root motion will kick in on next frame. + * It is possible to kill in-game physics, and then use root motion seemlessly. + */ +simulated event RootMotionModeChanged(SkeletalMeshComponent SkelComp); + +/** Notification that Root Motion has been processed. */ +simulated event RootMotionProcessed(SkeletalMeshComponent SkelComp); + +/** + * Notification called after root motion has been extracted, and before it's been used. + * This notification can be used to alter extracted root motion before it is forwarded to physics. + * It is only called when bRootMotionExtractedNotify is TRUE on the SkeletalMeshComponent. + * @note: It is fairly slow in Script, so enable only when really needed. + */ +simulated event RootMotionExtracted(SkeletalMeshComponent SkelComp, out BoneAtom ExtractedRootMotionDelta); + +/** called after initializing the AnimTree for the given SkeletalMeshComponent that has this Actor as its Owner + * this is a good place to cache references to skeletal controllers, etc that the Actor modifies + */ +event PostInitAnimTree(SkeletalMeshComponent SkelComp); + +/** Looks up the GUID of a package on disk. The package must NOT be in the autodownload cache. + * This may require loading the header of the package in question and is therefore slow. + */ +native static final function Guid GetPackageGuid(name PackageName); + +/** Notification forwarded from RB_BodyInstance, when a spring is over extended and disabled. */ +simulated event OnRigidBodySpringOverextension(RB_BodyInstance BodyInstance); + +/** whether this Actor is in the persistent level, i.e. not a sublevel */ +native final function bool IsInPersistentLevel(optional bool bIncludeLevelStreamingPersistent) const; + + +/** + * Returns aim-friction zone extents for this actor. + * Extents are in world units centered around Actor's location, and assumed to be + * oriented to face the viewer (like a billboard sprite). + */ +simulated function GetAimFrictionExtent(out float Width, out float Height, out vector Center) +{ + if (bCanBeFrictionedTo) + { + // Note this will be increasingly inaccurate with increasing vertical viewing angle. + // Consider transforming extents. + GetBoundingCylinder(Width, Height); + } + else + { + Width = 0.f; + Height = 0.f; + } + Center = Location; +} + +/** + * Returns aim-adhesion zone extents for this actor. + * Extents are in world units centered around Actor's location, and assumed to be + * oriented to face the viewer (like a billboard sprite). + */ +simulated function GetAimAdhesionExtent(out float Width, out float Height, out vector Center) +{ + if (bCanBeAdheredTo) + { + // Note this will be increasingly inaccurate with increasing vertical viewing angle. + // Consider transforming extents. + GetBoundingCylinder(Width, Height); + } + else + { + Width = 0.f; + Height = 0.f; + } + Center = Location; +} + +/** + * Called by AnimNotify_PlayParticleEffect + * Looks for a socket name first then bone name + * + * @param AnimNotifyData The AnimNotify_PlayParticleEffect which will have all of the various params on it + * + * @return bool true if the particle effect was played, false if not; + */ +event bool PlayParticleEffect( const AnimNotify_PlayParticleEffect AnimNotifyData ) +{ + if (WorldInfo.NetMode == NM_DedicatedServer) + { + `Log("(Actor): PlayParticleEffect on dedicated server!"); + return true; + } + return false; +} + +/** + * Called by AnimNotify_CreateForceField + * Looks for a socket name first then bone name + * + * @param AnimNotifyData The AnimNotify_ForceField which will have all of the various params on it + * + * @return bool true if the forcefield was created, false if not; + */ +event bool CreateForceField( const AnimNotify_Forcefield AnimNotifyData ) +{ + return false; +} + +/** + * Called by AnimNotify_Trails + * + * @param AnimNotifyData The AnimNotify_Trails which will have all of the various params on it + */ +event TrailsNotify( const AnimNotify_Trails AnimNotifyData ); + +/** + * Called by AnimNotify_Trails + * + * @param AnimNotifyData The AnimNotify_Trails which will have all of the various params on it + */ +event TrailsNotifyTick( const AnimNotify_Trails AnimNotifyData ); + +/** + * Called by AnimNotify_Trails + * + * @param AnimNotifyData The AnimNotify_Trails which will have all of the various params on it + */ +event TrailsNotifyEnd( const AnimNotify_Trails AnimNotifyData ); + +/** Allows us to have dynamic trail particles */ +native function ParticleSystem GetAnimTrailParticleSystem( const AnimNotify_Trails AnimNotifyData ) const; + +/** whether this Actor can be modified by Kismet actions + * primarily used by error checking to warn LDs when their Kismet may not apply changes correctly (especially on clients) + * @param AskingOp - Kismet operation to which this Actor is linked + * @param Reason (out) - If this function returns false, contains the reason why the Kismet action is not allowed to execute on this Actor + * @return whether the AskingOp can correctly modify this Actor + */ +native final virtual function bool SupportsKismetModification(SequenceOp AskingOp, out string Reason) const; + +/** Notification called when one of our meshes gets his AnimTree updated */ +simulated event AnimTreeUpdated(SkeletalMeshComponent SkelMesh); + +/** called on all dynamic or net relevant actors after rewinding a demo + * primarily used to propagate properties to components, since components are ignored for rewinding + */ +simulated event PostDemoRewind(); + +/** called ONLY for bNoDelete Actors on the client when the server was replicating data on this Actor, + * but no longer considers it relevant (i.e. the actor channel was destroyed) + * for !bNoDelete Actors this results in destruction, so cleanup code can be done there, but bNoDelete Actors + * just keep going with whatever data was last received, so this is their chance to perform any cleanup + */ +simulated event ReplicationEnded(); + +/** + * Calculates a direction (unit vector) to avoid all actors contained in Obstacles list, assuming each entry in Obstacles is also + * avoiding this actor. Based loosely on RVO as described in http://gamma.cs.unc.edu/RVO/icra2008.pdf . + */ +final native function vector GetAvoidanceVector(const out array Obstacles, vector GoalLocation, float CollisionRadius, float MaxSpeed, optional int NumSamples = 8, optional float VelocityStepRate = 0.1f, optional float MaxTimeTilOverlap = 1.f); + +/** Steps from each position given the respective velocities performing simple radius checks */ +final native function bool WillOverlap(vector PosA, vector VelA, vector PosB, vector VelB, float StepSize, float Radius, out float Time); + +/** + * replaces IsA(NavigationPoint) check for primitivecomponents + */ +native function bool ShouldBeHiddenBySHOW_NavigationNodes(); + +/** + * Can this actor receive touch screen events? + */ +function bool IsMobileTouchEnabled() +{ + return bEnableMobileTouch && bCollideActors; +} + +/** + * You must assign a MobileInputZone's OnTapDelegate to MobilePlayerInput.ProcessWorldTouch to catch this event. + * + * @param InPC The PlayerController that caused this event + * @param TouchLocation The screen-space location of the touch event + * + * @Return true if event was handled, false to pass through to actors that may be occluded by this one + */ +event bool OnMobileTouch(PlayerController InPC, Vector2D TouchLocation) +{ + TriggerEventClass(class'SeqEvent_MobileTouch', InPC, 0); + return true; +} + +/** + * Retrieve various actor metrics depending on the provided type. All of + * these will total the values of the given type for every component that + * makes up the actor. + * + * @param MetricsType The type of metric to calculate. + * + * METRICS_VERTS - Get the number of vertices. + * METRICS_TRIS - Get the number of triangles. + * METRICS_SECTIONS - Get the number of sections. + * + * @return INT The total of the given type for this actor. + */ +simulated native function int GetActorMetrics(EActorMetricsType MetricsType); + +/** + * Searches through this Actor's Components and returns the + * first SpriteComponent found. If none exist, returns NULL. + * + * @return SpriteComponent First found SpriteComponent for this actor. NULL if none are found. + */ +native function SpriteComponent GetActorSpriteComponent() const; + +`if(`__TW_) +// Called in addition to AdjustDamage, but specific to radius damage scaling +function AdjustRadiusDamage(out float InBaseDamage, float DamageScale, vector HurtOrigin); + +/** Called from SkeletalMeshComponent::PlayParticleEffect() */ +simulated function OnAnimNotifyParticleSystemSpawned( const AnimNotify_PlayParticleEffect AnimNotifyData, ParticleSystemComponent PSC ); + +/** Accumlated actor tick time + * Use this instead of WorldInfo.TimeSeconds if the actor is affected by CustomTimeDilation (e.g. Pawns, Weapons) + * To reduce confusion any container vars should be labelled with the suffix "ActorTime" + */ +native final function float GetActorTimeSeconds() const; +native final function float ActorTimeSince(float Time) const; +`endif + +defaultproperties +{ + // For safety, make everything before the async work. Move actors to + // the during group one at a time to find bugs. + TickGroup=TG_PreAsyncWork + CustomTimeDilation=+1.0 + + DrawScale=+00001.000000 + DrawScale3D=(X=1,Y=1,Z=1) + bJustTeleported=true + Role=ROLE_Authority + RemoteRole=ROLE_None + NetPriority=+00001.000000 + bMovable=true + InitialState=None + NetUpdateFrequency=100 + MessageClass=class'LocalMessage' + bEditable=true + bHiddenEdGroup=false + bHiddenEdLayer=false + bHiddenEdTemporary=false + bHiddenEdLevel=false + bHiddenEdScene=false + bReplicateMovement=true + bRouteBeginPlayEvenIfStatic=TRUE + bPushedByEncroachers=true + bCanStepUpOn=TRUE + + SupportedEvents(0)=class'SeqEvent_Touch' + SupportedEvents(1)=class'SeqEvent_Destroyed' + SupportedEvents(2)=class'SeqEvent_TakeDamage' + SupportedEvents(3)=class'SeqEvent_HitWall' + SupportedEvents(4)=class'SeqEvent_AnimNotify' + SupportedEvents(5)=class'SeqEvent_MobileTouch' + ReplicatedCollisionType=COLLIDE_Max + + bAllowFluidSurfaceInteraction=TRUE + + EditorIconColor=(R=255,G=255,B=255,A=255) + bSkipAttachedMoves=true + + // NVCHANGE_BEGIN_TURB: Multiple PhysX levels + bLoadIfPhysXLevel0=true + bLoadIfPhysXLevel1=true + bLoadIfPhysXLevel2=true + // NVCHANGE_END_TURB: Multiple PhysX levels +} diff --git a/Engine/Classes/ActorComponent.uc b/Engine/Classes/ActorComponent.uc new file mode 100644 index 0000000..bde6882 --- /dev/null +++ b/Engine/Classes/ActorComponent.uc @@ -0,0 +1,46 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorComponent extends Component + native + noexport + abstract; + +var native transient const pointer Scene{FSceneInterface}; +var transient const Actor Owner; +var native transient const bool bAttached; +var const bool bTickInEditor; + +/** Is this component in need of an update? */ +var transient const bool bNeedsReattach; + +/** Is this component's transform in need of an update? */ +var transient const bool bNeedsUpdateTransform; + +/** The ticking group this component belongs to */ +var const ETickingGroup TickGroup; + +/** Changes the ticking group for this component */ +native final function SetTickGroup(ETickingGroup NewTickGroup); + +/** + * Sets whether or not the physics for this object should be 'fixed' (ie kinematic) or allowed to move with dynamics. + * If bFixed is true, all bodies within this component will be fixed. + * If bFixed is false, bodies will be set back to the default defined by their BodySetup. + */ +native final function SetComponentRBFixed(bool bFixed); + +/** force this component to be updated right now + * component must be directly attached to its Owner (not attached to another component) + * @param bTransformOnly - if true, only update transform, otherwise do a full reattachment + */ +native final function ForceUpdate(bool bTransformOnly); + +/** detaches the component from whatever it's attached to */ +native final function DetachFromAny(); + +defaultproperties +{ + // All things now default to being ticked during async work + TickGroup=TG_DuringAsyncWork +} diff --git a/Engine/Classes/ActorFactory.uc b/Engine/Classes/ActorFactory.uc new file mode 100644 index 0000000..d7e7570 --- /dev/null +++ b/Engine/Classes/ActorFactory.uc @@ -0,0 +1,91 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactory extends Object + native + collapsecategories + hidecategories(Object) + editinlinenew + config(Editor) + abstract; + +cpptext +{ + /** Called to actual create an actor at the supplied location/rotation, using the properties in the ActorFactory */ + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); + + /** + * If the ActorFactory thinks it could create an Actor with the current settings. + * Can Used to determine if we should add to context menu or if the factory can be used for drag and drop. + * + * @param OutErrorMsg Receives localized error string name if returning FALSE. + * @param bFromAssetOnly If true, the actor factory will check that a valid asset has been assigned from selection. If the factory always requires an asset to be selected, this param does not matter + * @return True if the actor can be created with this factory + */ + virtual UBOOL CanCreateActor( FString& OutErrorMsg, UBOOL bFromAssetOnly = FALSE ); + + /** Fill in parameters automatically, possibly using the specified selection set. */ + virtual void AutoFillFields(class USelection* Selection) {} + + /** + * Clears references to resources [usually set by the call to AutoFillFields] when the factory has done its work. The default behavior + * (which is to call AutoFillFields() with an empty selection set) should be sufficient for most factories, but this method is provided + * to allow customized behavior. + */ + virtual void ClearFields(); + + /** Name to put on context menu. */ + virtual FString GetMenuName() { return MenuName; } + + /** Initialize NewActorClass if necessary, and return default actor for that class. */ + virtual AActor* GetDefaultActor(); + + protected: + /** + * This will check whether there is enough space to spawn an character. + * Additionally it will check the ActorFactoryData to for any overrides + * ( e.g. bCheckSpawnCollision ) + * + * @return if there is enough space to spawn character at this location + **/ + UBOOL IsEnoughRoomToSpawnPawn( const FVector* const Location, const class USeqAct_ActorFactory* const ActorFactoryData ) const; + +} + +/** class to spawn during gameplay; only used if NewActorClass is left at the default */ +var class GameplayActorClass; + +/** Name used as basis for 'New Actor' menu. */ +var string MenuName; + +/** Indicates how far up the menu item should be. The higher the number, the higher up the list.*/ +var config int MenuPriority; + +/** DEPRECATED - Alternate value for menu priority; Used to allow things like modifier keys to access items in a different order. */ +var deprecated int AlternateMenuPriority; + +`if(`__TW_) +var string NewActorClassName; +`else +/** name of actor subclass this actorfactory creates - dynamically loaded. Overrides NewActorClass. */ +var config string NewActorClassName; +`endif + +/** Actor subclass this ActorFactory creates. */ +var class NewActorClass; + +/** Whether to appear on menu (or this Factory only used through scripts etc.) */ +var bool bPlaceable; + +/** Whether to appear in the editor add actor quick menu */ +var bool bShowInEditorQuickMenu; + +/** Allows script to modify new actor */ +simulated event PostCreateActor(Actor NewActor, optional const SeqAct_ActorFactory ActorFactoryData); + +defaultproperties +{ + MenuName="Add Actor" + bPlaceable=true + bShowInEditorQuickMenu=false; +} \ No newline at end of file diff --git a/Engine/Classes/ActorFactoryAI.uc b/Engine/Classes/ActorFactoryAI.uc new file mode 100644 index 0000000..7772f1f --- /dev/null +++ b/Engine/Classes/ActorFactoryAI.uc @@ -0,0 +1,42 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryAI extends ActorFactory + config(Editor) + native; + +cpptext +{ + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); + + /** + * If the ActorFactory thinks it could create an Actor with the current settings. + * Can Used to determine if we should add to context menu or if the factory can be used for drag and drop. + * + * @param OutErrorMsg Receives localized error string name if returning FALSE. + * @param bFromAssetOnly If true, the actor factory will check that a valid asset has been assigned from selection. If the factory always requires an asset to be selected, this param does not matter + * @return True if the actor can be created with this factory + */ + virtual UBOOL CanCreateActor( FString& OutErrorMsg, UBOOL bFromAssetOnly = FALSE ); + + virtual AActor* GetDefaultActor(); +}; + +var() class ControllerClass; +var() class PawnClass; +var() string PawnName; + +/** whether or not to give the spawned Pawn the default inventory for the gametype being played */ +var() bool bGiveDefaultInventory; +/** additional inventory to give the Pawn */ +var() array< class > InventoryList; +/** what team to put the AI on */ +var() int TeamIndex; + +defaultproperties +{ + ControllerClass=class'AIController' + + TeamIndex=255 + bPlaceable=false +} diff --git a/Engine/Classes/ActorFactoryActor.uc b/Engine/Classes/ActorFactoryActor.uc new file mode 100644 index 0000000..21de1b0 --- /dev/null +++ b/Engine/Classes/ActorFactoryActor.uc @@ -0,0 +1,31 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryActor extends ActorFactory + config(Editor) + native; + +cpptext +{ + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); + + /** + * If the ActorFactory thinks it could create an Actor with the current settings. + * Can Used to determine if we should add to context menu or if the factory can be used for drag and drop. + * + * @param OutErrorMsg Receives localized error string name if returning FALSE. + * @param bFromAssetOnly If true, the actor factory will check that a valid asset has been assigned from selection. If the factory always requires an asset to be selected, this param does not matter + * @return True if the actor can be created with this factory + */ + virtual UBOOL CanCreateActor( FString& OutErrorMsg, UBOOL bFromAssetOnly = FALSE ); + + virtual AActor* GetDefaultActor(); +}; + +var() class ActorClass; + +defaultproperties +{ + ActorClass=class'Actor' + bPlaceable=FALSE +} diff --git a/Engine/Classes/ActorFactoryAmbientSound.uc b/Engine/Classes/ActorFactoryAmbientSound.uc new file mode 100644 index 0000000..70c0ec4 --- /dev/null +++ b/Engine/Classes/ActorFactoryAmbientSound.uc @@ -0,0 +1,39 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * The base class of all ambient sound types + */ +class ActorFactoryAmbientSound extends ActorFactory + config( Editor ) + collapsecategories + hidecategories( Object ) + native; + +cpptext +{ + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); + virtual void AutoFillFields( class USelection* Selection ); + + /** + * If the ActorFactory thinks it could create an Actor with the current settings. + * Can Used to determine if we should add to context menu or if the factory can be used for drag and drop. + * + * @param OutErrorMsg Receives localized error string name if returning FALSE. + * @param bFromAssetOnly If true, the actor factory will check that a valid asset has been assigned from selection. If the factory always requires an asset to be selected, this param does not matter + * @return True if the actor can be created with this factory + */ + virtual UBOOL CanCreateActor( FString& OutErrorMsg, UBOOL bFromAssetOnly = FALSE ); + + virtual FString GetMenuName( void ); + + void SetSoundCue( class AAmbientSound* NewSound ); +} + +var() SoundCue AmbientSoundCue; + +defaultproperties +{ + MenuName="Add AmbientSound" + NewActorClass=class'Engine.AmbientSound' + bShowInEditorQuickMenu=true; +} diff --git a/Engine/Classes/ActorFactoryAmbientSoundMovable.uc b/Engine/Classes/ActorFactoryAmbientSoundMovable.uc new file mode 100644 index 0000000..8daf2e7 --- /dev/null +++ b/Engine/Classes/ActorFactoryAmbientSoundMovable.uc @@ -0,0 +1,19 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryAmbientSoundMovable extends ActorFactoryAmbientSound + config( Editor ) + hidecategories( Object ) + native; + +cpptext +{ + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); +} + +defaultproperties +{ + MenuName="Add AmbientSoundMovable" + NewActorClass=class'Engine.AmbientSoundMovable' + bShowInEditorQuickMenu=false; +} diff --git a/Engine/Classes/ActorFactoryAmbientSoundNonLoop.uc b/Engine/Classes/ActorFactoryAmbientSoundNonLoop.uc new file mode 100644 index 0000000..a6dac16 --- /dev/null +++ b/Engine/Classes/ActorFactoryAmbientSoundNonLoop.uc @@ -0,0 +1,19 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryAmbientSoundNonLoop extends ActorFactoryAmbientSoundSimple + config( Editor ) + collapsecategories + hidecategories( Object ) + native; + +cpptext +{ + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); +} + +defaultproperties +{ + MenuName="Add AmbientSoundNonLoop" + NewActorClass=class'Engine.AmbientSoundNonLoop' +} diff --git a/Engine/Classes/ActorFactoryAmbientSoundNonLoopingToggleable.uc b/Engine/Classes/ActorFactoryAmbientSoundNonLoopingToggleable.uc new file mode 100644 index 0000000..380e59b --- /dev/null +++ b/Engine/Classes/ActorFactoryAmbientSoundNonLoopingToggleable.uc @@ -0,0 +1,19 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryAmbientSoundNonLoopingToggleable extends ActorFactoryAmbientSoundSimpleToggleable + config( Editor ) + collapsecategories + hidecategories( Object ) + native; + +cpptext +{ + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); +} + +defaultproperties +{ + MenuName="Add AmbientSoundNonLoopingToggleable" + NewActorClass=class'Engine.AmbientSoundNonLoopingToggleable' +} diff --git a/Engine/Classes/ActorFactoryAmbientSoundSimple.uc b/Engine/Classes/ActorFactoryAmbientSoundSimple.uc new file mode 100644 index 0000000..4e14149 --- /dev/null +++ b/Engine/Classes/ActorFactoryAmbientSoundSimple.uc @@ -0,0 +1,36 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryAmbientSoundSimple extends ActorFactory + config( Editor ) + collapsecategories + hidecategories( Object ) + native; + +cpptext +{ + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); + virtual void AutoFillFields( class USelection* Selection ); + + /** + * If the ActorFactory thinks it could create an Actor with the current settings. + * Can Used to determine if we should add to context menu or if the factory can be used for drag and drop. + * + * @param OutErrorMsg Receives localized error string name if returning FALSE. + * @param bFromAssetOnly If true, the actor factory will check that a valid asset has been assigned from selection. If the factory always requires an asset to be selected, this param does not matter + * @return True if the actor can be created with this factory + */ + virtual UBOOL CanCreateActor( FString& OutErrorMsg, UBOOL bFromAssetOnly = FALSE ); + + virtual FString GetMenuName( void ); + + void SetSoundSlot( class AAmbientSoundSimple* NewSound ); +} + +var() SoundNodeWave SoundNodeWave; + +defaultproperties +{ + MenuName="Add AmbientSoundSimple" + NewActorClass=class'Engine.AmbientSoundSimple' +} diff --git a/Engine/Classes/ActorFactoryAmbientSoundSimpleToggleable.uc b/Engine/Classes/ActorFactoryAmbientSoundSimpleToggleable.uc new file mode 100644 index 0000000..9e8eb5f --- /dev/null +++ b/Engine/Classes/ActorFactoryAmbientSoundSimpleToggleable.uc @@ -0,0 +1,19 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryAmbientSoundSimpleToggleable extends ActorFactoryAmbientSoundSimple + config( Editor ) + collapsecategories + hidecategories( Object ) + native; + +cpptext +{ + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); +} + +defaultproperties +{ + MenuName="Add AmbientSoundSimpleToggleable" + NewActorClass=class'Engine.AmbientSoundSimpleToggleable' +} diff --git a/Engine/Classes/ActorFactoryApexClothing.uc b/Engine/Classes/ActorFactoryApexClothing.uc new file mode 100644 index 0000000..0767d23 --- /dev/null +++ b/Engine/Classes/ActorFactoryApexClothing.uc @@ -0,0 +1,66 @@ +/*============================================================================= + ActorFactoryApexClothing.uc: Implement APEX Clothing Actor Factory + Copyright 2008-2009 NVIDIA corporation.. +=============================================================================*/ +class ActorFactoryApexClothing extends ActorFactorySkeletalMesh + config(Editor) + hidecategories(Object) + native(Physics); + +/** List of clothing assets associated with each material in this mesh. */ +var() array ClothingAssets; + +/** Allows setting the RBChannel flag on the spawned rigid body's StaticMeshComponent. */ +var() const ERBCollisionChannel ClothingRBChannel; + +/** Define the channels with which this actor will collide. */ +var() const RBCollisionChannelContainer ClothingRBCollideWithChannels; + +// NVCHANGE_BEGIN: DJS - Add clothing wind support to clothing actor factory +/** If TRUE, WindVelocity is applied in the local space of the component, rather than world space. */ +var() bool bLocalSpaceWind; + +/** The Wind Velocity applied to Apex Clothing */ +var() vector WindVelocity; + +/** Time taken for ApexClothing to reach WindVelocity */ +var() float WindVelocityBlendTime; +// NVCHANGE_END: DJS - Add clothing wind support to clothing actor factory + +// NVCHANGE_BEGIN: hlanker - Add wind noise +/** Maximum noise amplitude */ +var() float WindStrengthNoiseBounds; + +/** Maximum wind strength change per second */ +var() float WindStrengthNoiseStepSize; + +/** Higher probability to stay around the center */ +var() bool bWindStrengthNoiseCentered; + +/** Maximum angle (in radian) on direction noise*/ +var() float WindDirNoiseBounds; + +/** Maximum angle change (in radian per second) */ +var() float WindDirNoiseStepSize; + +/** Higher probability to stay around the center */ +var() bool bWindDirNoiseCentered; +// NVCHANGE_END: hlanker - Add wind noise + +cpptext +{ + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); + virtual UBOOL CanCreateActor(FString& OutErrorMsg, UBOOL bFromAssetOnly = FALSE); + virtual void AutoFillFields(class USelection* Selection); + virtual FString GetMenuName(); +} + +defaultproperties +{ + MenuName="Add Clothing"; + NewActorClass=class'Engine.SkeletalMeshActor' + GameplayActorClass=class'Engine.SkeletalMeshActorSpawnable' + + ClothingRBChannel=RBCC_Clothing + ClothingRBCollideWithChannels=(Default=TRUE,BlockingVolume=TRUE,GameplayPhysics=TRUE,EffectPhysics=TRUE,ClothingCollision=TRUE) +} diff --git a/Engine/Classes/ActorFactoryApexDestructible.uc b/Engine/Classes/ActorFactoryApexDestructible.uc new file mode 100644 index 0000000..9064803 --- /dev/null +++ b/Engine/Classes/ActorFactoryApexDestructible.uc @@ -0,0 +1,41 @@ +/*============================================================================= + ActorFactoryApexDestructible.uc: Apex integration for Destructible Assets + Copyright 2008-2009 NVIDIA corporation.. +=============================================================================*/ + +class ActorFactoryApexDestructible extends ActorFactory + config(Editor) + native; + +cpptext +{ + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); + virtual UBOOL CanCreateActor(FString& OutErrorMsg, UBOOL bFromAssetOnly = FALSE); + virtual void AutoFillFields(class USelection* Selection); + virtual FString GetMenuName(); +} +/** Starts the actor in an awake(dynamic) state */ +var() bool bStartAwake; + +/** Allows setting the RBChannel flag on the spawned rigid body's StaticMeshComponent. */ +var() ERBCollisionChannel RBChannel; + +/** Define the channels with which this actor will collide. */ +var() const RBCollisionChannelContainer CollideWithChannels; + +var() ApexDestructibleAsset DestructibleAsset; + +defaultproperties +{ + MenuName="Add ApexDestructibleActor" + NewActorClass=class'Engine.ApexDestructibleActor' + GameplayActorClass=class'Engine.ApexDestructibleActorSpawnable' + bStartAwake=FALSE + RBChannel=RBCC_EffectPhysics + CollideWithChannels={( + Default=TRUE, + BlockingVolume=TRUE, + GameplayPhysics=TRUE, + EffectPhysics=TRUE + )} +} diff --git a/Engine/Classes/ActorFactoryArchetype.uc b/Engine/Classes/ActorFactoryArchetype.uc new file mode 100644 index 0000000..ca84a7c --- /dev/null +++ b/Engine/Classes/ActorFactoryArchetype.uc @@ -0,0 +1,32 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryArchetype extends ActorFactory + config(Editor) + native; + +cpptext +{ + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); + + /** + * If the ActorFactory thinks it could create an Actor with the current settings. + * Can Used to determine if we should add to context menu or if the factory can be used for drag and drop. + * + * @param OutErrorMsg Receives localized error string name if returning FALSE. + * @param bFromAssetOnly If true, the actor factory will check that a valid asset has been assigned from selection. If the factory always requires an asset to be selected, this param does not matter + * @return True if the actor can be created with this factory + */ + virtual UBOOL CanCreateActor( FString& OutErrorMsg, UBOOL bFromAssetOnly = FALSE ); + + virtual void AutoFillFields(class USelection* Selection); + virtual FString GetMenuName(); + virtual AActor* GetDefaultActor(); +} + +var() Actor ArchetypeActor; + +defaultproperties +{ + MenuName="Add Archetype" +} diff --git a/Engine/Classes/ActorFactoryCoverLink.uc b/Engine/Classes/ActorFactoryCoverLink.uc new file mode 100644 index 0000000..8562da3 --- /dev/null +++ b/Engine/Classes/ActorFactoryCoverLink.uc @@ -0,0 +1,15 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryCoverLink extends ActorFactory + config(Editor) + collapsecategories + hidecategories(Object) + native; + +defaultproperties +{ + MenuName="Add CoverLink" + NewActorClass=class'Engine.CoverLink' + bShowInEditorQuickMenu=true +} diff --git a/Engine/Classes/ActorFactoryDecal.uc b/Engine/Classes/ActorFactoryDecal.uc new file mode 100644 index 0000000..b4db5e9 --- /dev/null +++ b/Engine/Classes/ActorFactoryDecal.uc @@ -0,0 +1,59 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryDecal extends ActorFactory + config(Editor) + native(Decal); + +cpptext +{ + /** + * Called to create an actor at the supplied location/rotation + * + * @param Location Location to create the actor at + * @param Rotation Rotation to create the actor with + * @param ActorFactoryData Kismet object which spawns actors, could potentially have settings to use/override + * + * @return The newly created actor, NULL if it could not be created + */ + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); + + /** + * If the ActorFactory thinks it could create an Actor with the current settings. + * Can Used to determine if we should add to context menu or if the factory can be used for drag and drop. + * + * @param OutErrorMsg Receives localized error string name if returning FALSE. + * @param bFromAssetOnly If true, the actor factory will check that a valid asset has been assigned from selection. If the factory always requires an asset to be selected, this param does not matter + * @return True if the actor can be created with this factory + */ + virtual UBOOL CanCreateActor(FString& OutErrorMsg, UBOOL bFromAssetOnly = FALSE); + + /** + * Fill the data fields of this actor with the current selection + * + * @param Selection Selection to use to fill this actor's data fields with + */ + virtual void AutoFillFields(class USelection* Selection); + + /** + * Returns the name this factory should show up as in a context-sensitive menu + * + * @return Name this factory should show up as in a menu + */ + virtual FString GetMenuName(); + + /** + * Clears references to resources [usually set by the call to AutoFillFields] when the factory has done its work. The default behavior + * (which is to call AutoFillFields() with an empty selection set) should be sufficient for most factories, but this method is provided + * to allow customized behavior. + */ + virtual void ClearFields(); +} + +var() MaterialInterface DecalMaterial; + +defaultproperties +{ + MenuName="Add Decal" + NewActorClass=class'Engine.DecalActor' +} diff --git a/Engine/Classes/ActorFactoryDecalMovable.uc b/Engine/Classes/ActorFactoryDecalMovable.uc new file mode 100644 index 0000000..95f5cad --- /dev/null +++ b/Engine/Classes/ActorFactoryDecalMovable.uc @@ -0,0 +1,12 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryDecalMovable extends ActorFactoryDecal + config(Editor) + native(Decal); + +defaultproperties +{ + MenuName="Add Movable Decal" + NewActorClass=class'Engine.DecalActorMovable' +} diff --git a/Engine/Classes/ActorFactoryDominantDirectionalLight.uc b/Engine/Classes/ActorFactoryDominantDirectionalLight.uc new file mode 100644 index 0000000..8902bf7 --- /dev/null +++ b/Engine/Classes/ActorFactoryDominantDirectionalLight.uc @@ -0,0 +1,28 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryDominantDirectionalLight extends ActorFactory + config(Editor) + collapsecategories + hidecategories(Object) + native; + +cpptext +{ + /** + * If the ActorFactory thinks it could create an Actor with the current settings. + * Can Used to determine if we should add to context menu or if the factory can be used for drag and drop. + * + * @param OutErrorMsg Receives localized error string name if returning FALSE. + * @param bFromAssetOnly If true, the actor factory will check that a valid asset has been assigned from selection. If the factory always requires an asset to be selected, this param does not matter + * @return True if the actor can be created with this factory + */ + virtual UBOOL CanCreateActor( FString& OutErrorMsg, UBOOL bFromAssetOnly = FALSE ); +} + +defaultproperties +{ + MenuName="Add Light (DominantDirectionalLight)" + NewActorClass=class'Engine.DominantDirectionalLight' + bShowInEditorQuickMenu=true +} diff --git a/Engine/Classes/ActorFactoryDominantDirectionalLightMovable.uc b/Engine/Classes/ActorFactoryDominantDirectionalLightMovable.uc new file mode 100644 index 0000000..c81dc3c --- /dev/null +++ b/Engine/Classes/ActorFactoryDominantDirectionalLightMovable.uc @@ -0,0 +1,27 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryDominantDirectionalLightMovable extends ActorFactory + config(Editor) + collapsecategories + hidecategories(Object) + native; + +cpptext +{ + /** + * Returns whether the ActorFactory thinks it could create an Actor with the current settings. + * Can be used to determine if we should add to context menu or if the factory can be used for drag and drop. + * + * @param OutErrorMsg Receives localized error string name if returning FALSE. + * @param bFromAssetOnly If TRUE, the actor factory will check that a valid asset has been assigned from selection. If the factory always requires an asset to be selected, this param does not matter + * @return TRUE if the actor can be created with this factory + */ + virtual UBOOL CanCreateActor( FString& OutErrorMsg, UBOOL bFromAssetOnly = FALSE ); +} + +defaultproperties +{ + MenuName="Add Light (DominantDirectionalLightMovable)" + NewActorClass=class'Engine.DominantDirectionalLightMovable' +} diff --git a/Engine/Classes/ActorFactoryDynamicSM.uc b/Engine/Classes/ActorFactoryDynamicSM.uc new file mode 100644 index 0000000..ede688e --- /dev/null +++ b/Engine/Classes/ActorFactoryDynamicSM.uc @@ -0,0 +1,54 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryDynamicSM extends ActorFactory + config(Editor) + native + abstract; + +cpptext +{ + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); + + /** + * If the ActorFactory thinks it could create an Actor with the current settings. + * Can Used to determine if we should add to context menu or if the factory can be used for drag and drop. + * + * @param OutErrorMsg Receives localized error string name if returning FALSE. + * @param bFromAssetOnly If true, the actor factory will check that a valid asset has been assigned from selection. If the factory always requires an asset to be selected, this param does not matter + * @return True if the actor can be created with this factory + */ + virtual UBOOL CanCreateActor( FString& OutErrorMsg, UBOOL bFromAssetOnly = FALSE ); + + virtual void AutoFillFields(class USelection* Selection); + virtual FString GetMenuName(); + virtual void PostLoad(); +} + +var() StaticMesh StaticMesh; +var() vector DrawScale3D; + +/** + * For encroachers, don't do the overlap check when they move. You will not get touch events for this actor moving, but it is much faster. + * So if you want touch events from volumes or triggers you need to set this to be FALSE. + * This is an optimisation for large numbers of PHYS_RigidBody actors for example. + * @see Actor.uc bNoEncroachCheck + */ +var() bool bNoEncroachCheck; +var() bool bNotifyRigidBodyCollision; +var() ECollisionType CollisionType; +var() bool bBlockRigidBody; + +/** Try and use physics hardware for this spawned object. */ +var() bool bUseCompartment; + +/** If false, primitive does not cast dynamic shadows. */ +var() bool bCastDynamicShadow; + +defaultproperties +{ + DrawScale3D=(X=1,Y=1,Z=1) + CollisionType=COLLIDE_NoCollision + bCastDynamicShadow=true + bBlockRigidBody=FALSE +} diff --git a/Engine/Classes/ActorFactoryEmitter.uc b/Engine/Classes/ActorFactoryEmitter.uc new file mode 100644 index 0000000..fcb1bb8 --- /dev/null +++ b/Engine/Classes/ActorFactoryEmitter.uc @@ -0,0 +1,36 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryEmitter extends ActorFactory + config(Editor) + collapsecategories + hidecategories(Object) + native; + +cpptext +{ + + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); + + /** + * If the ActorFactory thinks it could create an Actor with the current settings. + * Can Used to determine if we should add to context menu or if the factory can be used for drag and drop. + * + * @param OutErrorMsg Receives localized error string name if returning FALSE. + * @param bFromAssetOnly If true, the actor factory will check that a valid asset has been assigned from selection. If the factory always requires an asset to be selected, this param does not matter + * @return True if the actor can be created with this factory + */ + virtual UBOOL CanCreateActor( FString& OutErrorMsg, UBOOL bFromAssetOnly = FALSE ); + + virtual void AutoFillFields(class USelection* Selection); + virtual FString GetMenuName(); +} + +var() ParticleSystem ParticleSystem; + +defaultproperties +{ + MenuName="Add Emitter" + NewActorClass=class'Engine.Emitter' + GameplayActorClass=class'Engine.EmitterSpawnable' +} diff --git a/Engine/Classes/ActorFactoryFlex.uc b/Engine/Classes/ActorFactoryFlex.uc new file mode 100644 index 0000000..b27b9c7 --- /dev/null +++ b/Engine/Classes/ActorFactoryFlex.uc @@ -0,0 +1,35 @@ +/** + * Copyright 1998-2012 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryFlex extends ActorFactory + config(Editor) + collapsecategories + hidecategories(Object) + native; + +var() StaticMesh StaticMesh; + +cpptext +{ + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); + + /** + * If the ActorFactory thinks it could create an Actor with the current settings. + * Can Used to determine if we should add to context menu or if the factory can be used for drag and drop. + * + * @param OutErrorMsg Receives localized error string name if returning FALSE. + * @param bFromAssetOnly If true, the actor factory will check that a valid asset has been assigned from selection. If the factory always requires an asset to be selected, this param does not matter + * @return True if the actor can be created with this factory + */ + virtual UBOOL CanCreateActor( FString& OutErrorMsg, UBOOL bFromAssetOnly = FALSE ); + + virtual void AutoFillFields(class USelection* Selection); + virtual FString GetMenuName(); +} + +defaultproperties +{ + MenuName="Add FlexActor" + NewActorClass=class'Engine.FlexActor' + +} diff --git a/Engine/Classes/ActorFactoryFlexForceField.uc b/Engine/Classes/ActorFactoryFlexForceField.uc new file mode 100644 index 0000000..ac74fc1 --- /dev/null +++ b/Engine/Classes/ActorFactoryFlexForceField.uc @@ -0,0 +1,51 @@ +/*============================================================================= + ActorFactoryFlexForceField.uc: Implement Flex force field Actor Factory + Copyright 2008-2011 NVIDIA corporation.. +=============================================================================*/ +class ActorFactoryFlexForceField extends ActorFactory + config(Editor) + DontCollapseCategories + native(Physics); + +/** Rotational field strength */ +var(ForceField) float RotationalFieldStrength; +/** Radial field strength */ +var(ForceField) float RadialFieldStrength; +/** Lift field strength */ +var(ForceField) float LiftFieldStrength; + +/** Height of capsule field */ +var(ForceField) float CapsuleFieldHeight ; +/** Bottom radius of capsule field */ +var(ForceField) float CapsuleFieldBottomRadius ; +/** Top radius of capsule field */ +var(ForceField) float CapsuleFieldTopRadius ; +/** Percentage of distance from boundary to center where fade out starts */ +var(ForceField) float BoundaryFadePercentage ; + +/** Percentage of noise applied to force field. 0 = None 1 = Infinite */ +var(ForceField) float Noise ; + +cpptext +{ + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); + virtual FString GetMenuName(); +} + +defaultproperties +{ + RotationalFieldStrength = 750 + RadialFieldStrength = -400 + LiftFieldStrength = 0.0 + + CapsuleFieldHeight = 200.0; + CapsuleFieldBottomRadius = 100.0; + CapsuleFieldTopRadius = 50.0; + + BoundaryFadePercentage = 0.1 + + Noise = 0.0 + + MenuName="Add FlexForceField" + NewActorClass=class'Engine.FlexForceFieldActor' +} diff --git a/Engine/Classes/ActorFactoryFogVolumeConstantDensityInfo.uc b/Engine/Classes/ActorFactoryFogVolumeConstantDensityInfo.uc new file mode 100644 index 0000000..6aefdf1 --- /dev/null +++ b/Engine/Classes/ActorFactoryFogVolumeConstantDensityInfo.uc @@ -0,0 +1,29 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryFogVolumeConstantDensityInfo extends ActorFactory + config(Editor) + native(FogVolume); + +cpptext +{ + /** + * If the ActorFactory thinks it could create an Actor with the current settings. + * Used to determine if we should add to context menu for example. + * + * @param OutErrorMsg Receives localized error string name if returning FALSE. + * @param bFromAssetOnly If true, the actor factory will check that a valid asset has been assigned from selection. If the factory always requires an asset to be selected, this param does not matter + */ + virtual UBOOL CanCreateActor( FString& OutErrorMsg, UBOOL bFromAssetOnly ); + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); + virtual void AutoFillFields(class USelection* Selection); +} + +var MaterialInterface SelectedMaterial; +var bool bNothingSelected; + +defaultproperties +{ + MenuName="Add FogVolumeConstantDensityInfo" + NewActorClass=class'Engine.FogVolumeConstantDensityInfo' +} diff --git a/Engine/Classes/ActorFactoryFogVolumeLinearHalfspaceDensityInfo.uc b/Engine/Classes/ActorFactoryFogVolumeLinearHalfspaceDensityInfo.uc new file mode 100644 index 0000000..92f99d0 --- /dev/null +++ b/Engine/Classes/ActorFactoryFogVolumeLinearHalfspaceDensityInfo.uc @@ -0,0 +1,12 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryFogVolumeLinearHalfspaceDensityInfo extends ActorFactoryFogVolumeConstantDensityInfo + config(Editor) + native(FogVolume); + +defaultproperties +{ + MenuName="Add FogVolumeLinearHalfspaceDensityInfo" + NewActorClass=class'Engine.FogVolumeLinearHalfspaceDensityInfo' +} diff --git a/Engine/Classes/ActorFactoryFogVolumeSphericalDensityInfo.uc b/Engine/Classes/ActorFactoryFogVolumeSphericalDensityInfo.uc new file mode 100644 index 0000000..19e9f76 --- /dev/null +++ b/Engine/Classes/ActorFactoryFogVolumeSphericalDensityInfo.uc @@ -0,0 +1,17 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryFogVolumeSphericalDensityInfo extends ActorFactoryFogVolumeConstantDensityInfo + config(Editor) + native(FogVolume); + +cpptext +{ + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); +} + +defaultproperties +{ + MenuName="Add FogVolumeSphericalDensityInfo" + NewActorClass=class'Engine.FogVolumeSphericalDensityInfo' +} diff --git a/Engine/Classes/ActorFactoryFracturedStaticMesh.uc b/Engine/Classes/ActorFactoryFracturedStaticMesh.uc new file mode 100644 index 0000000..4fb4e96 --- /dev/null +++ b/Engine/Classes/ActorFactoryFracturedStaticMesh.uc @@ -0,0 +1,35 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryFracturedStaticMesh extends ActorFactory + config(Editor) + native; + +cpptext +{ + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); + + /** + * If the ActorFactory thinks it could create an Actor with the current settings. + * Can Used to determine if we should add to context menu or if the factory can be used for drag and drop. + * + * @param OutErrorMsg Receives localized error string name if returning FALSE. + * @param bFromAssetOnly If true, the actor factory will check that a valid asset has been assigned from selection. If the factory always requires an asset to be selected, this param does not matter + * @return True if the actor can be created with this factory + */ + virtual UBOOL CanCreateActor( FString& OutErrorMsg, UBOOL bFromAssetOnly = FALSE ); + + virtual void AutoFillFields(class USelection* Selection); + virtual FString GetMenuName(); +} + +var() FracturedStaticMesh FracturedStaticMesh; +var() vector DrawScale3D; + +defaultproperties +{ + DrawScale3D=(X=1,Y=1,Z=1) + + MenuName="Add FracturedStaticMesh" + NewActorClass=class'Engine.FracturedStaticMeshActor' +} diff --git a/Engine/Classes/ActorFactoryInteractiveFoliage.uc b/Engine/Classes/ActorFactoryInteractiveFoliage.uc new file mode 100644 index 0000000..edd9db6 --- /dev/null +++ b/Engine/Classes/ActorFactoryInteractiveFoliage.uc @@ -0,0 +1,12 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryInteractiveFoliage extends ActorFactoryStaticMesh + config(Editor) + native(Foliage); + +defaultproperties +{ + MenuName="Add InteractiveFoliageActor" + NewActorClass=class'Engine.InteractiveFoliageActor' +} diff --git a/Engine/Classes/ActorFactoryLensFlare.uc b/Engine/Classes/ActorFactoryLensFlare.uc new file mode 100644 index 0000000..f6b548f --- /dev/null +++ b/Engine/Classes/ActorFactoryLensFlare.uc @@ -0,0 +1,35 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryLensFlare extends ActorFactory + config(Editor) + collapsecategories + hidecategories(Object) + native; + +cpptext +{ + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); + + /** + * If the ActorFactory thinks it could create an Actor with the current settings. + * Can Used to determine if we should add to context menu or if the factory can be used for drag and drop. + * + * @param OutErrorMsg Receives localized error string name if returning FALSE. + * @param bFromAssetOnly If true, the actor factory will check that a valid asset has been assigned from selection. If the factory always requires an asset to be selected, this param does not matter + * @return True if the actor can be created with this factory + */ + virtual UBOOL CanCreateActor( FString& OutErrorMsg, UBOOL bFromAssetOnly = FALSE ); + + virtual void AutoFillFields(class USelection* Selection); + virtual FString GetMenuName(); +} + +var() LensFlare LensFlareObject; + +defaultproperties +{ + MenuName="Add LensFlare" + NewActorClass=class'Engine.LensFlareSource' + //GameplayActorClass=class'Engine.EmitterSpawnable' +} diff --git a/Engine/Classes/ActorFactoryLight.uc b/Engine/Classes/ActorFactoryLight.uc new file mode 100644 index 0000000..db91d44 --- /dev/null +++ b/Engine/Classes/ActorFactoryLight.uc @@ -0,0 +1,15 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryLight extends ActorFactory + config(Editor) + collapsecategories + hidecategories(Object) + native; + +defaultproperties +{ + MenuName="Add Light (Point)" + NewActorClass=class'Engine.PointLight' + bShowInEditorQuickMenu=true +} diff --git a/Engine/Classes/ActorFactoryMover.uc b/Engine/Classes/ActorFactoryMover.uc new file mode 100644 index 0000000..28dec17 --- /dev/null +++ b/Engine/Classes/ActorFactoryMover.uc @@ -0,0 +1,14 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryMover extends ActorFactoryDynamicSM + config(Editor) + collapsecategories + hidecategories(Object) + native; + +defaultproperties +{ + MenuName="Add InterpActor" + NewActorClass=class'Engine.InterpActor' +} diff --git a/Engine/Classes/ActorFactoryPathNode.uc b/Engine/Classes/ActorFactoryPathNode.uc new file mode 100644 index 0000000..e8820be --- /dev/null +++ b/Engine/Classes/ActorFactoryPathNode.uc @@ -0,0 +1,15 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryPathNode extends ActorFactory + config(Editor) + collapsecategories + hidecategories(Object) + native; + +defaultproperties +{ + MenuName="Add PathNode" + NewActorClass=class'Engine.PathNode' + bShowInEditorQuickMenu=true +} diff --git a/Engine/Classes/ActorFactoryPhysicsAsset.uc b/Engine/Classes/ActorFactoryPhysicsAsset.uc new file mode 100644 index 0000000..19504ac --- /dev/null +++ b/Engine/Classes/ActorFactoryPhysicsAsset.uc @@ -0,0 +1,55 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryPhysicsAsset extends ActorFactory + config(Editor) + collapsecategories + hidecategories(Object) + native; + +var() PhysicsAsset PhysicsAsset; +var() SkeletalMesh SkeletalMesh; + +var() bool bStartAwake; +var() bool bDamageAppliesImpulse; +var() bool bNotifyRigidBodyCollision; +var() vector InitialVelocity; +var() vector DrawScale3D; + +/** Try and use physics hardware for this spawned object. */ +var() bool bUseCompartment; + +/** If false, primitive does not cast dynamic shadows. */ +var() bool bCastDynamicShadow; + +cpptext +{ + virtual void PreSave(); + + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); + + /** + * If the ActorFactory thinks it could create an Actor with the current settings. + * Can Used to determine if we should add to context menu or if the factory can be used for drag and drop. + * + * @param OutErrorMsg Receives localized error string name if returning FALSE. + * @param bFromAssetOnly If true, the actor factory will check that a valid asset has been assigned from selection. If the factory always requires an asset to be selected, this param does not matter + * @return True if the actor can be created with this factory + */ + virtual UBOOL CanCreateActor( FString& OutErrorMsg, UBOOL bFromAssetOnly = FALSE ); + + virtual void AutoFillFields(class USelection* Selection); + virtual FString GetMenuName(); +} + +defaultproperties +{ + MenuName="Add PhysicsAsset" + NewActorClass=class'Engine.KAsset' + GameplayActorClass=class'Engine.KAssetSpawnable' + + DrawScale3D=(X=1,Y=1,Z=1) + bStartAwake=true + bDamageAppliesImpulse=true + bCastDynamicShadow=true +} diff --git a/Engine/Classes/ActorFactoryPlayerStart.uc b/Engine/Classes/ActorFactoryPlayerStart.uc new file mode 100644 index 0000000..58eecdf --- /dev/null +++ b/Engine/Classes/ActorFactoryPlayerStart.uc @@ -0,0 +1,15 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryPlayerStart extends ActorFactory + config(Editor) + collapsecategories + hidecategories(Object) + native; + +defaultproperties +{ + MenuName="Add PlayerStart" + NewActorClass=class'Engine.PlayerStart' + bShowInEditorQuickMenu=true +} diff --git a/Engine/Classes/ActorFactoryPylon.uc b/Engine/Classes/ActorFactoryPylon.uc new file mode 100644 index 0000000..98e8c21 --- /dev/null +++ b/Engine/Classes/ActorFactoryPylon.uc @@ -0,0 +1,15 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryPylon extends ActorFactory + config(Editor) + collapsecategories + hidecategories(Object) + native; + +defaultproperties +{ + MenuName="Add Pylon" + NewActorClass=class'Engine.Pylon' + bShowInEditorQuickMenu=true +} diff --git a/Engine/Classes/ActorFactoryRigidBody.uc b/Engine/Classes/ActorFactoryRigidBody.uc new file mode 100644 index 0000000..057a983 --- /dev/null +++ b/Engine/Classes/ActorFactoryRigidBody.uc @@ -0,0 +1,80 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryRigidBody extends ActorFactoryDynamicSM + config(Editor) + collapsecategories + hidecategories(Object) + native; + +/** Should spawned Actor start simulating as soon as its created, or be 'asleep' until hit. */ +var() bool bStartAwake; + +/** Sets the bDamageAppliesImpulse flag on the new Actor. */ +var() bool bDamageAppliesImpulse; + +/** Indicates if the initial velocity settings below should be considered in the world space or local space of the spawn target actor. */ +var() bool bLocalSpaceInitialVelocity; + +/** Velocity that new rigid bodies will have when created. In the ref frame of the spawn target actor. */ +var() vector InitialVelocity; + +/** + * If valid, Velocity added to InitialVelocity when creating actor. + * This is here in addition to InitialVelocity to maintain backwards compatibility. + */ +var() DistributionVector AdditionalVelocity; + +/** + * If valid, Angular Velocity given to newly spawned Actor. + */ +var() DistributionVector InitialAngularVelocity; + +/** Allows setting the RBChannel flag on the spawned rigid body's StaticMeshComponent. */ +var() ERBCollisionChannel RBChannel; + + +/** Enable 'Stay upright' torque, that tries to keep Z axis of KActor pointing along world Z */ +var() bool bEnableStayUprightSpring; + +/** Torque applied to try and keep KActor horizontal. */ +var() float StayUprightTorqueFactor; + +/** Max torque that can be applied to try and keep KActor horizontal */ +var() float StayUprightMaxTorque; + +cpptext +{ + // UObject interface + virtual void PostLoad(); + + /** + * If the ActorFactory thinks it could create an Actor with the current settings. + * Can Used to determine if we should add to context menu or if the factory can be used for drag and drop. + * + * @param OutErrorMsg Receives localized error string name if returning FALSE. + * @param bFromAssetOnly If true, the actor factory will check that a valid asset has been assigned from selection. If the factory always requires an asset to be selected, this param does not matter + * @return True if the actor can be created with this factory + */ + virtual UBOOL CanCreateActor( FString& OutErrorMsg, UBOOL bFromAssetOnly = FALSE ); + + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); +} + +defaultproperties +{ + MenuName="Add RigidBody" + + NewActorClass=class'Engine.KActor' + GameplayActorClass=class'Engine.KActorSpawnable' + + bNoEncroachCheck=true + bStartAwake=true + bDamageAppliesImpulse=true + CollisionType=COLLIDE_BlockAll + RBChannel=RBCC_GameplayPhysics + bBlockRigidBody=TRUE + + StayUprightTorqueFactor=1000.0 + StayUprightMaxTorque=1500.0 +} diff --git a/Engine/Classes/ActorFactorySkeletalMesh.uc b/Engine/Classes/ActorFactorySkeletalMesh.uc new file mode 100644 index 0000000..e21d0ee --- /dev/null +++ b/Engine/Classes/ActorFactorySkeletalMesh.uc @@ -0,0 +1,35 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactorySkeletalMesh extends ActorFactory + config(Editor) + native; + +cpptext +{ + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); + + /** + * If the ActorFactory thinks it could create an Actor with the current settings. + * Can Used to determine if we should add to context menu or if the factory can be used for drag and drop. + * + * @param OutErrorMsg Receives localized error string name if returning FALSE. + * @param bFromAssetOnly If true, the actor factory will check that a valid asset has been assigned from selection. If the factory always requires an asset to be selected, this param does not matter + * @return True if the actor can be created with this factory + */ + virtual UBOOL CanCreateActor( FString& OutErrorMsg, UBOOL bFromAssetOnly = FALSE ); + + virtual void AutoFillFields(class USelection* Selection); + virtual FString GetMenuName(); +} + +var() SkeletalMesh SkeletalMesh; +var() AnimSet AnimSet; +var() name AnimSequenceName; + +defaultproperties +{ + MenuName="Add SkeletalMesh" + NewActorClass=class'Engine.SkeletalMeshActor' + GameplayActorClass=class'Engine.SkeletalMeshActorSpawnable' +} diff --git a/Engine/Classes/ActorFactorySkeletalMeshCinematic.uc b/Engine/Classes/ActorFactorySkeletalMeshCinematic.uc new file mode 100644 index 0000000..c7e0fa9 --- /dev/null +++ b/Engine/Classes/ActorFactorySkeletalMeshCinematic.uc @@ -0,0 +1,12 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactorySkeletalMeshCinematic extends ActorFactorySkeletalMesh + config(Editor) + hidecategories(Object); + +defaultproperties +{ + MenuName="Add SkeletalMeshCinematic" + NewActorClass=class'Engine.SkeletalMeshCinematicActor' +} \ No newline at end of file diff --git a/Engine/Classes/ActorFactorySkeletalMeshMAT.uc b/Engine/Classes/ActorFactorySkeletalMeshMAT.uc new file mode 100644 index 0000000..2fc0baf --- /dev/null +++ b/Engine/Classes/ActorFactorySkeletalMeshMAT.uc @@ -0,0 +1,12 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactorySkeletalMeshMAT extends ActorFactorySkeletalMesh + config(Editor) + hidecategories(Object); + +defaultproperties +{ + MenuName="Add SkeletalMeshMAT" + NewActorClass=class'Engine.SkeletalMeshActorMAT' +} diff --git a/Engine/Classes/ActorFactoryStaticMesh.uc b/Engine/Classes/ActorFactoryStaticMesh.uc new file mode 100644 index 0000000..ae7b350 --- /dev/null +++ b/Engine/Classes/ActorFactoryStaticMesh.uc @@ -0,0 +1,35 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryStaticMesh extends ActorFactory + config(Editor) + native; + +cpptext +{ + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); + + /** + * If the ActorFactory thinks it could create an Actor with the current settings. + * Can Used to determine if we should add to context menu or if the factory can be used for drag and drop. + * + * @param OutErrorMsg Receives localized error string name if returning FALSE. + * @param bFromAssetOnly If true, the actor factory will check that a valid asset has been assigned from selection. If the factory always requires an asset to be selected, this param does not matter + * @return True if the actor can be created with this factory + */ + virtual UBOOL CanCreateActor( FString& OutErrorMsg, UBOOL bFromAssetOnly = FALSE ); + + virtual void AutoFillFields(class USelection* Selection); + virtual FString GetMenuName(); +} + +var() StaticMesh StaticMesh; +var() vector DrawScale3D; + +defaultproperties +{ + DrawScale3D=(X=1,Y=1,Z=1) + + MenuName="Add StaticMesh" + NewActorClass=class'Engine.StaticMeshActor' +} diff --git a/Engine/Classes/ActorFactoryTrigger.uc b/Engine/Classes/ActorFactoryTrigger.uc new file mode 100644 index 0000000..a4d9838 --- /dev/null +++ b/Engine/Classes/ActorFactoryTrigger.uc @@ -0,0 +1,15 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryTrigger extends ActorFactory + config(Editor) + collapsecategories + hidecategories(Object) + native; + +defaultproperties +{ + MenuName="Add Trigger" + NewActorClass=class'Engine.Trigger' + bShowInEditorQuickMenu=true +} diff --git a/Engine/Classes/ActorFactoryVehicle.uc b/Engine/Classes/ActorFactoryVehicle.uc new file mode 100644 index 0000000..cb8d957 --- /dev/null +++ b/Engine/Classes/ActorFactoryVehicle.uc @@ -0,0 +1,31 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ActorFactoryVehicle extends ActorFactory + config(Editor) + native; + +cpptext +{ + virtual AActor* CreateActor( const FVector* const Location, const FRotator* const Rotation, const class USeqAct_ActorFactory* const ActorFactoryData ); + + /** + * If the ActorFactory thinks it could create an Actor with the current settings. + * Can Used to determine if we should add to context menu or if the factory can be used for drag and drop. + * + * @param OutErrorMsg Receives localized error string name if returning FALSE. + * @param bFromAssetOnly If true, the actor factory will check that a valid asset has been assigned from selection. If the factory always requires an asset to be selected, this param does not matter + * @return True if the actor can be created with this factory + */ + virtual UBOOL CanCreateActor( FString& OutErrorMsg, UBOOL bFromAssetOnly = FALSE ); + + virtual AActor* GetDefaultActor(); +}; + +var() class VehicleClass; + +defaultproperties +{ + VehicleClass=class'Vehicle' + bPlaceable=false +} diff --git a/Engine/Classes/Admin.uc b/Engine/Classes/Admin.uc new file mode 100644 index 0000000..5940d8f --- /dev/null +++ b/Engine/Classes/Admin.uc @@ -0,0 +1,79 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class Admin extends PlayerController + config(Game); + +simulated event PostBeginPlay() +{ + Super.PostBeginPlay(); + AddCheats(); +} + +// Execute an administrative console command on the server. +exec function Admin( string CommandLine ) +{ + ServerAdmin(CommandLine); +} + +reliable server function ServerAdmin( string CommandLine ) +{ + local string Result; + + Result = ConsoleCommand( CommandLine ); + if( Result!="" ) + ClientMessage( Result ); +} + +exec function KickBan( string S ) +{ + ServerKickBan(S); +} + +reliable server function ServerKickBan( string S ) +{ + WorldInfo.Game.KickBan(S); +} + +exec function Kick( string S ) +{ + ServerKick(S); +} + +reliable server function ServerKick( string S ) +{ + WorldInfo.Game.Kick(S); +} + +exec function PlayerList() +{ + local PlayerReplicationInfo PRI; + + `log("Player List:"); + ForEach DynamicActors(class'PlayerReplicationInfo', PRI) + `log(PRI.PlayerName@"( ping"@PRI.Ping$")"); +} + +exec function RestartMap() +{ + ServerRestartMap(); +} + +reliable server function ServerRestartMap() +{ + ClientTravel( "?restart", TRAVEL_Relative ); +} + +exec function Switch( string URL ) +{ + ServerSwitch(URL); +} + +reliable server function ServerSwitch(string URL) +{ + WorldInfo.ServerTravel(URL); +} + +defaultproperties +{ +} diff --git a/Engine/Classes/AdvancedReachSpec.uc b/Engine/Classes/AdvancedReachSpec.uc new file mode 100644 index 0000000..068eec3 --- /dev/null +++ b/Engine/Classes/AdvancedReachSpec.uc @@ -0,0 +1,24 @@ +//============================================================================= +// AdvancedReachSpec. +// +// An AdvancedReachspec can only be used by Controllers with bCanDoSpecial==true +// +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +class AdvancedReachSpec extends ReachSpec + native; + +cpptext +{ + virtual FPlane PathColor() + { + // purple path = advanced + return FPlane(1.f,0.f,1.f, 0.f); + } + virtual INT CostFor(APawn* P); +} + +defaultproperties +{ + bCanCutCorners=false +} + diff --git a/Engine/Classes/AkBank.uc b/Engine/Classes/AkBank.uc new file mode 100644 index 0000000..24e74a4 --- /dev/null +++ b/Engine/Classes/AkBank.uc @@ -0,0 +1,25 @@ +class AkBank extends Object + native; + +var() bool AutoLoad; // Auto-load bank when its package is accessed for the first time +var() bool GenerateDefinition; // This bank is part of the 'Generate All Definitions' list + +cpptext +{ + virtual void PostLoad(); + virtual void BeginDestroy(); + + UBOOL Load(); + UBOOL LoadAsync( void* in_pfnBankCallback, void* in_pCookie ); + void Unload(); + void UnloadAsync( void* in_pfnBankCallback, void* in_pCookie ); + + void GetEventsReferencingBank( TArray& Events ); + void GenerateDefinitionFile(); +} + +defaultproperties +{ + AutoLoad=true + GenerateDefinition=true +} diff --git a/Engine/Classes/AkBaseSoundObject.uc b/Engine/Classes/AkBaseSoundObject.uc new file mode 100644 index 0000000..a341cc1 --- /dev/null +++ b/Engine/Classes/AkBaseSoundObject.uc @@ -0,0 +1,13 @@ +/** + * Common Base class for AkEvents and SoundCues. + * The goal is mainly to reduce the footprint in the integration. + */ + +class AkBaseSoundObject extends Object + native + abstract; + +cpptext +{ + virtual UBOOL IsAudible( const FVector& SourceLocation, const FVector& ListenerLocation, AActor* SourceActor, INT& bIsOccluded, UBOOL bCheckOcclusion ) {return FALSE;} +} \ No newline at end of file diff --git a/Engine/Classes/AkEvent.uc b/Engine/Classes/AkEvent.uc new file mode 100644 index 0000000..7899d92 --- /dev/null +++ b/Engine/Classes/AkEvent.uc @@ -0,0 +1,108 @@ +class AkEvent extends AkBaseSoundObject + native; + +var() AkBank RequiredBank; + +/** The range at which the sound has attenuated completely (-1: no sound; 0: 2D; 3D otherwise) */ +var(TW) const float MaxAudibleDistance; +/** (Advanced) Check this flag to be able to modify MaxAudibleDistance instead of using the "MaxAttenuation" value from WWise */ +var(TW) const bool bOverrideMaxAudibleDistance; + +/** How long this event plays for */ +var(TW) editconst float Duration; + +/** Whether the sound is modified by the distance to listener */ +var(TW) const bool bUseListenerDistance; + +/** Whether to use the environment this event is played in to determine what sound Wwise should play */ +var(TW) const bool bUseEnvironmentReverbSwitchGroup; + +/** Whether to have the Doppler effect applied */ +var(TW) const bool bUseDoppler; + +/** Forces this event to be played at a location (using a pooled component) when played from WwiseClientHearSound */ +var(TW) const bool bForceHearSoundLocational; + +/** Whether this event needs its occlusion updated over time */ +var(TW) const bool bNeedsOcclusionUpdates; +/** How often to update occlusion or obstruction on owning component. Zero means never check. */ +var const float OcclusionUpdateInterval; +/** If set, skip occlusion trace for updates (overrides bNeedsOcclusionUpdates) AND the initial audible test */ +var(TW) const bool bNeverOcclude; + +/** Whether this event is a background music track or not (used to set up exit cue callback) */ +var(TW) const bool bIsMusicTrack; + +struct native EventSwitchInfo +{ + var() name SwitchGroupName; + var name SwitchName; +}; + +struct native EventRTPCInfo +{ + var() name RTPCName; + var float RTPCValue; +}; + +/** Add a tag if you want this event to use a specific Wwise game sync (switch/RTPC). + * In script, you will then have to check for the tag and add a game sync to the + * appropriate custom array. + */ +var(TW) array CustomTags; +var transient array CustomSwitches; +var transient array CustomRTPCs; + +/** Whether to use advanced sound functionality with the sound + * having a rotational direction, and able to play dynamic + * echo sounds + */ +var(Advanced) bool bUseAdvancedSoundFunctionality; + +/** Left Front Echo Sound */ +var(Advanced) AkEvent EchoFront; +/** Right Front Echo Sound */ +var(Advanced) AkEvent EchoLeft; +/** Left Rear Echo Sound */ +var(Advanced) AkEvent EchoRight; +/** Right Rear Echo Sound */ +var(Advanced) AkEvent EchoRear; +/** Mono Echo Sound */ +var(Advanced) AkEvent EchoMono; + +cpptext +{ + virtual void PostLoad(); + void FixRequiredBank(); + + UBOOL IsAudible( const FVector& SourceLocation, const FVector& ListenerLocation, AActor* SourceActor, INT& bIsOccluded, UBOOL bCheckOcclusion ); + + UBOOL LoadBank(); + +#if __TW_WWISE_ && WITH_EDITOR + void GenerateDefaultSettings(); + void GenerateMaxAudibleDistance(); + void GenerateMaxDuration(); +#endif +}; + +simulated function SetCustomRTPC( name RTPCName, float RTPCValue ) +{ + local int RTPCIdx; + + RTPCIdx = CustomRTPCs.Find( 'RTPCName', RTPCName ); + if( RTPCIdx == INDEX_NONE ) + { + CustomRTPCs.Add( 1 ); + RTPCIdx = CustomRTPCs.Length - 1; + CustomRTPCs[RTPCIdx].RTPCName = RTPCName; + } + + CustomRTPCs[RTPCIdx].RTPCValue = RTPCValue; +} + +defaultproperties +{ + MaxAudibleDistance=4000.0 + OcclusionUpdateInterval=0.2 +} diff --git a/Engine/Classes/AlienFXLEDInterface.uc b/Engine/Classes/AlienFXLEDInterface.uc new file mode 100644 index 0000000..649cc31 --- /dev/null +++ b/Engine/Classes/AlienFXLEDInterface.uc @@ -0,0 +1,25 @@ +class AlienFXLEDInterface extends PlatformInterfaceBase + native(PlatformInterface); + +var int Red; +var int Green; +var int Blue; + + /** +* Perform any initialization +*/ +native event Init(); +native event Activate(); +native event bool SetColor(byte RedPercent, byte GreenPercent, byte BluePercent, byte Brightness = 255); + +native event bool LedRestoreLighting(); +native event bool LedStopEffects(); +native function UpdateAlienFX(); +//Depreciated dont use +native event bool LEDSetFlashingRBG(byte redPercentage, byte greenPercentage, byte bluePercentage, +int milliSecondsDuration, int milliSecondsInterval); +//Depreciated dont use +native event bool LEDPulseLighting(byte redPercentage, byte greenPercentage, byte bluePercentage, int +milliSecondsDuration, int milliSecondsInterval); + + diff --git a/Engine/Classes/AmbientOcclusionEffect.uc b/Engine/Classes/AmbientOcclusionEffect.uc new file mode 100644 index 0000000..b59a2e1 --- /dev/null +++ b/Engine/Classes/AmbientOcclusionEffect.uc @@ -0,0 +1,206 @@ +/** + * AmbientOcclusionEffect - A screen space ambient occlusion implementation. + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AmbientOcclusionEffect extends PostProcessEffect + native; + +/** The color that will replace scene color where there is a lot of occlusion. */ +var(Color) interp LinearColor OcclusionColor; + +/** + * Power to apply to the calculated occlusion value. + * Higher powers result in more contrast, but will need other factors like OcclusionScale to be tweaked as well. + */ +var(Color) float OcclusionPower ; + +/** Scale to apply to the calculated occlusion value. */ +var(Color) float OcclusionScale ; + +/** Bias to apply to the calculated occlusion value. */ +var(Color) float OcclusionBias ; + +/** Minimum occlusion value after all other transforms have been applied. */ +var(Color) float MinOcclusion; + +/** SSAO2 is SSAO with quality improvements, it is now the new method so the flag is no longer needed */ +var deprecated bool SSAO2; + +/** SSAO quality improvements, less noise, more detail, no darkening of flat surfaces, no overbright on convex, parameter retweak needed */ +var(Occlusion) bool bAngleBasedSSAO; + +/** Distance to check around each pixel for occluders, in world units. */ +var(Occlusion) float OcclusionRadius ; + +/** Attenuation factor that determines how much to weigh in samples based on distance, larger values result in a faster falloff over distance. */ +var deprecated float OcclusionAttenuation ; + +enum EAmbientOcclusionQuality +{ + AO_High, + AO_Medium, + AO_Low +}; + +/** + * Quality of the ambient occlusion effect. Low quality gives the best performance and is appropriate for gameplay. + * Medium quality smooths noise between frames at a slightly higher performance cost. High quality uses extra samples to preserve detail. + */ +var(Occlusion) EAmbientOcclusionQuality OcclusionQuality; + +/** + * Distance at which to start fading out the occlusion factor, in world units. + * This is useful for hiding distant artifacts on skyboxes. + */ +var(Occlusion) float OcclusionFadeoutMinDistance; + +/** Distance at which the occlusion factor should be fully faded, in world units. */ +var(Occlusion) float OcclusionFadeoutMaxDistance; + +/** + * Distance in front of a pixel that an occluder must be to be considered a different object, in world units. + * This threshold is used to identify halo regions around nearby objects, for example a first person weapon. + */ +var(Halo) float HaloDistanceThreshold; + +/** + * Scale factor to increase HaloDistanceThreshold for distant pixels. + * A value of .001 would result in HaloDistanceThreshold being 1 unit larger at a distance of 1000 world units. + */ +var(Halo) float HaloDistanceScale; + +/** + * Occlusion factor to assign to samples determined to be contributing to a halo. + * 0 would result in full occlusion for that sample, increasing values map to quadratically decreasing occlusion values. + */ +var(Halo) float HaloOcclusion; + +/** Difference in depth that two pixels must be to be considered an edge, and therefore not blurred across, in world units. */ +var(Filter) float EdgeDistanceThreshold; + +/** + * Scale factor to increase EdgeDistanceThreshold for distant pixels. + * A value of .001 would result in EdgeDistanceThreshold being 1 unit larger at a distance of 1000 world units. + */ +var(Filter) float EdgeDistanceScale; + +/** + * Distance in world units which should map to the kernel size in screen space. + * This is useful to reduce filter kernel size for distant pixels and keep detail, at the cost of leaving more noise in the result. + */ +var(Filter) float FilterDistanceScale; + +/** Size of the blur filter, in pixels. */ +var deprecated int FilterSize; + +/** + * Time in which the occlusion history should approximately converge. + * Longer times (.5s) allow more smoothing between frames and less noise but history streaking is more noticeable. + * 0 means the feature is off (less GPU performance and memory overhead) + */ +var(History) float HistoryConvergenceTime; + +/** + * Time in which the weight history should approximately converge. + */ +var float HistoryWeightConvergenceTime; + +`if(`__TW_GAMEWORKS_HBAO_) +/** AO radius in meters */ +var(HBAO) float HBAO_Radius; + +/** To hide low-tessellation artifacts, 0.0~1.0 */ +var(HBAO) float HBAO_Bias; + +/** Scale factor for the detail AO, the greater the darker, 0.0~2.0 */ +var(HBAO) float HBAO_DetailAO; + +/** Scale factor for the coarse AO, the greater the darker, 0.0~2.0 */ +var(HBAO) float HBAO_CoarseAO; + +/** Final AO output is pow(AO, powerExponent) */ +var(HBAO) float HBAO_PowerExponent; + +/** To return white AO for ViewDepths > MaxViewDepth */ +var(HBAO) bool HBAO_EnableDepthThreshold; + +/** Custom view-depth threshold */ +var(HBAO) float HBAO_MaxViewDepth; + +/** The higher, the sharper the AO-to-white transitions */ +var(HBAO) float HBAO_Sharpness; + +/** To blur the AO with an edge-preserving blur */ +var(HBAO) bool HBAO_EnableBlur; + +/** BLUR_RADIUS_2, BLUR_RADIUS_4, or BLUR_RADIUS_8 */ +enum EHBAOBlurRadius +{ + HBAO_BLUR_RADIUS_2, + HBAO_BLUR_RADIUS_4, + HBAO_BLUR_RADIUS_8 +}; +var(HBAO) EHBAOBlurRadius HBAO_BlurRadius; + +/** The higher, the more the blur preserves edges, 0.0~16.0 */ +var(HBAO) float HBAO_BlurSharpness; + +`endif + +cpptext +{ + // UPostProcessEffect interface + + /** + * Creates a proxy to represent the render info for a post process effect + * @param WorldSettings - The world's post process settings for the view. + * @return The proxy object. + */ + virtual class FPostProcessSceneProxy* CreateSceneProxy(const FPostProcessSettings* WorldSettings); + + /** + * @param View - current view + * @return TRUE if the effect should be rendered + */ + virtual UBOOL IsShown(const FSceneView* View) const; + + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); +} + +defaultproperties +{ + bAffectsLightingOnly=TRUE + SceneDPG = SDPG_World; + OcclusionColor=(R=0.0,G=0.0,B=0.0,A=1.0) + OcclusionPower=4.0 + OcclusionScale=20.0 + OcclusionBias=0 + MinOcclusion=.1 + OcclusionRadius=25.0 + OcclusionQuality=AO_Medium + OcclusionFadeoutMinDistance=4000.0 + OcclusionFadeoutMaxDistance=4500.0 + HaloDistanceThreshold=40.0 + HaloDistanceScale=.1 + HaloOcclusion=.04 + EdgeDistanceThreshold=10.0 + EdgeDistanceScale=.003 + FilterDistanceScale=10.0 + HistoryConvergenceTime=0 + HistoryWeightConvergenceTime=.07 + bAngleBasedSSAO=FALSE + +`if(`__TW_GAMEWORKS_HBAO_) + HBAO_Radius=1.0 + HBAO_Bias=0.1 + HBAO_DetailAO=0.0 + HBAO_CoarseAO=1.0 + HBAO_PowerExponent=2.0 + HBAO_EnableDepthThreshold=false + HBAO_MaxViewDepth=0.0 + HBAO_Sharpness=100.0 + HBAO_EnableBlur=true + HBAO_BlurRadius=HBAO_BLUR_RADIUS_4 + HBAO_BlurSharpness=4.0 +`endif +} \ No newline at end of file diff --git a/Engine/Classes/AmbientSound.uc b/Engine/Classes/AmbientSound.uc new file mode 100644 index 0000000..4e01a4a --- /dev/null +++ b/Engine/Classes/AmbientSound.uc @@ -0,0 +1,46 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +// Base ambient sound actor + +class AmbientSound extends Keypoint + AutoExpandCategories( Audio ) + ClassGroup(Sounds) + native( Sound ); + +/** Should the audio component automatically play on load? */ +var() bool bAutoPlay; + +/** Audio component to play */ +var( Audio ) editconst const AudioComponent AudioComponent; + +/** Is the audio component currently playing? */ +var private bool bIsPlaying; + +defaultproperties +{ + Begin Object NAME=Sprite + Sprite=Texture2D'EditorResources.AmbientSoundIcons.S_Ambient_Sound' + Scale=0.25 + SpriteCategoryName="Sounds" + End Object + + Begin Object Class=DrawSoundRadiusComponent Name=DrawSoundRadius0 + SphereColor=(R=255,G=153,B=0) + End Object + Components.Add(DrawSoundRadius0) + + Begin Object Class=AudioComponent Name=AudioComponent0 + PreviewSoundRadius=DrawSoundRadius0 + bAutoPlay=false + bStopWhenOwnerDestroyed=true + bShouldRemainActiveIfDropped=true + End Object + AudioComponent=AudioComponent0 + Components.Add(AudioComponent0) + + bAutoPlay=TRUE + + RemoteRole=ROLE_None +} diff --git a/Engine/Classes/AmbientSoundMovable.uc b/Engine/Classes/AmbientSoundMovable.uc new file mode 100644 index 0000000..a4b5861 --- /dev/null +++ b/Engine/Classes/AmbientSoundMovable.uc @@ -0,0 +1,25 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +// An ambient sound that moves in the world + +class AmbientSoundMovable extends AmbientSound + native( Sound ); + +defaultproperties +{ + Begin Object NAME=Sprite + Sprite=Texture2D'EditorResources.AmbientSoundIcons.S_Ambient_Sound_Moveable' + Scale=0.25 + End Object + + Begin Object Name=DrawSoundRadius0 + SphereColor=(R=102,G=204,B=51) + End Object + + TickGroup=TG_DuringAsyncWork + Physics=PHYS_Interpolating + bMovable=TRUE + bStatic=FALSE +} diff --git a/Engine/Classes/AmbientSoundNonLoop.uc b/Engine/Classes/AmbientSoundNonLoop.uc new file mode 100644 index 0000000..acd3048 --- /dev/null +++ b/Engine/Classes/AmbientSoundNonLoop.uc @@ -0,0 +1,30 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +// Version of AmbientSoundSimple that picks a random non-looping sound to play. + +class AmbientSoundNonLoop extends AmbientSoundSimple + native( Sound ); + +defaultproperties +{ + DrawScale=2.0 + + Begin Object NAME=Sprite + Sprite=Texture2D'EditorResources.AmbientSoundIcons.S_Ambient_Sound_Non_Loop' + Scale=0.25 + End Object + + Begin Object Name=DrawSoundRadius0 + SphereColor=(R=255,G=0,B=51) + End Object + + Begin Object Name=AudioComponent0 + bShouldRemainActiveIfDropped=true + End Object + + Begin Object Class=SoundNodeAmbientNonLoop Name=SoundNodeAmbientNonLoop0 + End Object + SoundNodeInstance=SoundNodeAmbientNonLoop0 +} diff --git a/Engine/Classes/AmbientSoundNonLoopingToggleable.uc b/Engine/Classes/AmbientSoundNonLoopingToggleable.uc new file mode 100644 index 0000000..06c464b --- /dev/null +++ b/Engine/Classes/AmbientSoundNonLoopingToggleable.uc @@ -0,0 +1,30 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +// Version of AmbientSoundToggleable that picks a random non-looping sound to play. + +class AmbientSoundNonLoopingToggleable extends AmbientSoundSimpleToggleable + native( Sound ); + +defaultproperties +{ + DrawScale=1.0 + + Begin Object NAME=Sprite + Sprite=Texture2D'EditorResources.AmbientSoundIcons.S_Ambient_Sound_Non_Loop' + Scale=0.25 + End Object + + Begin Object Name=DrawSoundRadius0 + SphereColor=(R=255,G=0,B=51) + End Object + + Begin Object Name=AudioComponent0 + bShouldRemainActiveIfDropped=true + End Object + + Begin Object Class=SoundNodeAmbientNonLoopToggle Name=SoundNodeAmbientNonLoopToggle0 + End Object + SoundNodeInstance=SoundNodeAmbientNonLoopToggle0 +} diff --git a/Engine/Classes/AmbientSoundSimple.uc b/Engine/Classes/AmbientSoundSimple.uc new file mode 100644 index 0000000..d5dc6c3 --- /dev/null +++ b/Engine/Classes/AmbientSoundSimple.uc @@ -0,0 +1,38 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + + // A simplified ambient sound actor for enhanced workflow + +class AmbientSoundSimple extends AmbientSound + hidecategories( Audio ) + AutoExpandCategories( AmbientSoundSimple ) + native( Sound ); + +/** Mirrored property for easier editability, set in Spawned. */ +var() editinline editconst SoundNodeAmbient AmbientProperties; +/** Dummy sound cue property to force instantiation of subobject. */ +var editinline export const SoundCue SoundCueInstance; +/** Dummy sound node property to force instantiation of subobject. */ +var editinline export const SoundNodeAmbient SoundNodeInstance; + +defaultproperties +{ + Begin Object NAME=Sprite + Sprite=Texture2D'EditorResources.AmbientSoundIcons.S_Ambient_Sound_Simple' + Scale=0.25 + End Object + + Begin Object Name=DrawSoundRadius0 + SphereColor=(R=0,G=102,B=255) + End Object + + Begin Object Class=SoundNodeAmbient Name=SoundNodeAmbient0 + End Object + SoundNodeInstance=SoundNodeAmbient0 + + Begin Object Class=SoundCue Name=SoundCue0 + SoundClass=Ambient + End Object + SoundCueInstance=SoundCue0 +} diff --git a/Engine/Classes/AmbientSoundSimpleSpline.uc b/Engine/Classes/AmbientSoundSimpleSpline.uc new file mode 100644 index 0000000..f3b152e --- /dev/null +++ b/Engine/Classes/AmbientSoundSimpleSpline.uc @@ -0,0 +1,42 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +/** + * The class works similar to AmbientSoundSpline, but it allows to bind many waves as sound sources (instead of single sound cue). Moreover for each wave a range on spline can be defined. + */ + +class AmbientSoundSimpleSpline extends AmbientSoundSpline + AutoExpandCategories( AmbientSoundSpline ) + native( Sound ); + +/** Index of currently edited sound-slot */ +var(AmbientSoundSpline) editoronly int EditedSlot; + +cpptext +{ + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); +} + +defaultproperties +{ + Begin Object NAME=Sprite + Sprite=Texture2D'EditorResources.AmbientSoundIcons.S_Ambient_Sound_Simple' + Scale=0.25 + End Object + + Components.Remove( AudioComponent1 ) + + Begin Object Name=DrawSoundRadius0 + SphereColor=(R=0,G=102,B=255) + End Object + + Begin Object Class=SimpleSplineAudioComponent Name=AudioComponent2 + PreviewSoundRadius=DrawSoundRadius0 + bAutoPlay=false + bStopWhenOwnerDestroyed=true + bShouldRemainActiveIfDropped=true + End Object + AudioComponent=AudioComponent2 + Components.Add(AudioComponent2) +} diff --git a/Engine/Classes/AmbientSoundSimpleSplineNonLoop.uc b/Engine/Classes/AmbientSoundSimpleSplineNonLoop.uc new file mode 100644 index 0000000..089ae03 --- /dev/null +++ b/Engine/Classes/AmbientSoundSimpleSplineNonLoop.uc @@ -0,0 +1,29 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AmbientSoundSimpleSplineNonLoop extends AmbientSoundSimpleSpline; + +defaultproperties +{ + Begin Object Name=DrawSoundRadius0 + SphereColor=(R=255,G=0,B=51) + End Object + + Begin Object NAME=Sprite + Sprite=Texture2D'EditorResources.AmbientSoundIcons.S_Ambient_Sound_Non_Loop' + Scale=0.25 + End Object + + Components.Remove( AudioComponent2 ) + + Begin Object Class=SimpleSplineNonLoopAudioComponent Name=AudioComponent3 + PreviewSoundRadius=DrawSoundRadius0 + bAutoPlay=false + bStopWhenOwnerDestroyed=true + bShouldRemainActiveIfDropped=true + End Object + + AudioComponent=AudioComponent3 + Components.Add(AudioComponent3) +} diff --git a/Engine/Classes/AmbientSoundSimpleToggleable.uc b/Engine/Classes/AmbientSoundSimpleToggleable.uc new file mode 100644 index 0000000..aa89732 --- /dev/null +++ b/Engine/Classes/AmbientSoundSimpleToggleable.uc @@ -0,0 +1,146 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +// An ambient sound that can be turned on or off + +class AmbientSoundSimpleToggleable extends AmbientSoundSimple + AutoExpandCategories( AmbientSoundSimpleToggleable ) + native( Sound ); + +/** used to update status of toggleable level placed ambient sounds on clients */ +var repnotify bool bCurrentlyPlaying; + +var() bool bFadeOnToggle; +var() float FadeInDuration; +var() float FadeInVolumeLevel; +var() float FadeOutDuration; +var() float FadeOutVolumeLevel; + +/** Used to track whether the sound's auto-play setting should be ignored or not */ +var transient bool bIgnoreAutoPlay; + +struct CheckpointRecord +{ + var bool bCurrentlyPlaying; +}; + +replication +{ + if( Role == ROLE_Authority ) + bCurrentlyPlaying; +} + +simulated event PostBeginPlay() +{ + Super.PostBeginPlay(); + + bCurrentlyPlaying = AudioComponent.bAutoPlay; +} + +simulated event ReplicatedEvent(name VarName) +{ + if( VarName == 'bCurrentlyPlaying' ) + { + if( bCurrentlyPlaying ) + { + StartPlaying(); + } + else + { + StopPlaying(); + } + } + else + { + Super.ReplicatedEvent( VarName ); + } +} + +simulated function StartPlaying() +{ + if( bFadeOnToggle ) + { + AudioComponent.FadeIn( FadeInDuration, FadeInVolumeLevel ); + } + else + { + AudioComponent.Play(); + } + + bCurrentlyPlaying = TRUE; +} + +simulated function StopPlaying() +{ + if( bFadeOnToggle ) + { + AudioComponent.FadeOut( FadeOutDuration, FadeOutVolumeLevel ); + } + else + { + AudioComponent.Stop(); + } + + bCurrentlyPlaying = FALSE; +} + +/** + * Handling Toggle event from Kismet. + */ +simulated function OnToggle( SeqAct_Toggle Action ) +{ + if( Action.InputLinks[0].bHasImpulse || ( Action.InputLinks[2].bHasImpulse && !AudioComponent.bWasPlaying ) ) + { + StartPlaying(); + } + else + { + // The sound has been intentionally toggled off, ignore autoplay from now on + bIgnoreAutoPlay = TRUE; + StopPlaying(); + } + + // we now need to replicate this Actor so clients get the updated status + ForceNetRelevant(); +} + +function CreateCheckpointRecord( out CheckpointRecord Record ) +{ + Record.bCurrentlyPlaying = bCurrentlyPlaying; +} + +function ApplyCheckpointRecord( const out CheckpointRecord Record ) +{ + bCurrentlyPlaying = Record.bCurrentlyPlaying; + if( bCurrentlyPlaying ) + { + StartPlaying(); + } + else + { + StopPlaying(); + } +} + +defaultproperties +{ + Begin Object NAME=Sprite + Sprite=Texture2D'EditorResources.AmbientSoundIcons.S_Ambient_Sound_Toggleable' + Scale=0.25 + End Object + + Begin Object Name=DrawSoundRadius0 + SphereColor=(R=255,G=255,B=102) + End Object + + bAutoPlay=FALSE + bStatic=false + bNoDelete=true + bIgnoreAutoPlay=FALSE + + FadeInDuration=1.f + FadeInVolumeLevel=1.f + FadeOutDuration=1.f + FadeOutVolumeLevel=0.f +} diff --git a/Engine/Classes/AmbientSoundSpline.uc b/Engine/Classes/AmbientSoundSpline.uc new file mode 100644 index 0000000..6f7acfd --- /dev/null +++ b/Engine/Classes/AmbientSoundSpline.uc @@ -0,0 +1,61 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +/** + * Sound is emmited by virtual speaker. Virtual speaker is placed in evaluated in the mean loudest position in listener's scope. + * The points used to virtual speaker evaluation are placed on spline. + */ + +class AmbientSoundSpline extends AmbientSound + AutoExpandCategories( AmbientSoundSpline ) + native( Sound ); +/** + * Maximal distance on spline between points, that are used to eval virtual speaker position (Minimal number of points is 3) + * Points are placed on spline automatically. + */ +var(AmbientSoundSpline) editoronly float DistanceBetweenPoints; + +/** SplineComponent with spline curve defining the source of sound */ +var(AmbientSoundSpline) editoronly SplineComponent SplineComponent; + +/** Only to test algorithm finding nearest point. Editor shows virtual speaker position for listener placed in TestPoint.*/ +var editoronly vector TestPoint; + +cpptext +{ + virtual void PostLoad(); + virtual void PostEditMove(UBOOL bFinished); + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + +#if WITH_EDITOR + virtual void EditorApplyTranslation(const FVector& DeltaTranslation, UBOOL bAltDown, UBOOL bShiftDown, UBOOL bCtrlDown); + + /** Force all spline data to be consistent. */ + virtual void UpdateSpline(); + + /** Recalculate spline after any control point was moved. */ + virtual void UpdateSplineGeometry(); +#endif +} + +defaultproperties +{ + DistanceBetweenPoints=200.0 + + Components.Remove( AudioComponent0 ) + + Begin Object Class=SplineComponentSimplified Name=SplineComponent0 + End Object + SplineComponent=SplineComponent0 + Components.Add( SplineComponent0 ) + + Begin Object Class=SplineAudioComponent Name=AudioComponent1 + PreviewSoundRadius=DrawSoundRadius0 + bAutoPlay=false + bStopWhenOwnerDestroyed=true + bShouldRemainActiveIfDropped=true + End Object + AudioComponent=AudioComponent1 + Components.Add(AudioComponent1) +} \ No newline at end of file diff --git a/Engine/Classes/AmbientSoundSplineMultiCue.uc b/Engine/Classes/AmbientSoundSplineMultiCue.uc new file mode 100644 index 0000000..7bc5f34 --- /dev/null +++ b/Engine/Classes/AmbientSoundSplineMultiCue.uc @@ -0,0 +1,36 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + + + +class AmbientSoundSplineMultiCue extends AmbientSoundSpline + AutoExpandCategories( AmbientSoundSpline ) + native( Sound ); + +/** Index of currently edited sound-slot */ +var(AmbientSoundSpline) editoronly int EditedSlot; + +cpptext +{ + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); +} + +defaultproperties +{ + Begin Object NAME=Sprite + Sprite=Texture2D'EditorResources.AmbientSoundIcons.S_Ambient_Sound_Simple' + Scale=0.25 + End Object + + Components.Remove( AudioComponent1 ) + + Begin Object Class=MultiCueSplineAudioComponent Name=AudioComponent2 + PreviewSoundRadius=DrawSoundRadius0 + bAutoPlay=false + bStopWhenOwnerDestroyed=true + bShouldRemainActiveIfDropped=true + End Object + AudioComponent=AudioComponent2 + Components.Add(AudioComponent2) +} diff --git a/Engine/Classes/AnalyticEventsBase.uc b/Engine/Classes/AnalyticEventsBase.uc new file mode 100644 index 0000000..f7b6730 --- /dev/null +++ b/Engine/Classes/AnalyticEventsBase.uc @@ -0,0 +1,225 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * This is the base class for per-platform support for uploading analytics events + */ + +class AnalyticEventsBase extends PlatformInterfaceBase + native(PlatformInterface) + config(Engine); + +/** Named param/value string pairing */ +struct native EventStringParam +{ + /** parameter name */ + var string ParamName; + /** parameter value */ + var string ParamValue; + + structcpptext + { + FEventStringParam(const FString& InNameStr,const FString& InValueStr) + { + appMemzero(this, sizeof(FEventStringParam)); + ParamName = InNameStr; + ParamValue = InValueStr; + } + FEventStringParam(EEventParm) + { + appMemzero(this, sizeof(FEventStringParam)); + } + } +}; + +/** TRUE if a session has been started and is currently in progress */ +var const bool bSessionInProgress; + +/** + * TRUE if the analytics session should be auto started and stopped on application + * startup. This makes it easier, but some providers may require additional information + * before a session can be started. + * + * For example, Swrve requires a UserId to be set before a session can be started. + * Since this may come from an outside source (backend server), it might not be possible + * to start the analytics session immediately. + * + * If this value is false, StartSession and EndSession must be called manually by the + * game code at some point. + */ +var config bool bAutoStartSession; + +/** + * When the app is paused (backgrounded on iOS) for more than the specified number + * of seconds, it signals supporting analytics providers to restart the session. + * Idea is that if a user backgrounds the app for a brief period, the session should + * not end, but if they don't come back to the app for a period of time, it should + * constitute a new session. + * + * A value of zero means the session should not be restarted when paused for any length of time. + * + * Most analytics providers have a built-in timeout for a session that cannot + * be overridden, but it is usually quite long (ie, Swrve times out after 60 minutes). + * + * This is currently only supported on iOS. + */ +var config int SessionPauseThresholdSec; + +/** stores the UserId if one has been provided. See SetUserID for details. */ +var const string UserId; + +/** + * @return TRUE if a session has been started and is currently in progress + */ +function bool IsSessionInProgress() +{ + return bSessionInProgress; +} + +/** + * Perform any initialization. Called once after singleton instantiation + */ +native event Init(); + +/** + * Set the UserID for use with analytics. Some providers require a unique ID + * to be provided when supplying events, and some providers create their own. + * If you are using a provider that requires you to supply the ID, use this + * method to set it. It is probably best for online games to use the McpId + */ +native event SetUserId(string NewUserId); + +/** + * Start capturing stats for upload + */ +native event StartSession(); + +/** + * End capturing stats and queue the upload + */ +native event EndSession(); + +/** + * Adds a named event to the session + * + * @param EventName unique string for named event + * @param bTimed if true then event is logged with timing + */ +native event LogStringEvent(string EventName, bool bTimed); + +/** + * Ends a timed string event + * + * @param EventName unique string for named event + */ +native event EndStringEvent(string EventName); + +/** + * Adds a named event to the session with a single parameter/value + * + * @param EventName unique string for named + * @param ParamName parameter name for the event + * @param ParamValue parameter value for the event + * @param bTimed if true then event is logged with timing + */ +native event LogStringEventParam(string EventName, string ParamName, string ParamValue, bool bTimed); + +/** + * Ends a timed event with a single parameter/value. Param values are updated for ended event. + * + * @param EventName unique string for named + * @param ParamName parameter name for the event + * @param ParamValue parameter value for the event + */ +native event EndStringEventParam(string EventName, string ParamName, string ParamValue); + +/** + * Adds a named event to the session with an array of parameter/values + * + * @param EventName unique string for named + * @param ParamArray array of parameter name/value pairs + * @param bTimed if true then event is logged with timing + */ +native event LogStringEventParamArray(string EventName, array ParamArray, bool bTimed); + +/** + * Ends a timed event with an array of parameter/values. Param values are updated for ended event unless array is empty + * + * @param EventName unique string for named + * @param ParamArray array of parameter name/value pairs. If array is empty ending the event wont update values + */ +native event EndStringEventParamArray(string EventName, array ParamArray); + +/** + * Adds a named error event with corresponding error message + * + * @param ErrorName unique string for error event + * @param ErrorMessage message detailing the error encountered + */ +native event LogErrorMessage(string ErrorName, string ErrorMessage); + +/** + * Update a single user attribute. + * + * Note that not all providers support user attributes. In this case this method + * is equivalent to sending a regular event. + * + * @param AttributeName - the name of the attribute + * @param AttributeValue - the value of the attribute. + */ +native event LogUserAttributeUpdate(string AttributeName, string AttributeValue); + +/** + * Update an array of user attributes. + * + * Note that not all providers support user attributes. In this case this method + * is equivalent to sending a regular event. + * + * @param AttributeArray - the array of attribute name/values to set. + */ +native event LogUserAttributeUpdateArray(array AttributeArray); + +/** + * Record an in-game purchase of a an item. + * + * Note that not all providers support item purchase events. In this case this method + * is equivalent to sending a regular event. + * + * @param ItemId - the ID of the item, should be registered with the provider first. + * @param Currency - the currency of the purchase (ie, Gold, Coins, etc), should be registered with the provider first. + * @param PerItemCost - the cost of one item in the currency given. + * @param ItemQuantity - the number of Items purchased. + */ +native event LogItemPurchaseEvent(string ItemId, string Currency, int PerItemCost, int ItemQuantity); + +/** + * Record a purchase of in-game currency using real-world money. + * + * Note that not all providers support currency events. In this case this method + * is equivalent to sending a regular event. + * + * @param GameCurrencyType - type of in game currency purchased, should be registered with the provider first. + * @param GameCurrencyAmount - amount of in game currency purchased. + * @param RealCurrencyType - real-world currency type (like a 3-character ISO 4217 currency code, but provider dependent). + * @param RealMoneyCost - cost of the currency in real world money, expressed in RealCurrencyType units. + * @param PaymentProvider - Provider who brokered the transaction. Generally arbitrary, but examples are PayPal, Facebook Credits, App Store, etc. + */ +native event LogCurrencyPurchaseEvent(string GameCurrencyType, int GameCurrencyAmount, string RealCurrencyType, float RealMoneyCost, string PaymentProvider); + +/** + * Record a gift of in-game currency from the game itself. + * + * Note that not all providers support currency events. In this case this method + * is equivalent to sending a regular event. + * + * @param GameCurrencyType - type of in game currency given, should be registered with the provider first. + * @param GameCurrencyAmount - amount of in game currency given. + */ +native event LogCurrencyGivenEvent(string GameCurrencyType, int GameCurrencyAmount); + +/** + * Flush any cached events to the analytics provider. + * + * Note that not all providers support explicitly sending any cached events. In this case this method + * does nothing. + */ +native event SendCachedEvents(); \ No newline at end of file diff --git a/Engine/Classes/AnimMetaData.uc b/Engine/Classes/AnimMetaData.uc new file mode 100644 index 0000000..41ed1b9 --- /dev/null +++ b/Engine/Classes/AnimMetaData.uc @@ -0,0 +1,22 @@ + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * Definition of AnimMetaData class + * Warning: those are not instanced per AnimNodeSequence, they are solely attached to an AnimSequence. + * Therefore they can be affecting multiple nodes at the same time! + */ + +class AnimMetaData extends Object + native(Anim) + abstract + editinlinenew + hidecategories(Object) + collapsecategories; + +cpptext +{ + virtual void AnimSet(UAnimNodeSequence* SeqNode); + virtual void AnimUnSet(UAnimNodeSequence* SeqNode); + virtual void TickMetaData(UAnimNodeSequence* SeqNode); +} + diff --git a/Engine/Classes/AnimMetaData_SkelControl.uc b/Engine/Classes/AnimMetaData_SkelControl.uc new file mode 100644 index 0000000..b1029c3 --- /dev/null +++ b/Engine/Classes/AnimMetaData_SkelControl.uc @@ -0,0 +1,36 @@ + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimMetaData_SkelControl extends AnimMetaData + native(Anim); + +/** List of Bone Controllers Names to control. */ +var() Array SkelControlNameList; + +/** + * If TRUE, then it requires bControlledByAnimMetadata to be set as well on the BoneController. + * It will then affect AnimMetadataWeight instead of ControlStrength. + * And BoneController will only be turned on if there is such metadata present in the animation. + * FALSE will set directly the BoneController's ControlStrength when that metadata is present. + */ +var() bool bFullControlOverController; + +// deprecated. +var deprecated name SkelControlName; + +cpptext +{ + virtual void PostLoad(); + virtual void AnimSet(UAnimNodeSequence* SeqNode); + virtual void AnimUnSet(UAnimNodeSequence* SeqNode); + virtual void TickMetaData(UAnimNodeSequence* SeqNode); + virtual UBOOL ShouldCallSkelControlTick(USkelControlBase* SkelControl, UAnimNodeSequence* SeqNode); + virtual void SkelControlTick(USkelControlBase* SkelControl, UAnimNodeSequence* SeqNode); +} + +defaultproperties +{ + bFullControlOverController=TRUE +} \ No newline at end of file diff --git a/Engine/Classes/AnimMetaData_SkelControlKeyFrame.uc b/Engine/Classes/AnimMetaData_SkelControlKeyFrame.uc new file mode 100644 index 0000000..3d61bd5 --- /dev/null +++ b/Engine/Classes/AnimMetaData_SkelControlKeyFrame.uc @@ -0,0 +1,20 @@ + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimMetaData_SkelControlKeyFrame extends AnimMetaData_SkelControl + native(Anim); + +/** Modifiers for what time and what strength for this skelcontrol **/ +var() editinline array KeyFrames; + +cpptext +{ + virtual void SkelControlTick(USkelControlBase* SkelControl, UAnimNodeSequence* SeqNode); +} + +defaultproperties +{ + bFullControlOverController=FALSE +} \ No newline at end of file diff --git a/Engine/Classes/AnimNode.uc b/Engine/Classes/AnimNode.uc new file mode 100644 index 0000000..ffdeb96 --- /dev/null +++ b/Engine/Classes/AnimNode.uc @@ -0,0 +1,284 @@ + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimNode extends AnimObject + native(Anim) + hidecategories(Object) + abstract; + +/** Enumeration for slider types */ +enum ESliderType +{ + ST_1D, + ST_2D +}; + +/** Curve Key + @CurveName : Morph Target name to blend + @Weight : Weight of the Morph Target +**/ +struct CurveKey +{ + var name CurveName; + var float Weight; +}; + +/** This node is considered 'relevant' - that is, has >0 weight in the final blend. */ +var transient const bool bRelevant; +/** set to TRUE when this node became relevant this round of updates. Will be set to false on the next tick. */ +var transient const bool bJustBecameRelevant; +/** If TRUE, this node will be ticked, even if bPauseAnims is TRUE on the SkelMeshComp. */ +var(Performance) bool bTickDuringPausedAnims; +/** This node is editor only and used for something like placement preview */ +var const bool bEditorOnly; + +/** Used to avoid ticking a node twice if it has multiple parents. */ +var transient const int NodeTickTag; +/** Initialization tag, for deferred InitAnim. */ +var transient const INT NodeInitTag; +/** Used to avoid a node triggerring event twice if it has multiple parents. */ +var transient const int NodeEndEventTick; +/** Index in AnimTick Array. Serialized, because we serialize TickArrayIndex in UAnimTree. */ +var const int TickArrayIndex; +/** Used to indicate whether the BoneAtom cache for this node is up-to-date or not. */ +var transient const int NodeCachedAtomsTag; + +/** Total apparent weight this node has in the final blend of all animations. */ +var const float NodeTotalWeight; + +/** Array of Parent nodes, which in most cases only has 1 element. */ +var duplicatetransient Array ParentNodes; + +/** This is the name used to find an AnimNode by name from a tree. */ +var() name NodeName; + +/** Temporarily disable caching when calling Super::GetBoneAtoms so it's not done multiple times. */ +var const transient bool bDisableCaching; +/** If a node is linked to more than once in the graph, this is a cache of the results, to avoid re-evaluating the results. */ +var transient array CachedBoneAtoms; +/** Num Desired Bones used in CachedBoneAtoms. If we request something different, CachedBoneAtoms array is not going to be valid. */ +var transient byte CachedNumDesiredBones; +/** Cached root motion delta, to avoid recalculating (see above). */ +var transient BoneAtom CachedRootMotionDelta; +/** Cached bool indicating if node supplies root motion, to avoid recalculating (see above). */ +var transient int bCachedHasRootMotion; +/** Cached curve keys to avoid recalculating (see above). */ +var transient array CachedCurveKeys; + +/** used when iterating over nodes via GetNodes() and related functions to skip nodes that have already been processed */ +var transient int SearchTag; + +/** Array of blended curve key for editor only **/ +var(Morph) editoronly editconst transient array LastUpdatedAnimMorphKeys; + +/** Flags to control if Script Events should be called. Note that those will affect performance, so be careful! */ +var() bool bCallScriptEventOnInit; +var() bool bCallScriptEventOnBecomeRelevant; +var() bool bCallScriptEventOnCeaseRelevant; + +cpptext +{ + UAnimNode * GetAnimNode() { return this;} + // UAnimNode interface + + /** Do any initialisation, and then call InitAnim on all children. Should not discard any existing anim state though. */ + virtual void InitAnim( USkeletalMeshComponent* meshComp, UAnimNodeBlendBase* Parent ); + /** Deferred Initialization, called only when the node is relevant in the tree. */ + virtual void DeferredInitAnim() {} + /** Call DeferredInitAnim() if the node required it. Recurses through the Tree. Increase UAnimNode::CurrentSeachTag before calling. */ + virtual void CallDeferredInitAnim(); + + /** AnimSets have been updated, update all animations */ + virtual void AnimSetsUpdated() {} + + /** + * Called just after a node has been copied from its AnimTreeTemplate version. + * This is called on the copy, and SourceNode is the node within the AnimTreeTemplate. + */ + virtual void PostAnimNodeInstance(UAnimNode* SourceNode, TMap& SrcToDestNodeMap) {} + + /** + * Called when we need to reset our values to the source. This is called on a node that already has all pointers set up correctly + */ + virtual void ResetAnimNodeToSource(UAnimNode *SourceNode); + + /** + * Update this node, then call TickAnim on all children. + * @param DeltaSeconds Amount of time to advance this node. + * @param TotalWeight The eventual weight that this node will have in the final blend. This is the multiplication of weights of all nodes above this one. + */ + virtual void TickAnim(FLOAT DeltaSeconds) {} + + /** Parent node is requesting a blend out. Give node a chance to delay that. */ + virtual UBOOL CanBlendOutFrom() { return TRUE; } + + /** parent node is requesting a blend in. Give node a chance to delay that. */ + virtual UBOOL CanBlendTo() { return TRUE; } + + /** + * Add this node and all children to array. Node are added so a parent is always before its children in the array. + * @param bForceTraversal Disables optimization when calling this from the root. (precached AnimTickArray returned). + */ + void GetNodes(TArray& Nodes, bool bForceTraversal=FALSE); + + /** Add this node and all children of the specified class to array. Node are added so a parent is always before its children in the array. */ + void GetNodesByClass(TArray& Nodes, class UClass* BaseClass); + + /** Return an array with all UAnimNodeSequence childs, including this node. */ + void GetAnimSeqNodes(TArray& Nodes, FName InSynchGroupName=NAME_None); + + virtual void BuildParentNodesArray(); + /** Used for building array of AnimNodes in 'tick' order - that is, all parents of a node are added to array before it. */ + virtual void BuildTickArray(TArray& OutTickArray) {} + + /** + * Get the local transform for each bone. If a blend, will recursively ask children and blend etc. + * DesiredBones should be in strictly increasing order. + */ + virtual void GetBoneAtoms(FBoneAtomArray& Atoms, const TArray& DesiredBones, FBoneAtom& RootMotionDelta, INT& bHasRootMotion, FCurveKeyArray& CurveKeys); + + /** + * Will copy the cached results into the OutAtoms array if they are up to date and return TRUE + * If cache is not up to date, does nothing and retuns FALSE. + */ + virtual UBOOL GetCachedResults(FBoneAtomArray& OutAtoms, FBoneAtom& OutRootMotionDelta, INT& bOutHasRootMotion, FCurveKeyArray& OutCurveKeys, INT NumDesiredBones); + + /** Save the supplied array of BoneAtoms in the CachedBoneAtoms. */ + virtual UBOOL ShouldSaveCachedResults(); + void SaveCachedResults(const FBoneAtomArray& NewAtoms, const FBoneAtom& NewRootMotionDelta, INT bNewHasRootMotion, const FCurveKeyArray& NewCurveKeys, INT NumDesiredBones); + + /** + * Whether we should keep the cached result for the next frame or not + * This is to avoid keeping cached result once it ticks. + * It will release cache result if this returns FALSE + **/ + virtual UBOOL ShouldKeepCachedResult() { return FALSE; } + + /** + * Clear Cached Result + **/ + virtual void ClearCachedResult(); + + /** Get notification that this node has become relevant for the final blend. ie TotalWeight is now > 0 */ + virtual void OnBecomeRelevant(); + + /** Get notification that this node is no longer relevant for the final blend. ie TotalWeight is now == 0 */ + virtual void OnCeaseRelevant(); + + /** Utility for counting the number of parents of this node that have been ticked. */ + UBOOL WereAllParentsTicked() const; + + /** Returns TRUE if this node is a child of Node */ + UBOOL IsChildOf(UAnimNode* Node); + + /** Returns TRUE if this node is a child of Node */ + UBOOL IsChildOf_Internal(UAnimNode* Node); + + /** Optimisation way to see if this is a UAnimTree */ + virtual UAnimTree* GetAnimTree() { return NULL; } + + virtual void SetAnim( FName SequenceName ) {} + virtual void SetPosition( FLOAT NewTime, UBOOL bFireNotifies ) {} + + /** Override these functions to disable loading of editor only nodes */ + virtual UBOOL NeedsLoadForClient() const; + virtual UBOOL NeedsLoadForServer() const; + + /// ANIMTREE EDITOR + + /** + * Draws this node in the AnimTreeEditor. + * + * @param Canvas The canvas to use. + * @param SelectedNodes Reference to array of all currently selected nodes, potentially including this node + * @param bShowWeight If TRUE, show the global percentage weight of this node, if applicable. + */ + virtual void DrawNode(FCanvas* Canvas, const TArray& SelectedNodes, UBOOL bShowWeight) { DrawAnimNode(Canvas, SelectedNodes, bShowWeight); } + + /** + * Draws this anim node in the AnimTreeEditor. + * + * @param Canvas The canvas to use. + * @param SelectedNodes Reference to array of all currently selected nodes, potentially including this node + * @param bShowWeight If TRUE, show the global percentage weight of this node, if applicable. + */ + virtual void DrawAnimNode(FCanvas* Canvas, const TArray& SelectedNodes, UBOOL bShowWeight) {} + + /** Return title to display for this Node in the AnimTree editor. */ + virtual FString GetNodeTitle() { return TEXT(""); } + + /** For editor use. */ + virtual FIntPoint GetConnectionLocation(INT ConnType, int ConnIndex); + + /** Return the number of sliders */ + virtual INT GetNumSliders() const { return 0; } + + /** Return the slider type of slider Index */ + virtual ESliderType GetSliderType(INT InIndex) const { return ST_1D; } + + /** Return current position of slider for this node in the AnimTreeEditor. Return value should be within 0.0 to 1.0 range. */ + virtual FLOAT GetSliderPosition(INT SliderIndex, INT ValueIndex) { return 0.f; } + + /** Called when slider is moved in the AnimTreeEditor. NewSliderValue is in range 0.0 to 1.0. */ + virtual void HandleSliderMove(INT SliderIndex, INT ValueIndex, FLOAT NewSliderValue) {} + + /** Get the number to draw under the slider to show the current value being previewed. */ + virtual FString GetSliderDrawValue(INT SliderIndex) { return FString(TEXT("")); } + + /** internal code for GetNodes(); should only be called from GetNodes() or from the GetNodesInternal() of this node's parent */ + virtual void GetNodesInternal(TArray& Nodes); + + /** Called after (copy/)pasted - reset values or re-link if needed**/ + virtual void OnPaste(); + + // STATIC ANIMTREE UTILS + + /** flag to prevent calling GetNodesInternal() from anywhere besides GetNodes() or another GetNodesInternal(), since + * we can't make it private/protected because UAnimNodeBlendBase needs to be able to call it on its children + */ + static UBOOL bNodeSearching; + /** current tag value used for SearchTag on nodes being iterated over. Incremented every time a new search is started */ + static INT CurrentSearchTag; + /** Array to keep track of those nodes requiring an actual clear of the cache */ + static TArray NodesRequiringCacheClear; + + /** + * Fills the Atoms array with the specified skeletal mesh reference pose. + * + * @param Atoms [out] Output array of relative bone transforms. Must be the same length as RefSkel when calling function. + * @param DesiredBones Indices of bones we want to modify. Parents must occur before children. + * @param RefSkel Input reference skeleton to create atoms from. + */ + static void FillWithRefPose(TArray& Atoms, const TArray& DesiredBones, const TArray& RefSkel); + static void FillWithRefPose(FBoneAtomArray& Atoms, const TArray& DesiredBones, const TArray& RefSkel); + + /** Utility for taking an array of bone indices and ensuring that all parents are present (ie. all bones between those in the array and the root are present). */ + static void EnsureParentsPresent( TArray& BoneIndices, USkeletalMesh* SkelMesh ); + + /** Utility functions to ease off Casting */ + virtual class UAnimNodeSlot* GetAnimNodeSlot() { return NULL; } + virtual class UAnimNodeAimOffset* GetAnimNodeAimOffset() { return NULL; } + virtual class UAnimNodeSequence* GetAnimNodeSequence() { return NULL; } +} + +/** Called from InitAnim. Allows initialization of script-side properties of this node. */ +event OnInit(); +/** Get notification that this node has become relevant for the final blend. ie TotalWeight is now > 0 */ +event OnBecomeRelevant(); +/** Get notification that this node is no longer relevant for the final blend. ie TotalWeight is now == 0 */ +event OnCeaseRelevant(); + +/** + * Find an Animation Node in the Animation Tree whose NodeName matches InNodeName. + * Will search this node and all below it. + * Warning: The search is O(n^2), so for large AnimTrees, cache result. + */ +native final function AnimNode FindAnimNode(name InNodeName); + +native function PlayAnim(bool bLoop = false, float Rate = 1.0f, float StartTime = 0.0f); +native function StopAnim(); +// calls PlayAnim with the current settings +native function ReplayAnim(); + diff --git a/Engine/Classes/AnimNodeAdditiveBlending.uc b/Engine/Classes/AnimNodeAdditiveBlending.uc new file mode 100644 index 0000000..1456208 --- /dev/null +++ b/Engine/Classes/AnimNodeAdditiveBlending.uc @@ -0,0 +1,37 @@ + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimNodeAdditiveBlending extends AnimNodeBlend + native(Anim); + +/** + * if TRUE, pass through (skip additive animation blending) when mesh is not rendered + */ +var(Performance) bool bPassThroughWhenNotRendered; + +cpptext +{ + virtual void InitAnim(USkeletalMeshComponent* MeshComp, UAnimNodeBlendBase* Parent); + virtual void TickAnim(FLOAT DeltaSeconds); + void GetChildAtoms(INT ChildIndex, FBoneAtomArray& Atoms, const TArray& DesiredBones, FBoneAtom& RootMotionDelta, INT& bHasRootMotion, FCurveKeyArray& CurveKeys); + virtual void GetBoneAtoms(FBoneAtomArray& Atoms, const TArray& DesiredBones, FBoneAtom& RootMotionDelta, INT& bHasRootMotion, FCurveKeyArray& CurveKeys); +} + +/** + * Overridden so we can keep child zero weight at 1. + */ +native function SetBlendTarget( float BlendTarget, float BlendTime ); + +defaultproperties +{ + bPassThroughWhenNotRendered=TRUE + bFixNumChildren=TRUE + Children(0)=(Name="Base Anim Input",Weight=1.f) + Children(1)=(Name="Additive Anim Input",Weight=1.f) + Child2Weight=1.f + Child2WeightTarget=1.f + + CategoryDesc = "Additive" +} diff --git a/Engine/Classes/AnimNodeAimOffset.uc b/Engine/Classes/AnimNodeAimOffset.uc new file mode 100644 index 0000000..abd4873 --- /dev/null +++ b/Engine/Classes/AnimNodeAimOffset.uc @@ -0,0 +1,255 @@ + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AnimNodeAimOffset extends AnimNodeBlendBase + native(Anim) + hidecategories(Object); + +/** + * 9 control points range: + * + * Left Center Right + * + * LU CU RU Up + * LC CC RC Center + * LD CD RD Down + */ +struct immutablewhencooked native AimTransform +{ + var() Quat Quaternion; + var() Vector Translation; +}; + + +/** + * definition of an AimComponent. + */ +struct immutablewhencooked native AimComponent +{ + /** Bone transformed */ + var() Name BoneName; + + /** Left column */ + var() AimTransform LU; + var() AimTransform LC; + var() AimTransform LD; + + /** Center */ + var() AimTransform CU; + var() AimTransform CC; + var() AimTransform CD; + + /** Right */ + var() AimTransform RU; + var() AimTransform RC; + var() AimTransform RD; +}; + + + +/** Handy enum for working with directions. */ +enum EAnimAimDir +{ + ANIMAIM_LEFTUP, + ANIMAIM_CENTERUP, + ANIMAIM_RIGHTUP, + ANIMAIM_LEFTCENTER, + ANIMAIM_CENTERCENTER, + ANIMAIM_RIGHTCENTER, + ANIMAIM_LEFTDOWN, + ANIMAIM_CENTERDOWN, + ANIMAIM_RIGHTDOWN +}; + +/** Convert Aim(X,Y) into a an enum that we use for blending into the main loop. */ +enum EAimID +{ + EAID_LeftUp, + EAID_LeftDown, + EAID_RightUp, + EAID_RightDown, + EAID_ZeroUp, + EAID_ZeroDown, + EAID_ZeroLeft, + EAID_ZeroRight, + EAID_CellLU, + EAID_CellCU, + EAID_CellRU, + EAID_CellLC, + EAID_CellCC, + EAID_CellRC, + EAID_CellLD, + EAID_CellCD, + EAID_CellRD, +}; + +/** Angle of aiming, between -1..+1 */ +var() Vector2d Aim; + +/** Angle offset applied to Aim before processing */ +var() Vector2d AngleOffset; + +/** If true, ignore Aim, and use the ForcedAimDir enum instead to determine which aim direction to draw. */ +var() bool bForceAimDir; + +/** If the LOD of this skeletal mesh is at or above this LOD, then this node will do nothing. */ +var(Performance) int PassThroughAtOrAboveLOD; + +/** If bForceAimDir is true, this is the direction to render the character aiming in. */ +var() EAnimAimDir ForcedAimDir; + +/** Internal, array of required bones. Selected bones and their parents for local to component space transformation. */ +var transient Array RequiredBones; +/** Look Up Table for AimCpnt Indices */ +var transient Array AimCpntIndexLUT; + +/** + * Pointer to AimOffset node in package (AnimTreeTemplate), to avoid duplicating profile data. + * Always NULL in AimOffset Editor (in ATE). + */ +var transient AnimNodeAimOffset TemplateNode; + +/** Bake offsets from animations. */ +var() bool bBakeFromAnimations; + +struct immutablewhencooked native AimOffsetProfile +{ + /** Name of this aim-offset profile. */ + var() const editconst name ProfileName; + + /** Maximum horizontal range (min, max) for horizontal aiming. */ + var() Vector2d HorizontalRange; + + /** Maximum horizontal range (min, max) for vertical aiming. */ + var() Vector2d VerticalRange; + + /** + * Array of AimComponents. + * Represents the selected bones and their transformations. + */ + var Array AimComponents; + + /** + * Names of animations to use when automatically generating offsets based animations for each direction. + * Animations are not actually used in-game - just for editor. + */ + var() Name AnimName_LU; + var() Name AnimName_LC; + var() Name AnimName_LD; + var() Name AnimName_CU; + var() Name AnimName_CC; + var() Name AnimName_CD; + var() Name AnimName_RU; + var() Name AnimName_RC; + var() Name AnimName_RD; + + structdefaultproperties + { + ProfileName="Default" + HorizontalRange=(X=-1,Y=+1) + VerticalRange=(X=-1,Y=+1) + } +}; + +/** Array of different aiming 'profiles' */ +var() editfixedsize array Profiles; + +/** + * Index of currently active Profile. + * Use the SetActiveProfileByName or SetActiveProfileByIndex function to change. +*/ +var() const editconst int CurrentProfileIndex; + +/** + * if TRUE, pass through (skip additive animation blending) when mesh is not rendered + */ +var(Performance) bool bPassThroughWhenNotRendered; +/** When moving the slider, keep nodes with same property in sync. */ +var(Editor) bool bSynchronizeNodesInEditor; + +cpptext +{ + // UObject interface + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + /** Deferred Initialization, called only when the node is relevant in the tree. */ + virtual void DeferredInitAnim(); + + /** Used to save pointer to AimOffset node in package, to avoid duplicating profile data. */ + virtual void PostAnimNodeInstance(UAnimNode* SourceNode, TMap& SrcToDestNodeMap); + + /** returns current aim. Override this to pull information from somewhere else, like Pawn actor for example. */ + virtual FVector2D GetAim() { return Aim; } + + virtual void GetBoneAtoms(FBoneAtomArray& Atoms, const TArray& DesiredBones, FBoneAtom& RootMotionDelta, INT& bHasRootMotion, FCurveKeyArray& CurveKeys); + + /** + * Function called after Aim has been extracted and processed (offsets, range, clamping...). + * Gives a chance to PostProcess it before being used by the AimOffset Node. + * Note that X,Y range should remain [-1,+1]. + */ + virtual void PostAimProcessing(FVector2D &AimOffsetPct) {} + + /** Util for getting the current AimOffsetProfile. */ + FAimOffsetProfile* GetCurrentProfile(); + + /** Update cached list of required bones, use to transform skeleton from parent space to component space. */ + void UpdateListOfRequiredBones(); + + /** Returns TRUE if AimComponents contains specified bone */ + UBOOL ContainsBone(const FName &BoneName); + + /** Util for grabbing the quaternion on a specific bone in a specific direction. */ + FQuat GetBoneAimQuaternion(INT CompIndex, EAnimAimDir InAimDir); + /** Util for grabbing the translation on a specific bone in a specific direction. */ + FVector GetBoneAimTranslation(INT CompIndex, EAnimAimDir InAimDir); + + /** Util for setting the quaternion on a specific bone in a specific direction. */ + void SetBoneAimQuaternion(INT CompIndex, EAnimAimDir InAimDir, const FQuat & InQuat); + /** Util for setting the translation on a specific bone in a specific direction. */ + void SetBoneAimTranslation(INT CompIndex, EAnimAimDir InAimDir, FVector InTrans); + + /** Bake in Offsets from supplied Animations. */ + void BakeOffsetsFromAnimations(); + void ExtractOffsets(TArray& RefBoneAtoms, TArray& BoneAtoms, EAnimAimDir InAimDir); + INT GetComponentIdxFromBoneIdx(const INT BoneIndex, UBOOL bCreateIfNotFound=0); + /** + * Extract Parent Space Bone Atoms from Animation Data specified by Name. + * Returns TRUE if successful. + */ + UBOOL ExtractAnimationData(UAnimNodeSequence *SeqNode, FName AnimationName, TArray& BoneAtoms); + + // For slider support + virtual INT GetNumSliders() const { return 1; } + virtual ESliderType GetSliderType(INT InIndex) const { return ST_2D; } + virtual FLOAT GetSliderPosition(INT SliderIndex, INT ValueIndex); + virtual void HandleSliderMove(INT SliderIndex, INT ValueIndex, FLOAT NewSliderValue); + virtual void SynchronizeNodesInEditor(); + virtual FString GetSliderDrawValue(INT SliderIndex); + + /** Utility functions to ease off Casting */ + virtual class UAnimNodeAimOffset* GetAnimNodeAimOffset() { return this; } +} + +/** + * Change the currently active profile to the one with the supplied name. + * If a profile with that name does not exist, this does nothing. + */ +native function SetActiveProfileByName(name ProfileName); + +/** + * Change the currently active profile to the one with the supplied index. + * If ProfileIndex is outside range, this does nothing. + */ +native function SetActiveProfileByIndex(int ProfileIndex); + +defaultproperties +{ + bSynchronizeNodesInEditor=TRUE + bPassThroughWhenNotRendered=FALSE + bFixNumChildren=TRUE + Children(0)=(Name="Input",Weight=1.0) + + ForcedAimDir=ANIMAIM_CENTERCENTER + PassThroughAtOrAboveLOD=1000 +} diff --git a/Engine/Classes/AnimNodeBlend.uc b/Engine/Classes/AnimNodeBlend.uc new file mode 100644 index 0000000..5b39a66 --- /dev/null +++ b/Engine/Classes/AnimNodeBlend.uc @@ -0,0 +1,48 @@ + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimNodeBlend extends AnimNodeBlendBase + native(Anim) + hidecategories(Object); + +var float Child2Weight; + +var float Child2WeightTarget; +var float BlendTimeToGo; // Seconds + +/** + * if TRUE, do not blend when the Skeletal Mesh is not visible. + * Optimization to save on blending time when meshes are not rendered. + * Instant switch instead. + */ +var() bool bSkipBlendWhenNotRendered; + +cpptext +{ + // AnimNode interface + virtual void TickAnim(FLOAT DeltaSeconds); + + virtual INT GetNumSliders() const { return 1; } + virtual FLOAT GetSliderPosition(INT SliderIndex, INT ValueIndex); + virtual void HandleSliderMove(INT SliderIndex, INT ValueIndex, FLOAT NewSliderValue); + virtual FString GetSliderDrawValue(INT SliderIndex); +} + +/** + * Set desired balance of this blend. + * + * @param BlendTarget Target amount of weight to put on Children(1) (second child). Between 0.0 and 1.0. + * 1.0 means take all animation from second child. + * @param BlendTime How long to take to get to BlendTarget. + */ +native function SetBlendTarget( float BlendTarget, float BlendTime ); + +defaultproperties +{ + Children(0)=(Name="Child1",Weight=1.0) + Children(1)=(Name="Child2") + bFixNumChildren=TRUE + bSkipBlendWhenNotRendered=TRUE +} diff --git a/Engine/Classes/AnimNodeBlendBase.uc b/Engine/Classes/AnimNodeBlendBase.uc new file mode 100644 index 0000000..b3075af --- /dev/null +++ b/Engine/Classes/AnimNodeBlendBase.uc @@ -0,0 +1,124 @@ + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimNodeBlendBase extends AnimNode + native(Anim) + hidecategories(Object) + abstract; + +/** Link to a child AnimNode. */ +struct native AnimBlendChild +{ + /** Name of link. */ + var() Name Name; + /** Child AnimNode. */ + var editinline export AnimNode Anim; + /** Weight with which this child will be blended in. Sum of all weights in the Children array must be 1.0 */ + var float Weight; + /** Weight used for blending. See AnimBlendType. */ + var const transient float BlendWeight; + /** + * Whether this child's skeleton should be mirrored. + * Do not use this lightly, mirroring is rather expensive. + * So minimize the number of times mirroring is done in the tree. + */ + var bool bMirrorSkeleton; + /** Is Children Additive Animation. */ + var bool bIsAdditive; + /** For editor use. */ + var editoronly int DrawY; +}; + +/** Array of children AnimNodes. These will be blended together and the results returned by GetBoneAtoms. */ +var editfixedsize editinline export array Children; + +/** Whether children connectors (ie elements of the Children array) may be added/removed. */ +var bool bFixNumChildren; +/** Type of animation blending. Affects how the weight interpolates. */ +var() AlphaBlendType BlendType; + +cpptext +{ + /** Call DeferredInitAnim() if the node required it. Recurses through the Tree. Increase UAnimNode::CurrentSeachTag before calling. */ + virtual void CallDeferredInitAnim(); + + // UAnimNode interface + virtual void TickAnim(FLOAT DeltaSeconds); + + virtual void BuildParentNodesArray(); + virtual void BuildTickArray(TArray& OutTickArray); + + FORCEINLINE FLOAT GetBlendWeight(FLOAT ChildWeight); + FORCEINLINE void SetBlendTypeWeights(); + virtual void GetBoneAtoms(FBoneAtomArray& Atoms, const TArray& DesiredBones, FBoneAtom& RootMotionDelta, INT& bHasRootMotion, FCurveKeyArray& CurveKeys); + virtual void GetChildBoneAtoms( INT ChildIdx, FBoneAtomArray& Atoms, const TArray& DesiredBones, FBoneAtom& RootMotionDelta, INT& bHasRootMotion, FCurveKeyArray& CurveKeys ); + + /** + * Get mirrored bone atoms from desired child index. + * Bones are mirrored using the SkelMirrorTable. + */ + void GetMirroredBoneAtoms(FBoneAtomArray& Atoms, INT ChildIndex, const TArray& DesiredBones, FBoneAtom& RootMotionDelta, INT& bHasRootMotion, FCurveKeyArray& CurveKeys); + + /** + * Draws this node in the AnimTreeEditor. + * + * @param Canvas The canvas to use. + * @param SelectedNodes Reference to array of all currently selected nodes, potentially including this node + * @param bShowWeight If TRUE, show the global percentage weight of this node, if applicable. + */ + virtual void DrawAnimNode(FCanvas* Canvas, const TArray& SelectedNodes, UBOOL bShowWeight); + virtual FString GetNodeTitle(); + + virtual FIntPoint GetConnectionLocation(INT ConnType, INT ConnIndex); + virtual INT Extend2DSlider(FCanvas* Canvas, const FIntPoint &SliderPos, INT SliderWidth, UBOOL bAABBLiesWithinViewport, INT LoSliderHandleHeight) { return 0; } + + /** For debugging. Return the sum of the weights of all children nodes. Should always be 1.0. */ + FLOAT GetChildWeightTotal(); + + /** Notification to this blend that a child UAnimNodeSequence has reached the end and stopped playing. Not called if child has bLooping set to true or if user calls StopAnim. */ + virtual void OnChildAnimEnd(UAnimNodeSequence* Child, FLOAT PlayedTime, FLOAT ExcessTime); + + /** A child connector has been added */ + virtual void OnAddChild(INT ChildNum); + /** A child connector has been removed */ + virtual void OnRemoveChild(INT ChildNum); + /** A child Anim has been modified*/ + virtual void OnChildAnimChange(INT ChildNum){}; + + /** Rename all child nodes upon Add/Remove, so they match their position in the array. */ + virtual void RenameChildConnectors(); + + /** internal code for GetNodes(); should only be called from GetNodes() or from the GetNodesInternal() of this node's parent */ + virtual void GetNodesInternal(TArray& Nodes); + + /** Called after (copy/)pasted - reset values or re-link if needed**/ + virtual void OnPaste(); + + /** + * Resolve conflicts for blend curve weights if same morph target exists + * + * @param InChildrenCurveKeys Array of curve keys for children. The index should match up with Children. + * @param OutCurveKeys Result output after blending is resolved + * + * @return Number of new addition to OutCurveKeys + */ + virtual INT BlendCurveWeights(const FArrayCurveKeyArray& InChildrenCurveKeys, FCurveKeyArray& OutCurveKeys); + +protected: + /** + * Update Child Weight : Make sure childIndex isn't OOB + */ + virtual void UpdateChildWeight(INT ChildIndex); +} + +native function PlayAnim(bool bLoop = false, float Rate = 1.0f, float StartTime = 0.0f); +native function StopAnim(); +// calls PlayAnim with the current settings +native function ReplayAnim(); + +defaultproperties +{ + BlendType=ABT_Linear +} diff --git a/Engine/Classes/AnimNodeBlendByBase.uc b/Engine/Classes/AnimNodeBlendByBase.uc new file mode 100644 index 0000000..551589d --- /dev/null +++ b/Engine/Classes/AnimNodeBlendByBase.uc @@ -0,0 +1,40 @@ + +/** + * AnimNodeBlendByBase.uc + * Looks at the base of the Pawn that owns this node and blends accordingly. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimNodeBlendByBase extends AnimNodeBlendList + native(Anim); + +cpptext +{ + virtual void TickAnim(FLOAT DeltaSeconds); +} + +enum EBaseBlendType +{ + BBT_ByActorTag, + BBT_ByActorClass, +}; + +/** Type of comparison to do */ +var() EBaseBlendType Type; +/** Actor tag that will match the base */ +var() Name ActorTag; +/** Actor class that will match the base */ +var() class ActorClass; +/** Duration of blend */ +var() float BlendTime; +/** Cached Base Actor */ +var transient Actor CachedBase; + +defaultproperties +{ + bFixNumChildren=TRUE + Children(0)=(Name="Normal") + Children(1)=(Name="Based") + BlendTime=0.2f +} diff --git a/Engine/Classes/AnimNodeBlendByPhysics.uc b/Engine/Classes/AnimNodeBlendByPhysics.uc new file mode 100644 index 0000000..79214f4 --- /dev/null +++ b/Engine/Classes/AnimNodeBlendByPhysics.uc @@ -0,0 +1,34 @@ +/** + * AnimNodeBlendByPhysics.uc + * Looks at the physics of the Pawn that owns this node and blends accordingly. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimNodeBlendByPhysics extends AnimNodeBlendList + native(Anim); + +cpptext +{ + virtual void TickAnim(FLOAT DeltaSeconds); +} + +defaultproperties +{ + bFixNumChildren=true + Children(0)=(Name="PHYS_None") + Children(1)=(Name="PHYS_Walking") + Children(2)=(Name="PHYS_Falling") + Children(3)=(Name="PHYS_Swimming") + Children(4)=(Name="PHYS_Flying") + Children(5)=(Name="PHYS_Rotating") + Children(6)=(Name="PHYS_Projectile") + Children(7)=(Name="PHYS_Interpolating") + Children(8)=(Name="PHYS_Spider") + Children(9)=(Name="PHYS_Ladder") + Children(10)=(Name="PHYS_RigidBody") + Children(11)=(Name="PHYS_SoftBody") + Children(12)=(Name="PHYS_NavMeshWalking") + Children(13)=(Name="PHYS_Unused") + Children(14)=(Name="PHYS_Custom") +} diff --git a/Engine/Classes/AnimNodeBlendByPosture.uc b/Engine/Classes/AnimNodeBlendByPosture.uc new file mode 100644 index 0000000..1f2461b --- /dev/null +++ b/Engine/Classes/AnimNodeBlendByPosture.uc @@ -0,0 +1,24 @@ +/** + * AnimNodeBlendByPosture.uc + * Looks at the posture of the Pawn that owns this node and blends accordingly. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimNodeBlendByPosture extends AnimNodeBlendList + native(Anim); + +/* + * Note: this is obsolete. This class is going to be removed soon. + */ + +cpptext +{ + virtual void TickAnim(FLOAT DeltaSeconds); +} + +defaultproperties +{ + Children(0)=(Name="Standing") + Children(1)=(Name="Crouched") +} diff --git a/Engine/Classes/AnimNodeBlendByProperty.uc b/Engine/Classes/AnimNodeBlendByProperty.uc new file mode 100644 index 0000000..411fd49 --- /dev/null +++ b/Engine/Classes/AnimNodeBlendByProperty.uc @@ -0,0 +1,66 @@ +/** + * AnimNodeBlendByProperty.uc + * Looks at a specific property of the Pawn and will blend between two inputs based on its value + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimNodeBlendByProperty extends AnimNodeBlendList + native(Anim); + +/** Property Name to look up */ +var() name PropertyName; +/** If Property should be looked up on the Owner's base instead of the Owner. */ +var() bool bUseOwnersBase; +/** Name of cached property. Used to detect changes and invalidating the cached property. */ +var transient name CachedPropertyName; +/** Cached property object pointer. Avoids slow FindField on a per tick basis, and cast. */ +var const transient native Pointer CachedFloatProperty{UFloatProperty}; +var const transient native Pointer CachedBoolProperty{UBoolProperty}; +var const transient native Pointer CachedByteProperty{UByteProperty}; +/** Force an update on the node */ +var const transient bool bForceUpdate; +/** Track Owner changes */ +var transient Actor CachedOwner; + +var() float BlendTime; +var() float FloatPropMin; +var() float FloatPropMax; + +/** Use BlendToChild1Time/BlendToChild2Time instead of BlendTime? */ +var() bool bUseSpecificBlendTimes; +var() float BlendToChild1Time; +var() float BlendToChild2Time; + +/** When moving the slider, keep nodes with same property in sync. */ +var(Editor) bool bSynchronizeNodesInEditor; + +cpptext +{ + virtual void InitAnim(USkeletalMeshComponent* MeshComp, UAnimNodeBlendBase* Parent); + virtual void TickAnim(FLOAT DeltaSeconds); + virtual FString GetNodeTitle(); + virtual void HandleSliderMove(INT SliderIndex, INT ValueIndex, FLOAT NewSliderValue); + /** Parent node is requesting a blend out. Give node a chance to delay that. */ + virtual UBOOL CanBlendOutFrom(); + /** parent node is requesting a blend in. Give node a chance to delay that. */ + virtual UBOOL CanBlendTo(); +} + +defaultproperties +{ + Children(0)=(Name="Child1") + Children(1)=(Name="Child2") + + bSynchronizeNodesInEditor=TRUE + bFixNumChildren=FALSE + bForceChildFullWeightWhenBecomingRelevant=FALSE + + BlendTime=0.1 + + BlendToChild1Time=0.1 + BlendToChild2Time=0.1 + + FloatPropMin=0.0 + FloatPropMax=1.0 +} diff --git a/Engine/Classes/AnimNodeBlendBySpeed.uc b/Engine/Classes/AnimNodeBlendBySpeed.uc new file mode 100644 index 0000000..64f47b5 --- /dev/null +++ b/Engine/Classes/AnimNodeBlendBySpeed.uc @@ -0,0 +1,65 @@ +/** + * AnimNodeBlendBySpeed + * + * Blends between child nodes based on the owners speed and the defined constraints. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AnimNodeBlendBySpeed extends AnimNodeBlendList + native(Anim); + +/** How fast they are moving this frame. */ +var float Speed; +/** Last Channel being used */ +var int LastChannel; +/** How fast to blend when going up */ +var() float BlendUpTime; +/** How fast to blend when going down */ +var() float BlendDownTime; +/** When should we start blending back down */ +var() float BlendDownPerc; +/** Weights/ constraints used for transition between child nodes */ +var() array Constraints; +/** Use acceleration instead of Velocity to determine speed */ +var() bool bUseAcceleration; +/** Optional delay before blending to the next channel */ +var() float BlendUpDelay, BlendDownDelay; +var transient float BlendDelayRemaining; + +cpptext +{ + // AnimNode interface + + /** + * Blend animations based on an Owner's velocity. + * + * @param DeltaSeconds Time since last tick in seconds. + */ + virtual void TickAnim(FLOAT DeltaSeconds); + + /** + * Resets the last channel on becoming active. + */ + virtual void OnBecomeRelevant(); + + virtual INT GetNumSliders() const { return 1; } + virtual FLOAT GetSliderPosition(INT SliderIndex, INT ValueIndex); + virtual void HandleSliderMove(INT SliderIndex, INT ValueIndex, FLOAT NewSliderValue); + virtual FString GetSliderDrawValue(INT SliderIndex); + + // AnimNodeBlendBySpeed interface + + /** + * Function called to calculate the speed that should be used for this node. + * Allows subclasses to easily modify the speed used. + */ + virtual FLOAT CalcSpeed(); +} + +defaultproperties +{ + BlendUpTime=0.1; + BlendDownTime=0.1; + BlendDownPerc=0.2; + Constraints=(0,180,350,900); +} diff --git a/Engine/Classes/AnimNodeBlendDirectional.uc b/Engine/Classes/AnimNodeBlendDirectional.uc new file mode 100644 index 0000000..3652bf5 --- /dev/null +++ b/Engine/Classes/AnimNodeBlendDirectional.uc @@ -0,0 +1,52 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +// This special blend node will use the LookDir and Acceleration from the Actor that +// owns the SkeletalMeshComponent to blend the four directional animations together. + +// TODO: This node could also 'lock' animation rate/phase together for its children (for cadence matching)? Should this be a general blender property? + +class AnimNodeBlendDirectional extends AnimNodeBlendBase + native(Anim) + hidecategories(Object); + +/** Allows control over how quickly the directional blend should be allowed to change. */ +var() float DirDegreesPerSecond; + +/** In radians. Between -PI and PI. 0.0 is running the way we are looking. */ +var float DirAngle; + +/** If the LOD for the mesh is at or above this LOD level, only use a single directional animation instead of blending. */ +var() int SingleAnimAtOrAboveLOD; + +/** Rotational offset to apply */ +var Rotator RotationOffset; + +/** Use acceleration instead of Velocity to determine speed */ +var() bool bUseAcceleration; + +cpptext +{ + // AnimNode interface + virtual void TickAnim(FLOAT DeltaSeconds); + + virtual INT GetNumSliders() const { return 1; } + virtual FLOAT GetSliderPosition(INT SliderIndex, INT ValueIndex); + virtual void HandleSliderMove(INT SliderIndex, INT ValueIndex, FLOAT NewSliderValue); + virtual FString GetSliderDrawValue(INT SliderIndex); +} + +defaultproperties +{ + Children(0)=(Name="Forward",Weight=1.0) + Children(1)=(Name="Backward") + Children(2)=(Name="Left") + Children(3)=(Name="Right") + bFixNumChildren=true + + DirDegreesPerSecond=360.0 + + SingleAnimAtOrAboveLOD=1000 + + CategoryDesc = "Directional" +} diff --git a/Engine/Classes/AnimNodeBlendList.uc b/Engine/Classes/AnimNodeBlendList.uc new file mode 100644 index 0000000..4cb54f3 --- /dev/null +++ b/Engine/Classes/AnimNodeBlendList.uc @@ -0,0 +1,79 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +// This class of blend node will ramp the 'active' child up to 1.0 + +class AnimNodeBlendList extends AnimNodeBlendBase + native(Anim) + hidecategories(Object); + +/** Array of target weights for each child. Size must be the same as the Children array. */ +var array TargetWeight; + +/** How long before current blend is complete (ie. active child reaches 100%) */ +var float BlendTimeToGo; + +/** Child currently active - that is, at or ramping up to 100%. */ +var INT ActiveChildIndex; + +/** Call play anim when active child is changed */ +var() bool bPlayActiveChild; + +/** + * If TRUE (Default), then when the node becomes relevant, the Active Child will be forced to full weight. + * This is a general optimization, as multiple nodes tend to change state at the same time, this will + * reduce the maximum number of blends and animation decompression done at the same time. + * Setting it to FALSE, will let the node interpolate animation normally. + */ +var(Performance) bool bForceChildFullWeightWhenBecomingRelevant; + +/** + * if TRUE, do not blend when the Skeletal Mesh is not visible. + * Optimization to save on blending time when meshes are not rendered. + * Instant switch instead. + */ +var(Performance) bool bSkipBlendWhenNotRendered; + +/** slider position, for animtree editor */ +var const float SliderPosition; + +/** ActiveChildIndex for use in editor only, to debug transitions */ +var() editoronly INT EditorActiveChildIndex; + +cpptext +{ + // UObject interface + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + // AnimNode interface + virtual void InitAnim( USkeletalMeshComponent* meshComp, UAnimNodeBlendBase* Parent ); + virtual void ResetAnimNodeToSource(UAnimNode *SourceNode); + virtual void TickAnim(FLOAT DeltaSeconds); + + // AnimTree editor interface + virtual INT GetNumSliders() const { return 1; } + virtual FLOAT GetSliderPosition(INT SliderIndex, INT ValueIndex); + virtual void HandleSliderMove(INT SliderIndex, INT ValueIndex, FLOAT NewSliderValue); + virtual FString GetSliderDrawValue(INT SliderIndex); + + // AnimNodeBlendBase interface + virtual void OnAddChild(INT ChildNum); + virtual void OnRemoveChild(INT ChildNum); + + // AnimNodeBlendList interface + /** Called after (copy/)pasted - reset values or re-link if needed**/ + virtual void OnPaste(); + +} + +native function SetActiveChild( INT ChildIndex, FLOAT BlendTime ); + +defaultproperties +{ + bSkipBlendWhenNotRendered=TRUE + bForceChildFullWeightWhenBecomingRelevant=TRUE + Children(0)=(Name="Child1") + bFixNumChildren=FALSE + + CategoryDesc = "BlendBy" +} diff --git a/Engine/Classes/AnimNodeBlendMultiBone.uc b/Engine/Classes/AnimNodeBlendMultiBone.uc new file mode 100644 index 0000000..5393118 --- /dev/null +++ b/Engine/Classes/AnimNodeBlendMultiBone.uc @@ -0,0 +1,77 @@ +/** + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + + +class AnimNodeBlendMultiBone extends AnimNodeBlendBase + native(Anim) + hidecategories(Object); + +struct native ChildBoneBlendInfo +{ + /** Weight scaling for each bone of the skeleton. Must be same size as RefSkeleton of SkeletalMesh. If all 0.0, no animation can ever be drawn from Child2. */ + var array TargetPerBoneWeight; + + /** Used in InitAnim, so you can set up partial blending in the defaultproperties. See SetTargetStartBone. */ + var() name InitTargetStartBone; + + /** Used in InitAnim, so you can set up partial blending in the defaultproperties. See SetTargetStartBone. */ + var() float InitPerBoneIncrease; + + // + // Internal variables + // + + /** Old StartBone, to monitor changes */ + var const name OldStartBone; + /** Old OldBoneIncrease, to monitor changes */ + var const float OldBoneIncrease; + + /** + * Indices of bones required from Target (at LOD 0), if Target's weight is >0.0. + * Bones are only in this array if their per-bone weight is >0.0 (or they have a child in the array). + * Indices should be strictly increasing. + */ + var transient array TargetRequiredBones; + + structdefaultproperties + { + InitPerBoneIncrease=1.0 + } +}; + +/** List of blend targets - one per bone to blend */ +var() array BlendTargetList; + +/** +* Indices of bones required from Source (at LOD 0), if Target's weight is 1.0. +* Bones are only in this array if their per-bone weight is <1.0 (or they have a child in the array). +* Indices should be strictly increasing. +*/ +var transient array SourceRequiredBones; + + +cpptext +{ + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + // AnimNode interface + virtual void InitAnim( USkeletalMeshComponent* meshComp, UAnimNodeBlendBase* Parent ); + virtual void GetBoneAtoms(FBoneAtomArray& Atoms, const TArray& DesiredBones, FBoneAtom& RootMotionDelta, INT& bHasRootMotion, FCurveKeyArray& CurveKeys); + + /** Utility for creating the TargetPerBoneWeight array. Starting from the named bone, walk down the heirarchy increasing the weight by PerBoneIncrease each step. */ + virtual void SetTargetStartBone( INT TargetIdx, FName StartBoneName, FLOAT PerBoneIncrease = 1.f ); +} + +/** Updating the StartBoneName or PerBoneIncrease, will cause the TargetPerBoneWeight to be automatically re-updated, you'll loose custom values! */ +//@todo - support opt. params +native noexport final function SetTargetStartBone( int TargetIdx, name StartBoneName, optional float PerBoneIncrease /* = 1.f */ ); + +defaultproperties +{ + Children(0)=(Name="Source",Weight=1.0) + Children(1)=(Name="Target") + + CategoryDesc = "Filter" +} diff --git a/Engine/Classes/AnimNodeBlendPerBone.uc b/Engine/Classes/AnimNodeBlendPerBone.uc new file mode 100644 index 0000000..cefa45c --- /dev/null +++ b/Engine/Classes/AnimNodeBlendPerBone.uc @@ -0,0 +1,45 @@ + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AnimNodeBlendPerBone extends AnimNodeBlend + native(Anim); + + +/** If TRUE, blend will be done in local space. */ +var() const bool bForceLocalSpaceBlend; + +/** List of branches to mask in from child2 */ +var() Array BranchStartBoneName; + +/** per bone weight list, built from list of branches. */ +var Array Child2PerBoneWeight; + +/** Required bones for local to component space conversion */ +var Array LocalToCompReqBones; + +cpptext +{ + /** Do any initialisation, and then call InitAnim on all children. Should not discard any existing anim state though. */ + virtual void InitAnim(USkeletalMeshComponent* meshComp, UAnimNodeBlendBase* Parent); + // AnimNode interface + virtual void TickAnim(FLOAT DeltaSeconds); + // AnimNode interface + virtual void GetBoneAtoms(FBoneAtomArray& Atoms, const TArray& DesiredBones, FBoneAtom& RootMotionDelta, INT& bHasRootMotion, FCurveKeyArray& CurveKeys); + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual void BuildWeightList(); +} + +/** + * Overridden so we can keep child zero weight at 1. + */ +native function SetBlendTarget( float BlendTarget, float BlendTime ); + +defaultproperties +{ + Children(0)=(Name="Source",Weight=1.0) + Children(1)=(Name="Target") + bFixNumChildren=TRUE + + CategoryDesc = "Filter" +} diff --git a/Engine/Classes/AnimNodeCrossfader.uc b/Engine/Classes/AnimNodeCrossfader.uc new file mode 100644 index 0000000..69774d0 --- /dev/null +++ b/Engine/Classes/AnimNodeCrossfader.uc @@ -0,0 +1,95 @@ +/** + * AnimNodeCrossfader + * This single node allows to crossfade between 2 animations through script control. + * A typical usage scenario would be to blend between 2 player idle animations. + * This blend requires 2 AnimNodeSequence as childs, you cannot connect 2 blends nor any other node types. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimNodeCrossfader extends AnimNodeBlend + native(Anim) + hidecategories(Object); + +cpptext +{ + // UAnimNode interface + virtual void InitAnim( USkeletalMeshComponent* meshComp, UAnimNodeBlendBase* Parent ); + virtual void TickAnim(FLOAT DeltaSeconds); +} + +// +// Exposed (script modifable) parameters +// + +/** default animation sequence played upon startup */ +var() name DefaultAnimSeqName; + +// +// Internal (C++) variables +// + +/** true if not blending out of the current one shot anim. Anim will just freeze at last frame */ +var const bool bDontBlendOutOneShot; + +/** Blend Out time for current One Shot anim */ +var const float PendingBlendOutTimeOneShot; + + +/** + * Play a One Shot animation. + * + * @param AnimSeqName Name of animation sequence to play + * @param BlendInTime time to blend from current animation to this (new) one. + * @param BlendOutTime time to blend from this animation (before it finishes playing) back to the previous one. + * @param bDontBlendOut if true, animation will freeze at last frame, and not blend back to the old one. + * @param Rate Playing rate of animation. + */ + +native noexport final function PlayOneShotAnim +( + name AnimSeqName, + optional float BlendInTime, + optional float BlendOutTime, + optional bool bDontBlendOut, + optional float Rate +); + + +/** + * Blend to a looping animation. + * + * @param AnimSeqName Name of animation sequence to play. + * @param BlendInTime time to blend from current animation to this (new) one. + * @param Rate Playing rate of animation. + */ + +native noexport final function BlendToLoopingAnim +( + name AnimSeqName, + optional float BlendInTime, + optional float Rate +); + + +/** + * Get Animation Name currently playing + * + * @return animation name currently being played. + */ + +native final function Name GetAnimName(); + + +/** + * Get active AnimNodeSequence child. To access animation properties and control functions. + * + * @return AnimNodeSequence currently playing. + */ + +native final function AnimNodeSequence GetActiveChild(); + + +defaultproperties +{ +} diff --git a/Engine/Classes/AnimNodeFrame.uc b/Engine/Classes/AnimNodeFrame.uc new file mode 100644 index 0000000..91fdf9a --- /dev/null +++ b/Engine/Classes/AnimNodeFrame.uc @@ -0,0 +1,84 @@ +/** + * This class is used for rendering a box around a group of kismet objects in the kismet editor, for organization + * and clarity. Corresponds to a "comment box" in the kismet editor. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AnimNodeFrame extends AnimObject + native(Anim); + +cpptext +{ +#if WITH_EDITOR + /** Draws the box part of the comment (including handle) */ + void DrawFrameBox(FCanvas* Canvas, UBOOL bSelected); + + /** + * Draws this node in the AnimTreeEditor. + * + * @param Canvas The canvas to use. + * @param SelectedNodes Reference to array of all currently selected nodes, potentially including this node + * @param bShowWeight If TRUE, show the global percentage weight of this node, if applicable. + */ + virtual void DrawNode(FCanvas* Canvas, const TArray& SelectedNodes, UBOOL bShowWeight); + +#endif +} + +/** Horizontal size of comment box in pixels. */ +var() int SizeX; + +/** Vertical size of comment box in pixels. */ +var() int SizeY; + +/** Width of border of comment box in pixels. */ +var() int BorderWidth; + +/** Should we draw a box for this comment object, or leave it just as text. */ +var() bool bDrawBox; + +/** If we are drawing a box, should it be filled, or just an outline. */ +var() bool bFilled; + +/** If bDrawBox and bFilled are true, and FillMaterial or FillTexture are true, should be tile it across the box or stretch to fit. */ +var() bool bTileFill; + +/** If we are drawing a box for this comment object, what colour should the border be. */ +var() color BorderColor; + +/** If bDrawBox and bFilled are true, what colour should the background be. */ +var() color FillColor; + +/** + * If bDrawBox and bFilled, you can optionally specify a texture to fill the box with. + * If both FillTexture and FillMaterial are specified, the FillMaterial will be used. + */ +var() editoronly Texture2D FillTexture; + +/** + * If bDrawBox and bFilled, you can optionally specify a material to fill the box with. + * If both FillTexture and FillMaterial are specified, the FillMaterial will be used. + */ +var() editoronly Material FillMaterial; + +var() editoronly String ObjComment; + +defaultproperties +{ + //bDrawFirst=true + //ObjName="Sequence Comment" + //ObjComment="Comment" + + SizeX=128 + SizeY=64 + + DrawWidth=128 + DrawHeight=64 + + BorderWidth=1 + bFilled=true + + FillColor=(R=255,G=255,B=255,A=16) + BorderColor=(R=0,G=0,B=0,A=255) + bDrawBox = true +} diff --git a/Engine/Classes/AnimNodeMirror.uc b/Engine/Classes/AnimNodeMirror.uc new file mode 100644 index 0000000..9ca35b7 --- /dev/null +++ b/Engine/Classes/AnimNodeMirror.uc @@ -0,0 +1,23 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AnimNodeMirror extends AnimNodeBlendBase + native(Anim) + hidecategories(Object); + +var() bool bEnableMirroring; + +cpptext +{ + virtual void GetBoneAtoms(FBoneAtomArray& Atoms, const TArray& DesiredBones, FBoneAtom& RootMotionDelta, INT& bHasRootMotion, FCurveKeyArray& CurveKeys); +} + +defaultproperties +{ + Children(0)=(Name="Child",Weight=1.0) + bFixNumChildren=true + + bEnableMirroring=true + + CategoryDesc = "Mirror" +} diff --git a/Engine/Classes/AnimNodePlayCustomAnim.uc b/Engine/Classes/AnimNodePlayCustomAnim.uc new file mode 100644 index 0000000..587cb4c --- /dev/null +++ b/Engine/Classes/AnimNodePlayCustomAnim.uc @@ -0,0 +1,152 @@ + +/** + * Gives code control to override an AnimTree branch, with a custom animation. + * . Normal branch is the normal tree branch (for example Human upper body). + * . Custom branch must be connected to an AnimNodeSequence. + * This node can then take over the upper body to play a cutom animation given various parameters. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AnimNodePlayCustomAnim extends AnimNodeBlend + DependsOn(AnimNodeSequence) + native(Anim); + +cpptext +{ + virtual void TickAnim(FLOAT DeltaSeconds); + + virtual INT GetNumSliders() const { return 0; } +}; + +/** True, when we're playing a custom animation */ +var bool bIsPlayingCustomAnim; +/** save blend out time when playing a one shot animation. */ +var float CustomPendingBlendOutTime; + + +/** + * Play a custom animation. + * Supports many features, including blending in and out. + * + * @param AnimName Name of animation to play. + * @param Rate Rate animation should be played at. + * @param BlendInTime Blend duration to play anim. + * @param BlendOutTime Time before animation ends (in seconds) to blend out. + * -1.f means no blend out. + * 0.f = instant switch, no blend. + * otherwise it's starting to blend out at AnimDuration - BlendOutTime seconds. + * @param bLooping Should the anim loop? (and play forever until told to stop) + * @param bOverride play same animation over again only if bOverride is set to true. + * + * @return PlayBack length of animation. + */ +final native function float PlayCustomAnim +( + name AnimName, + float Rate, + optional float BlendInTime, + optional float BlendOutTime, + optional bool bLooping, + optional bool bOverride +); + + +/** + * Play a custom animation. + * Auto adjusts the animation's rate to match a given duration in seconds. + * Supports many features, including blending in and out. + * + * @param AnimName Name of animation to play. + * @param Duration duration in seconds the animation should be played. + * @param BlendInTime Blend duration to play anim. + * @param BlendOutTime Time before animation ends (in seconds) to blend out. + * -1.f means no blend out. + * 0.f = instant switch, no blend. + * otherwise it's starting to blend out at AnimDuration - BlendOutTime seconds. + * @param bLooping Should the anim loop? (and play forever until told to stop) + * @param bOverride play same animation over again only if bOverride is set to true. + */ +final native function PlayCustomAnimByDuration +( + name AnimName, + float Duration, + optional float BlendInTime, + optional float BlendOutTime, + optional bool bLooping, + optional bool bOverride +); + + +/** + * Stop playing a custom animation. + * Used for blending out of a looping custom animation. + */ +final native function StopCustomAnim(float BlendOutTime); + + +/** + * Set Custom animation. + */ +final function SetCustomAnim(Name AnimName) +{ + local AnimNodeSequence SeqNode; + + SeqNode = AnimNodeSequence(Children[1].Anim); + if( SeqNode != None ) + { + SeqNode.SetAnim(AnimName); + } +} + + +/** Set bCauseActorAnimEnd flag */ +final function SetActorAnimEndNotification(bool bNewStatus) +{ + local AnimNodeSequence SeqNode; + + SeqNode = AnimNodeSequence(Children[1].Anim); + if( SeqNode != None ) + { + SeqNode.bCauseActorAnimEnd = bNewStatus; + } +} + + +/** Returns AnimNodeSequence playing the custom animation */ +final function AnimNodeSequence GetCustomAnimNodeSeq() +{ + return AnimNodeSequence(Children[1].Anim); +} + + +/** + * Set custom animation root bone options. + */ +final function SetRootBoneAxisOption +( + optional ERootBoneAxis AxisX = RBA_Default, + optional ERootBoneAxis AxisY = RBA_Default, + optional ERootBoneAxis AxisZ = RBA_Default +) +{ + local AnimNodeSequence AnimSeq; + + AnimSeq = GetCustomAnimNodeSeq(); + if( AnimSeq != None ) + { + AnimSeq.SetRootBoneAxisOption(AxisX, AxisY, AxisZ); + } + else + { + `Warn(GetFuncName() @ "Custom AnimNodeSequence not found for" @ Self); + } +} + + +defaultproperties +{ + NodeName="CustomAnim" + bFixNumChildren=TRUE + Children(0)=(Name="Normal") + Children(1)=(Name="Custom") +} diff --git a/Engine/Classes/AnimNodeRandom.uc b/Engine/Classes/AnimNodeRandom.uc new file mode 100644 index 0000000..7af046c --- /dev/null +++ b/Engine/Classes/AnimNodeRandom.uc @@ -0,0 +1,72 @@ + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimNodeRandom extends AnimNodeBlendList + native(Anim) + hidecategories(Object); + +cpptext +{ + virtual void TickAnim(FLOAT DeltaSeconds); + virtual void InitAnim( USkeletalMeshComponent* meshComp, UAnimNodeBlendBase* Parent ); + /** A child has been added, update RandomInfo accordingly */ + virtual void OnAddChild(INT ChildNum); + /** A child has been removed, update RandomInfo accordingly */ + virtual void OnRemoveChild(INT ChildNum); + + /** Notification to this blend that a child UAnimNodeSequence has reached the end and stopped playing. Not called if child has bLooping set to true or if user calls StopAnim. */ + virtual void OnChildAnimEnd(UAnimNodeSequence* Child, FLOAT PlayedTime, FLOAT ExcessTime); + + /** Notification when node becomes relevant. */ + virtual void OnBecomeRelevant(); + + INT PickNextAnimIndex(); + void PlayPendingAnimation(FLOAT BlendTime=0.f, FLOAT StartTime=0.f); +} + +struct native RandomAnimInfo +{ + /** Chance this child will be selected */ + var() float Chance; + /** Minimum number of loops to play this animation */ + var() Byte LoopCountMin; + /** Maximum number of loops to play this animation */ + var() Byte LoopCountMax; + /** Blend in time for this child */ + var() float BlendInTime; + /** Animation Play Rate Scale */ + var() Vector2D PlayRateRange; + /** If it's a still frame, don't play animation. Just randomly pick one, and stick to it until we lose focus */ + var() bool bStillFrame; + + /** Number of loops left to play for this round */ + var transient byte LoopCount; + /** Keep track of last position */ + var transient float LastPosition; + + structdefaultproperties + { + Chance=1.f + LoopCountMin=0 + LoopCountMax=0 + BlendInTime=0.25f + PlayRateRange=(X=1.f,Y=1.f) + } +}; + +var() editfixedsize editinline Array RandomInfo; + +/** Pointer to AnimNodeSequence currently playing random animation. */ +var transient AnimNodeSequence PlayingSeqNode; +var transient INT PendingChildIndex; +var transient bool bPickedPendingChildIndex; + +defaultproperties +{ + ActiveChildIndex=-1 + PendingChildIndex=-1 + + CategoryDesc = "Random" +} diff --git a/Engine/Classes/AnimNodeScalePlayRate.uc b/Engine/Classes/AnimNodeScalePlayRate.uc new file mode 100644 index 0000000..57b68d8 --- /dev/null +++ b/Engine/Classes/AnimNodeScalePlayRate.uc @@ -0,0 +1,22 @@ + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AnimNodeScalePlayRate extends AnimNodeBlendBase + native(Anim) + hidecategories(Object); + +var() float ScaleByValue; + +cpptext +{ + virtual void TickAnim(FLOAT DeltaSeconds); + virtual FLOAT GetScaleValue(); +} + +defaultproperties +{ + Children(0)=(Name="Input",Weight=1.0) + bFixNumChildren=TRUE + ScaleByValue=1 +} diff --git a/Engine/Classes/AnimNodeScaleRateBySpeed.uc b/Engine/Classes/AnimNodeScaleRateBySpeed.uc new file mode 100644 index 0000000..474aa3c --- /dev/null +++ b/Engine/Classes/AnimNodeScaleRateBySpeed.uc @@ -0,0 +1,19 @@ + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AnimNodeScaleRateBySpeed extends AnimNodeScalePlayRate + native(Anim) + hidecategories(Object); + +var() float BaseSpeed; + +cpptext +{ + virtual FLOAT GetScaleValue(); +} + +defaultproperties +{ + BaseSpeed=350 +} diff --git a/Engine/Classes/AnimNodeSequence.uc b/Engine/Classes/AnimNodeSequence.uc new file mode 100644 index 0000000..16cb276 --- /dev/null +++ b/Engine/Classes/AnimNodeSequence.uc @@ -0,0 +1,338 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AnimNodeSequence extends AnimNode + native(Anim) + hidecategories(Object); + +/** This name will be looked for in all AnimSet's specified in the AnimSets array in the SkeletalMeshComponent. */ +var() const name AnimSeqName; + +/** Speed at which the animation will be played back. Multiplied by the RateScale in the AnimSequence. Default is 1.0 */ +var() float Rate; + +/** Whether this animation is currently playing ie. if the CurrentTime will be advanced when Tick is called. */ +var() bool bPlaying; + +/** If animation is looping. If false, animation will stop when it reaches end, otherwise will continue from beginning. */ +var() bool bLooping; + +/** Should this node call the OnAnimEnd event on its parent Actor when it reaches the end and stops. */ +var() bool bCauseActorAnimEnd; + +/** Should this node call the OnAnimPlay event on its parent Actor when PlayAnim is called on it. */ +var() bool bCauseActorAnimPlay; + +/** Always return a zero rotation (unit quaternion) for the root bone of this animation. */ +var() bool bZeroRootRotation; +/** Always return root bone translation at the origin. */ +var() bool bZeroRootTranslation; +/** if TRUE, don't display a warning when animation is not found. */ +var() bool bDisableWarningWhenAnimNotFound; + +/** Current position (in seconds) */ +var() const float CurrentTime; +// Keep track of where animation was at before being ticked +var const transient float PreviousTime; + +/** This is the time at which to end the anim. Example: You have a 10 second anim where you just want a portion of the anim! Great for prototyping! */ +var const transient float EndTime; + +/** Pointer to actual AnimSequence. Found from SkeletalMeshComponent using AnimSeqName when you call SetAnim. */ +var transient const AnimSequence AnimSeq; + +/** Bone -> Track mapping info for this player node. Index into the LinkupCache array in the AnimSet. Found from AnimSet when you call SetAnim. */ +var transient const int AnimLinkupIndex; + +/** + * Total weight that this node must be at in the final blend for notifies to be executed. + * This is ignored when the node is part of a group. + */ +var() float NotifyWeightThreshold; +/** Whether any notifies in the animation sequence should be executed for this node. */ +var() bool bNoNotifies; +/** Forces the skeletal mesh into the ref pose by setting bForceRespose on the skelmesh comp when not playing. (Optimization) */ +var() bool bForceRefposeWhenNotPlaying; +/** + * Flag that indicates if Notifies are currently being executed. + * Allows you to avoid doing dangerous things to this Node while this is going on. + */ +var bool bIsIssuingNotifies; + +/** name of group this node belongs to */ +var(Group) const Name SynchGroupName; +/** If TRUE, this node can never be a synchronization master node, always slave. */ +var(Group) bool bForceAlwaysSlave; + +/** + * TRUE by default. This node can be synchronized with others, when part of a SynchGroup. + * Set to FALSE if node shouldn't be synchronized, but still part of notification group. + */ +var(Group) const bool bSynchronize; +/** Relative position offset. */ +var(Group) float SynchPosOffset; +/** Reverse synchronization. Go in opposite direction. */ +var(Group) const bool bReverseSync; + +/** Display time line slider */ +var(Display) bool bShowTimeLineSlider; + +/** Reference to the CameraAnim to play in conjunction with this animation. */ +var(Camera) CameraAnim CameraAnim; +/** Ref to the CameraAnimInst that is currently playing. */ +var transient CameraAnimInst ActiveCameraAnimInstance; +/** True to loop the CameraAnim, false for a one-off. */ +var(Camera) bool bLoopCameraAnim; +/** True to randomize the CameraAnims start position, so it doesn't look the same every time. Ignored if bLoopCameraAnim is false. */ +var(Camera) bool bRandomizeCameraAnimLoopStartTime; +/** "Intensity" multiplier applied to the camera anim. */ +var(Camera) float CameraAnimScale; +/** How fast to playback the camera anim. */ +var(Camera) float CameraAnimPlayRate; +/** How long to blend in the camera anim. */ +var(Camera) float CameraAnimBlendInTime; +/** How long to blend out the camera anim. */ +var(Camera) float CameraAnimBlendOutTime; + +/** + * This will actually call MoveActor to move the Actor owning this SkeletalMeshComponent. + * You can specify the behaviour for each axis (mesh space). + * Doing this for multiple skeletal meshes on the same Actor does not make much sense! + */ +enum ERootBoneAxis +{ + /** the default behaviour, leave root translation from animation and do no affect owning Actor movement. */ + RBA_Default, + /** discard any root bone movement, locking it to the first frame's location. */ + RBA_Discard, + /** discard root movement on animation, and forward its velocity to the owning actor. */ + RBA_Translate, +}; + +var() const ERootBoneAxis RootBoneOption[3]; // [X, Y, Z] axes + +/** + * Root Motion Rotation. + */ +enum ERootRotationOption +{ + /** Default, leaves root rotation in the animation. Does not affect actor. */ + RRO_Default, + /** Discards root rotation from the animation, locks to first frame rotation of animation. Does not affect actor's rotation. */ + RRO_Discard, + /** Discard root rotation from animation, and forwards it to the actor. (to be used by it or not). */ + RRO_Extract, +}; + +var() const ERootRotationOption RootRotationOption[3]; // Roll (X), Pitch (Y), Yaw (Z) axes. + +/** + * EDITOR ONLY + * Add Ref Pose to Additive Animation, so it can be viewed fully into the AnimSetViewer. + */ +var const bool bEditorOnlyAddRefPoseToAdditiveAnimation; + +/** List of SkelControl controlled by MetaData */ +var const transient Array MetaDataSkelControlList; + +/** This allows up to return from FinishAnim on blendout when wanted */ +var transient bool bCheckForFinishAnimEarly; +/** only setup to work with AnimNodeSlot and FinishAnim right now */ +var transient bool bBlendingOut; + +cpptext +{ +protected: + // Internal + /** Returns the camera associated with the skelmesh's owner, if any. */ + ACamera* GetPlayerCamera() const; + +public: + // UObject interface + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual void BeginDestroy(); + + // AnimNode interface + virtual void InitAnim( USkeletalMeshComponent* meshComp, UAnimNodeBlendBase* Parent ); + /** Deferred Initialization, called only when the node is relevant in the tree. */ + virtual void DeferredInitAnim(); + virtual void ResetAnimNodeToSource(UAnimNode *SourceNode); + virtual UBOOL GetCachedResults(FBoneAtomArray& OutAtoms, FBoneAtom& OutRootMotionDelta, INT& bOutHasRootMotion, FCurveKeyArray& OutCurveKeys, INT NumDesiredBones); + virtual UBOOL ShouldSaveCachedResults(); + void ConditionalClearCachedData(); + /** + * Whether we should keep the cached result for the next frame or not + * This is to avoid keeping cached result on memory once it ticks. + * It will release cache result if this returns FALSE + **/ + virtual UBOOL ShouldKeepCachedResult(); + + /** AnimSets have been updated, update all animations */ + virtual void AnimSetsUpdated(); + + virtual void TickAnim(FLOAT DeltaSeconds); // Progress the animation state, issue AnimEnd notifies. + virtual void GetBoneAtoms(FBoneAtomArray& Atoms, const TArray& DesiredBones, FBoneAtom& RootMotionDelta, INT& bHasRootMotion, FCurveKeyArray& CurveKeys); + + /** + * Draws this node in the AnimTreeEditor. + * + * @param Canvas The canvas to use. + * @param SelectedNodes Reference to array of all currently selected nodes, potentially including this node + * @param bShowWeight If TRUE, show the global percentage weight of this node, if applicable. + */ + virtual void DrawAnimNode(FCanvas* Canvas, const TArray& SelectedNodes, UBOOL bShowWeight); + virtual FString GetNodeTitle(); + + // AnimNodeSequence interface + void GetAnimationPose(UAnimSequence* InAnimSeq, INT& InAnimLinkupIndex, FBoneAtomArray& Atoms, const TArray& DesiredBones, FBoneAtom& RootMotionDelta, INT& bHasRootMotion, FCurveKeyArray& CurveKeys); + + // Extract root motion for animation using a specified start and end time + void ExtractRootMotionUsingSpecifiedTimespan (UAnimSequence* InAnimSeq, const INT &TrackIndex, FBoneAtom& RootBoneAtom, FBoneAtom& RootBoneAtomDeltaMotion, INT& bHasRootMotion, FLOAT StartTime, FLOAT EndTime) const; + + /** + * Extract Root Motion for the current Animation Pose. + */ + inline virtual void ExtractRootMotion (UAnimSequence* InAnimSeq, const INT &TrackIndex, FBoneAtom& RootBoneAtom, FBoneAtom& RootBoneAtomDeltaMotion, INT& bHasRootMotion) + { + ExtractRootMotionUsingSpecifiedTimespan(InAnimSeq, TrackIndex, RootBoneAtom, RootBoneAtomDeltaMotion, bHasRootMotion, PreviousTime, CurrentTime); + } + + /** Advance animation time. Take care of issuing notifies, looping and so on */ + void AdvanceBy(FLOAT MoveDelta, FLOAT DeltaSeconds, UBOOL bFireNotifies); + + /** Issue any notifies that are passed when moving from the current position to DeltaSeconds in the future. Called from TickAnim. */ + void IssueNotifies(FLOAT DeltaSeconds); + + /** Allow negative play rates and still get animnotifies$$$**/ + void IssueNegativeRateNotifies(FLOAT DeltaSecond); + + /** + * notification that current animation has reached the end (will be called even if it loops, unlike OnAnimEnd) + * @param PlayedTime Time in seconds of animation played. (play rate independant). + * @param ExcessTime Time in seconds beyond end of animation. (play rate independant). + */ + virtual void OnAnimComplete( FLOAT PlayedTime, FLOAT ExcessTime ) {} + + /** + * notification that current animation finished playing. + * @param PlayedTime Time in seconds of animation played. (play rate independant). + * @param ExcessTime Time in seconds beyond end of animation. (play rate independant). + */ + virtual void OnAnimEnd(FLOAT PlayedTime, FLOAT ExcessTime); + + // AnimTree editor interface + virtual INT GetNumSliders() const { return bShowTimeLineSlider ? 1 : 0; } + virtual FLOAT GetSliderPosition(INT SliderIndex, INT ValueIndex); + virtual void HandleSliderMove(INT SliderIndex, INT ValueIndex, FLOAT NewSliderValue); + virtual FString GetSliderDrawValue(INT SliderIndex); + + /** Restart camera animations */ + virtual void OnBecomeRelevant(); + + /** Pause camera animations */ + virtual void OnCeaseRelevant(); + + /** Starts playing any camera anim we want to play in conjunction with this anim. */ + void StartCameraAnim(); + /** Stops playing any active camera anim playing in conjunction with this anim. */ + void StopCameraAnim(); + + /** Update animation usage **/ +#if !FINAL_RELEASE + virtual void UpdateAnimationUsage( FLOAT DeltaSeconds ); +#endif //#if !FINAL_RELEASE + + /** Initialize morph curve information **/ + void InitCurveData(); + +/** Utility functions to ease off Casting */ + virtual class UAnimNodeSequence* GetAnimNodeSequence() { return this; } +} + +/** Change the animation this node is playing to the new name. Will be looked up in owning SkeletaMeshComponent's AnimSets array. */ +native function SetAnim( name Sequence ); + +/** Start the current animation playing with the supplied parameters. */ +native function PlayAnim(bool bLoop = false, float InRate = 1.0f, float StartTime = 0.0f); + +/** Stop the current animation playing. CurrentTime will stay where it was. */ +native function StopAnim(); + +// calls PlayAnim with the current settings +native function ReplayAnim(); + +/** Force the animation to a particular time. NewTime is in seconds. */ +native function SetPosition(float NewTime, bool bFireNotifies); + +/** Get normalized position, from 0.f to 1.f. */ +native function float GetNormalizedPosition() const; + +/** + * Finds out normalized position of a synchronized node given a relative position of a group. + * Takes into account node's relative SynchPosOffset. + */ +native function float FindGroupRelativePosition(FLOAT GroupRelativePosition) const; +/** + * Finds out position of a synchronized node given a relative position of a group. + * Takes into account node's relative SynchPosOffset. + */ +native function float FindGroupPosition(FLOAT GroupRelativePosition) const; +/** + * Get relative position of a synchronized node. + * Taking into account node's relative offset. + */ +native function float GetGroupRelativePosition() const; + +/** Returns the global play rate of this animation. Taking into account all Rate Scales */ +native function float GetGlobalPlayRate(); + +/** Returns the duration (in seconds) of the current animation at the current play rate. Returns 0.0 if no animation. */ +native function float GetAnimPlaybackLength(); + +/** + * Returns in seconds the time left until the animation is done playing. + * This is assuming the play rate is not going to change. + */ +native function float GetTimeLeft(); + +/** + * Set custom animation root bone options. + */ +final native function SetRootBoneAxisOption +( + ERootBoneAxis AxisX = RBA_Default, + ERootBoneAxis AxisY = RBA_Default, + ERootBoneAxis AxisZ = RBA_Default + ); + +/** + * Set custom animation root rotation options. + */ +final native function SetRootBoneRotationOption +( + ERootRotationOption AxisX = RRO_Default, + ERootRotationOption AxisY = RRO_Default, + ERootRotationOption AxisZ = RRO_Default +); + + + +defaultproperties +{ + Rate=1.0 + NotifyWeightThreshold=0.0 + bSynchronize=TRUE + + RootBoneOption[0] = RBA_Default + RootBoneOption[1] = RBA_Default + RootBoneOption[2] = RBA_Default + + RootRotationOption[0]=RRO_Default + RootRotationOption[1]=RRO_Default + RootRotationOption[2]=RRO_Default + + CameraAnimPlayRate=1.f + CameraAnimScale=1.f + CameraAnimBlendInTime=0.2f + CameraAnimBlendOutTime=0.2f +} diff --git a/Engine/Classes/AnimNodeSequenceBlendBase.uc b/Engine/Classes/AnimNodeSequenceBlendBase.uc new file mode 100644 index 0000000..3dac309 --- /dev/null +++ b/Engine/Classes/AnimNodeSequenceBlendBase.uc @@ -0,0 +1,95 @@ + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * This class encapsulates a common interface to extract multiple animation data and blend it. + */ + +class AnimNodeSequenceBlendBase extends AnimNodeSequence + native(Anim) + abstract; + +/** + * Structure regrouping all we need to extract an animation. + */ +struct native AnimInfo +{ + /** Animation Name */ + var const Name AnimSeqName; + + /** + * Pointer to actual AnimSequence. + * Found from SkeletalMeshComponent using AnimSeqName when you call SetAnim. + */ + var transient const AnimSequence AnimSeq; + + /** + * Bone -> Track mapping info for this player node. + * Index into the LinkupCache array in the AnimSet. + * Found from AnimSet when you call SetAnim. + */ + var transient const int AnimLinkupIndex; +}; + + +/** + * Structure to define animation blending. + */ +struct native AnimBlendInfo +{ + /** Name of animation sequence*/ + var() Name AnimName; + + /** Animation info */ + var AnimInfo AnimInfo; + + /** Weight i the blend */ + var transient float Weight; +}; + +/** Array of animations to blend */ +var(Animations) editfixedsize editinline export Array Anims; + +cpptext +{ + // UObject interface + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + virtual void InitAnim(USkeletalMeshComponent* MeshComp, UAnimNodeBlendBase* Parent); + /** Deferred Initialization, called only when the node is relevant in the tree. */ + virtual void DeferredInitAnim(); + /** AnimSets have been updated, update all animations */ + virtual void AnimSetsUpdated(); + + /** make sure animations are up date */ + virtual void CheckAnimsUpToDate(); + + /** Lookup animation data for a given animation name */ + void SetAnimInfo(FName InSequenceName, FAnimInfo& InAnimInfo); + + /** Extract animations and do the blend. */ + virtual void GetBoneAtoms(FBoneAtomArray& Atoms, const TArray& DesiredBones, FBoneAtom& RootMotionDelta, INT& bHasRootMotion, FCurveKeyArray& CurveKeys); + + /** Update animation usage **/ + virtual void UpdateAnimationUsage( FLOAT DeltaSeconds ); + + /** Get AnimInfo total weight */ + FLOAT GetAnimInfoTotalWeight(); + + + /** + * Resolve conflicts for blend curve weights if same morph target exists + * + * @param InChildrenCurveKeys Array of curve keys for children. The index should match up with Children. + * @param OutCurveKeys Result output after blending is resolved + * + * @return Number of new addition to OutCurveKeys + */ + virtual INT BlendCurveWeights(const FArrayCurveKeyArray& InChildrenCurveKeys, FCurveKeyArray& OutCurveKeys); +} + +defaultproperties +{ + Anims(0)=(Weight=1.0) + Anims(1)=() +} \ No newline at end of file diff --git a/Engine/Classes/AnimNodeSequenceBlendByAim.uc b/Engine/Classes/AnimNodeSequenceBlendByAim.uc new file mode 100644 index 0000000..4450c1f --- /dev/null +++ b/Engine/Classes/AnimNodeSequenceBlendByAim.uc @@ -0,0 +1,74 @@ + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AnimNodeSequenceBlendByAim extends AnimNodeSequenceBlendBase + native(Anim) + hidecategories(Animations); + +/** Angle of aiming, between -1..+1 */ +var() Vector2d Aim; +/** Keep track if aim changed to force an update of the node */ +var transient const Vector2d PreviousAim; +var() Vector2d HorizontalRange; +var() Vector2d VerticalRange; + +/** Angle offset applied to Aim before processing */ +var() Vector2d AngleOffset; + +// +// Animations +// + +// Left +var() Name AnimName_LU; +var() Name AnimName_LC; +var() Name AnimName_LD; + +// Center +var() Name AnimName_CU; +var() Name AnimName_CC; +var() Name AnimName_CD; + +// Right +var() Name AnimName_RU; +var() Name AnimName_RC; +var() Name AnimName_RD; + +cpptext +{ + /** Override this function in a subclass, and return normalized Aim from Pawn. */ + virtual FVector2D GetAim(); + + // AnimNode interface + virtual void TickAnim(FLOAT DeltaSeconds); + + // For slider support + virtual INT GetNumSliders() const { return 1; } + virtual ESliderType GetSliderType(INT InIndex) const { return ST_2D; } + virtual FLOAT GetSliderPosition(INT SliderIndex, INT ValueIndex); + virtual void HandleSliderMove(INT SliderIndex, INT ValueIndex, FLOAT NewSliderValue); + virtual FString GetSliderDrawValue(INT SliderIndex); +} + +/** + * Makes sure animations are updated. + * If you're changing any of the AnimName_XX during game, call this function afterwards. + */ +native final function CheckAnimsUpToDate(); + +defaultproperties +{ + HorizontalRange=(X=-1,Y=+1) + VerticalRange=(X=-1,Y=+1) + + Anims(0)=(Weight=1.0) + Anims(1)=() + Anims(2)=() + Anims(3)=() + Anims(4)=() + Anims(5)=() + Anims(6)=() + Anims(7)=() + Anims(8)=() +} \ No newline at end of file diff --git a/Engine/Classes/AnimNodeSlot.uc b/Engine/Classes/AnimNodeSlot.uc new file mode 100644 index 0000000..d6174a6 --- /dev/null +++ b/Engine/Classes/AnimNodeSlot.uc @@ -0,0 +1,267 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * Slot for Matinee controlled Animation Trees. + * Each slot will be able to blend a defined number of channels (AnimNodeSequence connections). + */ + +class AnimNodeSlot extends AnimNodeBlendBase + native(Anim) + hidecategories(Object); + +/** True, when we're playing a custom animation */ +var const bool bIsPlayingCustomAnim; +/** save blend out time when playing a one shot animation. */ +var const FLOAT PendingBlendOutTime; +/** Child index playing a custom animation */ +var const INT CustomChildIndex; +/** Child currently active, being blended to */ +var const INT TargetChildIndex; +/** Array of target weights for each child. Size must be the same as the Children array. */ +var Array TargetWeight; +/** How long before current blend is complete (ie. target child reaches 100%) */ +var const FLOAT BlendTimeToGo; + +/** + * If TRUE (default), then forward the AnimEnd notification when we start blending out the animation. + * This usually improves transitions and blends, as we can start playing new animations as soon as this one + * starts blending out, as opposed to waiting until it is fully blended out. + * Setting this to FALSE, will trigger the standard behavior of triggering AnimEnd notifies when the animation is really done playing. + */ +var() bool bEarlyAnimEndNotify; + +/** + * if TRUE, do not blend when the Skeletal Mesh is not visible. + * Optimization to save on blending time when meshes are not rendered. + * Instant switch instead. + */ +var() bool bSkipBlendWhenNotRendered; + +/** If TRUE, Additive Animations override the source input. + * If FALSE, Additive Animations are added to source input. (DEFAULT) + */ +var() bool bAdditiveAnimationsOverrideSource; + +/** TRUE if current it's used by Matinee, InterpTrackAnimControl + * FALSE if not + */ +var const transient bool bIsBeingUsedByInterpGroup; + +/** allow bPauseAnims to be supported for this node type if we want */ +var() bool bDontAddToAlwaysTickArray; + +`if(`__TW_) +/** Prevent notifies from being triggered by anim blend children */ +var bool bNoNotifies; +`endif + +cpptext +{ + // AnimNode interface + virtual void InitAnim(USkeletalMeshComponent* MeshComp, UAnimNodeBlendBase* Parent); +#if __TW_ANIMATION_ + /** Deferred Initialization, called only when the node is relevant in the tree. */ + virtual void DeferredInitAnim(); +#endif + + /** Update position of given channel */ + virtual void MAT_SetAnimPosition(INT ChannelIndex, FName InAnimSeqName, FLOAT InPosition, UBOOL bFireNotifies, UBOOL bLooping, UBOOL bEnableRootMotion); + /** Update weight of channels */ + virtual void MAT_SetAnimWeights(const FAnimSlotInfo& SlotInfo); + /** Rename all child nodes upon Add/Remove, so they match their position in the array. */ + virtual void RenameChildConnectors(); + + // AnimNode interface + virtual void TickAnim(FLOAT DeltaSeconds); + virtual void GetBoneAtoms(FBoneAtomArray& Atoms, const TArray& DesiredBones, FBoneAtom& RootMotionDelta, INT& bHasRootMotion, FCurveKeyArray& CurveKeys); + + // AnimNodeBlendBase interface + virtual void OnAddChild(INT ChildNum); + virtual void OnRemoveChild(INT ChildNum); + /** A child Anim has been modified */ + virtual void OnChildAnimChange(INT ChildNum); + /** Child AnimNodeSequence hit end of animation */ + virtual void OnChildAnimEnd(UAnimNodeSequence* Child, FLOAT PlayedTime, FLOAT ExcessTime); + + virtual INT GetNumSliders() const { return 0; } + + /** + * When requested to play a new animation, we need to find a new child. + * We'd like to find one that is unused for smooth blending, + * but that may be a luxury that is not available. + */ + INT FindBestChildToPlayAnim(FName AnimToPlay, UBOOL bOverride); + + void SetActiveChild(INT ChildIndex, FLOAT BlendTime); + void UpdateWeightsForAdditiveAnimations(); + + /** Called after (copy/)pasted - reset values or re-link if needed**/ + virtual void OnPaste(); + + virtual void SelectedActiveSequence( UAnimNodeSequence* Seq ) {} + + /** Utility functions to ease off Casting */ + virtual class UAnimNodeSlot* GetAnimNodeSlot() { return this; } + + /** + * Clean up Slot Node Sequence Pool if used + * Called when world is cleaned up + */ + static void CleanUpSlotNodeSequencePool(); + + /** + * Release unused Sequence nodes if released + * Called before Tick is called, so that it doesn't leave any reference during tick + */ + static void FlushReleasedSequenceNodes(const USkeletalMeshComponent * SkelComp); + + /** + * Release unused Sequence nodes if released + * Called before Tick is called, so that it doesn't leave any reference during tick + */ + static void ReleaseSequenceNodes(const USkeletalMeshComponent * SkelComp); + + /** + * Release unused Sequence nodes if released + * Called before Tick is called, so that it doesn't leave any reference during tick + */ + static void PrintSlotNodeSequencePool(); + +protected: + /** + * Update Child Weight : Make sure childIndex isn't OOB + */ + virtual void UpdateChildWeight(INT ChildIndex); + + /** Make sure child exists **/ + void EnsureChildExists(INT ChildIndex, UBOOL bClaimOnly=FALSE); +} + +/** + * Play a custom animation. + * Supports many features, including blending in and out. + * + * @param AnimName Name of animation to play. + * @param Rate Rate animation should be played at. + * @param BlendInTime Blend duration to play anim. + * @param BlendOutTime Time before animation ends (in seconds) to blend out. + * -1.f means no blend out. + * 0.f = instant switch, no blend. + * otherwise it's starting to blend out at AnimDuration - BlendOutTime seconds. + * @param bLooping Should the anim loop? (and play forever until told to stop) + * @param bOverride play same animation over again only if bOverride is set to true. + * @param StartTime When to start the anim (e.g. start at 2 seconds into the anim) + * @param EndTime When to end the anim (e.g. end at 4 second into the anim) + * + * @return PlayBack length of animation. + */ +final native function float PlayCustomAnim +( + name AnimName, + float Rate, + optional float BlendInTime, + optional float BlendOutTime, + optional bool bLooping, + optional bool bOverride, + optional float StartTime, + optional float EndTime +); + + +/** + * Play a custom animation. + * Supports many features, including blending in and out. + * + * @param AnimName Name of animation to play. + * @param Duration duration in seconds the animation should be played. + * @param BlendInTime Blend duration to play anim. + * @param BlendOutTime Time before animation ends (in seconds) to blend out. + * -1.f means no blend out. + * 0.f = instant switch, no blend. + * otherwise it's starting to blend out at AnimDuration - BlendOutTime seconds. + * @param bLooping Should the anim loop? (and play forever until told to stop) + * @param bOverride play same animation over again only if bOverride is set to true. + * @return TRUE if animation is playing, FALSE if couldn't play it. + */ +final native function bool PlayCustomAnimByDuration +( + name AnimName, + float Duration, + optional float BlendInTime, + optional float BlendOutTime, + optional bool bLooping, + optional bool bOverride = TRUE +); + +/** Returns the Name of the currently played animation or '' otherwise. */ +final native function Name GetPlayedAnimation(); + +/** + * Stop playing a custom animation. + * Used for blending out of a looping custom animation. + */ +final native function StopCustomAnim(float BlendOutTime); + +/** + * Call this function to remove nodes from the AnimAlwaysTickArray so bPauseAnims will work, + * sets or clears the bDontAddToAlwaysTickArray + */ +final native function SetAllowPauseAnims(bool bSet); + +/** + * Switch currently played animation to another one. + */ +final native function SetCustomAnim(Name AnimName); + + +/** Set bCauseActorAnimEnd flag */ +final native function SetActorAnimEndNotification(bool bNewStatus); + +`if(`__TW_ANIMATION_) +/** Set NotifyWeightThreshold to prevent triggering notifies */ +final native function SetNotifyWeightThreshold(float Threshold); +`endif + +/** + * Returns AnimNodeSequence currently selected for playing animations. + * Note that calling PlayCustomAnim *may* change which node plays the animation. + * (Depending on the blend in time, and how many nodes are available, to provide smooth transitions. + */ +final native function AnimNodeSequence GetCustomAnimNodeSeq(); + + +/** + * Set custom animation root bone options. + */ +final native function SetRootBoneAxisOption +( + optional ERootBoneAxis AxisX = RBA_Default, + optional ERootBoneAxis AxisY = RBA_Default, + optional ERootBoneAxis AxisZ = RBA_Default + ); + +/** + * Set custom animation root rotation options. + */ +final native function SetRootBoneRotationOption +( + optional ERootRotationOption AxisX = RRO_Default, + optional ERootRotationOption AxisY = RRO_Default, + optional ERootRotationOption AxisZ = RRO_Default +); + +/* Advance time regarding child weights */ +final native function TickChildWeights(FLOAT DeltaSeconds); + +defaultproperties +{ + bAdditiveAnimationsOverrideSource=FALSE + bSkipBlendWhenNotRendered=FALSE // Should be investigated before turning back on. TTP #153546 + bEarlyAnimEndNotify=TRUE + TargetWeight(0)=1.f + Children(0)=(Name="Source",Weight=1.0) + Children(1)=(Name="Channel 01") + bFixNumChildren=FALSE + + NodeName="SlotName" +} diff --git a/Engine/Classes/AnimNodeSynch.uc b/Engine/Classes/AnimNodeSynch.uc new file mode 100644 index 0000000..f418218 --- /dev/null +++ b/Engine/Classes/AnimNodeSynch.uc @@ -0,0 +1,72 @@ + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * Animation Node used to synch childs. + * Would be typically used to synch several walk/run/crouch cycles together. + * + * This node works by using the most relevant node in the final blend as the master node, + * to update all the others (slaves). + * This requires all cycles to be relatively synched (i.e. left foot is down on all cycles at 0.25% of the animation, regarless of its length). + */ + +class AnimNodeSynch extends AnimNodeBlendBase + native(Anim); + +/** definition of a group of AnimNodeSequence to synchronize together */ +struct native SynchGroup +{ + /** Cached array of anim node sequence nodes to synchronize */ + var Array SeqNodes; + /** Last master node used, do not search for a new one, if this one has a full weight... */ + var transient AnimNodeSequence MasterNode; + /** Name of group. */ + var() Name GroupName; + /** If FALSE, do not trigger slave nodes notifies. */ + var() bool bFireSlaveNotifies; + /** Rate Scale */ + var() float RateScale; + + structdefaultproperties + { + RateScale=1.f + } +}; + + +/** List of groups to synchronize */ +var() Array Groups; + +cpptext +{ + virtual void InitAnim(USkeletalMeshComponent* MeshComp, UAnimNodeBlendBase* Parent); + virtual void TickAnim(FLOAT DeltaSeconds); + + void UpdateMasterNodeForGroup(FSynchGroup& SynchGroup); + void RepopulateGroups(); +} + + +/** Add a node to an existing group */ +native final function AddNodeToGroup(AnimNodeSequence SeqNode, Name GroupName); + +/** Remove a node from an existing group */ +native final function RemoveNodeFromGroup(AnimNodeSequence SeqNode, Name GroupName); + +/** Accesses the Master Node driving a given group */ +native final function AnimNodeSequence GetMasterNodeOfGroup(Name GroupName); + +/** Force a group at a relative position. */ +native final function ForceRelativePosition(Name GroupName, FLOAT RelativePosition); + +/** Get the relative position of a group. */ +native final function float GetRelativePosition(Name GroupName); + +/** Adjust the Rate Scale of a group */ +native final function SetGroupRateScale(Name GroupName, FLOAT NewRateScale); + +defaultproperties +{ + Children(0)=(Name="Input",Weight=1.0) + bFixNumChildren=TRUE +} diff --git a/Engine/Classes/AnimNode_MultiBlendPerBone.uc b/Engine/Classes/AnimNode_MultiBlendPerBone.uc new file mode 100644 index 0000000..a893de7 --- /dev/null +++ b/Engine/Classes/AnimNode_MultiBlendPerBone.uc @@ -0,0 +1,184 @@ + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AnimNode_MultiBlendPerBone extends AnimNodeBlendBase + native(Anim); + +/** Internal cached pointer to Pawn Owner */ +var const transient Pawn PawnOwner; + +/** Enum specifying how the weight should be checked */ +enum EWeightCheck +{ + /** If AnimNodeSlot is not playing an animation, pass through */ + EWC_AnimNodeSlotNotPlaying, +}; + +/** Rule put on a node. */ +struct native WeightNodeRule +{ + /** Name of node */ + var() Name NodeName; + /** Reference to node */ + var AnimNodeBlendBase CachedNode; + /** Reference to cached slot node */ + var AnimNodeSlot CachedSlotNode; + /** How the weight should be checked. */ + var() EWeightCheck WeightCheck; + /** Child index of node to check weight for */ + var() INT ChildIndex; + + structdefaultproperties + { + WeightCheck=EWC_AnimNodeSlotNotPlaying + } +}; + +/** Definition of a mask rule. */ +struct native WeightRule +{ + var() WeightNodeRule FirstNode; + var() WeightNodeRule SecondNode; +}; + + +struct native BranchInfo +{ + // Exposed properties + /** Name of bone branch is starting from */ + var() Name BoneName; + /** Used to set up smooth blending */ + var() float PerBoneWeightIncrease; + + structdefaultproperties + { + PerBoneWeightIncrease=1.f + } +}; + +/** Per bone masking definition */ +struct native PerBoneMaskInfo +{ + // Exposed properties + var() Array BranchList; + + /** Desired weight for this Mask */ + var() float DesiredWeight; + var() float BlendTimeToGo; + + /** + * Rules for turning off Mask. + * This system allows to turn off a mask based on a set of rules. + * Most of the time BlendPerBone is associated with a AnimNodeSlot + * to play cutsom animations. + * So with this system, it's possible to make the BlendPerBone a pass through node + * when no custom animation is played on the AnimNodeSlot. Hence optimizing significantly the tree. + * + * Example: + * - NodeName = Name of AnimNodeSlot + * - ChildIndex = 0 (source of AnimNodeSlot, when no custom animation is playing) + * - WeightCheck = EWC_ChildIndexFullWeight + * So this reads, if the Source children of the AnimNodeSlot is full weight + * (ie no custom animation is playing), then turn off this mask and + * make this BlendPerBone a pass through node. + * + * @note: When setting up multiple rules, ALL of them must be true in order to turn off the mask. + * if one fails, then the mask will NOT be disabled. + */ + var() Array WeightRuleList; + var() bool bWeightBasedOnNodeRules; + + /** + * If the owner is not a local human player, then ignore this branch. + * (ie AI, other players in network...) + */ + var() bool bDisableForNonLocalHumanPlayers; + + /** Set when there is a blend pending, and it's being delayed by CanBlendTo()/CanBlendOutFrom() */ + var transient bool bPendingBlend; + + // Internal properties + /** Weight scaling for each bone of the skeleton. Must be same size as RefSkeleton of SkeletalMesh. If all 0.0, no animation can ever be drawn from Child2. */ + var transient Array PerBoneWeights; + + /** + * Bones required to be transformed to mesh space. + * When doing a MeshSpace blending, this array defines which bones need to be blended that way + * as an optimization. As it is expensive to convert from Parent Bone Space -> Mesh Space and back. + * So this ensures that the conversion is only performed on the critical bones. + * These are the bones which have a different mask weight than their parents (so they will be blended) + * and their parents (needed to build the mesh space skeleton, as we are converting from PARENT bone space. + * The other bones can be done with the faster parent bone space blend. + */ + var transient Array TransformReqBone; + + /** Index to navigate above array */ + var transient INT TransformReqBoneIndex; +}; + +/** List of Masks. Matches size of Children array - 1 */ +var() editfixedsize editinline Array MaskList; + +/** Describes how a blend should be performed. */ +enum EBlendType +{ + EBT_ParentBoneSpace, + EBT_MeshSpace, +}; + +/** How rotation should be blended */ +var() EBlendType RotationBlendType; + +cpptext +{ + /** Do any initialisation, and then call InitAnim on all children. Should not discard any existing anim state though. */ + virtual void InitAnim(USkeletalMeshComponent* MeshComp, UAnimNodeBlendBase* Parent); + + /** Ticking, updates weights... */ + virtual void TickAnim(FLOAT DeltaSeconds); + + /** @see UAnimNode::GetBoneAtoms. */ + virtual void GetBoneAtoms(FBoneAtomArray& Atoms, const TArray& DesiredBones, FBoneAtom& RootMotionDelta, INT& bHasRootMotion, FCurveKeyArray& CurveKeys); + + // Special Optimized Paths + FORCEINLINE void MeshSpaceBlendMultipleMasks(FBoneAtomArray& Atoms, const TArray& DesiredBones, FBoneAtom& RootMotionDelta, INT& bHasRootMotion, TArray& RelevantChildren, FArrayBoneAtomArray& ChildAtomsArray, FArrayMatrixArray& MaskTMArray, const TArray & ChildrenHasRootMotion, const FBoneAtomArray & ChildrenRootMotion); + FORCEINLINE void LocalBlendMultipleMasks(FBoneAtomArray& Atoms, const TArray& DesiredBones, FBoneAtom& RootMotionDelta, INT& bHasRootMotion, TArray& RelevantChildren, FArrayBoneAtomArray& ChildAtomsArray, const TArray & ChildrenHasRootMotion, const FBoneAtomArray & ChildrenRootMotion); + FORCEINLINE void MeshSpaceBlendSingleMask(FBoneAtomArray& Atoms, const TArray& DesiredBones, FBoneAtom& RootMotionDelta, INT& bHasRootMotion, TArray& RelevantChildren, FArrayBoneAtomArray& ChildAtomsArray, FArrayMatrixArray& MaskTMArray, const TArray & ChildrenHasRootMotion, const FBoneAtomArray & ChildrenRootMotion); + FORCEINLINE void LocalBlendSingleMask(FBoneAtomArray& Atoms, const TArray& DesiredBones, FBoneAtom& RootMotionDelta, INT& bHasRootMotion, TArray& RelevantChildren, FArrayBoneAtomArray& ChildAtomsArray, const TArray & ChildrenHasRootMotion, const FBoneAtomArray & ChildrenRootMotion); + + /** Parent node is requesting a blend out. Give node a chance to delay that. */ + virtual UBOOL CanBlendOutFrom(); + /** parent node is requesting a blend in. Give node a chance to delay that. */ + virtual UBOOL CanBlendTo(); + + /** + * Utility for creating the Mask PerBoneWeights array. + * Walks down the hierarchy increasing the weight by PerBoneWeightIncrease each step. + */ + virtual void CalcMaskWeight(INT MaskIndex); + + virtual void UpdateRules(); + + /** Track Changes, and trigger updates */ + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + /** Rename Child connectors upon edit/remove */ + virtual void RenameChildConnectors(); + + // AnimNodeBlendBase interface + virtual void OnAddChild(INT ChildNum); + virtual void OnRemoveChild(INT ChildNum); +} + + +/** + * Control the weight of a given Mask. + */ +native final function SetMaskWeight(INT MaskIndex, FLOAT DesiredWeight, FLOAT BlendTime); + +defaultproperties +{ + Children(0)=(Name="Source",Weight=1.f) + CategoryDesc = "Filter" +} diff --git a/Engine/Classes/AnimNotify.uc b/Engine/Classes/AnimNotify.uc new file mode 100644 index 0000000..eb1cb86 --- /dev/null +++ b/Engine/Classes/AnimNotify.uc @@ -0,0 +1,78 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AnimNotify extends Object + native(Anim) + abstract + editinlinenew + hidecategories(Object) + collapsecategories; + +/** Color of Notify in editor */ +var editoronly Color NotifyColor; + +cpptext +{ + // AnimNotify interface. + virtual void Notify( class UAnimNodeSequence* NodeSeq ) {} + virtual void NotifyTick( class UAnimNodeSequence* NodeSeq, FLOAT AnimCurrentTime, FLOAT AnimTimeStep, FLOAT InTotalDuration ) {} + virtual void NotifyEnd( class UAnimNodeSequence* NodeSeq, FLOAT AnimCurrentTime ) {} + + virtual FString GetEditorComment() + { + return TEXT(""); + } + virtual FColor GetEditorColor() + { +#if WITH_EDITORONLY_DATA + return NotifyColor; +#else + return FColor( 0 ); +#endif // WITH_EDITORONLY_DATA + } + + /** + * Called by the AnimSet viewer when the 'parent' FAnimNotifyEvent is edited. + * + * @param NodeSeq The AnimNodeSequence this notify is associated with. + * @param OwnerEvent The FAnimNotifyEvent that 'owns' this AnimNotify. + */ + virtual void AnimNotifyEventChanged(class UAnimNodeSequence* NodeSeq, FAnimNotifyEvent* OwnerEvent) {} +} + +simulated function bool FindNextNotifyOfClass(AnimNodeSequence AnimSeqInstigator, class NotifyClass, out AnimNotifyEvent OutEvent) +{ + local AnimSequence Seq; + local int i; + local bool bFoundThis; + + if(AnimSeqInstigator.AnimSeq != None) + { + // we look through the notifies to find the end that corresponds to this start + Seq = AnimSeqInstigator.AnimSeq; + for(i=0; i CameraLensEffect; + +cpptext +{ + // AnimNotify interface. + virtual void Notify( class UAnimNodeSequence* NodeSeq ); + virtual FString GetEditorComment() { return TEXT("CameraEffect"); } +} + +defaultproperties +{ + +} diff --git a/Engine/Classes/AnimNotify_ClothingMaxDistanceScale.uc b/Engine/Classes/AnimNotify_ClothingMaxDistanceScale.uc new file mode 100644 index 0000000..ec68f37 --- /dev/null +++ b/Engine/Classes/AnimNotify_ClothingMaxDistanceScale.uc @@ -0,0 +1,39 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AnimNotify_ClothingMaxDistanceScale extends AnimNotify + native(Anim); + +/** The Particle system to play **/ +var() float StartScale; +var() float EndScale; + + +var() EMaxDistanceScaleMode ScaleMode; + +var float Duration; + +cpptext +{ + // AnimNotify interface. + virtual void Notify( class UAnimNodeSequence* NodeSeq ); + virtual void NotifyEnd( class UAnimNodeSequence* NodeSeq, FLOAT AnimCurrentTime ); + + /** + * Called by the AnimSet viewer when the 'parent' FAnimNotifyEvent is edited. + * + * @param NodeSeq The AnimNodeSequence this notify is associated with. + * @param OwnerEvent The FAnimNotifyEvent that 'owns' this AnimNotify. + */ + virtual void AnimNotifyEventChanged(class UAnimNodeSequence* NodeSeq, FAnimNotifyEvent* OwnerEvent); +} + +defaultproperties +{ + NotifyColor=(R=200,G=255,B=200) + + StartScale = 1; + EndScale = 1; + ScaleMode = MDSM_Multiply; +} + diff --git a/Engine/Classes/AnimNotify_Footstep.uc b/Engine/Classes/AnimNotify_Footstep.uc new file mode 100644 index 0000000..b54fd5f --- /dev/null +++ b/Engine/Classes/AnimNotify_Footstep.uc @@ -0,0 +1,28 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AnimNotify_Footstep extends AnimNotify + native(Anim); + +`if(`__TW_) +/** 0 = left foot, 1 = right foot, 2 = left hand, 3 = right hand */ +`else +/** 0=left 1=right */ +`endif +var() int FootDown; + +cpptext +{ + // AnimNotify interface. + virtual void Notify( class UAnimNodeSequence* NodeSeq ); +#if __TW_ + virtual FString GetEditorComment() { switch(FootDown){ case 0: return TEXT("Left Footstep"); case 1: return TEXT("Right Footstep"); case 2: return TEXT("Left Handstep"); case 3: return TEXT("Right Handstep"); default: return TEXT("");}; } +#else + virtual FString GetEditorComment() { return (FootDown == 0) ? TEXT("Left Footstep") : TEXT("Right Footstep"); } +#endif // __TW_ +} + +defaultproperties +{ + FootDown=0 +} diff --git a/Engine/Classes/AnimNotify_Forcefield.uc b/Engine/Classes/AnimNotify_Forcefield.uc new file mode 100644 index 0000000..bd6f2a5 --- /dev/null +++ b/Engine/Classes/AnimNotify_Forcefield.uc @@ -0,0 +1,29 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AnimNotify_ForceField extends AnimNotify + native(Anim); + + +/** Type of Forcefield **/ +var() instanced NxForceFieldComponent ForceFieldComponent; + +/** If this ForceField system should be attached to the location.**/ +var() bool bAttach; + +/** The socketname in which to attach the ForceField. Looks for a socket name first then bone name **/ +var() name SocketName; + +/** The bone name in which to attach the ForceField. Looks for a socket name first then bone name **/ +var() name BoneName; + +cpptext +{ + // AnimNotify interface. + virtual void Notify( class UAnimNodeSequence* NodeSeq ); + virtual FString GetEditorComment() { return TEXT("ForceField"); } +} + +defaultproperties +{ +} diff --git a/Engine/Classes/AnimNotify_Kismet.uc b/Engine/Classes/AnimNotify_Kismet.uc new file mode 100644 index 0000000..2d96c86 --- /dev/null +++ b/Engine/Classes/AnimNotify_Kismet.uc @@ -0,0 +1,14 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AnimNotify_Kismet extends AnimNotify + native(Anim); + +var() name NotifyName; + +cpptext +{ + // AnimNotify interface. + virtual void Notify( class UAnimNodeSequence* NodeSeq ); + virtual FString GetEditorComment() { return TEXT("Kismet"); } +} diff --git a/Engine/Classes/AnimNotify_PawnMaterialParam.uc b/Engine/Classes/AnimNotify_PawnMaterialParam.uc new file mode 100644 index 0000000..057c4d6 --- /dev/null +++ b/Engine/Classes/AnimNotify_PawnMaterialParam.uc @@ -0,0 +1,36 @@ + +/** + * AnimNotify_PawnMaterialParam + * + * Control MaterialInstanceConstant Scalar parameters through AnimNotifies + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimNotify_PawnMaterialParam extends AnimNotify_Scripted + native(Anim); + +var() Array ScalarParameterInterpArray; + +cpptext +{ + virtual FString GetEditorComment() { return TEXT("MatParam"); } +} + +event Notify(Actor Owner, AnimNodeSequence AnimSeqInstigator) +{ + local Pawn P; + local INT i; + local ScalarParameterInterpStruct ScalarParam; + + P = Pawn(Owner); + if( P != None ) + { + for(i=0; i PlayFrequency ) + { + return; + } + } + else if( PlayFrequency > 1.f ) + { + `log("Play FaceFX animation from notify" @ AnimSeqInstigator.AnimSeqName @ "for" @ Owner @ "GroupName:" @ GroupName @ "AnimName:" @ AnimName); + `log(" PlayFrequency > 1.0 is useless. Chance to play valid range is from 0.0 to 1.0."); + } + + if( Owner != None ) + { + //`log(Self @ "Play FaceFX animation from notify" @ AnimSeqInstigator.AnimSeqName @ "for" @ Owner @ "GroupName:" @ GroupName @ "AnimName:" @ AnimName @ "(bOverridePlayingAnim:"$ bOverridePlayingAnim @ "IsActorPlayingFaceFXAnim:" $ Owner.IsActorPlayingFaceFXAnim() $")"); + + // If actor can (is able to) play + if (Owner.CanActorPlayFaceFXAnim()) + { + // If a Face FX animation is already playing, should we override it? + if( bOverridePlayingAnim || !Owner.IsActorPlayingFaceFXAnim()) + { +// WWISEMODIF_START, alessard, nov-28-2008, WwiseAudioIntegration + if (Owner.PlayActorFaceFXAnim(FaceFXAnimSetRef, GroupName, AnimName, SoundCueToPlay, AkEventToPlay) == FALSE) +// WWISEMODIF_END + { + `log(AnimSeqInstigator.AnimSeq.Outer @ "(" @ AnimSeqInstigator.AnimSeqName @ ")" @ " - PlayFaceFXAnim notifier failed. Verify if this notifier is valid.",,'DevFaceFX'); + } + } + } + } +} + +defaultproperties +{ + bOverridePlayingAnim=TRUE + PlayFrequency=1.f +} diff --git a/Engine/Classes/AnimNotify_PlayParticleEffect.uc b/Engine/Classes/AnimNotify_PlayParticleEffect.uc new file mode 100644 index 0000000..4773b3e --- /dev/null +++ b/Engine/Classes/AnimNotify_PlayParticleEffect.uc @@ -0,0 +1,56 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AnimNotify_PlayParticleEffect extends AnimNotify + native(Anim); + +/** The Particle system to play **/ +var() ParticleSystem PSTemplate; + +/** If this effect should be considered extreme content **/ +var() bool bIsExtremeContent; + +/** If this is extreme content(bIsExtremeContent == TRUE), play this instead **/ +var() ParticleSystem PSNonExtremeContentTemplate; + +/** If this particle system should be attached to the location.**/ +var() bool bAttach; + +/** The socketname in which to play the particle effect. Looks for a socket name first then bone name **/ +var() name SocketName; + +/** The bone name in which to play the particle effect. Looks for a socket name first then bone name **/ +var() name BoneName; + +/** If TRUE, the particle system will play in the viewer as well as in game */ +var() editoronly bool bPreview; + +/** If Owner is hidden, skip particle effect */ +var() bool bSkipIfOwnerIsHidden; + +/** Parameter name for the bone socket actor - SkelMeshActorParamName in the LocationBoneSocketModule. + * (Default value in module is 'BoneSocketActor') + */ +var() name BoneSocketModuleActorName; + +`if(`__TW_) +var() bool bUsePostUpdateWorkTickGroup; +`endif + +cpptext +{ + // AnimNotify interface. + virtual void Notify( class UAnimNodeSequence* NodeSeq ); + virtual FString GetEditorComment() { return TEXT("VFX"); } +} + +defaultproperties +{ + NotifyColor=(R=200,G=255,B=200) + bSkipIfOwnerIsHidden=TRUE + BoneSocketModuleActorName="BoneSocketActor" +`if(`__TW_) + bUsePostUpdateWorkTickGroup=FALSE +`endif +} + diff --git a/Engine/Classes/AnimNotify_Rumble.uc b/Engine/Classes/AnimNotify_Rumble.uc new file mode 100644 index 0000000..36b5c7e --- /dev/null +++ b/Engine/Classes/AnimNotify_Rumble.uc @@ -0,0 +1,30 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AnimNotify_Rumble extends AnimNotify + native(Anim); + + +/** A predefined WaveForm **/ +var() class PredefinedWaveForm; + + +/** The waveform to play **/ +var() editinline ForceFeedbackWaveform WaveForm; + +/** If set the player must be based on this actor for the wave to be played */ +var() bool bCheckForBasedPlayer; + +/** If non-zero the effect will happen if the player is with in this radius of the playing actor */ +var() float EffectRadius; + +cpptext +{ + // AnimNotify interface. + virtual void Notify( class UAnimNodeSequence* NodeSeq ); + virtual FString GetEditorComment() { return TEXT("Rumble"); } +} + +defaultproperties +{ +} diff --git a/Engine/Classes/AnimNotify_Script.uc b/Engine/Classes/AnimNotify_Script.uc new file mode 100644 index 0000000..7e12e42 --- /dev/null +++ b/Engine/Classes/AnimNotify_Script.uc @@ -0,0 +1,25 @@ +/** + * The implmenting class (usually a pawn) needs to have a function named the same as the that is specified in the AnimNotify. + * + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AnimNotify_Script extends AnimNotify + native(Anim); + +var() name NotifyName; + +/** If this notify has a duration, name of the function to call each update */ +var() Name NotifyTickName; + +/** If this notify has a duration, name of the function to call at the end */ +var() Name NotifyEndName; + +cpptext +{ + // AnimNotify interface. + virtual void Notify( class UAnimNodeSequence* NodeSeq ); + virtual void NotifyTick( class UAnimNodeSequence* NodeSeq, FLOAT AnimCurrentTime, FLOAT AnimTimeStep, FLOAT InTotalDuration ); + virtual void NotifyEnd( class UAnimNodeSequence* NodeSeq, FLOAT AnimCurrentTime ); + virtual FString GetEditorComment() { return (NotifyName == NAME_None) ? TEXT("Script") : NotifyName.ToString(); } +} diff --git a/Engine/Classes/AnimNotify_Scripted.uc b/Engine/Classes/AnimNotify_Scripted.uc new file mode 100644 index 0000000..c2f6092 --- /dev/null +++ b/Engine/Classes/AnimNotify_Scripted.uc @@ -0,0 +1,16 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AnimNotify_Scripted extends AnimNotify + native(Anim) + abstract; + +event Notify( Actor Owner, AnimNodeSequence AnimSeqInstigator ); +event NotifyEnd( Actor Owner, AnimNodeSequence AnimSeqInstigator ); + +cpptext +{ + // AnimNotify interface. + virtual void Notify( class UAnimNodeSequence* NodeSeq ); + virtual void NotifyEnd( class UAnimNodeSequence* NodeSeq, FLOAT AnimCurrentTime ); +} diff --git a/Engine/Classes/AnimNotify_Sound.uc b/Engine/Classes/AnimNotify_Sound.uc new file mode 100644 index 0000000..31e242d --- /dev/null +++ b/Engine/Classes/AnimNotify_Sound.uc @@ -0,0 +1,33 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AnimNotify_Sound extends AnimNotify + native(Anim); + +var() SoundCue SoundCue; +var() bool bFollowActor; +var() Name BoneName; +var() bool bIgnoreIfActorHidden; + +/** This is the percent to play this Sound. Defaults to 100% (aka 1.0f) **/ +var() float PercentToPlay; +var() float VolumeMultiplier; +var() float PitchMultiplier; + +cpptext +{ + // AnimNotify interface. + virtual void Notify( class UAnimNodeSequence* NodeSeq ); + + virtual FString GetEditorComment() { return TEXT("Snd"); } +} + +defaultproperties +{ + PercentToPlay=1.0f + VolumeMultiplier=1.f + PitchMultiplier=1.f + bFollowActor=TRUE + + NotifyColor=(R=200,G=200,B=255) +} diff --git a/Engine/Classes/AnimNotify_Trails.uc b/Engine/Classes/AnimNotify_Trails.uc new file mode 100644 index 0000000..74b9b81 --- /dev/null +++ b/Engine/Classes/AnimNotify_Trails.uc @@ -0,0 +1,178 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * AnimNotify for having a Trails emitter spawn based on an animation. + */ +class AnimNotify_Trails extends AnimNotify + native(Anim); + +/** The Particle system to play */ +var(Trails) ParticleSystem PSTemplate; + +/** The Skeletal Mesh to sample the data from */ +var(Trails) editoronly editconst SkeletalMesh SampledSkeletalMesh; + +/** If this effect should be considered extreme content */ +var(Trails) bool bIsExtremeContent; + +/** The first edge socket - with the second edge defines the edges of the trail */ +var(Trails) name FirstEdgeSocketName; + +/** + * The control point socket - controls the UV tiling as well as + * tapering the two edges to this point. + */ +var(Trails) name ControlPointSocketName; + +/** The second edge socket - with the first edge defines the edges of the trail */ +var(Trails) name SecondEdgeSocketName; + +/** If TRUE, the particle system will play in the viewer as well as in game */ +var() editoronly bool bPreview; + +/** If TRUE, this will preview with listed PS and ignore AnimNotify_FX_Preview section in ini for pawn specific data */ +var() editoronly bool bPreviewForceExplicit; + +/** If Owner is hidden, skip particle effect */ +var() bool bSkipIfOwnerIsHidden; + +/** Locally store 'start' time to determine when regenerating the curve data is required. */ +var float LastStartTime; + +/** The end time (will auto-adjust Duration setting, and vice-versa) */ +var float EndTime; + +/** The timestep at which to sample the animation for trail points */ +var deprecated float SampleTimeStep; + +struct native TrailSocketSamplePoint +{ + /** Position of the socket relative to the root-bone at the sample point */ + var vector Position; + /** Velocity of the socket at the sample point */ + var vector Velocity; +}; + +struct native TrailSamplePoint +{ + /** The time value at this sample point, relative to the starting time. */ + var float RelativeTime; + /** The sample for the first edge */ + var TrailSocketSamplePoint FirstEdgeSample; + /** The sample for the control point */ + var TrailSocketSamplePoint ControlPointSample; + /** The sample for the second edge */ + var TrailSocketSamplePoint SecondEdgeSample; +}; + +var deprecated array TrailSampleData; + +var bool bResampleRequired; + +/** The frame rate (FPS) to sample the animation at for trail points */ +var(Trails) float SamplesPerSecond; + +struct native TrailSample +{ + /** The time value at this sample point, relative to the starting time. */ + var float RelativeTime; + /** The sample for the first edge */ + var vector FirstEdgeSample; + /** The sample for the control point */ + var vector ControlPointSample; + /** The sample for the second edge */ + var vector SecondEdgeSample; +}; + +/** The sampled data for the trail */ +var array TrailSampledData; + +/** Used by the event functions... */ +var transient float CurrentTime; +var transient float TimeStep; +var transient AnimNodeSequence AnimNodeSeq; + +/** + * Called from NotifyTick or NotifyEnd, this function will return the + * number of steps to take for a notify call given the index of the + * last sample that was processed. + * + * @param InLastTrailIndex The index of the last sample that was processed. + * + * @return INT The number of steps to take for the notify. + */ +function native int GetNumSteps(int InLastTrailIndex) const; + +cpptext +{ + // UObject interfrace. + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual void PostLoad(); + + // AnimNotify interface. + virtual void Notify(class UAnimNodeSequence* NodeSeq); + virtual void NotifyTick(class UAnimNodeSequence* NodeSeq, FLOAT AnimCurrentTime, FLOAT AnimTimeStep, FLOAT InTotalDuration); + virtual void NotifyEnd(class UAnimNodeSequence* NodeSeq, FLOAT AnimCurrentTime); + +protected: + enum ETrailNotifyType + { + TrailNotifyType_Start, + TrailNotifyType_Tick, + TrailNotifyType_End + }; + + /** + * Handle the various notifies. This should only be called internally! + * + * @param InNodeSeq The anim node sequence triggering the notify + * @param InNotifyType The type of notify that is being handled + */ + void HandleNotify(class UAnimNodeSequence* InNodeSeq, ETrailNotifyType InNotifyType); + +public: + virtual AActor* GetNotifyActor(class UAnimNodeSequence* NodeSeq); + + virtual FString GetEditorComment() { return TEXT("TRAILS"); } + + /** + * Find the ParticleSystemComponent used by this anim notify. + * + * @param NodeSeq The AnimNodeSequence this notify is associated with. + * + * @return UParticleSystemComponent The particle system component + */ + UParticleSystemComponent* GetPSysComponent(class UAnimNodeSequence* NodeSeq); + + /** + * Called by the AnimSet viewer when the 'parent' FAnimNotifyEvent is edited. + * + * @param NodeSeq The AnimNodeSequence this notify is associated with. + * @param OwnerEvent The FAnimNotifyEvent that 'owns' this AnimNotify. + */ + virtual void AnimNotifyEventChanged(class UAnimNodeSequence* NodeSeq, FAnimNotifyEvent* OwnerEvent); + + /** Store the animation data for the current settings. Editor-only. */ + void StoreAnimationData(class UAnimNodeSequence* NodeSeq); + + /** Check if the active SkeletalMesh should be sampled by the anim trial, returning true if successful */ + UBOOL AssociateSkeletalMeshWithAnimTrailData(class UAnimNodeSequence* NodeSeq); + + /** Verify the notify is setup correctly for sampling animation data. Editor-only. */ + UBOOL IsSetupValid(class UAnimNodeSequence* NodeSeq); +} + +defaultproperties +{ + bSkipIfOwnerIsHidden=TRUE + LastStartTime=0.0f + SamplesPerSecond=60 + SampleTimeStep=0.016f + + bResampleRequired=false + + FirstEdgeSocketName=EndControl + ControlPointSocketName=MidControl + SecondEdgeSocketName=StartControl + + NotifyColor=(R=255,G=64,B=255) +} diff --git a/Engine/Classes/AnimNotify_ViewShake.uc b/Engine/Classes/AnimNotify_ViewShake.uc new file mode 100644 index 0000000..73dff88 --- /dev/null +++ b/Engine/Classes/AnimNotify_ViewShake.uc @@ -0,0 +1,102 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AnimNotify_ViewShake extends AnimNotify_Scripted + native(Anim); + +/** + * Note: these shake-defining params are deprecated. Use ShakeParams. + * Leaving them here for now for compatibility with existing content (which will be + * upgraded via PostLoad()). + */ +/** Duration in seconds of shake */ +var private editconst float Duration; +/** view rotation amplitude (pitch,yaw,roll) */ +var private editconst vector RotAmplitude; +/** frequency of rotation shake */ +var private editconst vector RotFrequency; +/** relative view offset amplitude (x,y,z) */ +var private editconst vector LocAmplitude; +/** frequency of view offset shake */ +var private editconst vector LocFrequency; +/** fov shake amplitude */ +var private editconst float FOVAmplitude; +/** fov shake frequency */ +var private editconst float FOVFrequency; + +var() bool bDoControllerVibration; + +/** Radius within which to shake player views. If 0 only plays on the animated player */ +var() float ShakeRadius; + +/** Should use a bone location as the shake's epicenter? */ +var() bool bUseBoneLocation; +/** if so, bone name to use */ +var() name BoneName; + +var() export editinline CameraShake ShakeParams; + +cpptext +{ + virtual void PostLoad(); + virtual FString GetEditorComment() { return TEXT("CameraShake"); } +}; + +/** + * Trigger the view shake + * + * @param Owner - the actor that is playing this animation + * + * @param AnimSeqInstigator - the anim sequence that triggered the notify + */ +event Notify(Actor Owner, AnimNodeSequence AnimSeqInstigator) +{ + local vector ViewShakeOrigin; + local Pawn P; + local PlayerController PC; + + if (ShakeRadius == 0) + { + P = Pawn(Owner); + if (P != None && P.IsLocallyControlled()) + { + PC = PlayerController(P.Controller); + if (PC != None) + { + PC.ClientPlayCameraShake(ShakeParams); + } + } + } + else + { + // Figure out world origin of view shake + if( bUseBoneLocation && + AnimSeqInstigator != None && + AnimSeqInstigator.SkelComponent != None ) + { + ViewShakeOrigin = AnimSeqInstigator.SkelComponent.GetBoneLocation( BoneName ); + } + else + { + ViewShakeOrigin = Owner.Location; + } + + // propagate to all player controllers + if (Owner != None) + { + class'Camera'.static.PlayWorldCameraShake(ShakeParams, Owner, ViewShakeOrigin, 0.f, ShakeRadius, 1.f, bDoControllerVibration); + } + } +} + +defaultproperties +{ + ShakeRadius=4096.0 + Duration=1.f + RotAmplitude=(X=100,Y=100,Z=200) + RotFrequency=(X=10,Y=10,Z=25) + LocAmplitude=(X=0,Y=3,Z=6) + LocFrequency=(X=1,Y=10,Z=20) + FOVAmplitude=2 + FOVFrequency=5 +} diff --git a/Engine/Classes/AnimObject.uc b/Engine/Classes/AnimObject.uc new file mode 100644 index 0000000..795ca09 --- /dev/null +++ b/Engine/Classes/AnimObject.uc @@ -0,0 +1,63 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimObject extends Object + native(Anim) + hidecategories(Object) + abstract; + +/** For editor use. */ +var editoronly int DrawWidth; + +/** for editor use */ +var editoronly int DrawHeight; + +/** for editor use. */ +var editoronly int NodePosX; + +/** For editor use. */ +var editoronly int NodePosY; + +/** for editor use. */ +var editoronly int OutDrawY; + +/** + * Editor category for this object. Determines which animtree submenu this object + * should be placed in + */ +var editoronly string CategoryDesc; + +/** SkeletalMeshComponent owner */ +var const transient duplicatetransient SkeletalMeshComponent SkelComponent; + +cpptext +{ + virtual UAnimNode * GetAnimNode() { return NULL;} + virtual UMorphNodeBase * GetMorphNodeBase() { return NULL;} + virtual USkelControlBase * GetSkelControlBase() { return NULL; } + + /** + * Draws this node in the AnimTreeEditor. + * + * @param Canvas The canvas to use. + * @param SelectedNodes Reference to array of all currently selected nodes, potentially including this node + * @param bShowWeight If TRUE, show the global percentage weight of this node, if applicable. + */ + virtual void DrawNode(FCanvas* Canvas, const TArray& SelectedNodes, UBOOL bShowWeight) {} + /** Called after (copy/)pasted - reset values or re-link if needed**/ + virtual void OnPaste() {}; + +#if WITH_EDITORONLY_DATA + /** Calculate the bounding box of this sequence object. For use by Kismet. */ + FIntRect GetObjBoundingBox() + { + return FIntRect(NodePosX, NodePosY, NodePosX + DrawWidth, NodePosY + DrawHeight); + } +#endif +}; + +DefaultProperties +{ + +} diff --git a/Engine/Classes/AnimSequence.uc b/Engine/Classes/AnimSequence.uc new file mode 100644 index 0000000..3cf710a --- /dev/null +++ b/Engine/Classes/AnimSequence.uc @@ -0,0 +1,484 @@ +/** + * One animation sequence of keyframes. Contains a number of tracks of data. + * The Outer of AnimSequence is expected to be its AnimSet. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimSequence extends Object + native(Anim) + config(Engine) + hidecategories(Object); + +/* + * Triggers an animation notify. Each AnimNotifyEvent contains an AnimNotify object + * which has its Notify method called and passed to the animation. + */ +struct native AnimNotifyEvent +{ + var() float Time; + var() instanced AnimNotify Notify; + var() editoronly Name Comment; + var() float Duration; +}; + +/** + * Raw keyframe data for one track. Each array will contain either NumFrames elements or 1 element. + * One element is used as a simple compression scheme where if all keys are the same, they'll be + * reduced to 1 key that is constant over the entire sequence. + * + * @warning: manually mirrored in UnMiscDeclerations.h due to mixed native/ script serialization + */ +struct RawAnimSequenceTrack +{ + /** Position keys. */ + var array PosKeys; + /** Rotation keys. */ + var array RotKeys; +}; + +/** Name of the animation sequence. Used in AnimNodeSequence. */ +var name SequenceName; + +/** Animation notifies, sorted by time (earliest notification first). */ +var() editinline array Notifies; + +/** Animation Meta Data */ +var() editinline instanced Array MetaData; + +/* + * This is to support Skel Control Strength from animation data + * For example, if you'd like to scale bones via SkelControlSingleBone from animation data. + * This looks up SkelControlName in the Anim tree and apply strength at the point where it's set up + */ +struct native TimeModifier +{ + /** Time to apply **/ + var() float Time; + /** Target Strength of the Skel Control at this time **/ + /** This will linearly interpolate between multiple strength within one anim data**/ + var() float TargetStrength; +}; + +/* DEPRECATED VER_ADDED_ANIM_METADATA_FIXED_QUATERROR + * This contains all skel control modifiers + * The TimeModifier will be sorted by time + * Initially it starts from what strength it was when animation started. + */ +struct native SkelControlModifier +{ + /** SkelControl Node Name in the Anim Tree that would apply **/ + var() name SkelControlName; + + /** Modifiers for what time and what strength for this skelcontrol name**/ + var() editinline array Modifiers; +}; + +/** DEPRECATED VER_ADDED_ANIM_METADATA_FIXED_QUATERROR Bone Control Modifiers, sorted by time (earliest notification first). */ +var deprecated editinline array BoneControlModifiers; + +/** Length (in seconds) of this AnimSequence if played back with a speed of 1.0. */ +var float SequenceLength; + +/** Number of raw frames in this sequence (not used by engine - just for informational purposes). */ +var int NumFrames; + +/** Number for tweaking playback rate of this animation globally. */ +var() float RateScale; + +/** + * if TRUE, disable interpolation between last and first frame when looping. + */ +var() bool bNoLoopingInterpolation; + +/** + * Raw uncompressed keyframe data. RawAnimData is deprecated and moved to RawAnimationData + * to switch to native serialization. Down the road it should be switched to use lazy loading + * as the data is only used in the editor. It is used pervasively enough to be a separate change. + */ +var deprecated private const array RawAnimData; +var native private const array RawAnimationData; + +/** + * Keyframe position data for one track. Pos(i) occurs at Time(i). Pos.Num() always equals Time.Num(). + */ +struct native TranslationTrack +{ + var array PosKeys; + var array Times; +}; + +/** + * Keyframe rotation data for one track. Rot(i) occurs at Time(i). Rot.Num() always equals Time.Num(). + */ +struct native RotationTrack +{ + var array RotKeys; + var array Times; +}; + +/** + * Key frame curve data for one track + * CurveName: Morph Target Name + * CurveWeights: List of weights for each frame + */ +struct native CurveTrack +{ + var name CurveName; + var array CurveWeights; + + structcpptext + { + /** Returns TRUE if valid curve weight exists in the array*/ + UBOOL IsValidCurveTrack(); + /** This is very simple cut to 1 key method if all is same since I see so many redundant same value in every frame + * Eventually this can get more complicated + * Will return TRUE if compressed to 1. Return FALSE otherwise **/ + UBOOL CompressCurveWeights(); + } +}; + +/** + * Translation data post keyframe reduction. TranslationData.Num() is zero if keyframe reduction + * has not yet been applied. + */ +var transient const array TranslationData; + +/** + * Rotation data post keyframe reduction. RotationData.Num() is zero if keyframe reduction + * has not yet been applied. + */ +var transient const array RotationData; + +/* + * Curve data - no compression yet + */ +var const array CurveData; + +/** + * The compression scheme that was most recently used to compress this animation. + * May be NULL. + */ +var() editinline editconst editoronly AnimationCompressionAlgorithm CompressionScheme; + +/** + * Indicates animation data compression format. + */ +enum AnimationCompressionFormat +{ + ACF_None, + ACF_Float96NoW, + ACF_Fixed48NoW, + ACF_IntervalFixed32NoW, + ACF_Fixed32NoW, + ACF_Float32NoW, + ACF_Identity +}; + +/** The compression format that was used to compress translation tracks. */ +var const AnimationCompressionFormat TranslationCompressionFormat; + +/** The compression format that was used to compress rotation tracks. */ +var const AnimationCompressionFormat RotationCompressionFormat; + +struct native CompressedTrack +{ + var array ByteStream; + var array Times; + var float Mins[3]; + var float Ranges[3]; +}; + +/** + * An array of 4*NumTrack ints, arranged as follows: + * [0] Trans0.Offset + * [1] Trans0.NumKeys + * [2] Rot0.Offset + * [3] Rot0.NumKeys + * [4] Trans1.Offset + * . . . + */ +var array CompressedTrackOffsets; + +/** + * ByteStream for compressed animation data. + * All keys are currently stored at evenly-spaced intervals (ie no explicit key times). + * + * For a translation track of n keys, data is packed as n uncompressed float[3]: + * + * For a rotation track of n>1 keys, the first 24 bytes are reserved for compression info + * (eg Fixed32 stores float Mins[3]; float Ranges[3]), followed by n elements of the compressed type. + * For a rotation track of n=1 keys, the single key is packed as an FQuatFloat96NoW. + */ +var native array CompressedByteStream; + +/** + * Indicates animation data compression format. + */ +enum AnimationKeyFormat +{ + AKF_ConstantKeyLerp, + AKF_VariableKeyLerp, + AKF_PerTrackCompression, +}; + +var const AnimationKeyFormat KeyEncodingFormat; + +/** + * The runtime interface to decode and byte swap the compressed animation + * May be NULL. Set at runtime - does not exist in editor + */ +var private transient native pointer TranslationCodec; +var private transient native pointer RotationCodec; + +// Additive Animation Support +/** TRUE if this is an Additive Animation */ +var const bool bIsAdditive; +/** Reference pose for additive animation. Deprecated. */ +var const deprecated Array AdditiveRefPose; +/** Store Reference Pose animation used to create this additive one. For playback in editor only. */ +var const Array AdditiveBasePose; + +/** Reference animation name */ +var const editoronly Name AdditiveRefName; +/** TRUE if additive animation was built with looping interpolation. */ +var editoronly bool bAdditiveBuiltLooping; +/** If this animation is Additive, this is the reference to the Base Pose used. For automatic rebuilding in the editor. Made into a list to handle duplicate animations. */ +var editoronly Array AdditiveBasePoseAnimSeq; +/** If this animation is Additive, this is the reference to the Target Pose used. For automatic rebuilding in the editor. Made into a list to handle duplicate animations. */ +var editoronly Array AdditiveTargetPoseAnimSeq; +/** If this animation was used, either as a Base or Target Pose, to build additive animations, they are referenced there. For automatic rebuilding in the editor. */ +var editoronly Array RelatedAdditiveAnimSeqs; + +// Versioning Support +/** The version of the global encoding package used at the time of import */ +var const int EncodingPkgVersion; +/** Saved version number with CompressAnimations commandlet. To help with doing it in multiple passes. */ +var editoronly const int CompressCommandletVersion; + + /** + * Do not attempt to override compression scheme when running CompressAnimations commandlet. + * Some high frequency animations are too sensitive and shouldn't be changed. + */ +var() editoronly const bool bDoNotOverrideCompression; + +/** + * Debug flag to trace if this anim sequence was played. + */ +var const transient bool bHasBeenUsed; +/** + * Debug score to find out animation usage + */ +var const transient float UseScore; + +/** + * Used to track whether, or not, this sequence was compressed with it's full translation tracks + */ +var editoronly bool bWasCompressedWithoutTranslations; + +cpptext +{ + // UObject interface + + virtual void Serialize(FArchive& Ar); + virtual void PreSave(); + virtual void PostLoad(); + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual void BeginDestroy(); + + /** + * Used by various commandlets to purge editor only and platform-specific data from various objects + * + * @param PlatformsToKeep Platforms for which to keep platform-specific data + * @param bStripLargeEditorData If TRUE, data used in the editor, but large enough to bloat download sizes, will be removed + */ + virtual void StripData(UE3::EPlatformType PlatformsToKeep, UBOOL bStripLargeEditorData); + + // AnimSequence interface + + /** + * Reconstructs a bone atom from key-reduced tracks. + */ + static void ReconstructBoneAtom(FBoneAtom& OutAtom, + const FTranslationTrack& TranslationTrack, + const FRotationTrack& RotationTrack, + FLOAT SequenceLength, + FLOAT Time, + UBOOL bLooping); + + /** + * Reconstructs a bone atom from compressed tracks. + */ + static void ReconstructBoneAtom(FBoneAtom& OutAtom, + const FCompressedTrack& TranslationTrack, + const FCompressedTrack& RotationTrack, + AnimationCompressionFormat TranslationCompressionFormat, + AnimationCompressionFormat RotationCompressionFormat, + FLOAT SequenceLength, + FLOAT Time, + UBOOL bLooping); + + /** + * Reconstructs a bone atom from compressed tracks. + */ + static void ReconstructBoneAtom(FBoneAtom& OutAtom, + const BYTE* TransStream, + INT NumTransKeys, + const BYTE* RotStream, + INT NumRotKeys, + AnimationCompressionFormat TranslationCompressionFormat, + AnimationCompressionFormat RotationCompressionFormat, + FLOAT SequenceLength, + FLOAT Time, + UBOOL bLooping); + + /** + * Decompresses a translation key from the specified compressed translation track. + */ + static void ReconstructTranslation(class FVector& Out, const BYTE* Stream, INT KeyIndex, AnimationCompressionFormat TranslationCompressionFormat); + + /** + * Decompresses a rotation key from the specified compressed rotation track. + */ + static void ReconstructRotation(class FQuat& Out, const BYTE* Stream, INT KeyIndex, AnimationCompressionFormat RotationCompressionFormat, const FLOAT *Mins, const FLOAT *Ranges); + + /** + * Decompresses a translation key from the specified compressed translation track. + */ + static void ReconstructTranslation(class FVector& Out, const BYTE* Stream, INT KeyIndex); + + /** + * Decompresses a rotation key from the specified compressed rotation track. + */ + static void ReconstructRotation(class FQuat& Out, const BYTE* Stream, INT KeyIndex, UBOOL bTrackHasCompressionInfo, AnimationCompressionFormat RotationCompressionFormat); + + /** + * Populates the key reduced arrays from raw animation data. + */ + static void SeparateRawDataToTracks(const TArray& RawAnimData, + FLOAT SequenceLength, + TArray& OutTranslationData, + TArray& OutRotationData); + + /** + * Interpolate keyframes in this sequence to find the bone transform (relative to parent). + * + * @param OutAtom [out] Output bone transform. + * @param TrackIndex Index of track to interpolate. + * @param Time Time on track to interpolate to. + * @param bLooping TRUE if the animation is looping. + * @param bUseRawData If TRUE, use raw animation data instead of compressed data. + * @param CurveKeys List of Curve Keys if exists + */ + void GetBoneAtom(FBoneAtom& OutAtom, INT TrackIndex, FLOAT Time, UBOOL bLooping, UBOOL bUseRawData, FCurveKeyArray* CurveKeys = NULL) const; + + /** + * Interpolate keyframes in this sequence to find the bone transform (relative to parent). + * This returns the base pose used to create the additive animation. + * + * @param OutAtom [out] Output bone transform. + * @param TrackIndex Index of track to interpolate. + * @param Time Time on track to interpolate to. + * @param bLooping TRUE if the animation is looping. + */ + void GetAdditiveBasePoseBoneAtom(FBoneAtom& OutAtom, INT TrackIndex, FLOAT Time, UBOOL bLooping) const; + + /** + * Interpolate curve weights of the Time in this sequence if curve data exists + * + * @param Time Time on track to interpolate to. + * @param bLooping TRUE if the animation is looping. + * @param CurveKeys Add the curve keys if exists + */ + void GetCurveData(FLOAT Time, UBOOL bLooping, FCurveKeyArray& CurveKeys) const; + + /** Sort the Notifies array by time, earliest first. */ + void SortNotifies(); + + /** + * @return A reference to the AnimSet this sequence belongs to. + */ + UAnimSet* GetAnimSet() const; + + /** + * Returns the size of the object/ resource for display to artists/ LDs in the Editor. + * + * @return size of resource as to be displayed to artists/ LDs in the Editor. + */ + virtual INT GetResourceSize(); + + /** + * @return The approximate size of raw animation data. + */ + INT GetApproxRawSize() const; + + /** + * @return The approximate size of key-reduced animation data. + */ + INT GetApproxReducedSize() const; + + /** + * @return The approximate size of compressed animation data. + */ + INT GetApproxCompressedSize() const; + + /** + * Crops the raw anim data either from Start to CurrentTime or CurrentTime to End depending on + * value of bFromStart. Can't be called against cooked data. + * + * @param CurrentTime marker for cropping (either beginning or end) + * @param bFromStart whether marker is begin or end marker + * @return TRUE if the operation was successful. + */ + UBOOL CropRawAnimData( FLOAT CurrentTime, UBOOL bFromStart ); + /** + * Utility function for lossless compression of a FRawAnimSequenceTrack + * @return TRUE if keys were removed. + **/ + UBOOL CompressRawAnimSequenceTrack(FRawAnimSequenceTrack& RawTrack, float MaxPosDiff, float MaxAngleDiff); + /** + * Removes trivial frames -- frames of tracks when position or orientation is constant + * over the entire animation -- from the raw animation data. If both position and rotation + * go down to a single frame, the time is stripped out as well. + * @return TRUE if keys were removed. + */ + UBOOL CompressRawAnimData(float MaxPosDiff, float MaxAngleDiff); + /** + * Removes trivial frames -- frames of tracks when position or orientation is constant + * over the entire animation -- from the raw animation data. If both position and rotation + * go down to a single frame, the time is stripped out as well. + * @return TRUE if keys were removed. + */ + UBOOL CompressRawAnimData(); + + /** Clears any data in the AnimSequence, so it can be recycled when importing a new animation with same name over it. */ + void RecycleAnimSequence(); + + /** + * Clear references to additive animations. + * This is the following arrays: AdditiveBasePoseAnimSeq, AdditiveTargetPoseAnimSeq and RelatedAdditiveAnimSeqs. + * Handles dependencies, and removes us properly. + */ + void ClearAdditiveAnimReferences(); + void FixUpBadAnimNotifiers(); + + static UBOOL CopyAnimSequenceProperties(UAnimSequence* SourceAnimSeq, UAnimSequence* DestAnimSeq, UBOOL bSkipCopyingNotifies=FALSE); + static void CopyMetadata(UAnimSequence* SourceAnimSeq, UAnimSequence* DestAnimSeq); + static UBOOL CopyNotifies(UAnimSequence* SourceAnimSeq, UAnimSequence* DestAnimSeq); +} + +/** + * Get the time (in seconds) from the start of the animation that the first notify of the given class would fire + * + * @param NotifyClass Class of AnimNotify we are looking for (ie AnimNotify_Sound) + * @param PlayRate Rate that animation would be played at + * @param StartPosition Initial position in the animation to start checking from + * @return Time in seconds that notify would fire if anim was played at given rate + * Returns -1.f if no notify is found + */ +native function float GetNotifyTimeByClass( class NotifyClass, optional float PlayRate = 1.f, optional float StartPosition = -1.f, optional out AnimNotify out_Notify, optional out float out_Duration ); + +defaultproperties +{ + RateScale=1.0 +} diff --git a/Engine/Classes/AnimSet.uc b/Engine/Classes/AnimSet.uc new file mode 100644 index 0000000..e0b1c2f --- /dev/null +++ b/Engine/Classes/AnimSet.uc @@ -0,0 +1,144 @@ +/** + * This is a set of AnimSequences + * All sequence have the same number of tracks, and they relate to the same bone names. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimSet extends Object + native(Anim) + hidecategories(Object); + + +/** This is a mapping table between each bone in a particular skeletal mesh and the tracks of this animation set. */ +struct native AnimSetMeshLinkup +{ + /** + * Mapping table. Size must be same as size of SkelMesh reference skeleton. + * No index should be more than the number of tracks in this AnimSet. + * -1 indicates no track for this bone - will use reference pose instead. + */ + var array BoneToTrackTable; + + structcpptext + { + /** Reset this linkup and re-create between the provided skeletal mesh and anim set. */ + void BuildLinkup(USkeletalMesh* InSkelMesh, UAnimSet* InAnimSet); + } +}; + +/** + * Indicates that only the rotation should be taken from the animation sequence and the translation should come from the SkeletalMesh ref pose. + * Note that the root bone always takes translation from the animation, even if this flag is set. + * You can use the UseTranslationBoneNames array to specify other bones that should use translation with this flag set. + */ +var() bool bAnimRotationOnly; + +/** Bone name that each track relates to. TrackBoneName.Num() == Number of tracks. */ +var array TrackBoneNames; + +/** Actual animation sequence information. */ +var array Sequences; +/** Lookup-cache, populated in PostLoad. */ +var native transient Map{FName,INT} SequenceCache; + +/** Non-serialised cache of linkups between different skeletal meshes and this AnimSet. */ +var transient array LinkupCache; +/** Runtime built mapping table between SkeletalMeshes, and LinkupCache array indices. */ +var native transient Map{FName,INT} SkelMesh2LinkupCache; +/** + * Array of booleans that indicate whether or not to read the translation of a bone from animation or ref skeleton. + * This is basically a cooked down version of UseTranslationBoneNames for speed. + * Size matches the number of tracks. + */ +var transient Array BoneUseAnimTranslation; +/** Cooked down version of ForceMeshTranslationBoneNames */ +var transient Array ForceUseMeshTranslation; + +/** Names of bones that should use translation from the animation, if bAnimRotationOnly is set. */ +var() Array UseTranslationBoneNames; +/** List of bones which are ALWAYS going to use their translation from the mesh and not the animation. */ +var() Array ForceMeshTranslationBoneNames; +/** In the AnimSetEditor, when you switch to this AnimSet, it sees if this skeletal mesh is loaded and if so switches to it. */ +var name PreviewSkelMeshName; +/** Holds the name of the skeletal mesh whose reference skeleton best matches the TrackBoneName array. */ +var name BestRatioSkelMeshName; + +cpptext +{ + // UObject interface + virtual void PreSave(); + virtual void PostLoad(); + virtual void BeginDestroy(); + + // UAnimSet interface + /** + * See if we can play sequences from this AnimSet on the provided SkeletalMesh. + * Returns true if there is a bone in SkelMesh for every track in the AnimSet, + * or there is a track of animation for every bone of the SkelMesh. + * + * @param SkelMesh SkeletalMesh to compare the AnimSet against. + * @return TRUE if animation set can play on supplied SkeletalMesh, FALSE if not. + */ + UBOOL CanPlayOnSkeletalMesh(USkeletalMesh* SkelMesh) const; + + /** Get Ratio of how much that mesh fits that animation set */ + FLOAT GetSkeletalMeshMatchRatio(USkeletalMesh* SkelMesh) const; + + /** + * Returns the AnimSequence with the specified name in this set. + * + * @param SequenceName Name of sequence to find. + * @return Pointer to AnimSequence with desired name, or NULL if sequence was not found. + */ + UAnimSequence* FindAnimSequence(FName SequenceName); + + /** + * Find a mesh linkup table (mapping of sequence tracks to bone indices) for a particular SkeletalMesh + * If one does not already exist, create it now. + */ + INT GetMeshLinkupIndex(USkeletalMesh* SkelMesh); + + /** + * @return The track index for the bone with the supplied name, or INDEX_NONE if no track exists for that bone. + */ + INT FindTrackWithName(FName BoneName) const + { + return TrackBoneNames.FindItemIndex( BoneName ); + } + + /** + * Returns the size of the object/ resource for display to artists/ LDs in the Editor. + * + * @return size of resource as to be displayed to artists/ LDs in the Editor. + */ + INT GetResourceSize(); + + /** + * Clears all sequences and resets the TrackBoneNames table. + */ + void ResetAnimSet(); + /** + * Properly remove an AnimSequence from an AnimSet, and updates references it might have. + * @return TRUE if AnimSequence was properly removed, FALSE if it wasn't found. + */ + UBOOL RemoveAnimSequenceFromAnimSet(UAnimSequence* AnimSeq); + + /** Util that find all AnimSets and flushes their LinkupCache, then calls InitAnimTree on all SkeletalMeshComponents. */ + static void ClearAllAnimSetLinkupCaches(); + + /** + * Animation Usage Tracking + */ + void TraceAnimationUsage(); + void RecordAnimationUsage(); + + static void OutputAnimationUsage(); + static void CleanUpAnimationUsage(); + static void TickAnimationUsage(); +} + +defaultproperties +{ + bAnimRotationOnly=true +} diff --git a/Engine/Classes/AnimTree.uc b/Engine/Classes/AnimTree.uc new file mode 100644 index 0000000..1ee9e1e --- /dev/null +++ b/Engine/Classes/AnimTree.uc @@ -0,0 +1,275 @@ + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimTree extends AnimNodeBlendBase + native(Anim) + hidecategories(Object); + +/** Anim Tree template we were created from, or None if we are a template */ +var() const AnimTree AnimTreeTemplate; + +/** Enable pooling for this AnimTree. This will pool freed copies of this AnimTree for later reuse */ +var() bool bEnablePooling; + +/** Definition of a group of AnimNodeSequences */ +struct native AnimGroup +{ + /** Cached array of AnimNodeSequence nodes to update. */ + var transient const Array SeqNodes; + /** Master node for synchronization. (Highest weight of the group) */ + var transient const AnimNodeSequence SynchMaster; + /** Master node for notifications. (Highest weight of the group) */ + var transient const AnimNodeSequence NotifyMaster; + /* Name of group. */ + var() const Name GroupName; + /** Rate Scale */ + var() const float RateScale; + /** Tracked Synch Position */ + var const float SynchPctPosition; + + structdefaultproperties + { + RateScale=1.f + } +}; + +/** List of animations groups */ +var() Array AnimGroups; + +/** + * Skeleton Branches that should be composed first. + * This is to solve Controllers relying on bones to be updated before them. + */ +var deprecated Array PrioritizedSkelBranches; + +var() Array ComposePrePassBoneNames; +var() Array ComposePostPassBoneNames; + +struct native SkelControlListHead +{ + /** Name of bone that this list of SkelControls will be executed after. */ + var name BoneName; + + /** First Control in the linked list of SkelControls to execute. */ + var editinline export SkelControlBase ControlHead; + + /** For editor use. */ + var editoronly int DrawY; +}; + +/** Root of tree of MorphNodes. */ +var editinline export array RootMorphNodes; + +/** Array of lists of SkelControls. Each list is executed after the bone specified using BoneName is updated with animation data. */ +var editinline export array SkelControlLists; + +/** Array for storing pose when bUseSavedPose is TRUE */ +var array SavedPose; + +/** If TRUE, AnimTree will always just return cached pose, rather than evaluating entire anim tree. */ +var bool bUseSavedPose; + +////// AnimTree Editor support + +/** Y position of MorphNode input on AnimTree. */ +var editoronly int MorphConnDrawY; + +/** Used to avoid editing the same AnimTree in multiple AnimTreeEditors at the same time. */ +var editoronly transient bool bBeingEdited; + +/** Play rate used when previewing animations */ +var() editoronly float PreviewPlayRate; + +// DEPRECATED Preview data, editor only +var deprecated editoronly SkeletalMesh PreviewSkelMesh; +var deprecated editoronly SkeletalMesh SocketSkelMesh; +var deprecated editoronly StaticMesh SocketStaticMesh; +var deprecated editoronly Name SocketName; +var deprecated editoronly array PreviewAnimSets; +var deprecated editoronly array PreviewMorphSets; + +/** Structure to hold a preview mesh, and a name for quick selection from within the editor */ +struct native PreviewSkelMeshStruct +{ + /** Display name in combo box */ + var() Name DisplayName; + /** Preview Skeletal Mesh */ + var() SkeletalMesh PreviewSkelMesh; + /** MorphTargetSets used when previewing this AnimTree in the AnimTreeEditor. */ + var() Array PreviewMorphSets; +}; +/** SkeletalMesh used when previewing this AnimTree in the AnimTreeEditor. */ +var() editoronly Array PreviewMeshList; +var editoronly INT PreviewMeshIndex; + +/** previewing of socket */ +struct native PreviewSocketStruct +{ + /** Preview Name for quick selection */ + var() Name DisplayName; + /** Name of socket to use */ + var() Name SocketName; + /** Attached preview skeletal mesh */ + var() SkeletalMesh PreviewSkelMesh; + /** Attached preview staticmesh */ + var() StaticMesh PreviewStaticMesh; +}; +var() editoronly Array PreviewSocketList; +var editoronly INT PreviewSocketIndex; + +/** AnimSets used when previewing this AnimTree in the AnimTreeEditor. */ +struct native PreviewAnimSetsStruct +{ + var() Name DisplayName; + var() Array PreviewAnimSets; +}; +var() editoronly Array PreviewAnimSetList; +var editoronly INT PreviewAnimSetListIndex; + +/** Preview AnimSet Index in the list - used to assign/preview for AnimSequenceNode **/ +var editoronly INT PreviewAnimSetIndex; + +/** Saved position of camera used for previewing skeletal mesh in AnimTreeEditor. */ +var editoronly vector PreviewCamPos; + +/** Saved orientation of camera used for previewing skeletal mesh in AnimTreeEditor. */ +var editoronly rotator PreviewCamRot; + +/** Saved position of floor mesh used for in AnimTreeEditor preview window. */ +var editoronly vector PreviewFloorPos; + +/** Saved yaw rotation of floor mesh used for in AnimTreeEditor preview window. */ +var editoronly int PreviewFloorYaw; + +var editoronly array AnimNodeFrames; + +////// End AnimTree Editor support + +/** Keep track if ParentNodeArray has been built. Needs to happen in editor. Otherwise, we have to build it at runtime. */ +var duplicatetransient BOOL bParentNodeArrayBuilt; +/** Copy of the AnimTickArray, to be serialized, and not rebuilt at run time. */ +var duplicatetransient Array AnimTickArray; +/** This is to notify (depending on version) to rebuild animtree. This information is saved during Serialize, and it will be used in InitAnimTree **/ +/** was going to make this transient, but because of cooking problem, changing this to non-transient. Once tree is converted, it will be saved **/ +var bool bRebuildAnimTickArray; + +cpptext +{ + virtual void PostLoad(); + virtual void PostAnimNodeInstance(UAnimNode* SourceNode, TMap& SrcToDestNodeMap); + virtual void ResetAnimNodeToSource(UAnimNode *SourceNode); + + virtual void InitAnim(USkeletalMeshComponent* meshComp, UAnimNodeBlendBase* Parent); + virtual void GetBoneAtoms(FBoneAtomArray& Atoms, const TArray& DesiredBones, FBoneAtom& RootMotionDelta, INT& bHasRootMotion, FCurveKeyArray& CurveKeys); + + /** Optimisation way to see if this is a UAnimTree */ + virtual UAnimTree* GetAnimTree() { return this; } + + /** Remove from Sync Group **/ + void RemoveFromSyncGroup(UAnimNodeSequence * SeqNode); + void SyncGroupPreTickUpdate(); + void UpdateAnimNodeSeqGroups(FLOAT DeltaSeconds); + void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + /** Get all SkelControls within this AnimTree. */ + void GetSkelControls(TArray& OutControls); + + /** Get all MorphNodes within this AnimTree. */ + void GetMorphNodes(TArray& OutNodes); + + /** Call InitMorph on all morph nodes attached to the tree. */ + void InitTreeMorphNodes(USkeletalMeshComponent* InSkelComp); + + /** Calls GetActiveMorphs on each element of the RootMorphNodes array. */ + void GetTreeActiveMorphs(TArray& OutMorphs); + + /** Make a copy of entire tree, including all AnimNodes and SkelControls. + * @param NewTreeOuter Component that will hold this + * @param bAcceptPooled If true, function is allowed to return pooled anim tree*/ + UAnimTree* CopyAnimTree(UObject* NewTreeOuter, UBOOL bAcceptPooled = FALSE); + + /** Returns this Anim Tree to the global pool, if it is safe to do so */ + void ReturnToPool(); + + /** Utility function to return the size of the AnimTree pool */ + static INT GetPoolSize(); + + /** Utility function for copying a selection of nodes, maintaining any references between them, but leaving any external references. */ + static void CopyAnimNodes(const TArray& SrcNodes, UObject* NewOuter, TArray& DestNodes, TMap& SrcToDestNodeMap); + + /** Utility function for copying a selection of controls, maintaining any references between them, but leaving any external references. */ + static void CopySkelControls(const TArray& SrcControls, UObject* NewOuter, TArray& DestControls, TMap& SrcToDestControlMap); + + /** Utility function for copying a selection of morph nodes, maintaining any references between them, but leaving any external references. */ + static void CopyMorphNodes(const TArray& SrcNodes, UObject* NewOuter, TArray& DestNodes, TMap& SrcToDestNodeMap); + + + // UAnimNode interface + virtual FIntPoint GetConnectionLocation(INT ConnType, INT ConnIndex); + + /** + * Draws this node in the AnimTreeEditor. + * + * @param Canvas The canvas to use. + * @param SelectedNodes Reference to array of all currently selected nodes, potentially including this node + * @param bShowWeight If TRUE, show the global percentage weight of this node, if applicable. + */ + virtual void DrawAnimNode(FCanvas* Canvas, const TArray& SelectedNodes, UBOOL bShowWeight); + + /** + * This returns total size for this animtree including animnodes, skelcontrols, morphnodes + * This is only for ListAnimTress to get idea of how much size each tree cost in run-time + * Do not use this in GetResourceSize as it will be calculate multiple times of same data + */ + INT GetTotalNodeBytes(); + + /** + * Custom Serialize function + * This function will save some information we can use in InitAnimTree + */ + void Serialize( FArchive& Ar ); +} + + +native final function SkelControlBase FindSkelControl(name InControlName); + +native final function MorphNodeBase FindMorphNode(name InNodeName); + +/** + * When passing in TRUE, will cause tree to evaluate and then save resulting pose. From then on will continue to use that saved pose instead of re-evaluating the tree + * This feature is turned off when the SkeletalMesh changes + */ +native final function SetUseSavedPose(bool bUseSaved); + +// +// Anim Groups +// + +/** Add a node to an existing anim group */ +native final function bool SetAnimGroupForNode(AnimNodeSequence SeqNode, Name GroupName, optional bool bCreateIfNotFound); +/** Returns the master node driving synchronization for this group. */ +native final function AnimNodeSequence GetGroupSynchMaster(Name GroupName); +/** Returns the master node driving notifications for this group. */ +native final function AnimNodeSequence GetGroupNotifyMaster(Name GroupName); +/** Force a group at a relative position. */ +native final function ForceGroupRelativePosition(Name GroupName, FLOAT RelativePosition); +/** Get the relative position of a group. */ +native final function float GetGroupRelativePosition(Name GroupName); +/** Adjust the Rate Scale of a group */ +native final function SetGroupRateScale(Name GroupName, FLOAT NewRateScale); +/** Get the Rate Scale of a group */ +native final function float GetGroupRateScale(Name GroupName); +/** + * Returns the index in the AnimGroups list of a given GroupName. + * If group cannot be found, then INDEX_NONE will be returned. + */ +native final function INT GetGroupIndex(Name GroupName); + +defaultproperties +{ + Children(0)=(Name="Child",Weight=1.0) + bFixNumChildren=TRUE + PreviewPlayRate=1.f +} diff --git a/Engine/Classes/AnimationCompressionAlgorithm.uc b/Engine/Classes/AnimationCompressionAlgorithm.uc new file mode 100644 index 0000000..d1bdf96 --- /dev/null +++ b/Engine/Classes/AnimationCompressionAlgorithm.uc @@ -0,0 +1,236 @@ +/** + * Baseclass for animation compression algorithms. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimationCompressionAlgorithm extends Object + abstract + native(Anim) + DependsOn(AnimSequence) + hidecategories(Object); + +/** A human-readable name for this modifier; appears in editor UI. */ +var string Description; + +/** Compression algorithms requiring a skeleton should set this value to TRUE. */ +var bool bNeedsSkeleton; + +/** Format for bitwise compression of translation data. */ +var AnimationCompressionFormat TranslationCompressionFormat; + +/** Format for bitwise compression of rotation data. */ +var() AnimationCompressionFormat RotationCompressionFormat; + +cpptext +{ +public: + /** + * Reduce the number of keyframes and bitwise compress the specified sequence. + * + * @param AnimSeq The animation sequence to compress. + * @param SkelMesh The skeletal mesh against which to compress the animation. Not needed by all compression schemes. + * @param bOutput If FALSE don't generate output or compute memory savings. + * @return FALSE if a skeleton was needed by the algorithm but not provided. + */ + UBOOL Reduce(class UAnimSequence* AnimSeq, class USkeletalMesh* SkelMesh, UBOOL bOutput); + + /** + * Reduce the number of keyframes and bitwise compress all sequences in the specified animation set. + * + * @param AnimSet The animation set to compress. + * @param SkelMesh The skeletal mesh against which to compress the animation. Not needed by all compression schemes. + * @param bOutput If FALSE don't generate output or compute memory savings. + * @return FALSE if a skeleton was needed by the algorithm but not provided. + */ + UBOOL Reduce(class UAnimSet* AnimSet, class USkeletalMesh* SkelMesh, UBOOL bOutput); + +protected: + /** + * Implemented by child classes, this function reduces the number of keyframes in + * the specified sequence, given the specified skeleton (if needed). + * + * @return TRUE if the keyframe reduction was successful. + */ + virtual void DoReduction(class UAnimSequence* AnimSeq, class USkeletalMesh* SkelMesh, const TArray& BoneData) PURE_VIRTUAL(UAnimationCompressionAlgorithm::DoReduction,); + + /** + * Common compression utility to remove 'redundant' position keys in a set of tracks based on the provided delta threshold + * + * @param InputTracks Array of position track elements to reduce + * @param MaxPosDelta Maximum local-space threshold for stationary motion + */ + static void FilterTrivialPositionKeys( + TArray& Track, + FLOAT MaxPosDelta); + + /** + * Common compression utility to remove 'redundant' position keys in a single track based on the provided delta threshold + * + * @param Track Track to reduce + * @param MaxPosDelta Maximum local-space threshold for stationary motion + */ + static void FilterTrivialPositionKeys( + struct FTranslationTrack& Track, + FLOAT MaxPosDelta); + + /** + * Common compression utility to remove 'redundant' rotation keys in a set of tracks based on the provided delta threshold + * + * @param InputTracks Array of rotation track elements to reduce + * @param MaxRotDelta Maximum angle threshold to consider stationary motion + */ + static void FilterTrivialRotationKeys( + TArray& InputTracks, + FLOAT MaxRotDelta); + + /** + * Common compression utility to remove 'redundant' rotation keys in a set of tracks based on the provided delta threshold + * + * @param Track Track to reduce + * @param MaxRotDelta Maximum angle threshold to consider stationary motion + */ + static void FilterTrivialRotationKeys( + struct FRotationTrack& Track, + FLOAT MaxRotDelta); + + /** + * Common compression utility to remove 'redundant' keys based on the provided delta thresholds + * + * @param PositionTracks Array of position track elements to reduce + * @param RotationTracks Array of rotation track elements to reduce + * @param MaxPosDelta Maximum local-space threshold for stationary motion + * @param MaxRotDelta Maximum angle threshold to consider stationary motion + */ + static void FilterTrivialKeys( + TArray& PositionTracks, + TArray& RotationTracks, + FLOAT MaxPosDelta, + FLOAT MaxRotDelta); + + /** + * Remove translation keys from tracks marked bAnimRotationOnly. + * + * @param PositionTracks Array of position track elements to reduce + * @param AnimSeq AnimSequence the track is from. + * @param SkelMesh SkeletalMesh associated with the AnimSerquence + */ + static void FilterAnimRotationOnlyKeys(TArray& PositionTracks, UAnimSequence* AnimSeq, USkeletalMesh* SkelMesh); + + /** + * Common compression utility to retain only intermittent position keys. For example, + * calling with an Interval of 3 would keep every third key in the set and discard the rest + * + * @param PositionTracks Array of position track elements to reduce + * @param StartIndex Index at which to begin reduction + * @param Interval Interval of keys to retain + */ + static void FilterIntermittentPositionKeys( + TArray& PositionTracks, + INT StartIndex, + INT Interval); + + /** + * Common compression utility to retain only intermittent position keys. For example, + * calling with an Interval of 3 would keep every third key in the set and discard the rest + * + * @param Track Track to reduce + * @param StartIndex Index at which to begin reduction + * @param Interval Interval of keys to retain + */ + static void FilterIntermittentPositionKeys( + struct FTranslationTrack& Track, + INT StartIndex, + INT Interval); + + /** + * Common compression utility to retain only intermittent rotation keys. For example, + * calling with an Interval of 3 would keep every third key in the set and discard the rest + * + * @param RotationTracks Array of rotation track elements to reduce + * @param StartIndex Index at which to begin reduction + * @param Interval Interval of keys to retain + */ + static void FilterIntermittentRotationKeys( + TArray& RotationTracks, + INT StartIndex, + INT Interval); + + /** + * Common compression utility to retain only intermittent rotation keys. For example, + * calling with an Interval of 3 would keep every third key in the set and discard the rest + * + * @param Track Track to reduce + * @param StartIndex Index at which to begin reduction + * @param Interval Interval of keys to retain + */ + static void FilterIntermittentRotationKeys( + struct FRotationTrack& Track, + INT StartIndex, + INT Interval); + + /** + * Common compression utility to retain only intermittent animation keys. For example, + * calling with an Interval of 3 would keep every third key in the set and discard the rest + * + * @param PositionTracks Array of position track elements to reduce + * @param RotationTracks Array of rotation track elements to reduce + * @param StartIndex Index at which to begin reduction + * @param Interval Interval of keys to retain + */ + static void FilterIntermittentKeys( + TArray& PositionTracks, + TArray& RotationTracks, + INT StartIndex, + INT Interval); + + /** + * Common compression utility to populate individual rotation and translation track + * arrays from a set of raw animation tracks. Used as a precurser to animation compression. + * + * @param RawAnimData Array of raw animation tracks + * @param SequenceLength The duration of the animation in seconds + * @param OutTranslationData Translation tracks to fill + * @param OutRotationData Rotation tracks to fill + */ + static void SeparateRawDataIntoTracks( + const TArray& RawAnimData, + FLOAT SequenceLength, + TArray& OutTranslationData, + TArray& OutRotationData); + + /** + * Common compression utility to walk an array of rotation tracks and enforce + * that all adjacent rotation keys are represented by shortest-arc quaternion pairs. + * + * @param RotationData Array of rotation track elements to reduce. + */ + static void PrecalculateShortestQuaternionRoutes(TArray& RotationData); + +public: + + /** + * Encodes individual key arrays into an AnimSequence using the desired bit packing formats. + * + * @param Seq Pointer to an Animation Sequence which will contain the bit-packed data . + * @param TargetTranslationFormat The format to use when encoding translation keys. + * @param TargetRotationFormat The format to use when encoding rotation keys. + * @param TranslationData Translation Tracks to bit-pack into the Animation Sequence. + * @param RotationData Rotation Tracks to bit-pack into the Animation Sequence. + * @param IncludeKeyTable TRUE if the compressed data should also contain a table of frame indices for each key. (required by some codecs) + */ + static void BitwiseCompressAnimationTracks( + class UAnimSequence* Seq, + AnimationCompressionFormat TargetTranslationFormat, + AnimationCompressionFormat TargetRotationFormat, + const TArray& TranslationData, + const TArray& RotationData, + UBOOL IncludeKeyTable = FALSE); +} + +defaultproperties +{ + Description="None" + TranslationCompressionFormat=ACF_None + RotationCompressionFormat=ACF_Float96NoW +} diff --git a/Engine/Classes/AnimationCompressionAlgorithm_Automatic.uc b/Engine/Classes/AnimationCompressionAlgorithm_Automatic.uc new file mode 100644 index 0000000..bd75bb0 --- /dev/null +++ b/Engine/Classes/AnimationCompressionAlgorithm_Automatic.uc @@ -0,0 +1,51 @@ +/** + * Animation compression algorithm that is just a shell for trying the range of other compression schemes and pikcing the + * smallest result within a configurable error threshold. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimationCompressionAlgorithm_Automatic extends AnimationCompressionAlgorithm + hidecategories(AnimationCompressionAlgorithm) + native(Anim); + +/** Maximum amount of error that a compression technique can introduce in an end effector */ +var() float MaxEndEffectorError; + +var() bool bTryFixedBitwiseCompression; +var() bool bTryPerTrackBitwiseCompression; +var() bool bTryLinearKeyRemovalCompression; +var() bool bTryIntervalKeyRemoval; + +var() bool bRunCurrentDefaultCompressor; + +var() bool bAutoReplaceIfExistingErrorTooGreat; +var() bool bRaiseMaxErrorToExisting; + +cpptext +{ +protected: + /** + * Animation compression algorithm that optionally: + * 1) Forcefully removes a portion of keys (every other key, 2 out of every 3, etc...) + * 2) Removes any keys which can be linearly approximated by neighboring keys + * but always packs each track using per-track compression settings. + */ + virtual void DoReduction(class UAnimSequence* AnimSeq, class USkeletalMesh* SkelMesh, const TArray& BoneData); +} + +defaultproperties +{ + Description="Automatic" + + // Error threshold + MaxEndEffectorError = 1.0 + bTryFixedBitwiseCompression = TRUE + bTryPerTrackBitwiseCompression = TRUE + bTryLinearKeyRemovalCompression = TRUE + bTryIntervalKeyRemoval = TRUE + + bRunCurrentDefaultCompressor = FALSE + bAutoReplaceIfExistingErrorTooGreat = FALSE + bRaiseMaxErrorToExisting = FALSE +} diff --git a/Engine/Classes/AnimationCompressionAlgorithm_BitwiseCompressOnly.uc b/Engine/Classes/AnimationCompressionAlgorithm_BitwiseCompressOnly.uc new file mode 100644 index 0000000..6608d2d --- /dev/null +++ b/Engine/Classes/AnimationCompressionAlgorithm_BitwiseCompressOnly.uc @@ -0,0 +1,22 @@ +/** + * Bitwise animation compression only; performs no key reduction. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimationCompressionAlgorithm_BitwiseCompressOnly extends AnimationCompressionAlgorithm + native(Anim); + +cpptext +{ +protected: + /** + * Bitwise animation compression only; performs no key reduction. + */ + virtual void DoReduction(class UAnimSequence* AnimSeq, class USkeletalMesh* SkelMesh, const TArray& BoneData); +} + +defaultproperties +{ + Description="Bitwise Compress Only" +} diff --git a/Engine/Classes/AnimationCompressionAlgorithm_LeastDestructive.uc b/Engine/Classes/AnimationCompressionAlgorithm_LeastDestructive.uc new file mode 100644 index 0000000..fdb5e04 --- /dev/null +++ b/Engine/Classes/AnimationCompressionAlgorithm_LeastDestructive.uc @@ -0,0 +1,24 @@ +/** + * Reverts any animation compression, restoring the animation to the raw data. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimationCompressionAlgorithm_LeastDestructive extends AnimationCompressionAlgorithm + native(Anim); + +cpptext +{ +protected: + /** + * Uses the Bitwise compressor, with really light settings, so it acts pretty close to "no compression at all" + */ + virtual void DoReduction(class UAnimSequence* AnimSeq, class USkeletalMesh* SkelMesh, const TArray& BoneData); +} + +defaultproperties +{ + Description="Least Destructive" + TranslationCompressionFormat=ACF_None + RotationCompressionFormat=ACF_None +} diff --git a/Engine/Classes/AnimationCompressionAlgorithm_PerTrackCompression.uc b/Engine/Classes/AnimationCompressionAlgorithm_PerTrackCompression.uc new file mode 100644 index 0000000..af1aad7 --- /dev/null +++ b/Engine/Classes/AnimationCompressionAlgorithm_PerTrackCompression.uc @@ -0,0 +1,177 @@ +/** + * Keyframe reduction algorithm that removes keys which are linear interpolations of surrounding keys, as + * well as choosing the best bitwise compression for each track independently. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimationCompressionAlgorithm_PerTrackCompression extends AnimationCompressionAlgorithm_RemoveLinearKeys + hidecategories(AnimationCompressionAlgorithm) + native(Anim); + +/** Maximum threshold to use when replacing a component with zero. Lower values retain more keys, but yield less compression. */ +var(PerTrack) float MaxZeroingThreshold; + +/** Maximum position difference to use when testing if an animation key may be removed. Lower values retain more keys, but yield less compression. */ +var(PerTrack) float MaxPosDiffBitwise; + +/** Maximum angle difference to use when testing if an animation key may be removed. Lower values retain more keys, but yield less compression. */ +var(PerTrack) float MaxAngleDiffBitwise; + +/** Which encoding formats is the per-track compressor allowed to try on rotation keys */ +var(PerTrack) array AllowedRotationFormats; + +/** Which encoding formats is the per-track compressor allowed to try on translation keys */ +var(PerTrack) array AllowedTranslationFormats; + + +/** If TRUE, resample the animation to ResampleFramerate frames per second */ +var(Resampling) bool bResampleAnimation; + +/** When bResampleAnimation is true, this defines the desired framerate */ +var(Resampling) float ResampledFramerate; + +/** Animations with fewer keys than MinKeysForResampling will not be resampled. */ +var(Resampling) int MinKeysForResampling; + + +/** If TRUE, adjust the error thresholds based on the 'height' within the skeleton */ +var(AdaptiveError) bool bUseAdaptiveError; + +/** If TRUE, uses MinEffectorDiff as the threhsold for end effectors */ +var(AdaptiveError) bool bUseOverrideForEndEffectors; + +/** A bias added to the track height before using it to calculate the adaptive error */ +var(AdaptiveError) int TrackHeightBias; + +/** + * Reduces the error tolerance the further up the tree that a key occurs + * EffectiveErrorTolerance = Max(BaseErrorTolerance / Power(ParentingDivisor, Max(Height+Bias,0) * ParentingDivisorExponent), ZeroingThreshold) + * Only has an effect bUseAdaptiveError is TRUE + */ +var(AdaptiveError) float ParentingDivisor; + +/** + * Reduces the error tolerance the further up the tree that a key occurs + * EffectiveErrorTolerance = Max(BaseErrorTolerance / Power(ParentingDivisor, Max(Height+Bias,0) * ParentingDivisorExponent), ZeroingThreshold) + * Only has an effect bUseAdaptiveError is TRUE + */ +var(AdaptiveError) float ParentingDivisorExponent; + + +/** + * If true, the adaptive error system will determine how much error to allow for each track, based on the + * error introduced in end effectors due to errors in the track. + */ +var(AdaptiveError2) bool bUseAdaptiveError2; + +/** + * This ratio determines how much error in end effector rotation can come from a given track's rotation error or translation error. + * If 1, all of it must come from rotation error, if 0.5, half can come from each, and if 0.0, all must come from translation error. + */ +var(AdaptiveError2) float RotationErrorSourceRatio; + +/** + * This ratio determines how much error in end effector translation can come from a given track's rotation error or translation error. + * If 1, all of it must come from rotation error, if 0.5, half can come from each, and if 0.0, all must come from translation error. + */ +var(AdaptiveError2) float TranslationErrorSourceRatio; + +/** + * A fraction that determines how much of the total error budget can be introduced by any particular track + */ +var(AdaptiveError2) float MaxErrorPerTrackRatio; + +/** + * How big of a perturbation should be made when probing error propagation + */ +var float PerturbationProbeSize; + +/** + * Cached metastructures used within DoReduction, tied to a particular sequence and mesh + */ +var const native transient pointer PerReductionCachedData{struct FPerTrackCachedInfo}; + +cpptext +{ +protected: + /** + * Animation compression algorithm that optionally: + * 1) Forcefully removes a portion of keys (every other key, 2 out of every 3, etc...) + * 2) Removes any keys which can be linearly approximated by neighboring keys + * but always packs each track using per-track compression settings. + */ + virtual void DoReduction(class UAnimSequence* AnimSeq, class USkeletalMesh* SkelMesh, const TArray& BoneData); + + /** + * Compresses the tracks passed in using the underlying compressor for this key removal codec + */ + virtual void CompressUsingUnderlyingCompressor( + UAnimSequence* AnimSeq, + USkeletalMesh* SkelMesh, + const struct FAnimSetMeshLinkup& AnimLinkup, + const TArray& BoneData, + const TArray& TranslationData, + const TArray& RotationData, + const UBOOL bFinalPass); + + /** + * Pre-filters the tracks before running the main key removal algorithm + */ + virtual void FilterBeforeMainKeyRemoval( + UAnimSequence* AnimSeq, + USkeletalMesh* SkelMesh, + const struct FAnimSetMeshLinkup& AnimLinkup, + const TArray& BoneData, + TArray& TranslationData, + TArray& RotationData); +} + +defaultproperties +{ + Description="Compress each track independently" + + // Bitwise settings + MaxPosDiffBitwise = 0.007 + MaxAngleDiffBitwise = 0.002 + MaxZeroingThreshold = 0.0002 + + // Settings for resampling + ResampledFramerate = 15.0 + bResampleAnimation = FALSE + MinKeysForResampling = 10; + + // Settings for linear key removal (disabled by default) + bRetarget = FALSE + bActuallyFilterLinearKeys = FALSE + + // Settings for adaptive error thresholds + bUseAdaptiveError = FALSE + ParentingDivisor = 1.0 + ParentingDivisorExponent = 1.0 + TrackHeightBias = 1 + bUseOverrideForEndEffectors = FALSE + + + // Settings for adaptive error mode 2 + bUseAdaptiveError2 = FALSE + RotationErrorSourceRatio = 0.8 + TranslationErrorSourceRatio = 0.8 + MaxErrorPerTrackRatio = 0.3 + PerturbationProbeSize = 0.001 + + + // Allowed rotation formats + AllowedRotationFormats[0] = ACF_Identity + AllowedRotationFormats[1] = ACF_Fixed48NoW + + // Those below produce too much error (shaking), and have the side effect of producing worse overall compression, so they are being removed for now. +// AllowedRotationFormats[2] = ACF_IntervalFixed32NoW +// AllowedRotationFormats[3] = ACF_Fixed32NoW +// AllowedRotationFormats[4] = ACF_Float32NoW + + // Allowed translation formats + AllowedTranslationFormats[0] = ACF_Identity + AllowedTranslationFormats[1] = ACF_IntervalFixed32NoW + AllowedTranslationFormats[2] = ACF_Fixed48NoW +} diff --git a/Engine/Classes/AnimationCompressionAlgorithm_RemoveEverySecondKey.uc b/Engine/Classes/AnimationCompressionAlgorithm_RemoveEverySecondKey.uc new file mode 100644 index 0000000..7442f9f --- /dev/null +++ b/Engine/Classes/AnimationCompressionAlgorithm_RemoveEverySecondKey.uc @@ -0,0 +1,34 @@ +/** + * Keyframe reduction algorithm that simply removes every second key. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimationCompressionAlgorithm_RemoveEverySecondKey extends AnimationCompressionAlgorithm + native(Anim); + +/** Animations with fewer than MinKeys will not lose any keys. */ +var() int MinKeys; + +/** + * If bStartAtSecondKey is TRUE, remove keys 1,3,5,etc. + * If bStartAtSecondKey is FALSE, remove keys 0,2,4,etc. + */ +var() bool bStartAtSecondKey; + +cpptext +{ +protected: + /** + * Keyframe reduction algorithm that simply removes every second key. + * + * @return TRUE if the keyframe reduction was successful. + */ + virtual void DoReduction(class UAnimSequence* AnimSeq, class USkeletalMesh* SkelMesh, const TArray& BoneData); +} + +defaultproperties +{ + Description="Remove Every Second Key" + MinKeys=10 +} diff --git a/Engine/Classes/AnimationCompressionAlgorithm_RemoveLinearKeys.uc b/Engine/Classes/AnimationCompressionAlgorithm_RemoveLinearKeys.uc new file mode 100644 index 0000000..43d9351 --- /dev/null +++ b/Engine/Classes/AnimationCompressionAlgorithm_RemoveLinearKeys.uc @@ -0,0 +1,183 @@ +/** + * Keyframe reduction algorithm that simply removes keys which are linear interpolations of surrounding keys. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimationCompressionAlgorithm_RemoveLinearKeys extends AnimationCompressionAlgorithm + native(Anim); + +/** Maximum position difference to use when testing if an animation key may be removed. Lower values retain more keys, but yield less compression. */ +var(LinearKeyRemoval) float MaxPosDiff; + +/** Maximum angle difference to use when testing if an animation key may be removed. Lower values retain more keys, but yield less compression. */ +var(LinearKeyRemoval) float MaxAngleDiff; + +/** + * As keys are tested for removal, we monitor the effects all the way down to the end effectors. + * If their position changes by more than this amount as a result of removing a key, the key will be retained. + * This value is used for all bones except the end-effectors parent. + */ +var(LinearKeyRemoval) float MaxEffectorDiff; + +/** + * As keys are tested for removal, we monitor the effects all the way down to the end effectors. + * If their position changes by more than this amount as a result of removing a key, the key will be retained. + * This value is used for the end-effectors parent, allowing tighter restrictions near the end of a skeletal chain. + */ +var(LinearKeyRemoval) float MinEffectorDiff; + +/** + * Error threshold for End Effectors with Sockets attached to them. + * Typically more important bone, where we want to be less aggressive with compression. + */ +var(LinearKeyRemoval) float EffectorDiffSocket; + +/** + * A scale value which increases the likelihood that a bone will retain a key if it's parent also had a key at the same time position. + * Higher values can remove shaking artifacts from the animation, at the cost of compression. + */ +var(LinearKeyRemoval) float ParentKeyScale; + +/** + * TRUE = As the animation is compressed, adjust animated nodes to compensate for compression error. + * FALSE= Do not adjust animated nodes. + */ +var(LinearKeyRemoval) bool bRetarget; + +/** + * Controls whether the final filtering step will occur, or only the retargetting after bitwise compression. + * If both this and bRetarget are false, then the linear compressor will do no better than the underlying bitwise compressor, extremely slowly. + */ +var(LinearKeyRemoval) bool bActuallyFilterLinearKeys; + +cpptext +{ +protected: + /** + * Keyframe reduction algorithm that removes any keys which can be linearly approximated by neighboring keys. + */ + virtual void DoReduction(class UAnimSequence* AnimSeq, class USkeletalMesh* SkelMesh, const TArray& BoneData); + + /** + * Pre-filters the tracks before running the main key removal algorithm + */ + virtual void FilterBeforeMainKeyRemoval( + UAnimSequence* AnimSeq, + USkeletalMesh* SkelMesh, + const struct FAnimSetMeshLinkup& AnimLinkup, + const TArray& BoneData, + TArray& TranslationData, + TArray& RotationData); + + /** + * Compresses the tracks passed in using the underlying compressor for this key removal codec + */ + virtual void CompressUsingUnderlyingCompressor( + UAnimSequence* AnimSeq, + USkeletalMesh* SkelMesh, + const struct FAnimSetMeshLinkup& AnimLinkup, + const TArray& BoneData, + const TArray& TranslationData, + const TArray& RotationData, + const UBOOL bFinalPass); + + /** + * Updates the world bone transforms for a range of bone indices + */ + void UpdateWorldBoneTransformRange( + UAnimSequence* AnimSeq, + USkeletalMesh* SkelMesh, + const TArray& BoneData, + const struct FAnimSetMeshLinkup& AnimLinkup, + const TArray& RefSkel, + const TArray& PositionTracks, + const TArray& RotationTracks, + INT StartingBoneIndex, + INT EndingBoneIndex, + UBOOL UseRaw, + TArray& OutputWorldBones); + + /** + * To guide the key removal process, we need to maintain a table of world transforms + * for the bones we are investigating. This helper function fills a row of the + * table for a specified bone. + */ + void UpdateWorldBoneTransformTable( + UAnimSequence* AnimSeq, + USkeletalMesh* SkelMesh, + const TArray& BoneData, + const struct FAnimSetMeshLinkup& AnimLinkup, + const TArray& RefSkel, + INT BoneIndex, + UBOOL UseRaw, + TArray& OutputWorldBones); + + /** + * Creates a list of the bone atom result for every frame of a given track + */ + static void UpdateBoneAtomList( + UAnimSequence* AnimSeq, + INT BoneIndex, + INT TrackIndex, + INT NumFrames, + FLOAT TimePerFrame, + TArray& BoneAtoms, + const struct FAnimSetMeshLinkup& AnimLinkup, + const TArray& RefSkel); + + /** + * If the passed in animation sequence is additive, converts it to absolute (using the frame 0 pose) and returns TRUE + * (indicating it should be converted back to relative later with ConvertToRelativeSpace) + * + * @param AnimSeq The animation sequence being compressed + * + * @return TRUE if the animation was additive and has been converted to absolute space. + */ + UBOOL ConvertFromRelativeSpace(UAnimSequence* AnimSeq, const struct FAnimSetMeshLinkup& AnimLinkup); + + /** + * Converts an absolute animation sequence to a relative (additive) one. + * + * @param AnimSeq The animation sequence being compressed + * @param TranslationData Translation Tracks to convert to relative space + * @param RotationData Rotation Tracks to convert to relative space + * + */ + void ConvertToRelativeSpace(UAnimSequence* AnimSeq, TArray& TranslationData, TArray& RotationData, const struct FAnimSetMeshLinkup& AnimLinkup); + + /** + * Locates spans of keys within the position and rotation tracks provided which can be estimated + * through linear interpolation of the surrounding keys. The remaining key values are bit packed into + * the animation sequence provided + * + * @param AnimSeq The animation sequence being compressed + * @param SkelMesh The skeletal mesh to use to guide the compressor + * @param AnimLinkup The linkup between skeletal mesh an animation + * @param BoneData BoneData array describing the hierarchy of the animated skeleton + * @param TranslationData Translation Tracks to compress and bit-pack into the Animation Sequence. + * @param RotationData Rotation Tracks to compress and bit-pack into the Animation Sequence. + * @return None. + */ + void ProcessAnimationTracks( + UAnimSequence* AnimSeq, + USkeletalMesh* SkelMesh, + const struct FAnimSetMeshLinkup& AnimLinkup, + const TArray& BoneData, + TArray& PositionTracks, + TArray& RotationTracks); +} + +defaultproperties +{ + bNeedsSkeleton = TRUE + Description = "Remove Linear Keys" + MaxPosDiff = 0.001f + MaxAngleDiff = 0.00075f + MaxEffectorDiff = 0.001f // used to be 0.2 + MinEffectorDiff = 0.001f // used to be 0.1 + EffectorDiffSocket = 0.001f + ParentKeyScale = 2.0 + bRetarget = TRUE + bActuallyFilterLinearKeys = TRUE +} diff --git a/Engine/Classes/AnimationCompressionAlgorithm_RemoveTrivialKeys.uc b/Engine/Classes/AnimationCompressionAlgorithm_RemoveTrivialKeys.uc new file mode 100644 index 0000000..a4644ad --- /dev/null +++ b/Engine/Classes/AnimationCompressionAlgorithm_RemoveTrivialKeys.uc @@ -0,0 +1,34 @@ +/** + * Removes trivial frames -- frames of tracks when position or orientation is constant + * over the entire animation -- from the raw animation data. If both position and rotation + * go down to a single frame, the time is stripped out as well. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimationCompressionAlgorithm_RemoveTrivialKeys extends AnimationCompressionAlgorithm + native(Anim); + +var() float MaxPosDiff; +var() float MaxAngleDiff; + +cpptext +{ +protected: + /** + * Removes trivial frames -- frames of tracks when position or orientation is constant + * over the entire animation -- from the raw animation data. If both position and rotation + * go down to a single frame, the time is stripped out as well. + * + * @return TRUE if the keyframe reduction was successful. + */ + virtual void DoReduction(class UAnimSequence* AnimSeq, class USkeletalMesh* SkelMesh, const TArray& BoneData); +} + +defaultproperties +{ + Description="Remove Trivial Keys" + + MaxPosDiff=0.0001 + MaxAngleDiff=0.0003 +} diff --git a/Engine/Classes/AnimationCompressionAlgorithm_RevertToRaw.uc b/Engine/Classes/AnimationCompressionAlgorithm_RevertToRaw.uc new file mode 100644 index 0000000..95e081b --- /dev/null +++ b/Engine/Classes/AnimationCompressionAlgorithm_RevertToRaw.uc @@ -0,0 +1,25 @@ +/** + * Reverts any animation compression, restoring the animation to the raw data. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AnimationCompressionAlgorithm_RevertToRaw extends AnimationCompressionAlgorithm + native(Anim) + deprecated; + +cpptext +{ +protected: + /** + * Reverts any animation compression, restoring the animation to the raw data. + */ + virtual void DoReduction(class UAnimSequence* AnimSeq, class USkeletalMesh* SkelMesh, const TArray& BoneData); +} + +defaultproperties +{ + Description="Revert To Raw" + TranslationCompressionFormat=ACF_None + RotationCompressionFormat=ACF_None +} diff --git a/Engine/Classes/ApexAsset.uc b/Engine/Classes/ApexAsset.uc new file mode 100644 index 0000000..db21ee2 --- /dev/null +++ b/Engine/Classes/ApexAsset.uc @@ -0,0 +1,61 @@ +/*============================================================================= + ApexAsset.uc: Wrapper for an NxApexAsset, an APEX base class. Apex Asset + Copyright 2008-2009 NVIDIA corporation. +=============================================================================*/ + +/**** +* This is the base class for ApexAssets +* +**/ +class ApexAsset extends Object + hidecategories(Object) + native(Mesh); + +var const editinline string OriginalApexName; +var native transient const array ApexComponents; +var() const editinlineuse editoronly array NamedReferences; +var() const editconst editoronly string SourceFilePath; +var() const editconst editoronly string SourceFileTimestamp; + +cpptext +{ + public: + /** Display strings for the generic browser */ + virtual TArray GetGenericBrowserInfo(); + + /** virtual method to return the number of materials used by this asset */ + virtual UINT GetNumMaterials(void) const { return 0; } + /** virtual method to return a particular material by index */ + virtual UMaterialInterface *GetMaterial(UINT Index) const { return 0; } + /** Returns the default ::NxParameterized::Interface describing the Actor Desc for this asset. */ + virtual void * GetNxParameterized(void) { return 0; }; + /** Returns a *copy* of the :NxParameterized::Interface for this asset. Caller must manually 'destroy' it.*/ + virtual void * GetAssetNxParameterized(void) { return 0; }; + /*** Export asset to a file, in xml/bin format. + ** + ** @param Name: The name of file name for exported asset + ** @param isKeepUE3Coords: Export type, in original coords (true) or keep UE3 coords (false) + ** + **/ + virtual UBOOL Export(const FName& Name, UBOOL isKeepUE3Coords){ return true; }; + /** Re-assigns the APEX material resources by name with the current array of UE3 materials */ + virtual void UpdateMaterials(void) { }; + + + virtual void ResetNamedReferences(void); + virtual void AddNamedReference(class UApexAsset *obj); + virtual void RemoveNamedReference(class UApexAsset *obj); + virtual void NotifyApexEditMode(class ApexEditInterface *iface) { }; + + /** Whether the APEX asset's materials can be overridden in the actor's ApexComponent */ + virtual UBOOL SupportsMaterialOverride() const { return FALSE; } + + protected: + // Called when the Asset gets rebuilt (in editor only). + void OnApexAssetLost(void); + void OnApexAssetReset(void); +} + +defaultproperties +{ +} diff --git a/Engine/Classes/ApexClothingAsset.uc b/Engine/Classes/ApexClothingAsset.uc new file mode 100644 index 0000000..fff0ffa --- /dev/null +++ b/Engine/Classes/ApexClothingAsset.uc @@ -0,0 +1,171 @@ +/*============================================================================= + ApexClothingAsset.h: PhysX APEX integration. Clothing Asset + Copyright 2008-2009 NVIDIA Corporation. +=============================================================================*/ + +class ApexClothingAsset extends ApexAsset + hidecategories(Object) + native(Mesh); + +struct native ClothingLodInfo +{ + /** Mapping of clothing submesh to material array */ + var() const init editfixedsize array LODMaterialMap; +}; +/** Clothing Material Mapping for each graphical lod level */ +var() const editfixedsize array LodMaterialInfo; +var native pointer MApexAsset{class FIApexAsset}; +/** Clothing material override. Used only when UseClothingAssetMaterial is checked in the skeletal mesh component. */ +var() const editfixedsize array Materials; + +/** ApexClothingLibrary is only for legacy APEX 0.9 assets. */ +var const deprecated ApexGenericAsset ApexClothingLibrary; + +var() const bool bUseHardwareCloth; // if true use hardware clothing for simulation +var() const bool bFallbackSkinning; // if true, falls back to skinning clothing in software instead of using GPU skinning +var() const bool bSlowStart; // Designates the 'slowStart' flag; see APEX clothing documentation +var() const bool bRecomputeNormals; // Designates the 'recomputeNormals' flag; see APEX clothing documentation +var() const bool bAllowAdaptiveTargetFrequency; // Slightly modifies gravity to avoid high frequency jittering due to variable time steps. +var() const int UVChannelForTangentUpdate; // Which UV channel is used for updating tangent space. +var() const float MaxDistanceBlendTime; // The maximimum distance blend time (see APEX clothing documentation) +var() const float ContinuousRotationThreshold; // The angle in degrees to consider the clothing simulation continuous. +var() const float ContinuousDistanceThreshold; // The distance to consider the clothing simulation continuous. +var() const bool bResetAfterTeleport; // If true, it resets the simulation after a teleport. +var() const float LodWeightsMaxDistance; // LodWeightMaxDistance (see APEX clothing documentation) +var() const float LodWeightsDistanceWeight; // LodWeightDistanceWeight (see APEX clothing documentation) +var() const float LodWeightsBias; // LodWeightBias (see APEX clothing documentation) +var() const float LodWeightsBenefitsBias; // LodWeightMaxBenefitsBias (see APEX clothing documentation) + +/** +** If true, cloth is simulated in local space. +** Inertia effects are added based on inertiaScale (from the imported clothing asset) if 3.x simulation is used. +** This needs to be turned off for 2.8.x cloth (unless collisions are filtered correctly). +**/ +var() const bool bUseLocalSpaceSimulation; + +var bool bHasUniqueAssetMaterialNames; +var() const float LODDecayTime; // How fast LodWeightDistanceWeight is reduced to 0 when the clothing is not visible. + +/** Sound cue to play when the clothing starts moving */ +var(Sound) SoundCue SoundOnMove; +/** Sound cue to play when clothing is moving*/ +var(Sound) SoundCue SoundOnRest; +/** Sound cue to play when the clothing is settling down */ +var(Sound) SoundCue SoundWhileMoving; + +/** Speed above which the clothing is considered moving */ +var(Sound) float SpeedThresholdOnMove; +/** Speed below which the clothing is considered at rest */ +var(Sound) float SpeedThresholdOnRest; +/** Whether to ignore the triggers when the cloth first settles into place */ +var(Sound) bool IgnoreInitialTrigger; + +cpptext +{ + public: + /** Notification of the post load event. */ + virtual void PostLoad(); + + /**** Serializes the asset + * @param : Ar is a reference to the FArchive to either serialize from or to. + */ + virtual void Serialize(FArchive& Ar); + + /*** Returns the array of strings to display in the browser window */ + virtual TArray GetGenericBrowserInfo(); + + /*** This method is called when a generic asset is imported from an external file on disk. + ** + ** @param Buffer : A pointer to the raw data. + ** @param BufferSize : The length of the raw input data. + ** @param Name : The name of the asset which is being imported. + ** + ** @return : Returns true if the import was successful. + **/ + UBOOL Import( const BYTE* Buffer, INT BufferSize, const FString& Name,UBOOL convertToUE3Coordinates ); + + /*** Export asset to a file, in xml/bin format. + ** + ** @param Name: The name of file name for exported asset + ** @param isKeepUE3Coords: Export type, in original coords (true) or keep UE3 coords (false) + ** + **/ + virtual UBOOL Export(const FName& Name, UBOOL isKeepUE3Coords); + + /*** This method is called after a property has changed. */ + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + /** Fix up unique material names in the APEX asset after rename or duplication */ + virtual void PostRename(); + virtual void PostDuplicate(); + + /** This method is called prior to the object being destroyed */ + virtual void BeginDestroy(void); + + /*** This method is called when the asset is renamed + ** + ** @param : InName : The new name of the object + ** @param : NewOuter : The new outer object (package) for this object. + ** @param : Flags : The ERenameFlags to honor. + ** + ** @return : Returns TRUE if the rename was successful + **/ + virtual UBOOL Rename( const TCHAR* NewName=NULL, UObject* NewOuter=NULL, ERenameFlags Flags=REN_None ); + + /** virtual method to return the number of materials used by this asset */ + virtual UINT GetNumMaterials(void) const + { +#if WITH_EDITORONLY_DATA + return Materials.Num(); +#else + return 0; +#endif // WITH_EDITORONLY_DATA + } + /** Returns the default ::NxParameterized::Interface for this asset. */ + virtual UMaterialInterface* GetMaterial(UINT Index) const + { +#if WITH_EDITORONLY_DATA + return Materials(Index); +#else + return NULL; +#endif // WITH_EDITORONLY_DATA + } + + /** Returns the default ::NxParameterized::Interface for this object */ + virtual void * GetNxParameterized(void); + + /** Returns a *copy* of the :NxParameterized::Interface for this asset. Caller must manually 'destroy' it.*/ + virtual void * GetAssetNxParameterized(void); + + /** Interface to ApexGenericAsset */ + class FIApexAsset * GetApexGenericAsset() const { return MApexAsset; } + + /** Re-assigns the APEX material resources by name with the current array of UE3 materials */ + void UpdateMaterials(void); + virtual void NotifyApexEditMode(class ApexEditInterface *iface); + + /** Whether the APEX asset's materials can be overridden */ + virtual UBOOL SupportsMaterialOverride() const { return bHasUniqueAssetMaterialNames; } + + private: +} + +defaultproperties +{ + bUseHardwareCloth=true // if true use hardware clothing for simulation + bFallbackSkinning=false // if true, falls back to skinning clothing in software instead of using GPU skinning + bSlowStart=true // Designates the 'slowStart' flag; see APEX clothing documentation + bRecomputeNormals=false; + bAllowAdaptiveTargetFrequency=false; // Slightly modifies gravity to avoid high frequency jittering due to variable time steps. + UVChannelForTangentUpdate=0 // Which UV channel is used for updating tangent space. + MaxDistanceBlendTime=1 // The maximimum distance blend time (see APEX clothing documentation) + ContinuousRotationThreshold=84 // The angle in degrees to consider the clothing simulation continuous. + ContinuousDistanceThreshold=50.0f // The distance to consider the clothing simulation continuous. + bResetAfterTeleport = true // If true, it resets the simulation after a teleport + LodWeightsMaxDistance=10000 // LodWeightMaxDistance (see APEX clothing documentation) + LodWeightsDistanceWeight=1 // LodWeightDistanceWeight (see APEX clothing documentation) + LodWeightsBias=0 // LodWeightBias (see APEX clothing documentation) + LodWeightsBenefitsBias=0 // LodWeightMaxBenefitsBias (see APEX clothing documentation) + LODDecayTime=10.0f // LODDecayTime + bUseLocalSpaceSimulation=false +} diff --git a/Engine/Classes/ApexComponentBase.uc b/Engine/Classes/ApexComponentBase.uc new file mode 100644 index 0000000..496fb7c --- /dev/null +++ b/Engine/Classes/ApexComponentBase.uc @@ -0,0 +1,98 @@ +/*============================================================================= + ApexComponentBase.uc: PhysX APEX integration. Component Base + Copyright 2008-2009 NVIDIA Corporation. +=============================================================================*/ + +class ApexComponentBase extends MeshComponent + native(Mesh) + hidecategories(Object) + editinlinenew; + +/** This component's index buffer. */ +var protected{protected} const native transient pointer ComponentBaseResources{class FApexBaseResources}; + +/** A fence used to track when the rendering thread has released the component's resources. */ +var protected{protected} native const transient RenderCommandFence_Mirror ReleaseResourcesFence{FRenderCommandFence}; + +var() const ApexAsset Asset; +var() Color WireframeColor; + +var const bool bAssetChanged; + +cpptext +{ + public: + virtual physx::apex::NxApexRenderable *GetApexRenderable(void) const { return 0; } + // NVCHANGE_BEGIN: JCAO - Using the render proxy to render the destructible + // TODO: DestructiblePreview add the render proxy, then GetApexRenderableRT could be removed + virtual physx::apex::NxApexRenderable *GetApexRenderableRT(void) const { return 0; } + virtual physx::apex::NxDestructibleRenderable *GetDestructibleRenderableRT(void) const { return 0; } + // NVCHANGE_END: JCAO - Using the render proxy to render the destructible + + protected: + virtual void UpdateApexEditorState(UProperty* PropertyThatChanged = NULL) {} + + private: + friend class UApexAsset; + // Called when the Asset gets rebuilt (in editor only). + virtual void OnApexAssetLost(void) { } + virtual void OnApexAssetReset(void) { } + + public: + + //UObject + + //UActorComponent + virtual UBOOL IsValidComponent() const { return UMeshComponent::IsValidComponent(); } + + // UMeshComponent interface. + virtual INT GetNumElements(void) const; + virtual UMaterialInterface *GetMaterial(INT MaterialIndex) const; + + //UPrimitiveComponent + virtual void UpdateTransform(); + virtual void UpdateBounds(); + virtual void InitComponentRBPhys(UBOOL bFixed); + virtual void TermComponentRBPhys(FRBPhysScene *InScene); + + /** + * Called after all objects referenced by this object have been serialized. Order of PostLoad routed to + * multiple objects loaded in one set is not deterministic though ConditionalPostLoad can be forced to + * ensure an object has been "PostLoad"ed. + */ + virtual void PostLoad(); + + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + void PostEditMove(UBOOL bFinished); + + /** + * Check for asynchronous resource cleanup completion + * @return TRUE if the rendering resources have been released + */ + virtual UBOOL IsReadyForFinishDestroy(); + + protected: + /** Attaches the component to the scene, and initializes the component's resources if they have not been yet. */ + virtual void Attach(); + + /** + * Detach the component from the scene and remove its render proxy + * @param bWillReattach TRUE if the detachment will be followed by an attachment + */ + virtual void Detach(UBOOL bWillReattach = FALSE); + + friend class FApexBaseSceneProxy; +} + +defaultproperties +{ + // Various physics related items need to be ticked pre physics update + TickGroup=TG_PreAsyncWork + + CollideActors=True + BlockActors=True + BlockZeroExtent=True + BlockNonZeroExtent=True + BlockRigidBody=True + WireframeColor=(R=255,G=128,B=64,A=255) +} diff --git a/Engine/Classes/ApexDestructibleActor.uc b/Engine/Classes/ApexDestructibleActor.uc new file mode 100644 index 0000000..b67d6f2 --- /dev/null +++ b/Engine/Classes/ApexDestructibleActor.uc @@ -0,0 +1,199 @@ +/*============================================================================= + ApexDestructibleActor.uc: PhysX APEX integration. Destructible Actor + Copyright 2008-2009 NVIDIA Corporation. +=============================================================================*/ + +/*** This class defines a single instance of a destructible asset */ +class ApexDestructibleActor extends Actor + dependson(ApexDestructibleAsset) + dependson(LightComponent) + native(Mesh) + placeable + config(Engine); + + +/** Expose LightEnvironment to the user */ +var() DynamicLightEnvironmentComponent LightEnvironment; + +/** If set, use this actor's fracture materials instead of the asset's fracture materials. */ +var() bool bFractureMaterialOverride; + +/** Fracture effects for each fracture level. Used only if Fracture Material Override is set. */ +var() const editfixedsize array FractureMaterials; + +/** If checked, only a single effect from FractureMaterials is played within the bounding box of all fractured chunks. The effect chosen will be the one corresponding to the destructible's SupportDepth. */ +var() const bool bPlaySingleFractureMaterialEffect; + +/** The destructible static component. */ +var() const editconst ApexStaticDestructibleComponent StaticDestructibleComponent; + +/** LOD setting. LOD < 0 enables automatic LOD. LOD >= 0 forces an LOD setting. */ +var() const int LOD; + +/** Defines an array that designates which of the destructible chunks are visible */ +var init array VisibilityFactors; + +/** Cached sounds for fractures. */ +var transient array FractureSounds; +/** Cached particle effects for fractures. */ +var transient array FractureParticleEffects; + + +event SpawnFractureEmitter(ParticleSystem EmitterTemplate, vector SpawnLocation, vector SpawnDirection) +{ + local ParticleSystemComponent PSC; + local LightingChannelContainer Lights; + PSC = WorldInfo.MyEmitterPool.SpawnEmitter( EmitterTemplate, SpawnLocation, rotator(SpawnDirection) ); + Lights = PSC.LightingChannels; + // TODO: Modify Lights here according to FractureMaterial + Lights.Dynamic = TRUE; + Lights.bInitialized = TRUE; + PSC.SetLightingChannels(Lights); +} + +/** Initialize FractureSounds and FractureParticleEffects */ +native function CacheFractureEffects(); + +simulated event PostBeginPlay() +{ + Super.PostBeginPlay(); + + CacheFractureEffects(); +} + +/** Declares the TakeDamage script function */ +simulated native function TakeDamage +( + int Damage, /* The amount of Damage to apply */ + Controller EventInstigator, /* The instigator of this event */ + vector HitLocation, /* The location where the impact occured */ + vector Momentum, /* The momentum of the impact */ + class DamageType, /* The type of damage to apply */ + optional TraceHitInfo HitInfo, /* The detailed hit information for this damage event */ + optional Actor DamageCauser /* The actor which caused the damage */ +); + +/** Declares the radius damage script function */ +simulated native function TakeRadiusDamage +( + Controller InstigatedBy, /* The instigator for this radius damage */ + float BaseDamage, /* The base damage amount */ + float DamageRadius, /* The radius of the damage */ + class DamageType, /* The type of damage to apply */ + float Momentum, /* The momentum of the damage */ + vector HurtOrigin, /* The origin of the damage */ + bool bFullDamage, /* Whether or not to apply full damage or attenuated damage */ + Actor DamageCauser, /* The actor which caused the damage */ + optional float DamageFalloffExponent=1.f +); +function OnSetMaterial(SeqAct_SetMaterial Action) +{ + StaticDestructibleComponent.SetMaterial( Action.MaterialIndex, Action.NewMaterial ); +} +cpptext +{ + // Function to check whether Actor still has chunks, if it doesn't destroy actor. + virtual void TickAuthoritative( FLOAT DeltaSeconds ); + + /** Synchronizes this actor to all rigid body components **/ + virtual void SyncActorToRBPhysics(); + + /*** Sets the physics on this actor + * @param NewPhysics : Use PHYS_None for a static destructible, PHYS_RigidBody for a dynamic destructible. + * @param NewFloor : Not used. + * @param NewFloorV : Not used. + */ + virtual void setPhysics(BYTE NewPhysics, AActor *NewFloor, FVector NewFloorV); + + /** Process a property change event. + * @param PropertyThatChanged : The property value which changed + */ + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + /** Process an edit move event. + * + * @param : bFinished : True if the move is complete. + */ + virtual void PostEditMove(UBOOL bFinished); + + /** Notification of the post load event. */ + virtual void PostLoad(); + + /** + * Called by MirrorActors to perform a mirroring operation on the actor. Overridden since + * APEX destructible actors can't handle mirror transforms. + */ + virtual void EditorApplyMirror(const FVector& MirrorScale, const FVector& PivotLocation); + + /** Loads the editor parameters from the asset */ + void LoadEditorParametersFromAsset(); + + /** Update old actors. Only has an effect when called from the editor. */ + void FixupActor(); + + /** Spawn fracture effects at the given location & given direction for the given fracture depth. */ + void SpawnFractureEffects(FVector& Location, FVector& Direction, INT Depth); + + /** Customize Apex Destructible's physRigidBody so that it checks the collision with volumes. */ + virtual void physRigidBody(FLOAT DeltaTime); + + /** Overrides the damage for a DamageCauser, if such is specified + * @param BaseDamage: Output base damage + * @param DamageRadius: Output damage radius + * @param Momentum: Output momentum + * @param DamageCauser: DamageCauser for the override lookup + */ + virtual void OverrideDamageParams(FLOAT& BaseDamage, FLOAT& DamageRadius, FLOAT& Momentum, const AActor* DamageCauser) const; + + // AActor interface + virtual UBOOL ShouldTrace(UPrimitiveComponent* Primitive, AActor *SourceActor, DWORD TraceFlags); +} + +defaultproperties +{ + bEdShouldSnap=TRUE + bCollideActors=TRUE + bBlockActors=TRUE + bProjTarget=TRUE + bGameRelevant=TRUE + bRouteBeginPlayEvenIfStatic=FALSE + bCollideWhenPlacing=FALSE + bStatic=FALSE + bMovable=TRUE + bNoDelete=TRUE + bNoEncroachCheck=TRUE + bWorldGeometry=FALSE + bCanBeDamaged=TRUE + + LOD=-1 + + Begin Object Class=DynamicLightEnvironmentComponent Name=LightEnvironment0 + bEnabled=FALSE + End Object + Components.Add(LightEnvironment0) + + LightEnvironment = LightEnvironment0 + + Begin Object Class=ApexStaticDestructibleComponent Name=DestructibleComponent0 + bAllowApproximateOcclusion=TRUE + bCastDynamicShadow=FALSE + bForceDirectLightMap=TRUE + BlockRigidBody=TRUE + bAcceptsDecals=FALSE + LightEnvironment=LightEnvironment0 + End Object + CollisionComponent=DestructibleComponent0 + StaticDestructibleComponent=DestructibleComponent0 + Components.Add(DestructibleComponent0) + +// Begin Object Class=ApexDynamicDestructibleComponent Name=DestructibleComponent1 +// bAllowApproximateOcclusion=TRUE +// bCastDynamicShadow=FALSE +// bForceDirectLightMap=TRUE +// BlockRigidBody=TRUE +// bAcceptsDecals=FALSE +// LightEnvironment=LightEnvironment0 +// End Object +// DynamicDestructibleComponent=DestructibleComponent1 +// Components.Add(DestructibleComponent1) +} diff --git a/Engine/Classes/ApexDestructibleActorSpawnable.uc b/Engine/Classes/ApexDestructibleActorSpawnable.uc new file mode 100644 index 0000000..1de7d1e --- /dev/null +++ b/Engine/Classes/ApexDestructibleActorSpawnable.uc @@ -0,0 +1,11 @@ +/*============================================================================= + ApexDestructibleActorSpawnable .uc: PhysX APEX integration. + Copyright 2008-2009 NVIDIA Corporation. +==============================================================================*/ +class ApexDestructibleActorSpawnable extends ApexDestructibleActor + notplaceable; + +DefaultProperties +{ + bNoDelete=FALSE +} diff --git a/Engine/Classes/ApexDestructibleAsset.uc b/Engine/Classes/ApexDestructibleAsset.uc new file mode 100644 index 0000000..1da21db --- /dev/null +++ b/Engine/Classes/ApexDestructibleAsset.uc @@ -0,0 +1,632 @@ +/*============================================================================= + ApexDestructibleAsset.h: PhysX APEX integration. Destructible Asset + Copyright 2008-2009 NVIDIA Corporation. +=============================================================================*/ + +/** This class fully describes an APEX destructible asset and associated propreties */ +class ApexDestructibleAsset extends ApexAsset + hidecategories(Object) + dependson(PrimitiveComponent) + native(Mesh); +/** + Chunks up to the depth DefaultImpactDamageDepth will take impact damage, + unless IDO_On or IDO_Off is chosen. +*/ +enum EImpactDamageOverride +{ + IDO_None, + IDO_On, + IDO_Off +}; + +/** MApexAsset is a pointer to the Apex asset interface for this destructible asset */ +var native pointer MApexAsset{class FIApexAsset}; +/** Materials contains an array of Materials which can be remapped relative to this asset */ +var() const editfixedsize array Materials; +/** Fracture effects for each fracture level */ +var() const editfixedsize array FractureMaterials; +/** If checked, only a single effect from FractureMaterials is played within the bounding box of all fractured chunks. The effect chosen will be the one corresponding to the destructible's SupportDepth. */ +var() const bool bPlaySingleFractureMaterialEffect; +/** Default physical material to use for this asset. If the actor has a physical material defined in its mesh component, that will be used instead.*/ +var() PhysicalMaterial DefaultPhysMaterial; + +/** Make the Destructible Thumbnail component singular */ +var native pointer MDestructibleThumbnailComponent{class UApexStaticDestructibleComponent}; + +var bool bHasUniqueAssetMaterialNames; + +/** + Flags that may be set for all chunks at a particular depth in the fracture hierarchy +*/ +struct native NxDestructibleDepthParameters +{ + /** + Chunks at this hierarchy depth level may take impact damage if this flag is set. + Note, NxDestructibleParameters::forceToDamage must also be positive for this + to take effect. + */ + var deprecated bool TAKE_IMPACT_DAMAGE; + + /** + Chunks at this depth should have pose updates ignored. + */ + var deprecated bool IGNORE_POSE_UPDATES; + + /** + Chunks at this depth should be ignored in raycast callbacks. + */ + var deprecated bool IGNORE_RAYCAST_CALLBACKS; + + /** + Chunks at this depth should be ignored in contact callbacks. + */ + var deprecated bool IGNORE_CONTACT_CALLBACKS; + + /** + User defined flags. + */ + var deprecated bool USER_FLAG_0; + var deprecated bool USER_FLAG_1; + var deprecated bool USER_FLAG_2; + var deprecated bool USER_FLAG_3; + + /** + Chunks up to the depth DefaultImpactDamageDepth will take impact damage, + unless one of the override options (see EImpactDamageOverride) is chosen. + */ + var() EImpactDamageOverride ImpactDamageOverride; +}; + +/** + Flags that apply to a destructible actor +*/ +struct native NxDestructibleParametersFlag +{ + /** + If set, chunks will "remember" damage applied to them, so that many applications of a damage amount + below damageThreshold will eventually fracture the chunk. If not set, a single application of + damage must exceed damageThreshold in order to fracture the chunk. + */ + var() bool ACCUMULATE_DAMAGE; + + /** + If set, then chunks which are tagged as "support" chunks (via NxDestructibleChunkDesc::isSupportChunk) + will have environmental support in static destructibles. + + Note: if both ASSET_DEFINED_SUPPORT and WORLD_SUPPORT are set, then chunks must be tagged as + "support" chunks AND overlap the NxScene's static geometry in order to be environmentally supported. + */ + var() bool ASSET_DEFINED_SUPPORT; + + /** + If set, then chunks which overlap the NxScene's static geometry will have environmental support in + static destructibles. + + Note: if both ASSET_DEFINED_SUPPORT and WORLD_SUPPORT are set, then chunks must be tagged as + "support" chunks AND overlap the NxScene's static geometry in order to be environmentally supported. + */ + var() bool WORLD_SUPPORT; + + /** + Whether or not chunks at or deeper than the "debris" depth (see NxDestructibleParameters::debrisDepth) + will time out. The lifetime is a value between NxDestructibleParameters::debrisLifetimeMin and + NxDestructibleParameters::debrisLifetimeMax, based upon the destructible module's LOD setting. + */ + var() bool DEBRIS_TIMEOUT; + + /** + Whether or not chunks at or deeper than the "debris" depth (see NxDestructibleParameters::debrisDepth) + will be removed if they separate too far from their origins. The maxSeparation is a value between + NxDestructibleParameters::debrisMaxSeparationMin and NxDestructibleParameters::debrisMaxSeparationMax, + based upon the destructible module's LOD setting. + */ + var() bool DEBRIS_MAX_SEPARATION; + + /** + If set, the smallest chunks may be further broken down, either by fluid crumbles (if a crumble particle + system is specified in the NxDestructibleActorDesc), or by simply removing the chunk if no crumble + particle system is specified. Note: the "smallest chunks" are normally defined to be the deepest level + of the fracture hierarchy. However, they may be taken from higher levels of the hierarchy if + NxModuleDestructible::setMaxChunkDepthOffset is called with a non-zero value. + */ + var() bool CRUMBLE_SMALLEST_CHUNKS; + + /** + If set, the NxDestructibleActor::rayCast function will search within the nearest visible chunk hit + for collisions with child chunks. This is used to get a better raycast position and normal, in + case the parent collision volume does not tightly fit the graphics mesh. The returned chunk index + will always be that of the visible parent that is intersected, however. + */ + var() bool ACCURATE_RAYCASTS; + + /** + If set, the ValidBounds field of NxDestructibleParameters will be used. These bounds are translated + (but not scaled or rotated) to the origin of the destructible actor. If a chunk or chunk island moves + outside of those bounds, it is destroyed. + */ + var() bool USE_VALID_BOUNDS; + + /** + If initially static, the destructible will become part of an extended support structure if it is + in contact with another static destructible that also has this flag set. + */ + var() bool FORM_EXTENDED_STRUCTURES; +}; + +/** + Parameters that pertain to chunk damage +*/ +struct native NxDestructibleDamageParameters +{ + /** + The damage amount which will cause a chunk to fracture (break free) from the destructible. + This is obtained from the damage value passed into the NxDestructibleActor::applyDamage, + or NxDestructibleActor::applyRadiusDamage, or via impact (see 'forceToDamage', below). + */ + var() float DamageThreshold; + + /** + Controls the distance into the destructible to propagate damage. The damage applied to the chunk + is multiplied by DamageSpread, to get the propagation distance. All chunks within the radius + will have damage applied to them. The damage applied to each chunk varies with distance to the damage + application position. Full damage is taken at zero distance, and zero damage at the damage radius. + */ + var() float DamageSpread; + + /** + If a chunk is at a depth which has NX_DESTRUCTIBLE_TAKE_IMPACT_DAMAGE set (see DepthParameters), + then when a chunk has a collision in the NxScene, it will take damage equal to ImpactDamage mulitplied by + the impact force. + The default value is zero, which effectively disables impact damage. + */ + var() float ImpactDamage; + + /** + When a chunk takes impact damage due to physical contact (see DepthParameters), this parameter + is the maximum impulse the contact can generate. Weak materials such as glass may have this set to a low value, so that + heavier objects will pass through them during fracture. + N.B.: Setting this parameter to 0 disables the impulse cap; that is, zero is interpreted as infinite. + Default value = 0.0f. + */ + var() float ImpactResistance; + + /** + By default, impact damage will only be taken to this depth. For a particular depth, this + default may be overridden in the DepthParameters. If negative, impact damage + is disabled. + */ + var() int DefaultImpactDamageDepth; + + structdefaultproperties + { + DefaultImpactDamageDepth=-1 + } +}; + +/** + Parameters that pertain to chunk debris-level settings +*/ +struct native NxDestructibleDebrisParameters +{ + /** + "Debris chunks" (see debrisDepth, above) will be destroyed after a time (in seconds) + separated from non-debris chunks. The actual lifetime is interpolated between these + two values, based upon the module's LOD setting. To disable lifetime, clear the + NX_DESTRUCTIBLE_DEBRIS_TIMEOUT flag in the flags field. + If debrisLifetimeMax < debrisLifetimeMin, the mean of the two is used for both. + Default debrisLifetimeMin = 1.0, debrisLifetimeMax = 10.0f. + */ + var() float DebrisLifetimeMin; + var() float DebrisLifetimeMax; + + /** + "Debris chunks" (see debrisDepth, above) will be destroyed if they are separated from + their origin by a distance greater than maxSeparation. The actual maxSeparation is + interpolated between these two values, based upon the module's LOD setting. To disable + maxSeparation, clear the NX_DESTRUCTIBLE_DEBRIS_MAX_SEPARATION flag in the flags field. + If debrisMaxSeparationMax < debrisMaxSeparationMin, the mean of the two is used for both. + Default debrisMaxSeparationMin = 1.0, debrisMaxSeparationMax = 10.0f. + */ + var() float DebrisMaxSeparationMin; + var() float DebrisMaxSeparationMax; + + /** + "Debris chunks" (see debrisDepth, above) will be destroyed if they are separated from + their origin by a distance greater than maxSeparation multiplied by the original + destructible asset size. The actual maxSeparation is interpolated between these + two values, based upon the module's LOD setting. To disable maxSeparation, clear the + NX_DESTRUCTIBLE_DEBRIS_MAX_SEPARATION flag in the flags field. + If debrisMaxSeparationMax < debrisMaxSeparationMin, the mean of the two is used for both. + Default debrisMaxSeparationMin = 1.0, debrisMaxSeparationMax = 10.0f. + */ + var() Box ValidBounds; + + structdefaultproperties + { + ValidBounds=(Min=(X=-500000.f,Y=-500000.f,Z=-500000.f),Max=(X=500000.f,Y=500000.f,Z=500000.f)) + } +}; + +/** + Parameters that are less-often used +*/ +struct native NxDestructibleAdvancedParameters +{ + /** + Limits the amount of damage applied to a chunk. This is useful for preventing the entire destructible + from getting pulverized by a very large application of damage. This can easily happen when impact damage is + used, and the damage amount is proportional to the impact force (see forceToDamage). + */ + var() float DamageCap; + + /** + Large impact force may be reported if rigid bodies are spawned inside one another. In this case the realative velocity of the two + objects will be low. This variable allows the user to set a minimum velocity threshold for impacts to ensure that the objects are + moving at a min velocity in order for the impact force to be considered. + */ + var() float ImpactVelocityThreshold; + + /** + If greater than 0, the chunks' speeds will not be allowed to exceed this value. Use 0 + to disable this feature (this is the default). + */ + var() float MaxChunkSpeed; + + /** + See MassScale. Values less than 1 have the + effect of reducing the ratio of different masses. The closer MassScaleExponent is to zero, the + more the ratio will be "flattened." This helps PhysX converge when there is a very large number + of interacting rigid bodies (such as a pile of destructible chunks). + Valid range: [0,1]. Default = 0.5. + */ + var() float MassScaleExponent; + + /** + Dynamic chunk islands will have their masses divided by MassScale, raised to the power MassScaleExponent, + then multiplied by MassScale. See MassScaleExponent. + Valid range: (0,infinity). Default = 1.0. + */ + var() float MassScale; + + /** + Scale factor used to apply an impulse force along the normal of chunk when fractured. This is used + in order to "push" the pieces out as they fracture. + */ + var() float FractureImpulseScale; +}; + + +/** + Parameters that apply to a destructible actor +*/ +struct native NxDestructibleParameters +{ + /** + Parameters that pertain to chunk damage. See NxDestructibleDamageParameters. + */ + var(Damage) NxDestructibleDamageParameters DamageParameters; + + /** + Parameters that pertain to chunk debris-level settings. See NxDestructibleDebrisParameters. + */ + var(Debris) NxDestructibleDebrisParameters DebrisParameters; + + /** + Parameters that are less-often used. See NxDestructibleAdvancedParameters. + */ + var(Advanced) NxDestructibleAdvancedParameters AdvancedParameters; + + /** + The damage amount which will cause a chunk to fracture (break free) from the destructible. + This is obtained from the damage value passed into the NxDestructibleActor::applyDamage, + or NxDestructibleActor::applyRadiusDamage, or via impact (see 'forceToDamage', below). + */ + var deprecated float DamageThreshold; + + /** + Controls the distance into the destructible to propagate damage. The damage applied to the chunk + is multiplied by DamageSpread, to get the propagation distance. All chunks within the radius + will have damage applied to them. The damage applied to each chunk varies with distance to the damage + application position. Full damage is taken at zero distance, and zero damage at the damage radius. + */ + var deprecated float DamageToRadius; + + /** + Limits the amount of damage applied to a chunk. This is useful for preventing the entire destructible + from getting pulverized by a very large application of damage. This can easily happen when impact damage is + used, and the damage amount is proportional to the impact force (see forceToDamage). + */ + var deprecated float DamageCap; + + /** + If a chunk is at a depth which has NX_DESTRUCTIBLE_TAKE_IMPACT_DAMAGE set (see DepthParameters), + then when a chunk has a collision in the NxScene, it will take damage equal to ImpactDamage mulitplied by + the impact force. + The default value is zero, which effectively disables impact damage. + */ + var deprecated float ForceToDamage; + + /** + Large impact force may be reported if rigid bodies are spawned inside one another. In this case the realative velocity of the two + objects will be low. This variable allows the user to set a minimum velocity threshold for impacts to ensure that the objects are + moving at a min velocity in order for the impact force to be considered. + */ + var deprecated float ImpactVelocityThreshold; + + /** + When a chunk takes impact damage due to physical contact (see DepthParameters), this parameter + is the maximum impulse the contact can generate. Weak materials such as glass may have this set to a low value, so that + heavier objects will pass through them during fracture. + N.B.: Setting this parameter to 0 disables the impulse cap; that is, zero is interpreted as infinite. + Default value = 0.0f. + */ + var deprecated float MaterialStrength; + + /** + Damage applied to chunks may deform (move) a chunk without fracturing it, if damageToPercentDeformation is + positive. The damage applied to the chunk is multiplied by damageToPercentDeformation, and the resulting + "percent deformation" is used to translate and rotate the chunk. The translation is the "percent deformation" + times the size of the chunk, in the direction given by the 'direction' paramater in applyDamage + (see NxDestructibleActor). For radius damage, the direction is always radial from the impact position. + The rotation appplied is the "percent deformation" times one radian. + The default value is zero, which disables deformation. + */ + var deprecated float DamageToPercentDeformation; + + /** + If a chunk's percent deformation (see damageToPercentDeformation) exceeds deformationPercentLimit in + either translation or rotation, then the chunk will fracture. + */ + var deprecated float DeformationPercentLimit; + + /** + If initially static, the destructible will become part of an extended support structure if it is + in contact with another static destructible that also has this flag set. + */ + var deprecated bool bFormExtendedStructures; + + /** + The chunk hierarchy depth at which to create a support graph. Higher depth levels give more detailed support, + but will give a higher computational load. Chunks below the support depth will never be supported. + */ + var() int SupportDepth; + + /** + The chunks will not be broken free below this depth. + */ + var() int MinimumFractureDepth; + + /** + The chunk hierarchy depth at which chunks are considered to be "debris." Chunks at this depth or + below will be considered for various debris settings, such as debrisLifetime. + Negative values indicate that no chunk depth is considered debris. + Default value is -1. + */ + var() int DebrisDepth; + + /** + The chunk hierarchy depth up to which chunks will always be processed. These chunks are considered + to be essential either for gameplay or visually. + The minimum value is 0, meaning the level 0 chunk is always considered essential. + Default value is 0. + */ + var() int EssentialDepth; + + /** + "Debris chunks" (see debrisDepth, above) will be destroyed after a time (in seconds) + separated from non-debris chunks. The actual lifetime is interpolated between these + two values, based upon the module's LOD setting. To disable lifetime, clear the + NX_DESTRUCTIBLE_DEBRIS_TIMEOUT flag in the flags field. + If debrisLifetimeMax < debrisLifetimeMin, the mean of the two is used for both. + Default debrisLifetimeMin = 1.0, debrisLifetimeMax = 10.0f. + */ + var deprecated float DebrisLifetimeMin; + var deprecated float DebrisLifetimeMax; + + /** + "Debris chunks" (see debrisDepth, above) will be destroyed if they are separated from + their origin by a distance greater than maxSeparation. The actual maxSeparation is + interpolated between these two values, based upon the module's LOD setting. To disable + maxSeparation, clear the NX_DESTRUCTIBLE_DEBRIS_MAX_SEPARATION flag in the flags field. + If debrisMaxSeparationMax < debrisMaxSeparationMin, the mean of the two is used for both. + Default debrisMaxSeparationMin = 1.0, debrisMaxSeparationMax = 10.0f. + */ + var deprecated float DebrisMaxSeparationMin; + var deprecated float DebrisMaxSeparationMax; + + /** + "Debris chunks" (see debrisDepth, above) will be destroyed if they are separated from + their origin by a distance greater than maxSeparation multiplied by the original + destructible asset size. The actual maxSeparation is interpolated between these + two values, based upon the module's LOD setting. To disable maxSeparation, clear the + NX_DESTRUCTIBLE_DEBRIS_MAX_SEPARATION flag in the flags field. + If debrisMaxSeparationMax < debrisMaxSeparationMin, the mean of the two is used for both. + Default debrisMaxSeparationMin = 1.0, debrisMaxSeparationMax = 10.0f. + */ + var deprecated Box ValidBounds; + + /** + If greater than 0, the chunks' speeds will not be allowed to exceed this value. Use 0 + to disable this feature (this is the default). + */ + var deprecated float MaxChunkSpeed; + + /** + See MassScale. Values less than 1 have the + effect of reducing the ratio of different masses. The closer MassScaleExponent is to zero, the + more the ratio will be "flattened." This helps PhysX converge when there is a very large number + of interacting rigid bodies (such as a pile of destructible chunks). + Valid range: [0,1]. Default = 0.5. + */ + var deprecated float MassScaleExponent; + + /** + A collection of flags defined in NxDestructibleParametersFlag. + */ + var() NxDestructibleParametersFlag Flags; + + /** + The relative volume (chunk volume / whole destructible volume) below which GRBs are used + instead of RBs to represent chunks in the physics scene. + */ + var deprecated float GrbVolumeLimit; + + /** + Spacing of particle grid used to represent rigid bodies in GRB + */ + var deprecated float GrbParticleSpacing; + + /** + Scale factor used to apply an impulse force along the normal of chunk when fractured. This is used + in order to "push" the pieces out as they fracture. + */ + var deprecated float FractureImpulseScale; + + /** + Parameters that apply to every chunk at a given level. + the element [0] of the array applies to the level 0 (unfractured) chunk, element [1] applies + to the level 1 chunks, etc. + */ + var() editfixedsize array DepthParameters; + + /** + * Optional dominance group for dynamic chunks created when fractured. (ignored if > 31) + */ + var() int DynamicChunksDominanceGroup; + + /** + Whether or not to usedynamicChunksGroupsMask. If false, NULL will be passed into the DestructibleActor upon + instantiation, through the NxDestructibleActorDesc. + */ + var() bool UseDynamicChunksGroupsMask; + + /** Enum indicating what type of object this should be considered for rigid body collision. */ + var() const ERBCollisionChannel DynamicChunksChannel; + + /** Types of objects that this physics objects will collide with. */ + var() const RBCollisionChannelContainer DynamicChunksCollideWithChannels; + + structdefaultproperties + { + DynamicChunksDominanceGroup=-1; + } +}; + +/** + The name of the NxMeshParticleSystem to use for crumbling. This overrides the crumble system defined + in the NxDestructibleAsset if specified. +*/ +var() string CrumbleEmitterName; + +/** + The name of the NxMeshParticleSystem to use for fracture-line dust. This overrides the dust system defined + in the NxDestructibleAsset if specified. +*/ +var() string DustEmitterName; + +/** + Whether or not the destructible starts life as a dynamic actor +*/ +var deprecated bool bDynamic; + +/** + Parameters controlling the destruction properties. +*/ +var() NxDestructibleParameters DestructibleParameters; + +cpptext +{ + public: + /** Notification of the post load event. */ + virtual void PostLoad(); + + /**** Serializes the asset + * @param : Ar is a reference to the FArchive to either serialize from or to. + */ + virtual void Serialize(FArchive& Ar); + + /*** Returns the array of strings to display in the browser window */ + virtual TArray GetGenericBrowserInfo(); + + /*** This method is called when a generic asset is imported from an external file on disk. + ** + ** @param Buffer : A pointer to the raw data. + ** @param BufferSize : The length of the raw input data. + ** @param Name : The name of the asset which is being imported. + ** + ** @return : Returns true if the import was successful. + **/ + UBOOL Import( const BYTE* Buffer, INT BufferSize, const FString& Name,UBOOL convertToUE3Coordinates ); + + /*** Export asset to a file, in xml/bin format. + ** + ** @param Name: The name of file name for exported asset + ** @param isKeepUE3Coords: Export type, in original coords (true) or keep UE3 coords (false) + ** + **/ + virtual UBOOL Export(const FName& Name, UBOOL isKeepUE3Coords); + + /*** This method is called after a property has changed. */ + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + /** Fix up unique material names in the APEX asset after rename or duplication */ + virtual void PostRename(); + virtual void PostDuplicate(); + + /** This method is called prior to the object being destroyed */ + virtual void BeginDestroy(void); + + /** Releases a destructible actor. + ** @param ApexDestructibleActor : The destructibe actor to release. + ** @param Component : The associated component to release. + **/ + void ReleaseDestructibleActor( class physx::apex::NxDestructibleActor &ApexDestructibleActor, class UApexComponentBase &Component); + + /** create an APEX destructible preview object. + ** + ** @param : ApexDestructiblePreviewDesc : A descriptor for the preview object. + ** @param : Component : A reference to the component being creaated. + ** + ** @return : Returns the destructible preview object if successful or a NULL pointer if it failed. + **/ + physx::apex::NxDestructiblePreview *CreateDestructiblePreview(class UApexComponentBase &Component); + + /** Releases the previously created APEX destructible preview object. + ** + ** @param : ApexDestructiblePreview : A reference to the previously created destructible preview object. + ** @param : Component : A reference to the component object. + **/ + void ReleaseDestructiblePreview(physx::apex::NxDestructiblePreview &ApexDestructiblePreview, class UApexComponentBase &Component); + + /*** Returns the number of materials used by this asset */ + virtual UINT GetNumMaterials(void) const { return Materials.Num(); } + + /*** Returns a particular material by index **/ + virtual UMaterialInterface *GetMaterial(UINT Index) const { return Materials(Index); } + + /** Returns the default ::NxParameterized::Interface for this asset. **/ + virtual void * GetNxParameterized(void); + + /** Returns a *copy* of the :NxParameterized::Interface for this asset. Caller must manually 'destroy' it.*/ + virtual void * GetAssetNxParameterized(void); + + /** Returns the APEX asset interface pointer for this object */ + class FIApexAsset * GetApexGenericAsset() const { return MApexAsset; } + + /** A method to update the APEX named resource pointers with individual materials assigned to this asset */ + void UpdateMaterials(void); + + virtual void NotifyApexEditMode(class ApexEditInterface *iface); + + /** Whether the APEX asset's materials can be overridden in the actor's ApexComponent */ + virtual UBOOL SupportsMaterialOverride() const { return bHasUniqueAssetMaterialNames; } + + /** Update old assets. Only has an effect when called from the editor. */ + void FixupAsset(); + + private: +} + +defaultproperties +{ +} diff --git a/Engine/Classes/ApexDestructibleDamageParameters.uc b/Engine/Classes/ApexDestructibleDamageParameters.uc new file mode 100644 index 0000000..605c373 --- /dev/null +++ b/Engine/Classes/ApexDestructibleDamageParameters.uc @@ -0,0 +1,29 @@ +class ApexDestructibleDamageParameters extends Object + native(Physics) + hidecategories(Object); + +enum EDamageParameterOverrideMode +{ + DPOM_Absolute, // Parameters of TakeDamage of DamageCauserClass will be overridden with provided absolute values + DPOM_Multiplier, // Parameters of TakeDamage of DamageCauserClass will be multiplied with provided values +}; + +struct native DamageParameters +{ + var() EDamageParameterOverrideMode OverrideMode; + var() float BaseDamage; + var() float Radius; + var() float Momentum; +}; + +struct native DamagePair +{ + var() name DamageCauserName; + var() DamageParameters Params; +}; + +var() Array DamageMap; + +defaultproperties +{ +} diff --git a/Engine/Classes/ApexDynamicComponent.uc b/Engine/Classes/ApexDynamicComponent.uc new file mode 100644 index 0000000..09e3e47 --- /dev/null +++ b/Engine/Classes/ApexDynamicComponent.uc @@ -0,0 +1,24 @@ +/*============================================================================= + ApexDynamicComponent.uc: PhysX APEX integration. Dynamic Component + Copyright 2008-2009 NVIDIA Corporation. +=============================================================================*/ + +/* This class defines a default APEX dynamic component */ +class ApexDynamicComponent extends ApexComponentBase + native(Mesh); + +/* Render resources used by this component, and whose release progress is tracked by the FRenderCommandFence in FracturedBaseComponent. */ +var protected{protected} const native transient pointer ComponentDynamicResources{class FApexDynamicResources}; + +cpptext +{ +public: + +protected: + + friend class FApexDynamicSceneProxy; +} + +defaultproperties +{ +} diff --git a/Engine/Classes/ApexGenericAsset.uc b/Engine/Classes/ApexGenericAsset.uc new file mode 100644 index 0000000..c6c1204 --- /dev/null +++ b/Engine/Classes/ApexGenericAsset.uc @@ -0,0 +1,99 @@ +/*============================================================================= + ApexGenericAsset.h: PhysX APEX integration. Clothing Asset + Copyright 2008-2009 NVIDIA Corporation. +=============================================================================*/ + +/*** This class defines an Apex Generic Asset +* An Apex Generic asset is any APEX asset that is described purely as a data blob and does not have any factories associated with it. +*/ +class ApexGenericAsset extends ApexAsset + hidecategories(Object) + native(Mesh); + +/*** Contains a pointer to the allocated Apex asset interface */ +var native pointer MApexAsset{class FIApexAsset}; +var() const editfixedsize editoronly array Materials; + + +cpptext +{ + public: + /**** Serializes the asset + * @param : Ar is a reference to the FArchive to either serialize from or to. + */ + virtual void Serialize(FArchive& Ar); + + /*** Returns the array of strings to display in the browser window */ + virtual TArray GetGenericBrowserInfo(); + + /*** This method is called when a generic asset is imported from an external file on disk. + ** + ** @param Buffer : A pointer to the raw data. + ** @param BufferSize : The length of the raw input data. + ** @param Name : The name of the asset which is being imported. + ** + ** @return : Returns true if the import was successful. + **/ + UBOOL Import( const BYTE* Buffer, INT BufferSize, const FString& Name ); + + /*** This method is called after a property has changed. */ + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + /** This method is called prior to the object being destroyed */ + virtual void BeginDestroy(void); + + /*** This method is called when the asset is renamed + ** + ** @param : InName : The new name of the object + ** @param : NewOuter : The new outer object (package) for this object. + ** @param : Flags : The ERenameFlags to honor. + ** + ** @return : Returns TRUE if the rename was successful + **/ + virtual UBOOL Rename( const TCHAR* NewName=NULL, UObject* NewOuter=NULL, ERenameFlags Flags=REN_None ); + + /** Returns the default ::NxParameterized::Interface for this object */ + virtual void * GetNxParameterized(void); + /** Returns a *copy* of the :NxParameterized::Interface for this asset. Caller must manually 'destroy' it.*/ + virtual void * GetAssetNxParameterized(void); + + /** + * Returns a one line description of an object for viewing in the thumbnail view of the generic browser + */ + virtual FString GetDesc( void ); + + virtual void CreateDefaultAssetType(INT t,class UApexGenericAsset *parent); + + /** virtual method to return the number of materials used by this asset */ + virtual UINT GetNumMaterials(void) const + { +#if WITH_EDITORONLY_DATA + return Materials.Num(); +#else + return 0; +#endif // WITH_EDITORONLY_DATA + } + /** Returns the default ::NxParameterized::Interface for this asset. */ + virtual UMaterialInterface* GetMaterial(UINT Index) const + { +#if WITH_EDITORONLY_DATA + return Materials(Index); +#else + return NULL; +#endif // WITH_EDITORONLY_DATA + } + /** Re-assigns the APEX material resources by name with the current array of UE3 materials */ + void UpdateMaterials(void); + virtual void NotifyApexEditMode(class ApexEditInterface *iface); + + /** Returns the pointer to the FIApexAsset interface */ + class FIApexAsset * GetApexGenericAsset() const { return MApexAsset; } + + + private: +} + +defaultproperties +{ +} + diff --git a/Engine/Classes/ApexStaticComponent.uc b/Engine/Classes/ApexStaticComponent.uc new file mode 100644 index 0000000..4929bc3 --- /dev/null +++ b/Engine/Classes/ApexStaticComponent.uc @@ -0,0 +1,42 @@ +/*============================================================================= + ApexStaticComponent.uc: PhysX APEX integration. Static component + Copyright 2008-2009 NVIDIA Corporation. +=============================================================================*/ + +/*** +* This class defines the base component object for apex objects +**/ +class ApexStaticComponent extends ApexComponentBase + native(Mesh); + +cpptext +{ + public: + //UObject + /** Serializes this object + * + * @param : Ar the archive object to serialize into or out of. + */ + virtual void Serialize(FArchive& Ar); + + /*** Creates a primitive scene proxy for this object. + */ + virtual FPrimitiveSceneProxy* CreateSceneProxy(); + + protected: + /** + * @return FALSE since fractured geometry will handle its own decal detachment + */ + virtual UBOOL AllowDecalRemovalOnDetach() const + { + return FALSE; + } + + friend class FApexStaticSceneProxy; +} + +defaultproperties +{ + // By default static components use precomputed shadows. + bUsePrecomputedShadows=TRUE +} diff --git a/Engine/Classes/ApexStaticDestructibleComponent.uc b/Engine/Classes/ApexStaticDestructibleComponent.uc new file mode 100644 index 0000000..29d2342 --- /dev/null +++ b/Engine/Classes/ApexStaticDestructibleComponent.uc @@ -0,0 +1,119 @@ +/*============================================================================= + ApexStaticDestructibleComponent.uc: PhysX APEX integration. Destructible component + Copyright 2008-2009 NVIDIA Corporation. +=============================================================================*/ + +/*** +* This is the base class for static destructible components +*/ +class ApexStaticDestructibleComponent extends ApexStaticComponent + native(Mesh); + +/** Increasing this value will cause fracture chunks to be put to sleep more quickly. */ +var(Physics) float SleepEnergyThreshold; + +/** Increasing this value will cause fracture chunks to be gradually slowed down before putting them to sleep. */ +var(Physics) float SleepDamping; + +/** The APEX destructible actor (instantiated destructible asset) (duplicatetransients to avoid a pointer copy) */ +var native duplicatetransient pointer ApexDestructibleActor { physx::apex::NxDestructibleActor }; +/** The APEX preview class which can render a preview of a destructible asset */ +var native duplicatetransient pointer ApexDestructiblePreview { physx::apex::NxDestructiblePreview }; + +/** If this component is being used for a thumbnail render */ +var native bool bIsThumbnailComponent; + + +cpptext +{ + protected: + /** Internal function that updates physics objects to match the RBChannel/RBCollidesWithChannel info. */ + virtual void UpdatePhysicsToRBChannels(); + + /** This method handles property changes to the component */ + virtual void UpdateApexEditorState(UProperty* PropertyThatChanged = NULL); + + public: + /** This method returns the APEX renderable for this destructible component */ + virtual physx::apex::NxApexRenderable *GetApexRenderable(void) const; + // NVCHANGE_BEGIN: JCAO - Using the render proxy to render the destructible + virtual physx::apex::NxApexRenderable *GetApexRenderableRT(void) const; + virtual physx::apex::NxDestructibleRenderable *GetDestructibleRenderableRT(void) const; + // NVCHANGE_END: JCAO - Using the render proxy to render the destructible + /** Performs a per-frame tick operation on the apex static destructible component */ + virtual void Tick(FLOAT DeltaTime); + /** Returns true if the component is valid. */ + virtual UBOOL IsValidComponent() const; + + // PrimitiveComponent interface + /** Performs a LineCheck against this component object. + * @param Result : a reference to an FCheckResults class that contains the results. + * @param End : The end of the line check + * @param Start : The start of the line check + * @param Extent : The extent of the line check + * @param TraceFlags : Defines a bit sequence of which objects are considered for the line check. + * + * @return : Returns TRUE if the LineCheck hit. + **/ + virtual UBOOL LineCheck(FCheckResult& Result, const FVector& End, const FVector& Start, const FVector& Extent, DWORD TraceFlags); + + /** Performs a single Point inside/outside check against this component. + * @param Result : a reference to an FCheckResults class that contains the results. + * @param Location : The point location to check against. + * @param Extent : The extent of the point check + * @param TraceFlags : Defines a bit sequence of which objects are considered for the point check. + * + * @return : Returns TRUE if the point hit the component. + **/ + virtual UBOOL PointCheck(FCheckResult& Result,const FVector& Location,const FVector& Extent,DWORD TraceFlags); + + /** Initializes the rigid body physics components of this object. + * + * @param : bFixed : indicates whether or not the object is fixed + **/ + virtual void InitComponentRBPhys(UBOOL bFixed); + + /** Terminates the rigid body components in this object + * + * @param InScene : A pointer to the rigid body physics scene. + **/ + virtual void TermComponentRBPhys(FRBPhysScene *InScene); + + // StaticMeshComponent interface + /*** Cooks the convex hull data for this object at a specific scale. + * + * @param Level : A pointer to the ULevel this object is contained within. + * @param TotalScale3D : The scale this object is being cooked for. + * @param TriByteCount : Reference returns the number of bytes the trianngle data takes. + * @param TriMeshCount : A reference which returns the number of triangles meshes created + * @param HullByteCount : A reference which returns the number of bytes the convex hull took up. + * @param HullCount : A reference which returns the number of hulls which were created. + * + **/ + virtual void CookPhysConvexDataForScale(ULevel* Level, const FVector& TotalScale3D, INT& TriByteCount, INT& TriMeshCount, INT& HullByteCount, INT& HullCount); + + // We will release the ApexRenderable in the destroying phase + virtual void BeginDestroy(); + + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + virtual void SetMaterial(int ElementIndex, UMaterialInterface* Material); + +// NVCHANGE_BEGIN: APAN - Apex 1.2 - Update transform to destructible actor, (MoveActor) + virtual void UpdateRBKinematicData(); +// NVCHANGE_END: APAN - Apex 1.2 - Update transform to destructible actor, (MoveActor) + private: + /*** + * Called when the asset is lost or reset + **/ + virtual void OnApexAssetLost(void); + virtual void OnApexAssetReset(void); +} + +defaultproperties +{ + SleepEnergyThreshold=1250.0 + SleepDamping=0.2 + bIsThumbnailComponent=FALSE + bUsePrecomputedShadows=FALSE +} diff --git a/Engine/Classes/AppNotificationsBase.uc b/Engine/Classes/AppNotificationsBase.uc new file mode 100644 index 0000000..10ebfd6 --- /dev/null +++ b/Engine/Classes/AppNotificationsBase.uc @@ -0,0 +1,102 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * This is the base class for per-platform support for handling application notifications + */ + +class AppNotificationsBase extends PlatformInterfaceBase + native(PlatformInterface); + +/** Key/Value pairing for passing custom message strings to notifications */ +struct native NotificationMessageInfo +{ + /** Custom message info key identifier */ + var string Key; + /** Custom message info value */ + var string Value; +}; + +/** All the info relevant to a notification */ +struct native NotificationInfo +{ + /** True if the notification was scheduled locally */ + var bool bIsLocal; + /** Message to show for the body of the notification */ + var string MessageBody; + /** Badge # to show next to the app icon */ + var int BadgeNumber; + /** Custom messages to pass with the notification (key/value pairs) */ + var array MessageInfo; +}; + +/** All the info relevant to a notification */ +struct native LaunchNotificationInfo +{ + /** True if the app was launched because the user accepted a notification */ + var bool bWasLaunchedViaNotification; + /** Custom messages to pass with the notification (key/value pairs) */ + var NotificationInfo Notification; +}; + +/** Info filled in if the app was launched via a notification. */ +var const LaunchNotificationInfo AppLaunchNotification; + +/** + * Perform any initialization. Called once after singleton instantiation + */ +native event Init(); + +/** + * @return True if the app was launched via a notification + */ +function bool WasLaunchedViaNotification() +{ + return AppLaunchNotification.bWasLaunchedViaNotification; +} + +/** + * Schedule a local notification to occur for the current app on the device + * + * @param Notification info needed to define the local notification + * @param StartOffsetSeconds seconds to elapse before the notification is fired. 0 triggers immediately + */ +native function ScheduleLocalNotification(const out NotificationInfo Notification, int StartOffsetSeconds); + +/** + * Cancels all pending local notifications that have been scheduled previously + */ +native function CancelAllScheduledLocalNotifications(); + +/** + * delegate triggered when the app processes a local notification + * + * @param Notification info from the local notification + * @param bWasAppInactive TRUE if the app was in the foreground before the notification was processed + */ +delegate OnReceivedLocalNotification(const out NotificationInfo Notification, bool bWasAppActive); + +/** + * delegate triggered when the app processes a remote notification + * + * @param Notification info from the remote notification + * @param bWasAppInactive TRUE if the app was in the foreground before the notification was processed + */ +delegate OnReceivedRemoteNotification(const out NotificationInfo Notification, bool bWasAppActive); + +/** Debug loggin of a notification entry */ +function DebugLogNotification(const out NotificationInfo Notification) +{ + local int Idx; + + `log("Notification:" + @"bIsLocal="$Notification.bIsLocal + @"BadgeNumber="$Notification.BadgeNumber + @"MessageBody="$Notification.MessageBody); + + for (Idx=0; Idx < Notification.MessageInfo.Length; Idx++) + { + `log("Notification:" + @"key="$Notification.MessageInfo[Idx].Key + @"val="$Notification.MessageInfo[Idx].Value); + } +} \ No newline at end of file diff --git a/Engine/Classes/ArrowComponent.uc b/Engine/Classes/ArrowComponent.uc new file mode 100644 index 0000000..7ecba05 --- /dev/null +++ b/Engine/Classes/ArrowComponent.uc @@ -0,0 +1,28 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ArrowComponent extends PrimitiveComponent + native + noexport + collapsecategories + hidecategories(Object) + editinlinenew; + +var() color ArrowColor; +var() float ArrowSize; +/** If TRUE, don't show the arrow when SHOW_Sprites is disabled. */ +var() bool bTreatAsASprite; + +/** Sprite category that the arrow component belongs to, if being treated as a sprite. Value serves as a key into the localization file. */ +var editoronly name SpriteCategoryName; + +defaultproperties +{ + ArrowColor=(R=255,G=0,B=0,A=255) + ArrowSize=1.0 + // the arrow is generally for the editor, so by default do not load them in the game + HiddenGame=True + AlwaysLoadOnServer=false + AlwaysLoadOnClient=false + SpriteCategoryName="Misc" +} diff --git a/Engine/Classes/AudioComponent.uc b/Engine/Classes/AudioComponent.uc new file mode 100644 index 0000000..bec5604 --- /dev/null +++ b/Engine/Classes/AudioComponent.uc @@ -0,0 +1,263 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AudioComponent extends ActorComponent + native + noexport + collapsecategories + hidecategories(Object,ActorComponent) + dependson(ReverbVolume) + editinlinenew; + +var() SoundCue SoundCue; +var native const SoundNode CueFirstNode; // This is just a pointer to the root node in SoundCue. + +/** + * Struct used for storing one per-instance named paramter for this AudioComponent. + * Certain nodes in the SoundCue may reference parameters by name so they can be adjusted per-instance. + */ +struct native AudioComponentParam +{ + var() name ParamName; + var() float FloatParam; + var() SoundNodeWave WaveParam; +}; + +/** Array of per-instance parameters for this AudioComponent. */ +var() editinline array InstanceParameters; + +/** Spatialise to the owner's coordinates */ +var bool bUseOwnerLocation; +/** Auto start this component on creation */ +var bool bAutoPlay; +/** Auto destroy this component on completion */ +var bool bAutoDestroy; +/** Stop sound when owner is destroyed */ +var bool bStopWhenOwnerDestroyed; +/** Whether the wave instances should remain active if they're dropped by the prioritization code. Useful for e.g. vehicle sounds that shouldn't cut out. */ +var bool bShouldRemainActiveIfDropped; +/** whether we were occluded the last time we checked */ +var bool bWasOccluded; +/** If true, subtitles in the sound data will be ignored. */ +var transient bool bSuppressSubtitles; +/** Set to true when the component has resources that need cleanup */ +var transient bool bWasPlaying; +/** Is this audio component allowed to be spatialized? */ +var bool bAllowSpatialization; +/** Whether the current component has finished playing */ +var transient bool bFinished; +/** If TRUE, this sound will not be stopped when flushing the audio device. */ +var transient bool bApplyRadioFilter; +/** If TRUE, the decision on whether to apply the radio filter has been made. */ +var transient bool bRadioFilterSelected; + +/** Whether this audio component is previewing a sound */ +var transient bool bPreviewComponent; +/** If TRUE, this sound will not be stopped when flushing the audio device. */ +var transient bool bIgnoreForFlushing; + +/** + * Properties of the audio component set by its owning sound class + */ + +/** The amount of stereo sounds to bleed to the rear speakers */ +var transient float StereoBleed; +/** The amount of a sound to bleed to the LFE channel */ +var transient float LFEBleed; + +/** Whether audio effects are applied */ +var transient bool bEQFilterApplied; +/** Whether to artificially prioritise the component to play */ +var transient bool bAlwaysPlay; +/** Whether or not this sound plays when the game is paused in the UI */ +var transient bool bIsUISound; +/** Whether or not this audio component is a music clip */ +var transient bool bIsMusic; +/** Whether or not the audio component should be excluded from reverb EQ processing */ +var transient bool bReverb; +/** Whether or not this sound class forces sounds to the center channel */ +var transient bool bCenterChannelOnly; + +var duplicatetransient native const array WaveInstances{struct FWaveInstance}; +var duplicatetransient native const array SoundNodeData; + +/** + * We explicitly disregard SoundNodeOffsetMap/WaveMap/ResetWaveMap for GC as all references are already + * handled elsewhere and we can't NULL references anyways. + */ +var duplicatetransient native const Map{USoundNode*,UINT} SoundNodeOffsetMap; +var duplicatetransient native const multimap_mirror SoundNodeResetWaveMap{TMultiMap}; + +var duplicatetransient native const pointer Listener{struct FListener}; + +var duplicatetransient native const float PlaybackTime; +var duplicatetransient native const PortalVolume PortalVolume; +var duplicatetransient native vector Location; +var duplicatetransient native const vector ComponentLocation; + +/** Remember the last owner so we can remove it from the actor's component array even if it's already been detached */ +var transient const Actor LastOwner; + +/** Used by the subtitle manager to prioritize subtitles wave instances spawned by this component. */ +var native float SubtitlePriority; + +var float FadeInStartTime; +var float FadeInStopTime; +/** This is the volume level we are fading to **/ +var float FadeInTargetVolume; + +var float FadeOutStartTime; +var float FadeOutStopTime; +/** This is the volume level we are fading to **/ +var float FadeOutTargetVolume; + +var float AdjustVolumeStartTime; +var float AdjustVolumeStopTime; +/** This is the volume level we are adjusting to **/ +var float AdjustVolumeTargetVolume; +var float CurrAdjustVolumeTargetVolume; + +// Temporary variables for node traversal. +var native const SoundNode CurrentNotifyBufferFinishedHook; +var native const vector CurrentLocation; +var native const vector CurrentVelocity; +var native const float CurrentVolume; +var native const float CurrentPitch; +var native const float CurrentHighFrequencyGain; +var native const int CurrentUseSpatialization; +var native const int CurrentNotifyOnLoop; +var native const float OmniRadius; + +// Multipliers used before propagation to WaveInstance +var native const float CurrentVolumeMultiplier; +var native const float CurrentPitchMultiplier; +var native const float CurrentHighFrequencyGainMultiplier; + +var native const float CurrentVoiceCenterChannelVolume; +var native const float CurrentRadioFilterVolume; +var native const float CurrentRadioFilterVolumeThreshold; + +// To remember where the volumes are interpolating to and from +var native const double LastUpdateTime; +var native const float SourceInteriorVolume; +var native const float SourceInteriorLPF; +var native const float CurrentInteriorVolume; +var native const float CurrentInteriorLPF; + +/** location last time playback was updated */ +var transient const vector LastLocation; + +/** cache what volume settings we had last time so we don't have to search again if we didn't move */ +var native const InteriorSettings LastInteriorSettings; +var native const int LastReverbVolumeIndex; + +// Serialized multipliers used to e.g. override volume for ambient sound actors. +var() float VolumeMultiplier; +var() float PitchMultiplier; +var() float HighFrequencyGainMultiplier; + +/** while playing, this component will check for occlusion from its closest listener every this many seconds and call OcclusionChanged() if the status changes */ +var float OcclusionCheckInterval; +/** last time we checked for occlusion */ +var transient float LastOcclusionCheckTime; + +var const DrawSoundRadiusComponent PreviewSoundRadius; + +`if(`__TW_) +var SkeletalMeshComponent SkelMeshBase; +var name SkelMeshBaseBoneName; +`endif // __TW_ + +native final function Play(); +native final function Stop(); + +/** @return TRUE if this component is currently playing a SoundCue. */ +native final function bool IsPlaying(); + +/** @return TRUE if this component is currently fading in. */ +native final function bool IsFadingIn(); + +/** @return TRUE if this component is currently fading out. */ +native final function bool IsFadingOut(); + +/** + * This is called in place of "play". So you will say AudioComponent->FadeIn(). + * This is useful for fading in music or some constant playing sound. + * + * If FadeTime is 0.0, this is the same as calling Play() but just modifying the volume by + * FadeVolumeLevel. (e.g. you will play instantly but the FadeVolumeLevel will affect the AudioComponent) + * + * If FadeTime is > 0.0, this will call Play(), and then increase the volume level of this + * AudioCompoenent to the passed in FadeVolumeLevel over FadeInTime seconds. + * + * The VolumeLevel is MODIFYING the AudioComponent's "base" volume. (e.g. if you have an + * AudioComponent that is volume 1000 and you pass in .5 as your VolumeLevel then you will fade to 500 ) + * + * @param FadeInDuration how long it should take to reach the FadeVolumeLevel + * @param FadeVolumeLevel the percentage of the AudioComponents's calculated volume in which to fade to + **/ +native final function FadeIn( FLOAT FadeInDuration, FLOAT FadeVolumeLevel ); + +/** + * This is called in place of "stop". So you will say AudioComponent->FadeOut(). + * This is useful for fading out music or some constant playing sound. + * + * If FadeTime is 0.0, this is the same as calling Stop(). + * + * If FadeTime is > 0.0, this will decrease the volume level of this + * AudioCompoenent to the passed in FadeVolumeLevel over FadeInTime seconds. + * + * The VolumeLevel is MODIFYING the AudioComponent's "base" volume. (e.g. if you have an + * AudioComponent that is volume 1000 and you pass in .5 as your VolumeLevel then you will fade to 500 ) + * + * @param FadeOutDuration how long it should take to reach the FadeVolumeLevel + * @param FadeVolumeLevel the percentage of the AudioComponents's calculated volume in which to fade to + **/ +native final function FadeOut( FLOAT FadeOutDuration, FLOAT FadeVolumeLevel ); + +/** + * This will allow one to adjust the volume of an AudioComponent on the fly + **/ +native final function AdjustVolume( FLOAT AdjustVolumeDuration, FLOAT AdjustVolumeLevel ); + +native final function SetFloatParameter(name InName, float InFloat); + +native final function SetWaveParameter(name InName, SoundNodeWave InWave); + +/** stops the audio (if playing), detaches the component, and resets the component's properties to the values of its template */ +native final function ResetToDefaults(); + +/** called when we finish playing audio, either because it played to completion or because a Stop() call turned it off early */ +delegate OnAudioFinished(AudioComponent AC); + +/** Called when subtitles are sent to the SubtitleManager. Set this delegate if you want to hijack the subtitles for other purposes */ +delegate OnQueueSubtitles(array Subtitles, float CueDuration); + +/** called when OcclusionCheckInterval > 0.0 and the occlusion status changes */ +event OcclusionChanged(bool bNowOccluded) +{ + VolumeMultiplier *= bNowOccluded ? 0.5 : 2.0; +} + +defaultproperties +{ + bUseOwnerLocation=true + bAutoDestroy=false + bAutoPlay=false + bAllowSpatialization=true + + VolumeMultiplier=1.0 + PitchMultiplier=1.0 + HighFrequencyGainMultiplier=1.0 + + FadeInStopTime=-1.0f + FadeOutStopTime=-1.0f + AdjustVolumeStopTime=-1.0f + + FadeInTargetVolume=1.0f + FadeOutTargetVolume=1.0f + AdjustVolumeTargetVolume=1.0f + CurrAdjustVolumeTargetVolume=1.0f + + LastLocation=(X=1.0,Y=2.0,Z=3.0) // so spawning at origin doesn't use cached values +} diff --git a/Engine/Classes/AudioDevice.uc b/Engine/Classes/AudioDevice.uc new file mode 100644 index 0000000..248cd48 --- /dev/null +++ b/Engine/Classes/AudioDevice.uc @@ -0,0 +1,181 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class AudioDevice extends Subsystem + config( engine ) + native( AudioDevice ) + dependson( SoundClass ) + transient; + +/** + * Filled out with entries from DefaultEngine.ini + */ +enum ESoundClassName +{ + Master +}; + +/** + * Debug state of the audio system + */ +enum EDebugState +{ + // No debug sounds + DEBUGSTATE_None, + // No reverb sounds + DEBUGSTATE_IsolateDryAudio, + // Only reverb sounds + DEBUGSTATE_IsolateReverb, + // Force LPF on all sources + DEBUGSTATE_TestLPF, + // Bleed stereo sounds fully to the rear speakers + DEBUGSTATE_TestStereoBleed, + // Bleed all sounds to the LFE speaker + DEBUGSTATE_TestLFEBleed, + // Disable any LPF filter effects + DEBUGSTATE_DisableLPF, + // Disable any radio filter effects + DEBUGSTATE_DisableRadio, +}; + +/** + * The different voices available for TTS + */ +enum ETTSSpeaker +{ + TTSSPEAKER_Paul, + TTSSPEAKER_Harry, + TTSSPEAKER_Frank, + TTSSPEAKER_Dennis, + TTSSPEAKER_Kit, + TTSSPEAKER_Betty, + TTSSPEAKER_Ursula, + TTSSPEAKER_Rita, + TTSSPEAKER_Wendy, +}; + +/** + * Defines the properties of the listener + */ +struct native Listener +{ + var const PortalVolume PortalVolume; + var vector Location; + var vector Up; + var vector Right; + var vector Front; + var vector Velocity; +}; + +/** + * Structure for collating info about sound classes + */ +struct native AudioClassInfo +{ + var const int NumResident; + var const int SizeResident; + var const int NumRealTime; + var const int SizeRealTime; +}; + +/** The maximum number of concurrent audible sounds */ +var config const int MaxChannels; +/** The amount of memory to reserve for always resident sounds */ +var config const int CommonAudioPoolSize; +/** Low pass filter OneOverQ value */ +var config const float LowPassFilterResonance; +/** Sound duration in seconds below which sounds are entirely expanded to PCM at load time in the Editor. */ +var config const float MinCompressedDurationEditor; +/** Sound duration in seconds below which sounds are entirely expanded to PCM at load time in the Game. */ +var config const float MinCompressedDurationGame; + +/** Sound node wave to use for the radio chirp in sound */ +var config const string ChirpInSoundNodeWaveName; +var const SoundNodeWave ChirpInSoundNodeWave; +/** Sound node wave to use for the radio chirp out sound */ +var config const string ChirpOutSoundNodeWaveName; +var const SoundNodeWave ChirpOutSoundNodeWave; + +/** Pointer to permanent memory allocation stack. */ +var native const pointer CommonAudioPool; +/** Available size in permanent memory stack */ +var native const int CommonAudioPoolFreeBytes; + +var transient const array AudioComponents; +var native const array Sources{FSoundSource}; +var native const array FreeSources{FSoundSource}; +var native const Map{FWaveInstance*, FSoundSource*} WaveInstanceSourceMap; + +var native const bool bGameWasTicking; + +var native const array Listeners; +var native const QWORD CurrentTick; + +/** Map of available sound classes */ +var() Map{FName, class USoundClass*} SoundClasses; + +/** Source, current and destination properties of all sound classes */ +var Map{FName, struct FSoundClassProperties} SourceSoundClasses; +var Map{FName, struct FSoundClassProperties} CurrentSoundClasses; +var Map{FName, struct FSoundClassProperties} DestinationSoundClasses; + +/** Map of available sound modes */ +var native const Map{FName, class USoundMode*} SoundModes; + +/** Interface to audio effects processing */ +var native const pointer Effects{class FAudioEffectsManager}; + +var native const name BaseSoundModeName; +var native const SoundMode CurrentMode; +var native const double SoundModeStartTime; +var native const double SoundModeFadeInStartTime; +var native const double SoundModeFadeInEndTime; +var native const double SoundModeEndTime; + +/** The index of the volume the listener resides in */ +var native const int ListenerVolumeIndex; +var native const InteriorSettings ListenerInteriorSettings; + +/** The times of interior volumes fading in and out */ +var native const double InteriorStartTime; +var native const double InteriorEndTime; +var native const double ExteriorEndTime; +var native const double InteriorLPFEndTime; +var native const double ExteriorLPFEndTime; + +var native const float InteriorVolumeInterp; +var native const float InteriorLPFInterp; +var native const float ExteriorVolumeInterp; +var native const float ExteriorLPFInterp; + +/** An AudioComponent to play test sounds on */ +var const AudioComponent TestAudioComponent; + +/** Interface to text to speech processor */ +var native const pointer TextToSpeech{class FTextToSpeech}; + +/** The debug state of the audio device */ +var native const EDebugState DebugState; + +/** transient master volume multiplier that can be modified at runtime without affecting user settings automatically reset to 1.0 on level change */ +var transient float TransientMasterVolume; + +/** Timestamp of the last update */ +var transient float LastUpdateTime; + +/** flag to stop audio component spawning, used on map change */ +var transient bool bSoundSpawningEnabled; + +/** + * Sets a new sound mode and applies it to all appropriate sound classes + */ +native final function bool SetSoundMode( name NewMode ); + +/** Find SoundClass given a Name */ +native final function SoundClass FindSoundClass( Name SoundClassName ); + +defaultproperties +{ + TransientMasterVolume=1.0 +} diff --git a/Engine/Classes/AutoLadder.uc b/Engine/Classes/AutoLadder.uc new file mode 100644 index 0000000..8ef3836 --- /dev/null +++ b/Engine/Classes/AutoLadder.uc @@ -0,0 +1,13 @@ +/*============================================================================= +// AutoLadder - automatically placed at top and bottom of LadderVolume +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +============================================================================= */ + +class AutoLadder extends Ladder + notplaceable + native; + +defaultproperties +{ + bCollideWhenPlacing=false +} diff --git a/Engine/Classes/AutoNavMeshPathObstacleUnregister.uc b/Engine/Classes/AutoNavMeshPathObstacleUnregister.uc new file mode 100644 index 0000000..ded8506 --- /dev/null +++ b/Engine/Classes/AutoNavMeshPathObstacleUnregister.uc @@ -0,0 +1,23 @@ +/** + * this object's sole purpose is to bind the lifetime of itself with that of a pathobstacle.. such that when this + * object is garbage collected the path obstacle is unregistered. Only the object implementing Interface_navMeshpathObstacle should + * reference this, so that the lifetime of this object is direclty coupled with that object + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class AutoNavMeshPathObstacleUnregister extends Object + native(AI); + +var native Interface_NavMeshPathObstacle PathObstacleRef; + +cpptext +{ + virtual void BeginDestroy() + { + Super::BeginDestroy(); + if( PathObstacleRef.GetInterface() != NULL ) + { + PathObstacleRef->UnregisterObstacleWithNavMesh(); + } + } +}; \ No newline at end of file diff --git a/Engine/Classes/AutoTestManager.uc b/Engine/Classes/AutoTestManager.uc new file mode 100644 index 0000000..f54bb0b --- /dev/null +++ b/Engine/Classes/AutoTestManager.uc @@ -0,0 +1,887 @@ +//============================================================================= +// AutoTestManager +// +// The AutoTestManager is spawned by the GameInfo if requested by the URL. +// It provides an interface for performing in gameplay automated testing. +// +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class AutoTestManager extends Info + native + config(Game); + +//================================================================= +// AUTOMATED PERFORMANCE TESTING PROPERTIES +/** Whether the game is currently in automated perf test mode. */ +var bool bAutomatedPerfTesting; + +/** Amount of time remaining before match ends -- used for auto performance test shutdown */ +var int AutomatedPerfRemainingTime; + +/** This will auto continue to the next round. Very useful doing soak testing and testing traveling to next level **/ +var bool bAutoContinueToNextRound; + +/** Whether or not we are using the Automated Testing Map list **/ +var bool bUsingAutomatedTestingMapList; + +/** If TRUE, use OpenMap to transition; if FALSE, use SeamlessTravel **/ +var bool bAutomatedTestingWithOpen; + +/** + * The index of the current automated testing map. + * If < 0 we are in the transition map. + **/ +var int AutomatedTestingMapIndex; + +/** List of maps that we are going to be using for the AutomatedMapTesting **/ +var globalconfig array AutomatedMapTestingList; + +/** Number of times to run through the list. (0 in infinite) **/ +var globalconfig int NumAutomatedMapTestingCycles; + +/** Whether to exit when NumAutomatedMapTestingCycles is reached */ +var globalconfig bool bExitOnCyclesComplete; + +/** + * Number of matches played (maybe remove this before shipping) + * This is really useful for doing soak testing and such to see how long you lasted! + * NOTE: This is not replicated out to clients atm. + **/ +var int NumberOfMatchesPlayed; + +/** Keeps track of the current run so when we have repeats and such we know how far along we are **/ +var int NumMapListCyclesDone; + +/** This will be run at the start of each start match **/ +var string AutomatedTestingExecCommandToRunAtStartMatch; + +/** This will be the 'transition' map used w/ OpenMap runs **/ +var string AutomatedMapTestingTransitionMap; + +/** + * Whether or not this game should check for fragmentation. This can be used to have a specific game type check for fragmentation at some point + * (e.g. start/end of match, time period) + **/ +var bool bCheckingForFragmentation; + +/** Whether or not this game should check for memory leaks **/ +var bool bCheckingForMemLeaks; + +//==================================================================== +// SENTINEL PROPERTIES +/** Whether or this game is doing a bDoingASentinelRun test **/ +var bool bDoingASentinelRun; + +/** Used for the BeginRun Task___ strings, examples "FlyThrough", "FlyThroughSplitScreen", "BVT" */ +var String SentinelTaskDescription; + +/** Used for the BeginRun Task___ strings */ +var String SentinelTaskParameter; + +/** Used for the BeginRun Task___ strings */ +var String SentinelTagDesc; + +/** PlayerController used for Sentinel - picked randomly */ +var transient PlayerController SentinelPC; + +/** Locations where sentinel should go to */ +var transient array SentinelTravelArray; + +/** Iterator for looping through SentinelTravelArray - for loop is in state code, so can't define locally */ +var transient int SentinelNavigationIdx; + +/** Iterator for various sentinel state code loops - for loop is in state code, so can't define locally */ +var transient int SentinelIdx; + +/** Used to delay until streaming levels are fully loaded */ +var transient bool bSentinelStreamingLevelStillLoading; + +/** Change increments for iterating through rotations used at sentinel travel locations */ +var transient int NumRotationsIncrement; + +/** Change increments for iterating through sentinel travel locations */ +var transient int TravelPointsIncrement; + +/** How many minutes per map we are allowed to run. **/ +var config int NumMinutesPerMap; + +/** + * At each TravelTheWorld node we fire off all of the commands in this array. This is good for being able to + * do things like fire off a debug command without having to recook the entire map (e.g. MemLeakCheck at each node). + **/ +var config array CommandsToRunAtEachTravelTheWorldNode; + +/** Transient string that we need for our foreach in the TravelTheWorld state code **/ +var transient String CommandStringToExec; + +event PostBeginPlay() +{ + Super.PostBeginPlay(); + + SetTimer(1.0, true); +} + +/** + * Base AutoTestManager timer ticks once per second + * Checks if perf test timer has run out + */ +event Timer() +{ + if( bAutomatedPerfTesting && (AutomatedPerfRemainingTime > 0) && !bAutoContinueToNextRound ) + { + AutomatedPerfRemainingTime--; + if( AutomatedPerfRemainingTime <= 0 ) + { + // Exit at the end of the match if automated perf testing is enabled. + ConsoleCommand("EXIT"); + } + } +} + +/** + * Initialize AutoTestManager based on command line options + * @param Options is the full command line options string passed to GameInfo + */ +function InitializeOptions(string Options) +{ + local string InOpt; + + AutomatedPerfRemainingTime = 60 * WorldInfo.Game.TimeLimit; + + bAutomatedPerfTesting = ( WorldInfo.Game.ParseOption( Options, "AutomatedPerfTesting" ) ~= "1" ) || ( WorldInfo.Game.ParseOption( Options, "gAPT" ) ~= "1" ); + + bCheckingForFragmentation = ( WorldInfo.Game.ParseOption( Options, "CheckingForFragmentation" ) ~= "1" ) || ( WorldInfo.Game.ParseOption( Options, "gCFF" ) ~= "1" ); + + bCheckingForMemLeaks = ( WorldInfo.Game.ParseOption( Options, "CheckingForMemLeaks" ) ~= "1" ) || ( WorldInfo.Game.ParseOption( Options, "gCFML" ) ~= "1" ); + bDoingASentinelRun = ( WorldInfo.Game.ParseOption( Options, "DoingASentinelRun" ) ~= "1" ) || ( WorldInfo.Game.ParseOption( Options, "gDASR" ) ~= "1" ); + + SentinelTaskDescription = ( WorldInfo.Game.ParseOption( Options, "SentinelTaskDescription" ) ); + if( SentinelTaskDescription == "" ) + { + SentinelTaskDescription = ( WorldInfo.Game.ParseOption( Options, "gSTD" ) ); + } + + SentinelTaskParameter = ( WorldInfo.Game.ParseOption( Options, "SentinelTaskParameter" ) ); + if( SentinelTaskParameter == "" ) + { + SentinelTaskParameter = ( WorldInfo.Game.ParseOption( Options, "gSTP" ) ); + } + + SentinelTagDesc = ( WorldInfo.Game.ParseOption( Options, "SentinelTagDesc" ) ); + if( SentinelTagDesc == "" ) + { + SentinelTagDesc = ( WorldInfo.Game.ParseOption( Options, "gSTDD" ) ); + } + + InOpt = WorldInfo.Game.ParseOption( Options, "AutoContinueToNextRound"); + if( InOpt != "" ) + { + `log("AutoContinueToNextRound: "$bool(InOpt)); + bAutoContinueToNextRound = bool(InOpt); + } + + + InOpt = WorldInfo.Game.ParseOption( Options, "bUsingAutomatedTestingMapList"); + if( InOpt != "" ) + { + `log("bUsingAutomatedTestingMapList: "$bool(InOpt)); + bUsingAutomatedTestingMapList = bool(InOpt); + } + + if ( bUsingAutomatedTestingMapList ) + { + if (AutomatedMapTestingList.length == 0) + { + `log("*** No maps in automated test map list... Disabling bUsingAutomatedTestingMapList"); + bUsingAutomatedTestingMapList = false; + } + } + + InOpt = WorldInfo.Game.ParseOption( Options, "bAutomatedTestingWithOpen"); + if( InOpt != "" ) + { + `log("bAutomatedTestingWithOpen: "$bool(InOpt)); + bAutomatedTestingWithOpen = bool(InOpt); + } + + AutomatedTestingExecCommandToRunAtStartMatch = WorldInfo.Game.ParseOption( Options, "AutomatedTestingExecCommandToRunAtStartMatch"); + `log("AutomatedTestingExecCommandToRunAtStartMatch: "$AutomatedTestingExecCommandToRunAtStartMatch); + + AutomatedMapTestingTransitionMap = WorldInfo.Game.ParseOption( Options, "AutomatedMapTestingTransitionMap"); + `log("AutomatedMapTestingTransitionMap: "$AutomatedMapTestingTransitionMap); + + InOpt = WorldInfo.Game.ParseOption(Options, "AutomatedTestingMapIndex"); + if (InOpt != "") + { + `log("AutomatedTestingMapIndex: " $ int(InOpt)); + AutomatedTestingMapIndex = int(InOpt); + } + + if ( bAutomatedTestingWithOpen ) + { + InOpt = WorldInfo.Game.ParseOption(Options, "NumberOfMatchesPlayed"); + if (InOpt != "") + { + `log("NumberOfMatchesPlayed: " $ int(InOpt)); + NumberOfMatchesPlayed = int(InOpt); + } + + InOpt = WorldInfo.Game.ParseOption(Options, "NumMapListCyclesDone"); + if (InOpt != "") + { + `log("NumMapListCyclesDone: " $ int(InOpt)); + NumMapListCyclesDone = int(InOpt); + } + } + else + { + // Server travel uses a transition map automatically... + `log("*** Disabling automated transition map for ServerTravel"); + AutomatedMapTestingTransitionMap = ""; + } +} + +//// SENTINEL FUNCTIONS START +/** + * This will start a SentinelRun in the DB. Setting up the Run table with all of metadata that a run has. + * This will also set the GSentinelRunID so that the engine knows what the current run is. + * + * @param TaskDescription The name/description of the task that we are running + * @param TaskParameter Any Parameters that the task needs + * @param TagDesc A specialized tag (e.g. We are doing Task A with Param B and then "MapWithParticlesAdded" so it can be found) + **/ +native function BeginSentinelRun( const string TaskDescription, const string TaskParameter, const string TagDesc ); + + +/** + * This will output some set of data that we care about when we are doing Sentinel runs while we are + * doing a MP test or a BVT. + * Prob just stat unit and some other random stats (streaming fudge factor and such) + **/ +native function AddSentinelPerTimePeriodStats( const vector InLocation, const rotator InRotation ); + + +/** + * This will tell the DB to end the current Sentinel run (i.e. GSentinelRunID) and set that Run's RunResult to the passed in var. + * + * @param RunResult The result of this Sentinel run (e.g. OOM, Passed, etc.) + **/ +native function EndSentinelRun( EAutomatedRunResult RunResult ); + +//// This code is our "travel the map and get Sentinel data at each point //// +// so we need to do: +// 0) turn off streaming volume streaming of levels bIsUsingStreamingVolumes +// 1) unload all levels StreamLevelOut( ) +// 2) for each level in the P level +// load it and then grab all of the locations of the NavigationPoints and store it +// 3) turn back on the streaming volume support +// 4) iterate down the list of locations + +/** + * function to start the world traveling + **/ +function DoTravelTheWorld() +{ + GotoState( 'TravelTheWorld' ); +} + +/** + * This our state which allows us to have delayed actions while traveling the world (e.g. waiting for levels to stream in) + **/ +state TravelTheWorld +{ + function BeginState( name PreviousStateName ) + { + local PlayerController PC; + `log( "BeginState TravelTheWorld" ); + + Super.BeginState( PreviousStateName ); + + foreach LocalPlayerControllers( class'PlayerController', PC ) + { + SentinelPC = PC; + SentinelPC.Sentinel_SetupForGamebasedTravelTheWorld(); + break; + } + + SentinelPC.bIsUsingStreamingVolumes = FALSE; + + BeginSentinelRun( SentinelTaskDescription, SentinelTaskParameter, SentinelTagDesc ); + } + + function float CalcTravelTheWorldTime( const int NumTravelLocations, const int NumRotations ) + { + local float TotalTimeInSeconds; + local float PerTravelLocTime; + + // streaming out all maps + TotalTimeInSeconds += WorldInfo.StreamingLevels.length * 2.0f; + TotalTimeInSeconds += 10.0f; + + // gathering travel locations + TotalTimeInSeconds += WorldInfo.StreamingLevels.length * 10.0f; + TotalTimeInSeconds += 10.0f; + + // wait for kill all + TotalTimeInSeconds += 10.0f; + + // 4.0f is the avg cost for waiting for levels to stream in (guess basically) + // we do two rotations as we want to capture UnitFPS data without any text on the screen + PerTravelLocTime = 0.5f + 4.0f + 1.0f + 0.5f + 1.0f + (NumRotations*1.5f) + (NumRotations*1.5f);; + + TotalTimeInSeconds += (PerTravelLocTime * NumTravelLocations); + + + return TotalTimeInSeconds; + } + + function PrintOutTravelWorldTimes( const int TotalTimeInSeconds ) + { + `if(`notdefined(FINAL_RELEASE)) + local int Hours; + local int Minutes; + local int Seconds; + + Hours = TotalTimeInSeconds / (60 * 60); + Minutes = (TotalTimeInSeconds -(Hours * 60 * 60)) / 60; + Seconds = TotalTimeInSeconds - (Minutes * 60) - (Hours * 60 * 60); + + `log( WorldInfo.GetMapName() $ ": Traveling this map will take approx TotalSeconds: " $ TotalTimeInSeconds $ " Hours: " $ Hours $ " Minutes: " $ Minutes $ " Seconds: " $ Seconds ); + `endif + } + + /** + * Modify our Increments so that we get the most number of nodes traveled to + * best is to travel to all doing 8 directions + * next is to travel to all and do 4 directions + * next is to travel to as many as possible across the map doing 4 directions + * @param NumTravelLocations is the total number of destination positions + */ + function SetIncrementsForLoops( const float NumTravelLocations ) + { + local float TimeWeGetInSeconds; + + // @todo be able to pass in how much time we get in seconds + TimeWeGetInSeconds = NumMinutesPerMap * 60; + + // if we will be able to travel to all points! so only increment by 1 + if( CalcTravelTheWorldTime( NumTravelLocations, 8 ) < TimeWeGetInSeconds ) + { + TravelPointsIncrement = 1; + NumRotationsIncrement = 1; + `log( WorldInfo.GetMapName() $ " SetIncrementsForLoops: TravelPointsIncrement: " $ TravelPointsIncrement $ " NumRotationsIncrement: " $ NumRotationsIncrement $ " for NumTravelLocations: " $ NumTravelLocations); + PrintOutTravelWorldTimes( CalcTravelTheWorldTime( NumTravelLocations, 8 ) ); + } + // we can't get to all points so let's start reducing what we do + else + { + // if we can get to all points but only 4 rotations + if( CalcTravelTheWorldTime( NumTravelLocations, 4 ) < TimeWeGetInSeconds ) + { + TravelPointsIncrement = 1; + NumRotationsIncrement = 2; // (8/4) + `log( WorldInfo.GetMapName() $ " SetIncrementsForLoops: TravelPointsIncrement: " $ TravelPointsIncrement $ " NumRotationsIncrement: " $ NumRotationsIncrement $ " for NumTravelLocations: " $ NumTravelLocations); + PrintOutTravelWorldTimes( CalcTravelTheWorldTime( NumTravelLocations, 4 ) ); + + } + // we can't get to all points with 4 rotations so we need to increment our travelpoints faster + else + { + // not 100% precise but the travel time is bounded by num points + TravelPointsIncrement = CalcTravelTheWorldTime( NumTravelLocations, 4 ) / TimeWeGetInSeconds; + + NumRotationsIncrement = 2; // (8/4) + `log( WorldInfo.GetMapName() $ " SetIncrementsForLoops: TravelPointsIncrement: " $ TravelPointsIncrement $ " NumRotationsIncrement: " $ NumRotationsIncrement $ " for NumTravelLocations: " $ NumTravelLocations); + PrintOutTravelWorldTimes( CalcTravelTheWorldTime( NumTravelLocations/TravelPointsIncrement, 4 ) ); + } + } + + } + + +Begin: + // james pointed out that we could just save this out in the WorldInfo But that will take extra memory which could be thrown + // away for final release + + SentinelPC.Sentinel_PreAcquireTravelTheWorldPoints(); + + // we need to do some madness here as the async nature of the streaming makes it hard to just call and have the state be correct + for( SentinelIdx = 0; SentinelIdx < WorldInfo.StreamingLevels.length; ++SentinelIdx ) + { + `log( "StreamLevelOut: " $ Worldinfo.StreamingLevels[SentinelIdx].PackageName ); + SentinelPC.ClientUpdateLevelStreamingStatus( Worldinfo.StreamingLevels[SentinelIdx].PackageName, FALSE, FALSE, TRUE ); + } + sleep( 10.0f ); + WorldInfo.ForceGarbageCollection( TRUE ); + + for( SentinelIdx = 0; SentinelIdx < WorldInfo.StreamingLevels.length; ++SentinelIdx ) + { + `log( "Gathering locations for: " $ Worldinfo.StreamingLevels[SentinelIdx].PackageName ); + SentinelPC.ClientUpdateLevelStreamingStatus( Worldinfo.StreamingLevels[SentinelIdx].PackageName, TRUE, TRUE, TRUE ); + sleep( 7.0f ); // wait for the level to be streamed back in + + GetTravelLocations( WorldInfo.StreamingLevels[SentinelIdx].PackageName, SentinelPC, SentinelTravelArray ); + + DoSentinelActionPerLoadedMap(); + // turn on Memory checking + SentinelPC.ConsoleCommand( "FractureAllMeshesToMaximizeMemoryUsage" ); + SentinelPC.ConsoleCommand( "stat memory" ); + Sleep( 0.5f ); + DoSentinel_MemoryAtSpecificLocation( vect(0,0,0), rot(0,0,0) ); + SentinelPC.ConsoleCommand( "stat memory" ); + + SentinelPC.ClientUpdateLevelStreamingStatus( Worldinfo.StreamingLevels[SentinelIdx].PackageName, FALSE, FALSE, TRUE ); + sleep( 3.0f ); + WorldInfo.ForceGarbageCollection( TRUE ); + } + + + // this is the Single Level case (e.g. MP_ levels) + if( WorldInfo.StreamingLevels.length == 0 ) + { + GetTravelLocations( WorldInfo.StreamingLevels[SentinelIdx].PackageName, SentinelPC, SentinelTravelArray ); + DoSentinelActionPerLoadedMap(); + // turn on Memory checking + SentinelPC.ConsoleCommand( "FractureAllMeshesToMaximizeMemoryUsage" ); + SentinelPC.ConsoleCommand( "stat memory" ); + Sleep( 0.5f ); + DoSentinel_MemoryAtSpecificLocation( vect(0,0,0), rot(0,0,0) ); + SentinelPC.ConsoleCommand( "stat memory" ); + + sleep( 3.0f ); + WorldInfo.ForceGarbageCollection( TRUE ); + } + + `log( WorldInfo.GetMapName() $ " COMPLETED LEVEL INTEROGATION!! Total TravelPoints: " $ SentinelTravelArray.Length ); + SetIncrementsForLoops( SentinelTravelArray.Length ); + + + //// so now turn back on streaming AND turn back on streaming for _LOD levels + + for( SentinelIdx = 0; SentinelIdx < WorldInfo.StreamingLevels.length; ++SentinelIdx ) + { + if( LevelStreamingAlwaysLoaded(Worldinfo.StreamingLevels[SentinelIdx]) != none ) + { + `log( " Found a LevelStreamingAlwaysLoaded" @ Worldinfo.StreamingLevels[SentinelIdx].PackageName ); + SentinelPC.ClientUpdateLevelStreamingStatus( Worldinfo.StreamingLevels[SentinelIdx].PackageName, TRUE, TRUE, TRUE ); + } + } + + SentinelPC.bIsUsingStreamingVolumes = TRUE; + + + sleep( 10.0f ); + + SentinelPC.Sentinel_PostAcquireTravelTheWorldPoints(); + + sleep( 10.0f ); + + // add the first point in the list to the end (so we return back there for our final MemLeakCheck) + SentinelTravelArray.AddItem( SentinelTravelArray[0] ); + + `log( "Starting Traversal" ); + `log( " SentinelTravelArray.length " $ SentinelTravelArray.length ); + for( SentinelNavigationIdx = 0; SentinelNavigationIdx < SentinelTravelArray.length; SentinelNavigationIdx+=TravelPointsIncrement ) + { + `log( "Going to:" @ SentinelTravelArray[SentinelNavigationIdx] @ SentinelNavigationIdx $ " of " $ SentinelTravelArray.length ); + + SentinelPC.SetLocation( SentinelTravelArray[SentinelNavigationIdx] ); + SentinelPC.SetRotation( rot(0,0,0) ); + + sleep( 0.5f ); + + // wait until all levels are streamed back in + do + { + bSentinelStreamingLevelStillLoading = FALSE; + + for( SentinelIdx = 0; SentinelIdx < WorldInfo.StreamingLevels.length; ++SentinelIdx ) + { + if( WorldInfo.StreamingLevels[SentinelIdx].bHasLoadRequestPending == TRUE ) + { + `log( "levels not streamed in yet sleeping 1s" ); + bSentinelStreamingLevelStillLoading = TRUE; + Sleep( 1.0f ); + break; + } + } + } until( bSentinelStreamingLevelStillLoading == FALSE ); + + WorldInfo.ForceGarbageCollection( TRUE ); + sleep( 1.0f ); + + // this is our first point so grab the MemoryData + if( SentinelNavigationIdx == 0 ) + { + ConsoleCommand( "MemLeakCheck" ); + } + + + // turn on Memory checking + SentinelPC.ConsoleCommand( "stat memory" ); + Sleep( 0.5f ); + DoSentinel_MemoryAtSpecificLocation( SentinelPC.Location, SentinelPC.Rotation ); + SentinelPC.ConsoleCommand( "stat memory" ); + + // turn on stat unit and stat Scene rendering + SentinelPC.ConsoleCommand( "stat scenerendering" ); + SentinelPC.ConsoleCommand( "stat streaming" ); + Sleep( 1.0f ); + + for( SentinelIdx = 0; SentinelIdx < 8; SentinelIdx+=NumRotationsIncrement ) + { + //`log( "Setting rotation to: " $ 8192*SentinelIdx ); + SentinelPC.SetRotation( rot(0,1,0)*(8192*SentinelIdx) ); + Sleep( 1.5f ); + DoSentinel_ViewDependentMemoryAtSpecificLocation( SentinelPC.Location, SentinelPC.Rotation ); + } + + // turn off stat unit and stat scenerendering + SentinelPC.ConsoleCommand( "stat scenerendering" ); + SentinelPC.ConsoleCommand( "stat streaming" ); + + + // get UnitFPS data at each rotation + for( SentinelIdx = 0; SentinelIdx < 8; SentinelIdx+=NumRotationsIncrement ) + { + //`log( "Setting rotation to: " $ 8192*SentinelIdx ); + SentinelPC.SetRotation( rot(0,1,0)*(8192*SentinelIdx) ); + Sleep( 1.5f ); + DoSentinel_PerfAtSpecificLocation( SentinelPC.Location, SentinelPC.Rotation ); + } + + //ConsoleCommand( "MemLeakCheck" ); + foreach CommandsToRunAtEachTravelTheWorldNode( CommandStringToExec ) + { + //`log( `showvar(CommandStringToExec) ); + ConsoleCommand( CommandStringToExec ); + } + } + + ConsoleCommand( "MemLeakCheck" ); + + `log( "COMPLETED!!!!!!!" ); + ConsoleCommand( "exit" ); +} + +/** + * State code for handling GameInfo CauseEventCommand + */ +state SentinelHandleCauseEventCommand +{ + Begin: + // wait until all levels are streamed back in + do + { + bSentinelStreamingLevelStillLoading = FALSE; + + for( SentinelIdx = 0; SentinelIdx < WorldInfo.StreamingLevels.length; ++SentinelIdx ) + { + if( WorldInfo.StreamingLevels[SentinelIdx].bHasLoadRequestPending == TRUE ) + { + `log( "levels not streamed in yet sleeping 1s" ); + bSentinelStreamingLevelStillLoading = TRUE; + Sleep( 1.0f ); + break; + } + } + + } until( bSentinelStreamingLevelStillLoading == FALSE ); + + // check to see if we should fire off the FlyThrough event again as preround starting usually stops the first event + if( WorldInfo.Game.CauseEventCommand != "" ) + { + foreach WorldInfo.AllControllers(class'PlayerController', SentinelPC) + { + SentinelPC.ConsoleCommand( "ce " $ WorldInfo.Game.CauseEventCommand ); + break; + } + } + + // wait 500 ms to let the switching camera Hitch work itself out + if( ( SentinelTaskDescription == "FlyThrough" ) || ( SentinelTaskDescription == "FlyThroughSplitScreen" ) ) + { + SetTimer( 0.500f, TRUE, nameof(DoTimeBasedSentinelStatGathering) ); + } +} + +/** This will run on every map load. (e.g. You have P map which consists of N sublevels. For each SubLevel this will run. **/ +native function DoSentinelActionPerLoadedMap(); + +/** Add the audio related stats to the database **/ +native function HandlePerLoadedMapAudioStats(); + +/** This will look at the levels and then gather all of the travel points we are interested in **/ +native function GetTravelLocations( name LevelName, PlayerController PC, out array TravelPoints ); + +/** This will write out the Sentinel data at this location / rotation **/ +native function DoSentinel_MemoryAtSpecificLocation( const vector InLocation, const rotator InRotation ); + +native function DoSentinel_PerfAtSpecificLocation( const out vector InLocation, const out rotator InRotation ); + +native function DoSentinel_ViewDependentMemoryAtSpecificLocation( const out vector InLocation, const out rotator InRotation ); + + + +/** This function should be triggered via SetTimer ever few seconds to do the Per Time Period stats gathering **/ +function DoTimeBasedSentinelStatGathering() +{ + local PlayerController PC; + local vector ViewLocation; + local rotator ViewRotation; + + foreach LocalPlayerControllers( class'PlayerController', PC ) + { + break; + } + + PC.GetPlayerViewPoint( ViewLocation, ViewRotation ); + + // flythroughs uses the PC and not the pawn + if( ( SentinelTaskDescription != "FlyThrough" ) && ( SentinelTaskDescription != "FlyThroughSplitScreen" ) ) + { + if( PC.Pawn != None ) + { + ViewLocation = PC.Pawn.Location; + } + } + + //`log( "DoTimeBasedSentinelStatGathering: " $ ViewLocation @ ViewRotation ); + AddSentinelPerTimePeriodStats( ViewLocation, ViewRotation ); +} + + +//// SENTINEL FUNCTIONS END + +/** Determine if memory tracking will be triggered */ +native function DoMemoryTracking(); + +// AUTOMATED MAP TESTING FUNCTIONS START +/** + * Start the AutomatedMapTest transition timer which will sit there and poll the status of the streaming levels. + * When we are doing malloc profiling and such loading is a lot slower so we can't just assume some time limit before moving on. + **/ +event StartAutomatedMapTestTimer() +{ + SetTimer( 5.0, TRUE, nameof(StartAutomatedMapTestTimerWorker) ); +} + +/** This will look to make certain that all of the streaming levels are finished streaming **/ +function StartAutomatedMapTestTimerWorker() +{ + local int LevelIdx; + + if( WorldInfo != none ) + { + for( LevelIdx = 0; LevelIdx < WorldInfo.StreamingLevels.length; ++LevelIdx ) + { + if( WorldInfo.StreamingLevels[LevelIdx].bHasLoadRequestPending == TRUE ) + { + `log( "levels not streamed in yet sleeping 5s" ); + return; + } + } + + // now determine whether or not to check for mem leaks + if( bCheckingForMemLeaks ) + { + DoMemoryTracking(); + } + } + + ClearTimer( 'StartAutomatedMapTestTimerWorker' ); + SetTimer( 15.0,false,nameof(CloseAutomatedMapTestTimer) ); +} + +/** + * Restart the game when timer pops + */ +function CloseAutomatedMapTestTimer() +{ + if( Len(AutomatedMapTestingTransitionMap) > 0) + { + if (AutomatedTestingMapIndex < 0) + { + WorldInfo.Game.RestartGame(); + } + } + else + { + WorldInfo.Game.RestartGame(); + } +} + +function IncrementAutomatedTestingMapIndex() +{ + if( bUsingAutomatedTestingMapList == TRUE ) + { + if( bAutomatedTestingWithOpen == TRUE ) + { + `log( " NumMapListCyclesDone: " $ NumMapListCyclesDone $ " / " $ NumAutomatedMapTestingCycles ); + } + else + { + if (AutomatedTestingMapIndex >= 0) + { + AutomatedTestingMapIndex++; + } + } + `log( " NextIncrementAutomatedTestingMapIndex: " $ AutomatedTestingMapIndex $ " / " $ AutomatedMapTestingList.Length ); + } +} + +function IncrementNumberOfMatchesPlayed() +{ + `log( " Num Matches Played: " $ NumberOfMatchesPlayed ); + NumberOfMatchesPlayed++; +} + + +/** @return the map we should travel to during automated testing */ +function string GetNextAutomatedTestingMap() +{ + local string MapName; + local PlayerController PC; + local bool bResetMapIndex; + + if (bUsingAutomatedTestingMapList) + { + // check to see if we are over the end of the list and then increment num cycles and restart + if ((AutomatedTestingMapIndex >= 0) && (Len(AutomatedMapTestingTransitionMap) > 0)) + { + // If the testing map index is >= 0, we are in the transition map + // Increment the map index now... this is to avoid ever trying to set -0 + AutomatedTestingMapIndex++; + // + AutomatedTestingMapIndex *= -1; + MapName = AutomatedMapTestingTransitionMap; + } + else + { + // Remove the negative if we are using a transition map + if (Len(AutomatedMapTestingTransitionMap) > 0) + { + AutomatedTestingMapIndex *= -1; + } + + if (AutomatedTestingMapIndex >= AutomatedMapTestingList.Length) + { + AutomatedTestingMapIndex = 0; + NumMapListCyclesDone++; + bResetMapIndex = true; + } + MapName = AutomatedMapTestingList[AutomatedTestingMapIndex]; + } + + if (bAutomatedTestingWithOpen == true) + { + // see if we have done all of the cycles we were asked to do + if ((NumMapListCyclesDone >= NumAutomatedMapTestingCycles) && (NumAutomatedMapTestingCycles != 0)) + { + if ( bCheckingForMemLeaks ) + { + ConsoleCommand( "DEFERRED_STOPMEMTRACKING_AND_DUMP" ); + } + + if (bExitOnCyclesComplete) + { + ConsoleCommand( "EXIT" ); + } + } + } + else + { + foreach WorldInfo.AllControllers(class'PlayerController', PC) + { + // check to see if we are over the end of the list and then increment num cycles and restart + if (bResetMapIndex) + { + PC.PlayerReplicationInfo.AutomatedTestingData.NumMapListCyclesDone++; + } + + // see if we have done all of the cycles we were asked to do + if ((PC.PlayerReplicationInfo.AutomatedTestingData.NumMapListCyclesDone >= NumAutomatedMapTestingCycles) + && (NumAutomatedMapTestingCycles != 0) + ) + { + if( bCheckingForMemLeaks ) + { + ConsoleCommand( "DEFERRED_STOPMEMTRACKING_AND_DUMP" ); + } + + if (bExitOnCyclesComplete) + { + ConsoleCommand( "EXIT" ); + } + } + } + } + + `log("NextAutomatedTestingMap: " $ MapName); + return MapName; + } + + return ""; +} + +/** + * Used to initialize automated testing as needed when match starts. + * Called from GameInfo.StartMatch(). + */ +function StartMatch() +{ + local PlayerController PC; + + if ( bAutomatedTestingWithOpen ) + { + IncrementNumberOfMatchesPlayed(); + } + else + { + foreach WorldInfo.AllControllers(class'PlayerController', PC) + { + PC.IncrementNumberOfMatchesPlayed(); + break; + } + } + IncrementAutomatedTestingMapIndex(); + + if( bCheckingForFragmentation ) + { + ConsoleCommand( "MemFragCheck" ); + } + + if( AutomatedTestingExecCommandToRunAtStartMatch != "" ) + { + `log( "AutomatedTestingExecCommandToRunAtStartMatch: " $ AutomatedTestingExecCommandToRunAtStartMatch ); + ConsoleCommand( AutomatedTestingExecCommandToRunAtStartMatch ); + } +} + +/** + * Start Sentinel Run if needed + * @return true if normal gameinfo startmatch should be aborted + */ +function bool CheckForSentinelRun() +{ + if( bDoingASentinelRun ) + { + `log( "DoingASentinelRun! task "$SentinelTaskDescription ); + + // this will take over the normal match rules and do its own thing + if( SentinelTaskDescription ~= "TravelTheWorld" ) + { + WorldInfo.Game.DoTravelTheWorld(); + return true; + } + // any of these types are going to run in addition to what ever the player is doing + // they just go gather stats based on a timer + else + { + BeginSentinelRun( SentinelTaskDescription, SentinelTaskParameter, SentinelTagDesc ); + SetTimer( 3.0f, TRUE, nameof(DoTimeBasedSentinelStatGathering) ); + } + } + return false; +} + diff --git a/Engine/Classes/BlockingVolume.uc b/Engine/Classes/BlockingVolume.uc new file mode 100644 index 0000000..4dd0935 --- /dev/null +++ b/Engine/Classes/BlockingVolume.uc @@ -0,0 +1,59 @@ +//============================================================================= +// BlockingVolume: a bounding volume +// used to block certain classes of actors +// primary use is to provide collision for non-zero extent traces around static meshes +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= + +class BlockingVolume extends Volume + native + placeable; + +/** GameCameras ignore BlockingVolumes with bBlockCamera=false */ +var() bool bBlockCamera; + +cpptext +{ + UBOOL IgnoreBlockingBy( const AActor *Other ) const; +} + +/** Handling Toggle event from Kismet. */ +simulated function OnToggle(SeqAct_Toggle Action) +{ + // Turn ON + if (Action.InputLinks[0].bHasImpulse) + { + CollisionComponent.SetBlockRigidBody( TRUE ); + } + // Turn OFF + else if (Action.InputLinks[1].bHasImpulse) + { + CollisionComponent.SetBlockRigidBody( FALSE ); + } + // Toggle + else if (Action.InputLinks[2].bHasImpulse) + { + CollisionComponent.SetBlockRigidBody( !CollisionComponent.BlockRigidBody ); + } + + Super.OnToggle( Action ); +} + +defaultproperties +{ + Begin Object Name=BrushComponent0 + CollideActors=true + BlockActors=true + BlockZeroExtent=false + BlockNonZeroExtent=true + BlockRigidBody=true + bDisableAllRigidBody=false + RBChannel=RBCC_BlockingVolume + End Object + + bWorldGeometry=true + bCollideActors=True + bBlockActors=True + bBlockCamera=true + bMovable=false +} diff --git a/Engine/Classes/BlurEffect.uc b/Engine/Classes/BlurEffect.uc new file mode 100644 index 0000000..3d577a5 --- /dev/null +++ b/Engine/Classes/BlurEffect.uc @@ -0,0 +1,39 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * Blur post process effect + * + */ +class BlurEffect extends PostProcessEffect + native; + +/** Distance to blur in pixels */ +var() int BlurKernelSize; + +cpptext +{ + // UPostProcessEffect interface + + /** + * Creates a proxy to represent the render info for a post process effect + * @param WorldSettings - The world's post process settings for the view. + * @return The proxy object. + */ + virtual class FPostProcessSceneProxy* CreateSceneProxy(const FPostProcessSettings* WorldSettings); + + /** + * @param View - current view + * @return TRUE if the effect should be rendered + */ + virtual UBOOL IsShown(const FSceneView* View) const; + + // UObject inteface + + /** callback for changed property */ + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); +} + +defaultproperties +{ + BlurKernelSize=2 +} \ No newline at end of file diff --git a/Engine/Classes/BookMark.uc b/Engine/Classes/BookMark.uc new file mode 100644 index 0000000..73cfd4c --- /dev/null +++ b/Engine/Classes/BookMark.uc @@ -0,0 +1,24 @@ +/* epic =============================================== +* class BookMark +* +* A camera position the current level. + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class BookMark extends Object + hidecategories(Object) + native; + +/** Camera position/rotation */ +var() vector Location; +var() rotator Rotation; + +/** Array of levels that are hidden */ +var() array HiddenLevels; + +cpptext +{ +} + +defaultproperties +{ +} diff --git a/Engine/Classes/BookMark2D.uc b/Engine/Classes/BookMark2D.uc new file mode 100644 index 0000000..0cfccf2 --- /dev/null +++ b/Engine/Classes/BookMark2D.uc @@ -0,0 +1,22 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * Simple class to store 2D camera information. + */ +class BookMark2D extends Object + hidecategories(Object) + native; + +/** Zoom of the camera */ +var() float Zoom2D; + +/** Location of the camera */ +var() intpoint Location; + +cpptext +{ +} + +defaultproperties +{ +} diff --git a/Engine/Classes/BroadcastHandler.uc b/Engine/Classes/BroadcastHandler.uc new file mode 100644 index 0000000..aa7e4c5 --- /dev/null +++ b/Engine/Classes/BroadcastHandler.uc @@ -0,0 +1,119 @@ +//============================================================================= +// BroadcastHandler +// +// Message broadcasting is delegated to BroadCastHandler by the GameInfo. +// The BroadCastHandler handles both text messages (typed by a player) and +// localized messages (which are identified by a LocalMessage class and id). +// GameInfos produce localized messages using their DeathMessageClass and +// GameMessageClass classes. +// +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class BroadcastHandler extends Info + config(Game); + +var int SentText; +var config bool bMuteSpectators; // Whether spectators are allowed to speak. + +function UpdateSentText() +{ + SentText = 0; +} + +/* Whether actor is allowed to broadcast messages now. +*/ +function bool AllowsBroadcast( actor broadcaster, int InLen ) +{ + if ( bMuteSpectators && (PlayerController(Broadcaster) != None) + && PlayerController(Broadcaster).PlayerReplicationInfo.bOnlySpectator ) + return false; + + SentText += InLen; + return ( (WorldInfo.Pauser != None) || (SentText < 260) ); +} + + +function BroadcastText( PlayerReplicationInfo SenderPRI, PlayerController Receiver, coerce string Msg, optional name Type ) +{ + Receiver.TeamMessage( SenderPRI, Msg, Type ); +} + +function BroadcastLocalized( Actor Sender, PlayerController Receiver, class Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ) +{ + Receiver.ReceiveLocalizedMessage( Message, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject ); +} + +function Broadcast( Actor Sender, coerce string Msg, optional name Type ) +{ + local PlayerController P; + local PlayerReplicationInfo PRI; + + // see if allowed (limit to prevent spamming) + if ( !AllowsBroadcast(Sender, Len(Msg)) ) + return; + + if ( Pawn(Sender) != None ) + PRI = Pawn(Sender).PlayerReplicationInfo; + else if ( Controller(Sender) != None ) + PRI = Controller(Sender).PlayerReplicationInfo; + + foreach WorldInfo.AllControllers(class'PlayerController', P) + { + BroadcastText(PRI, P, Msg, Type); + } +} + +function BroadcastTeam( Controller Sender, coerce string Msg, optional name Type ) +{ + local PlayerController P; + + // see if allowed (limit to prevent spamming) + if ( !AllowsBroadcast(Sender, Len(Msg)) ) + return; + + foreach WorldInfo.AllControllers(class'PlayerController', P) + { + if (P.PlayerReplicationInfo.Team == Sender.PlayerReplicationInfo.Team) + { + BroadcastText(Sender.PlayerReplicationInfo, P, Msg, Type); + } + } +} + +/* + Broadcast a localized message to all players. + Most messages deal with 0 to 2 related PRIs. + The LocalMessage class defines how the PRI's and optional actor are used. +*/ +event AllowBroadcastLocalized( actor Sender, class Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ) +{ + local PlayerController P; + + foreach WorldInfo.AllControllers(class'PlayerController', P) + { + BroadcastLocalized(Sender, P, Message, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject); + } +} + +/* + Broadcast a localized message to all players on a team. + Most messages deal with 0 to 2 related PRIs. + The LocalMessage class defines how the PRI's and optional actor are used. +*/ +event AllowBroadcastLocalizedTeam( int TeamIndex, actor Sender, class Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ) +{ + local PlayerController P; + + foreach WorldInfo.AllControllers(class'PlayerController', P) + { + if ( (P.PlayerReplicationInfo != None) && (P.PlayerReplicationInfo.Team != None) && (P.PlayerReplicationInfo.Team.TeamIndex == TeamIndex) ) + { + BroadcastLocalized(Sender, P, Message, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject); + } + } +} + +defaultproperties +{ + TickGroup=TG_DuringAsyncWork +} \ No newline at end of file diff --git a/Engine/Classes/Brush.uc b/Engine/Classes/Brush.uc new file mode 100644 index 0000000..bcb7338 --- /dev/null +++ b/Engine/Classes/Brush.uc @@ -0,0 +1,125 @@ +//============================================================================= +// The brush class. +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class Brush extends Actor + hidecategories(Object) + hidecategories(Movement) + hidecategories(Display) + native; + +//----------------------------------------------------------------------------- +// Variables. + +// CSG operation performed in editor. +var() enum ECsgOper +{ + CSG_Active, // Active brush. + CSG_Add, // Add to world. + CSG_Subtract, // Subtract from world. + CSG_Intersect, // Form from intersection with world. + CSG_Deintersect, // Form from negative intersection with world. +} CsgOper; + +// Information. +var() color BrushColor; +var int PolyFlags; +var() bool bColored; +var bool bSolidWhenSelected; + +/** If TRUE, this brush class can be placed using the class browser like other simple class types */ +var bool bPlaceableFromClassBrowser; + +var export const Model Brush; +var editconst const BrushComponent BrushComponent; + +// Selection information for geometry mode + +struct native export GeomSelection +{ + var int Type; // EGeometrySelectionType_ + var int Index; // Index into the geometry data structures + var int SelectionIndex; // The selection index of this item +}; + +/** + * Stores selection information from geometry mode. This is the only information that we can't + * regenerate by looking at the source brushes following an undo operation. + */ + +var array SavedSelections; + +//----------------------------------------------------------------------------- +// cpptext. + +cpptext +{ + // UObject interface. + virtual void PostLoad(); + + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + /** Called after using geom mode to edit thie brush's geometry */ + virtual void PostEditBrush() {} + + virtual UBOOL IsABrush() const {return TRUE;} + + /** + * Note that the object has been modified. If we are currently recording into the + * transaction buffer (undo/redo), save a copy of this object into the buffer and + * marks the package as needing to be saved. + * + * @param bAlwaysMarkDirty if TRUE, marks the package dirty even if we aren't + * currently recording an active undo/redo transaction + */ + virtual void Modify(UBOOL bAlwaysMarkDirty = FALSE); + + /** + * Serialize function + * + * @param Ar Archive to serialize with + */ + virtual void Serialize(FArchive& Ar); + + /** + * Return whether this actor is a builder brush or not. + * + * @return TRUE if this actor is a builder brush, FALSE otherwise + */ + virtual UBOOL IsABuilderBrush() const; + + /** + * Return whether this actor is the current builder brush or not + * + * @return TRUE if htis actor is the current builder brush, FALSE otherwise + */ + virtual UBOOL IsCurrentBuilderBrush() const; + + // ABrush interface. + virtual void CopyPosRotScaleFrom( ABrush* Other ); + virtual void InitPosRotScale(); + +#if WITH_EDITOR + virtual void CheckForErrors(); +#endif + + /** + * Figures out the best color to use for this brushes wireframe drawing. + */ + + virtual FColor GetWireColor() const; +} + +defaultproperties +{ + Begin Object Class=BrushComponent Name=BrushComponent0 + End Object + BrushComponent=BrushComponent0 + CollisionComponent=BrushComponent0 + Components.Add(BrushComponent0) + + bStatic=True + bHidden=True + bNoDelete=True + bEdShouldSnap=True +} diff --git a/Engine/Classes/BrushComponent.uc b/Engine/Classes/BrushComponent.uc new file mode 100644 index 0000000..f5f8ee8 --- /dev/null +++ b/Engine/Classes/BrushComponent.uc @@ -0,0 +1,149 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class BrushComponent extends PrimitiveComponent + native + // removed noexport + collapsecategories + dependson(KMeshProps) + editinlinenew; + +var const Model Brush; + +// made class non-noexport (instead of simply mirroring FKCachedConvexData, actually expose it to script) + +struct native KCachedConvexDataElement +{ + /** Cooked data stream for physics engine for one convex hull. */ + var native init array ConvexElementData; + var native transient pointer ConvexMesh{class PxConvexMesh}; + + /** Caches the size of the convex hull byte buffer because the array is emptied when the mesh is actually instantiated */ + var native int ConvexMeshDataSize; + + structcpptext + { + FKCachedConvexDataElement() + : ConvexMesh(NULL), + ConvexMeshDataSize(0) + {} + + friend FArchive& operator<<( FArchive& Ar, FKCachedConvexDataElement& S ) + { + S.ConvexElementData.BulkSerialize(Ar); + if ( Ar.Ver() >= VER_PHYSX_3 ) + { + if ( 1 ) //!GIsCookingForFinalRelease || !Ar.IsSaving() ) + { + Ar << S.ConvexMeshDataSize; + //LOC_MOD + //check( !Ar.IsLoading() || S.ConvexMeshDataSize == S.ConvexElementData.Num() ); + } + } + else if ( Ar.IsLoading() ) + { + S.ConvexMeshDataSize = S.ConvexElementData.Num(); + } + return Ar; + } + } +}; + +/** Intermediate cooked data from the physics engine for a collection of convex hulls. */ +struct native KCachedConvexData +{ + /** Array of cooked physics data - one element for each convex hull.*/ + var native init array CachedConvexElements; + + structcpptext + { + friend FArchive& operator<<( FArchive& Ar, FKCachedConvexData& S ) +{ + Ar << S.CachedConvexElements; + return Ar; + } + } +}; + + +/** Simplified collision data for the mesh. */ +var KMeshProps.KAggregateGeom BrushAggGeom; + +/** Cached brush convex-mesh data for use with the physics engine. */ +var native private const transient noimport KCachedConvexData CachedPhysBrushData; + +/** + * Indicates version that CachedPhysBrushData was created at. + * Compared against CurrentCachedPhysDataVersion. + */ +var private const int CachedPhysBrushDataVersion; + +/** + * Normally a blocking volume is considered 'pure simplified collision', so when tracing for complex collision, never collide + * This flag overrides that behaviour + */ +var() bool bBlockComplexCollisionTrace; + +// made non-noexport (added cpptext here) +cpptext +{ + // UObject interface. + virtual void Serialize( FArchive& Ar ); + virtual void PreSave(); + virtual void FinishDestroy(); + + + // UPrimitiveComponent interface. + /** + * Creates a proxy to represent the primitive to the scene manager in the rendering thread. + * @return The proxy object. + */ + virtual FPrimitiveSceneProxy* CreateSceneProxy(); + + + virtual void InitComponentRBPhys(UBOOL bFixed); + + virtual UBOOL PointCheck(FCheckResult& Result,const FVector& Location,const FVector& Extent,DWORD TraceFlags); + virtual UBOOL LineCheck(FCheckResult& Result,const FVector& End,const FVector& Start,const FVector& Extent,DWORD TraceFlags); + + virtual void UpdateBounds(); + + /** + * Retrieves the materials used in this component + * + * @param OutMaterials The list of used materials. + */ + virtual void GetUsedMaterials( TArray& OutMaterials ) const; + + virtual BYTE GetStaticDepthPriorityGroup() const; + + // UBrushComponent interface. + virtual UBOOL IsValidComponent() const; + + // UBrushComponent interface + +#if WITH_EDITORONLY_DATA + /** Create the BrushAggGeom collection-of-convex-primitives from the Brush UModel data. */ + void BuildSimpleBrushCollision(); + + /** Build cached convex data for physics engine. */ + void BuildPhysBrushData(); +#endif // WITH_EDITOR + + void ClearPhysBrushData(); + + /*GJKResult*/ BYTE ClosestPointOnComponentToComponent(class UPrimitiveComponent*& OtherComponent,FVector& PointOnComponentA,FVector& PointOnComponentB); + + virtual /*GJKResult*/ BYTE ClosestPointOnComponentInternal(IGJKHelper* ExtentHelper, FVector& OutPointA, FVector& OutPointB); + + +} + +defaultproperties +{ + HiddenGame=True + bAcceptsLights=false + AlwaysLoadOnClient=false + AlwaysLoadOnServer=false + bUseAsOccluder=TRUE +} diff --git a/Engine/Classes/BrushShape.uc b/Engine/Classes/BrushShape.uc new file mode 100644 index 0000000..3c8c8fa --- /dev/null +++ b/Engine/Classes/BrushShape.uc @@ -0,0 +1,27 @@ +//============================================================================= +// BrushShape: A brush that acts as a template for geometry mode modifiers like "Lathe" +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class BrushShape extends Brush + placeable + native; + +cpptext +{ + virtual UBOOL IsABrushShape() const {return TRUE;} +} + +defaultproperties +{ + Begin Object Name=BrushComponent0 + CollideActors=false + bAcceptsLights=false + LightingChannels=(Dynamic=TRUE,bInitialized=TRUE) + BlockActors=false + BlockZeroExtent=false + BlockNonZeroExtent=false + BlockRigidBody=false + AlwaysLoadOnClient=True + AlwaysLoadOnServer=False + End Object +} diff --git a/Engine/Classes/Camera.uc b/Engine/Classes/Camera.uc new file mode 100644 index 0000000..2310b52 --- /dev/null +++ b/Engine/Classes/Camera.uc @@ -0,0 +1,1000 @@ +/** + * Camera: defines the Point of View of a player in world space. + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class Camera extends Actor + notplaceable + native(Camera) + dependson(EngineBaseTypes) + transient; + +/** PlayerController Owning this Camera Actor */ +var PlayerController PCOwner; + +/** Camera Mode */ +var Name CameraStyle; +/** default FOV */ +var float DefaultFOV; +/** true if FOV is locked to a constant value*/ +var bool bLockedFOV; +/** value FOV is locked at */ +var float LockedFOV; +/** FOV that is not effected by checkerboard resolution */ +var float UnmodifiedFOV; + +/** If we should insert black areas when rendering the scene to ensure an aspect ratio of ConstrainedAspectRatio */ +var bool bConstrainAspectRatio; +/** If bConstrainAspectRatio is true, add black regions to ensure aspect ratio is this. Ratio is horizontal/vertical. */ +var float ConstrainedAspectRatio; +/** Default aspect ratio */ +var float DefaultAspectRatio; + +/** Off-axis yaw angle offset */ +var float OffAxisYawAngle; + +/** Off-axis pitch angle offset */ +var float OffAxisPitchAngle; + +/** If we should apply FadeColor/FadeAmount to the screen. */ +var bool bEnableFading; +/** Color to fade to. */ +var color FadeColor; +/** Amount of fading to apply. */ +var float FadeAmount; + +/** Apply fading of audio alongside the video */ +var bool bFadeAudio; + +/** Indicates if CamPostProcessSettings should be used when using this Camera to view through. */ +var float CamOverridePostProcessAlpha; + +/** Post-process settings to use if bCamOverridePostProcess is TRUE. */ +var PostProcessSettings CamPostProcessSettings; + +/** Rendering overrides that are active on this camera. */ +var RenderingPerformanceOverrides RenderingOverrides; + +/** + * Forces Temporal AA to be disabled when True. + * This is useful for hiding reprojection artifacts while certain game specific translucent effects are active. + */ +var transient bool bForceDisableTemporalAA; + +/** Turn on scaling of color channels in final image using ColorScale property. */ +var bool bEnableColorScaling; +/** Allows control over scaling individual color channels in the final image. */ +var vector ColorScale; +/** Should interpolate color scale values */ +var bool bEnableColorScaleInterp; +/** Desired color scale which ColorScale will interpolate to */ +var vector DesiredColorScale; +/** Color scale value at start of interpolation */ +var vector OriginalColorScale; +/** Total time for color scale interpolation to complete */ +var float ColorScaleInterpDuration; +/** Time at which interpolation started */ +var float ColorScaleInterpStartTime; + +/** The actors which the camera shouldn't see. Used to hide actors which the camera penetrates. */ +//var array HiddenActors; + +/* Caching Camera, for optimization */ +struct native TCameraCache +{ + /** Cached Time Stamp */ + var float TimeStamp; + /** cached Point of View */ + var TPOV POV; +}; +var TCameraCache CameraCache, LastFrameCameraCache; + + +/** + * View Target definition + * A View Target is responsible for providing the Camera with an ideal Point of View (POV) + */ +struct native TViewTarget +{ + /** Target Actor used to compute ideal POV */ + var() Actor Target; + /** Controller of Target (only for non Locally controlled Pawns) */ + var() Controller Controller; + /** Point of View */ + var() TPOV POV; + /** Aspect ratio */ + var() float AspectRatio; + /** PlayerReplicationInfo (used to follow same player through pawn transitions, etc., when spectating) */ + var() PlayerReplicationInfo PRI; + +}; + +/** Current ViewTarget */ +var TViewTarget ViewTarget; +/** Pending view target for blending */ +var TViewTarget PendingViewTarget; +/** Time left when blending to pending view target */ +var float BlendTimeToGo; + +enum EViewTargetBlendFunction +{ + /** Camera does a simple linear interpolation. */ + VTBlend_Linear, + /** Camera has a slight ease in and ease out, but amount of ease cannot be tweaked. */ + VTBlend_Cubic, + /** Camera immediately accelerates, but smoothly decelerates into the target. Ease amount controlled by BlendExp. */ + VTBlend_EaseIn, + /** Camera smoothly accelerates, but does not decelerate into the target. Ease amount controlled by BlendExp. */ + VTBlend_EaseOut, + /** Camera smoothly accelerates and decelerates. Ease amount controlled by BlendExp. */ + VTBlend_EaseInOut, +}; + +/** A set of parameters to describe how to transition between viewtargets. */ +struct native ViewTargetTransitionParams +{ + /** Total duration of blend to pending view target. 0 means no blending. */ + var() float BlendTime; + /** Function to apply to the blend parameter */ + var() EViewTargetBlendFunction BlendFunction; + /** Exponent, used by certain blend functions to control the shape of the curve. */ + var() float BlendExp; + /** If TRUE, lock outgoing viewtarget to last frame's camera position for the remainder of the blend. + * This is useful if you plan to teleport the viewtarget, but want to keep the camera motion smooth. */ + var() bool bLockOutgoing; + + structdefaultproperties + { + BlendFunction=VTBlend_Cubic + BlendExp=2.f + bLockOutgoing=FALSE + } + + // providing the constructor by hand here, because we pass this as an optional parameter + // and when the parameter isn't there, the default contructor is called. + structcpptext + { + FViewTargetTransitionParams() + {} + FViewTargetTransitionParams(EEventParm) + : BlendTime(0.f), BlendFunction(VTBlend_Cubic), BlendExp(2.f), bLockOutgoing(FALSE) + {} + } +}; + +var ViewTargetTransitionParams BlendParams; + +/** List of camera modifiers to apply during update of camera position/ rotation */ +var Array ModifierList; + +/** Distance to place free camera from view target */ +var float FreeCamDistance; + +/** Offset to Z free camera position */ +var vector FreeCamOffset; + +/** camera fade management */ +var vector2d FadeAlpha; +var float FadeTime, FadeTimeRemaining; + + +// "Lens" effects (e.g. blood, dirt on camera) +/** CameraBlood emitter attached to this camera */ +var protected transient array CameraLensEffects; + + + +///////////////////// +// Camera Modifiers +///////////////////// + +/** Camera modifier for cone-driven screen shakes */ +var() editinline transient CameraModifier_CameraShake CameraShakeCamMod; +/** Class to use when instantiating screenshake modifier object. Provided to support overrides. */ +var() protected class CameraShakeCamModClass; + +enum ECameraAnimPlaySpace +{ + /** This anim is applied in camera space */ + CAPS_CameraLocal, + /** This anim is applied in world space */ + CAPS_World, + /** This anim is applied in a user-specified space (defined by UserPlaySpaceMatrix) */ + CAPS_UserDefined, +}; + +//////////////////////// +// CameraAnim support +//////////////////////// + +const MAX_ACTIVE_CAMERA_ANIMS = 8; + +/** Pool of anim instance objects available with which to play camera animations */ +var protected CameraAnimInst AnimInstPool[MAX_ACTIVE_CAMERA_ANIMS]; + +/** Array of anim instances that are currently playing and in-use */ +var protected array ActiveAnims; +/** Array of anim instances that are not playing and available */ +var protected array FreeAnims; + +/** Internal. Receives the output of individual camera animations. */ +var protected transient DynamicCameraActor AnimCameraActor; + +/** if true, server will use camera positions replicated from the client instead of calculating locally. */ +var bool bUseClientSideCameraUpdates; + +/** If true, replicate the client side camera position but don't use it, and draw the positions on the server */ +var bool bDebugClientSideCamera; + +/** if true, send a camera update to the server on next update */ +var bool bShouldSendClientSideCameraUpdate; + +cpptext +{ +protected: + void InitTempCameraActor(class ACameraActor* CamActor, class UCameraAnim* AnimToInitFor) const; + void ApplyAnimToCamera(class ACameraActor const* AnimatedCamActor, class UCameraAnimInst const* AnimInst, FTPOV& OutPOV); + + UCameraAnimInst* AllocCameraAnimInst(); + void ReleaseCameraAnimInst(UCameraAnimInst* Inst); + UCameraAnimInst* FindExistingCameraAnimInst(UCameraAnim const* Anim); + +public: + virtual void ModifyPostProcessSettings(FPostProcessSettings& PPSettings) const; + + void AssignViewTarget(AActor* NewTarget, FTViewTarget& VT, struct FViewTargetTransitionParams TransitionParams=FViewTargetTransitionParams(EC_EventParm)); + AActor* GetViewTarget(); + virtual UBOOL PlayerControlled(); +} + +/** + * Internal. Creates and initializes a new camera modifier of the specified class, returns the object ref. + */ +protected function CameraModifier CreateCameraModifier(class ModifierClass) +{ + local CameraModifier NewMod; + NewMod = new(Outer) ModifierClass; + NewMod.Init(); + NewMod.AddCameraModifier(Self); + return NewMod; +} + + +function PostBeginPlay() +{ + local int Idx; + + super.PostBeginPlay(); + + // Setup camera modifiers + if( (CameraShakeCamMod == None) && (CameraShakeCamModClass != None) ) + { + CameraShakeCamMod = CameraModifier_CameraShake(CreateCameraModifier(CameraShakeCamModClass)); + } + + // create CameraAnimInsts in pool + for (Idx=0; Idx 170 ) + { + bLockedFOV = FALSE; + return; + } + + bLockedFOV = TRUE; + LockedFOV = NewFOV; +} + +/** Checkerborad-free FOV */ +function SetUnmodifiedFOV(float NewFOV) +{ + UnmodifiedFOV = NewFOV; +} + +`if(`__TW_) +function float GetActualFOV() { return GetFOVAngle(); } +`endif + +/** + * Master function to retrieve Camera's actual view point. + * do not call this directly, call PlayerController::GetPlayerViewPoint() instead. + * + * @param OutCamLoc Camera Location + * @param OutCamRot Camera Rotation + */ +final function GetCameraViewPoint(out vector OutCamLoc, out rotator OutCamRot) +{ + // @debug: find out which calls are being made before the camera has been ticked + // and have therefore one frame of lag. + /* + if( CameraCache.TimeStamp != WorldInfo.TimeSeconds ) + { + `Log(WorldInfo.TimeSeconds @ GetFuncName() @ "one frame of lag"); + ScriptTrace(); + } + */ + + OutCamLoc = CameraCache.POV.Location; + OutCamRot = CameraCache.POV.Rotation; +} + +final function rotator GetCameraRotation() +{ + return CameraCache.POV.Rotation; +} + +/** + * Sets the new desired color scale and enables interpolation. + */ +simulated function SetDesiredColorScale(vector NewColorScale, float InterpTime) +{ + // if color scaling is not enabled + if (!bEnableColorScaling) + { + // set the default color scale + bEnableColorScaling = TRUE; + ColorScale.X = 1.f; + ColorScale.Y = 1.f; + ColorScale.Z = 1.f; + } + + // Don't bother interpolating if we're already scaling at the desired color + if( NewColorScale != ColorScale ) + { + // save the current as original + OriginalColorScale = ColorScale; + // set the new desired scale + DesiredColorScale = NewColorScale; + // set the interpolation duration/time + ColorScaleInterpStartTime = WorldInfo.TimeSeconds; + ColorScaleInterpDuration = InterpTime; + // and enable color scale interpolation + bEnableColorScaleInterp = TRUE; + } +} + +/** + * Performs camera update. + * Called once per frame after all actors have been ticked. + * Non-local players replicate the POV if bUseClientSideCameraUpdates is true + */ +simulated event UpdateCamera(float DeltaTime) +{ + if ( PCOwner.IsLocalPlayerController() || !bUseClientSideCameraUpdates || bDebugClientSideCamera ) + { + DoUpdateCamera(DeltaTime); + + if (WorldInfo.NetMode == NM_Client && bShouldSendClientSideCameraUpdate) + { + PCOwner.ServerUpdateCamera(CameraCache.POV.Location, (CameraCache.POV.Rotation.Pitch & 65535) + ((CameraCache.POV.Rotation.Yaw & 65535) << 16)); + bShouldSendClientSideCameraUpdate = FALSE; + } + } +} + +simulated function DoUpdateCamera(float DeltaTime) +{ + local TPOV NewPOV; + local float DurationPct, BlendPct; + + // update color scale interpolation + if (bEnableColorScaleInterp) + { + BlendPct = FClamp(`TimeSince(ColorScaleInterpStartTime)/ColorScaleInterpDuration,0.f,1.f); + ColorScale = VLerp(OriginalColorScale,DesiredColorScale,BlendPct); + // if we've maxed + if (BlendPct == 1.f) + { + // disable further interpolation + bEnableColorScaleInterp = FALSE; + } + } + + // Reset aspect ratio and postprocess override associated with CameraActor. + bConstrainAspectRatio = FALSE; + CamOverridePostProcessAlpha = 0.f; + + // Don't update outgoing viewtarget during an interpolation when bLockOutgoing is set. + if( PendingViewTarget.Target == None || !BlendParams.bLockOutgoing ) + { + // Update current view target + CheckViewTarget(ViewTarget); + UpdateViewTarget(ViewTarget, DeltaTime); + } + + // our camera is now viewing there + NewPOV = ViewTarget.POV; + ConstrainedAspectRatio = ViewTarget.AspectRatio; + + // if we have a pending view target, perform transition from one to another. + if( PendingViewTarget.Target != None ) + { + BlendTimeToGo -= DeltaTime; + + // Reset aspect ratio. The call to UpdateViewTarget() may turn this back on. + bConstrainAspectRatio = FALSE; + + // Update pending view target + CheckViewTarget(PendingViewTarget); + UpdateViewTarget(PendingViewTarget, DeltaTime); + + // blend.... + if( BlendTimeToGo > 0 ) + { + DurationPct = (BlendParams.BlendTime - BlendTimeToGo) / BlendParams.BlendTime; + + switch (BlendParams.BlendFunction) + { + case VTBlend_Linear: + BlendPct = Lerp(0.f, 1.f, DurationPct); + break; + case VTBlend_Cubic: + BlendPct = FCubicInterp(0.f, 0.f, 1.f, 0.f, DurationPct); + break; + case VTBlend_EaseIn: + BlendPct = FInterpEaseIn(0.f, 1.f, DurationPct, BlendParams.BlendExp); + break; + case VTBlend_EaseOut: + BlendPct = FInterpEaseOut(0.f, 1.f, DurationPct, BlendParams.BlendExp); + break; + case VTBlend_EaseInOut: + BlendPct = FInterpEaseInOut(0.f, 1.f, DurationPct, BlendParams.BlendExp); + break; + } + //BlendPct = FCubicInterp(0.f, class'DialogueManager'.default.OutTan, 1.f, class'DialogueManager'.default.InTan, 1.f - DurationPct); + + // Update pending view target blend + NewPOV = BlendViewTargets(ViewTarget, PendingViewTarget, BlendPct); + } + else + { + // we're done blending, set new view target + ViewTarget = PendingViewTarget; + + // clear pending view target + PendingViewTarget.Target = None; + PendingViewTarget.Controller = None; + + BlendTimeToGo = 0; + + // our camera is now viewing there + NewPOV = PendingViewTarget.POV; + } + + if( bConstrainAspectRatio ) + { + // NOTE: We don't interpolate aspect ratio since either the prior or pending view target's AspectRatio + // may be the default value (1.3333) unless the view target has a camera actor set to override + // the aspect ratio. We'll just use the pending view target's aspect. + ConstrainedAspectRatio = PendingViewTarget.AspectRatio; + } + } + + // Cache results + FillCameraCache(NewPOV); + + if (bEnableFading && FadeTimeRemaining > 0.0) + { + FadeTimeRemaining = FMax(FadeTimeRemaining - DeltaTime, 0.0); + if (FadeTime > 0.0) + { + FadeAmount = FadeAlpha.X + ((1.f - FadeTimeRemaining/FadeTime) * (FadeAlpha.Y - FadeAlpha.X)); + } + + if (bFadeAudio) + { + ApplyAudioFade(); + if (FadeAmount == 0) + { + bFadeAudio = false; + } + } + } +} + +/** Apply audio fading */ +native function ApplyAudioFade(); + +/** + * Blend 2 viewtargets. + * + * @param A Source view target + * @paramn B destination view target + * @param Alpha Alpha, % of blend from A to B. + */ +final function TPOV BlendViewTargets(const out TViewTarget A,const out TViewTarget B, float Alpha) +{ + local TPOV POV; + + POV.Location = VLerp(A.POV.Location, B.POV.Location, Alpha); + POV.FOV = Lerp(A.POV.FOV, B.POV.FOV, Alpha); + POV.Rotation = RLerp(A.POV.Rotation, B.POV.Rotation, Alpha, TRUE); + + return POV; +} + + +/** + * Cache update results + */ +final function FillCameraCache(const out TPOV NewPOV) +{ + // Backup last frame results. + if( CameraCache.TimeStamp != WorldInfo.TimeSeconds ) + { + LastFrameCameraCache = CameraCache; + } + CameraCache.TimeStamp = WorldInfo.TimeSeconds; + CameraCache.POV = NewPOV; +} + + +/** + * Make sure ViewTarget is valid + */ +native function CheckViewTarget(out TViewTarget VT); + + +/** + * Query ViewTarget and outputs Point Of View. + * + * @param OutVT ViewTarget to use. + * @param DeltaTime Delta Time since last camera update (in seconds). + */ +function UpdateViewTarget(out TViewTarget OutVT, float DeltaTime) +{ + local vector Loc, Pos, HitLocation, HitNormal; + local rotator Rot; + local Actor HitActor; + local CameraActor CamActor; + local bool bDoNotApplyModifiers; + local TPOV OrigPOV; + local Pawn TPawn; + + // Don't update outgoing viewtarget during an interpolation + if( PendingViewTarget.Target != None && OutVT == ViewTarget && BlendParams.bLockOutgoing ) + { + return; + } + + // store previous POV, in case we need it later + OrigPOV = OutVT.POV; + + // Default FOV on viewtarget + OutVT.POV.FOV = DefaultFOV; + + // Viewing through a camera actor. + CamActor = CameraActor(OutVT.Target); + if( CamActor != None ) + { + CamActor.GetCameraView(DeltaTime, OutVT.POV); + + // Grab aspect ratio from the CameraActor. + bConstrainAspectRatio = bConstrainAspectRatio || CamActor.bConstrainAspectRatio; + OutVT.AspectRatio = CamActor.AspectRatio; + + // See if the CameraActor wants to override the PostProcess settings used. + CamOverridePostProcessAlpha = CamActor.CamOverridePostProcessAlpha; + CamPostProcessSettings = CamActor.CamOverridePostProcess; + } + else + { + TPawn = Pawn(OutVT.Target); + // Give Pawn Viewtarget a chance to dictate the camera position. + // If Pawn doesn't override the camera view, then we proceed with our own defaults + if( TPawn == None || !TPawn.CalcCamera(DeltaTime, OutVT.POV.Location, OutVT.POV.Rotation, OutVT.POV.FOV) ) + { + // don't apply modifiers when using these debug camera modes. + bDoNotApplyModifiers = TRUE; + + switch( CameraStyle ) + { + case 'Fixed' : // do not update, keep previous camera position by restoring + // saved POV, in case CalcCamera changes it but still returns false + OutVT.POV = OrigPOV; + break; + + case 'ThirdPerson' : // Simple third person view implementation + case 'FreeCam' : + case 'FreeCam_Default': + Loc = OutVT.Target.Location; + Rot = OutVT.Target.Rotation; + + // Take into account Mesh Translation so it takes into account the PostProcessing we do there. + if ((TPawn != None) && (TPawn.Mesh != None)) + { + Loc += (TPawn.Mesh.Translation - TPawn.default.Mesh.Translation) >> OutVT.Target.Rotation; + } + + //OutVT.Target.GetActorEyesViewPoint(Loc, Rot); + if( CameraStyle == 'FreeCam' || CameraStyle == 'FreeCam_Default' ) + { + Rot = PCOwner.Rotation; + } +`if(`__TW_) + if( OutVT.Target != PCOwner ) + { + Loc += FreeCamOffset >> Rot; + Pos = Loc - Vector(Rot) * FreeCamDistance; + } + else + { + Pos = Loc; + } +`else + Loc += FreeCamOffset >> Rot; + Pos = Loc - Vector(Rot) * FreeCamDistance; +`endif + // @fixme, respect BlockingVolume.bBlockCamera=false + HitActor = Trace(HitLocation, HitNormal, Pos, Loc, FALSE, vect(12,12,12)); + OutVT.POV.Location = (HitActor == None) ? Pos : HitLocation; + OutVT.POV.Rotation = Rot; + break; + + case 'FirstPerson' : // Simple first person, view through viewtarget's 'eyes' + default : OutVT.Target.GetActorEyesViewPoint(OutVT.POV.Location, OutVT.POV.Rotation); + // Take into account Mesh Translation so it takes into account the PostProcessing we do there. + if ((TPawn != None) && (TPawn.Mesh != None)) + { + OutVT.POV.Location += (TPawn.Mesh.Translation - TPawn.default.Mesh.Translation) >> OutVT.Target.Rotation; + } + break; + + } + } + } + + if( !bDoNotApplyModifiers ) + { + // Apply camera modifiers at the end (view shakes for example) + ApplyCameraModifiers(DeltaTime, OutVT.POV); + } + //`log( WorldInfo.TimeSeconds @ GetFuncName() @ OutVT.Target @ OutVT.POV.Location @ OutVT.POV.Rotation @ OutVT.POV.FOV ); +} + + +/** + * Set a new ViewTarget with optional BlendTime + */ +native final function SetViewTarget(Actor NewViewTarget, optional ViewTargetTransitionParams TransitionParams); + + +/** + * Give each modifier a chance to change view rotation/deltarot + */ +function ProcessViewRotation(float DeltaTime, out rotator OutViewRotation, out Rotator OutDeltaRot) +{ + local int ModifierIdx; + + for( ModifierIdx = 0; ModifierIdx < ModifierList.Length; ModifierIdx++ ) + { + if( ModifierList[ModifierIdx] != None ) + { + if( ModifierList[ModifierIdx].ProcessViewRotation(ViewTarget.Target, DeltaTime, OutViewRotation, OutDeltaRot) ) + { + break; + } + } + } +} + +/** + * list important Camera variables on canvas. HUD will call DisplayDebug() on the current ViewTarget when + * the ShowDebug exec is used + * + * @param HUD - HUD with canvas to draw on + * @input out_YL - Height of the current font + * @input out_YPos - Y position on Canvas. out_YPos += out_YL, gives position to draw text for next debug line. + */ +simulated function DisplayDebug(HUD HUD, out float out_YL, out float out_YPos) +{ + local Vector EyesLoc; + local Rotator EyesRot; + local Canvas Canvas; + + Canvas = HUD.Canvas; + Canvas.SetDrawColor(255,255,255); + + Canvas.DrawText(" Camera Style:" $ CameraStyle @ "main ViewTarget:" $ ViewTarget.Target); + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + +`if(`__TW_) + Canvas.DrawText(" CamLoc:" $ CameraCache.POV.Location @ "CamRot:" $ CameraCache.POV.Rotation @ "FOV:" $ GetFOVAngle()); +`else + Canvas.DrawText(" CamLoc:" $ CameraCache.POV.Location @ "CamRot:" $ CameraCache.POV.Rotation @ "FOV:" $ CameraCache.POV.FOV); +`endif + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + + Canvas.DrawText(" AspectRatio:" $ ConstrainedAspectRatio); + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + + if( ViewTarget.Target != None ) + { + ViewTarget.Target.GetActorEyesViewPoint(EyesLoc, EyesRot); + Canvas.DrawText(" EyesLoc:" $ EyesLoc @ "EyesRot:" $ EyesRot); + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + } +} + + + +//////////////////////////////// +// Camera Lens Effects +//////////////////////////////// + +/** Finds the first instance of a lens effect of the given class, using linear search. */ +function EmitterCameraLensEffectBase FindCameraLensEffect(class LensEffectEmitterClass) +{ + local EmitterCameraLensEffectBase LensEffect; + + foreach CameraLensEffects(LensEffect) + { + if ( !LensEffect.bDeleteMe && + ( (LensEffect.Class == LensEffectEmitterClass) || + (LensEffect.EmittersToTreatAsSame.Find(LensEffectEmitterClass) != INDEX_NONE) || + (LensEffectEmitterClass.default.EmittersToTreatAsSame.Find(LensEffect.Class) != INDEX_NONE ) ) ) + { + return LensEffect; + } + } + + return None; +} + +/** + * Initiates a camera lens effect of the given class on this camera. + */ +function AddCameraLensEffect(class LensEffectEmitterClass) +{ + local vector CamLoc; + local rotator CamRot; + local EmitterCameraLensEffectBase LensEffect; + + if (LensEffectEmitterClass != None) + { + if (!LensEffectEmitterClass.default.bAllowMultipleInstances) + { + LensEffect = FindCameraLensEffect(LensEffectEmitterClass); + + if (LensEffect != None) + { + LensEffect.NotifyRetriggered(); + } + } + + if (LensEffect == None) + { + // spawn with viewtarget as the owner so bOnlyOwnerSee works as intended + LensEffect = Spawn( LensEffectEmitterClass, PCOwner.GetViewTarget() ); + if (LensEffect != None) + { + GetCameraViewPoint(CamLoc, CamRot); +`if(`__TW_) + LensEffect.UpdateLocation( CamLoc, CamRot, GetActualFOV() ); +`else + LensEffect.UpdateLocation(CamLoc, CamRot, GetFOVAngle()); +`endif + LensEffect.RegisterCamera(self); + + CameraLensEffects.AddItem(LensEffect); + } + } + } +} + +/** Removes this particular lens effect from the camera. */ +function RemoveCameraLensEffect(EmitterCameraLensEffectBase Emitter) +{ + CameraLensEffects.RemoveItem(Emitter); +} + +/** Removes all Camera Lens Effects. */ +function ClearCameraLensEffects() +{ + local EmitterCameraLensEffectBase LensEffect; + + foreach CameraLensEffects(LensEffect) + { + LensEffect.Destroy(); + } + + // empty the array. unnecessary, since destruction will call RemoveCameraLensEffect, + // but this gets it done in one fell swoop. + CameraLensEffects.length = 0; +} + +/** ------------------------------------------------------------ + * Camera Shakes + * ------------------------------------------------------------ */ + + +/** + * Play a camera shake + */ +function PlayCameraShake(CameraShake Shake, float Scale, optional ECameraAnimPlaySpace PlaySpace=CAPS_CameraLocal, optional rotator UserPlaySpaceRot) +{ + if (Shake != None) + { + CameraShakeCamMod.AddCameraShake(Shake, Scale, PlaySpace, UserPlaySpaceRot); + } +} + +/** Stop playing a camera shake. */ +function StopCameraShake(CameraShake Shake) +{ + if (Shake != None) + { + CameraShakeCamMod.RemoveCameraShake(Shake); + } +} + + +/** Internal. Returns intensity scalar in the range [0..1] for a shake originating at Epicenter. */ +static function float CalcRadialShakeScale(Camera Cam, vector Epicenter, float InnerRadius, float OuterRadius, float Falloff) +{ + local Vector POVLoc; + local float DistPct; + + // using camera location so stuff like spectator cameras get shakes applied sensibly as well + // need to ensure server has reasonably accurate camera position + POVLoc = Cam.Location; + + if (InnerRadius < OuterRadius) + { + DistPct = (VSize(Epicenter - POVLoc) - InnerRadius) / (OuterRadius - InnerRadius); + DistPct = 1.f - FClamp(DistPct, 0.f, 1.f); + return DistPct ** Falloff; + } + else + { + // ignore OuterRadius and do a cliff falloff at InnerRadius + return (VSize(Epicenter - POVLoc) < InnerRadius) ? 1.f : 0.f; + } +} + + +/** + * Static. Plays an in-world camera shake that affects all nearby players, with distance-based attenuation. + */ +static function PlayWorldCameraShake(CameraShake Shake, Actor ShakeInstigator, vector Epicenter, float InnerRadius, float OuterRadius, float Falloff, bool bTryForceFeedback, optional bool bOrientShakeTowardsEpicenter ) +{ + local PlayerController PC; + local float ShakeScale; + local Rotator CamRot; + local vector CamLoc; + + if( ShakeInstigator != None ) + { + foreach ShakeInstigator.LocalPlayerControllers(class'PlayerController', PC) + { + if (PC.PlayerCamera != None) + { + ShakeScale = CalcRadialShakeScale(PC.PlayerCamera, Epicenter, InnerRadius, OuterRadius, Falloff); + + if (bOrientShakeTowardsEpicenter && PC.Pawn != None) + { + PC.PlayerCamera.GetCameraViewPoint(CamLoc, CamRot); + PC.ClientPlayCameraShake(Shake, ShakeScale, bTryForceFeedback, CAPS_UserDefined, rotator(Epicenter - CamLoc)); + } + else + { + PC.ClientPlayCameraShake(Shake, ShakeScale, bTryForceFeedback); + + } + } + } + } +} + +function ClearAllCameraShakes() +{ + CameraShakeCamMod.RemoveAllCameraShakes(); +// StopAllCameraAnims(TRUE); +} + + +/** ------------------------------------------------------------ + * CameraAnim support + * ------------------------------------------------------------ */ + +/** Play the indicated CameraAnim on this camera. Returns the CameraAnim instance. */ +simulated native function CameraAnimInst PlayCameraAnim(CameraAnim Anim, optional float Rate=1.f, optional float Scale=1.f, optional float BlendInTime, optional float BlendOutTime, optional bool bLoop, optional bool bRandomStartTime, optional float Duration, optional bool bSingleInstance); + +/** + * Stop playing all instances of the indicated CameraAnim. + * bImmediate: TRUE to stop it right now, FALSE to blend it out over BlendOutTime. + */ +simulated native function StopAllCameraAnims(optional bool bImmediate); + +/** + * Stop playing all instances of the indicated CameraAnim. + * bImmediate: TRUE to stop it right now, FALSE to blend it out over BlendOutTime. + */ +simulated native function StopAllCameraAnimsByType(CameraAnim Anim, optional bool bImmediate); + +/** + * Stops the given CameraAnim instance from playing. The given pointer should be considered invalid after this. + */ +simulated native function StopCameraAnim(CameraAnimInst AnimInst, optional bool bImmediate); + + +defaultproperties +{ + DefaultFOV=90.f + DefaultAspectRatio=AspectRatio4x3 + bHidden=TRUE + RemoteRole=ROLE_None + FreeCamDistance=256.f + bUseClientSideCameraUpdates=TRUE + bDebugClientSideCamera=FALSE + + CameraShakeCamModClass=class'CameraModifier_CameraShake' +} diff --git a/Engine/Classes/CameraActor.uc b/Engine/Classes/CameraActor.uc new file mode 100644 index 0000000..66b4648 --- /dev/null +++ b/Engine/Classes/CameraActor.uc @@ -0,0 +1,119 @@ +/* + CameraActor + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class CameraActor extends Actor + native(Camera) + ClassGroup(Common) + placeable; + +var() bool bConstrainAspectRatio; + +var() interp float AspectRatio; + +var() interp float FOVAngle; + +var deprecated bool bCamOverridePostProcess; +/** Blend value for CamOverridePostProcess. 0.f means it's ignored, 1.f means use it exclusively. */ +var() interp float CamOverridePostProcessAlpha; +var() interp PostProcessSettings CamOverridePostProcess; + +var DrawFrustumComponent DrawFrustum; +var StaticMeshComponent MeshComp; + +cpptext +{ + // UObject interface + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual void PostLoad(); + + // AActor interface + virtual void Spawned(); +protected: + virtual void UpdateComponentsInternal(UBOOL bCollisionUpdate = FALSE); +public: + + // ACameraActor interface + void UpdateDrawFrustum(); + +#if WITH_EDITOR + virtual void CheckForErrors(); +#endif +} + +replication +{ + if (Role == ROLE_Authority) + FOVAngle, AspectRatio; +} + + +/** + * Returns camera's Point of View. + * Called by Camera.uc class. Subclass and postprocess to add any effects. + */ +simulated function GetCameraView(float DeltaTime, out TPOV OutPOV) +{ + GetActorEyesViewPoint(OutPOV.Location, OutPOV.Rotation); + OutPOV.FOV = FOVAngle; +} + + +/** + * list important CameraActor variables on canvas. HUD will call DisplayDebug() on the current ViewTarget when + * the ShowDebug exec is used + * + * @param HUD - HUD with canvas to draw on + * @input out_YL - Height of the current font + * @input out_YPos - Y position on Canvas. out_YPos += out_YL, gives position to draw text for next debug line. + */ +simulated function DisplayDebug(HUD HUD, out float out_YL, out float out_YPos) +{ + local float XL; + local Canvas Canvas; + + Canvas = HUD.Canvas; + + super.DisplayDebug( HUD, out_YL, out_YPos); + + Canvas.StrLen("TEST", XL, out_YL); + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + Canvas.DrawText("FOV:" $ FOVAngle, false); +} + +defaultproperties +{ + Physics=PHYS_Interpolating + + FOVAngle=90.0 + bConstrainAspectRatio=TRUE + AspectRatio=AspectRatio16x9 + + Begin Object Class=StaticMeshComponent Name=CamMesh0 + HiddenGame=TRUE + CollideActors=FALSE + BlockRigidBody=FALSE + CastShadow=FALSE + AlwaysLoadOnClient=FALSE + AlwaysLoadOnServer=FALSE + End Object + MeshComp=CamMesh0 + Components.Add(CamMesh0) + + Begin Object Class=DrawFrustumComponent Name=DrawFrust0 + AlwaysLoadOnClient=FALSE + AlwaysLoadOnServer=FALSE + End Object + DrawFrustum=DrawFrust0 + Components.Add(DrawFrust0) + + + RemoteRole=ROLE_None + NetUpdateFrequency=1.f + bNoDelete=TRUE + + bEdShouldSnap=TRUE +} diff --git a/Engine/Classes/CameraAnim.uc b/Engine/Classes/CameraAnim.uc new file mode 100644 index 0000000..b930edf --- /dev/null +++ b/Engine/Classes/CameraAnim.uc @@ -0,0 +1,91 @@ + +/** + * CameraAnim: defines a pre-packaged animation to be played on a camera. + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class CameraAnim extends Object + notplaceable + native(Camera); + +/** The InterpGroup that holds our actual interpolation data. */ +var InterpGroupCamera CameraInterpGroup; +/** This is to preview and they only exists in editor */ +var editoronly transient InterpGroup PreviewInterpGroup; + +/** Length, in seconds. */ +var const float AnimLength; + +/** AABB in local space. */ +var const box BoundingBox; + +/** The "base" postprocess settings to use, to support non-animating settings. */ +var const PostProcessSettings BasePPSettings; +var const float BasePPSettingsAlpha; + +/** The */ +var const float BaseFOV; + +cpptext +{ +protected: + void CalcLocalAABB(); + +public: + /** Overridden to calculate the bbox at save time. */ + virtual void PreSave(); + virtual void PostLoad(); + INT GetResourceSize(); + + UBOOL CreateFromInterpGroup(class UInterpGroup* SrcGroup, class USeqAct_Interp* Interp); + FBox GetAABB(FVector const& BaseLoc, FRotator const& BaseRot, FLOAT Scale) const; + + UBOOL InitializeCamera(class UInterpGroup* SrcGroup, class USeqAct_Interp* Interp); +}; + +defaultproperties +{ + AnimLength=3.f + BaseFOV=90 + + BasePPSettingsAlpha=1.f + + // override nothing unless explicitly chosen + BasePPSettings={( + bOverride_EnableBloom=FALSE, + bOverride_EnableDOF=FALSE, + bOverride_EnableMotionBlur=FALSE, + bOverride_EnableSceneEffect=FALSE, + bOverride_AllowAmbientOcclusion=FALSE, + bOverride_OverrideRimShaderColor=FALSE, + bOverride_Bloom_Scale=FALSE, + bOverride_Bloom_Threshold=FALSE, + bOverride_Bloom_Tint=FALSE, + bOverride_Bloom_ScreenBlendThreshold=FALSE, + bOverride_Bloom_InterpolationDuration=FALSE, + bOverride_DOF_FalloffExponent=FALSE, + bOverride_DOF_BlurKernelSize=FALSE, + bOverride_DOF_BlurBloomKernelSize=FALSE, + bOverride_DOF_MaxNearBlurAmount=FALSE, + bOverride_DOF_MaxFarBlurAmount=FALSE, + bOverride_DOF_FocusType=FALSE, + bOverride_DOF_FocusInnerRadius=FALSE, + bOverride_DOF_FocusDistance=FALSE, + bOverride_DOF_FocusPosition=FALSE, + bOverride_DOF_InterpolationDuration=FALSE, + bOverride_MotionBlur_MaxVelocity=FALSE, + bOverride_MotionBlur_Amount=FALSE, + bOverride_MotionBlur_FullMotionBlur=FALSE, + bOverride_MotionBlur_CameraRotationThreshold=FALSE, + bOverride_MotionBlur_CameraTranslationThreshold=FALSE, + bOverride_MotionBlur_InterpolationDuration=FALSE, + bOverride_Scene_Desaturation=FALSE, + bOverride_Scene_TonemapperScale=FALSE, + bOverride_Scene_ImageGrainScale=FALSE, + bOverride_Scene_HighLights=FALSE, + bOverride_Scene_MidTones=FALSE, + bOverride_Scene_Shadows=FALSE, + bOverride_Scene_InterpolationDuration=FALSE, + bOverride_RimShader_Color=FALSE, + bOverride_RimShader_InterpolationDuration=FALSE, + )} +} diff --git a/Engine/Classes/CameraAnimInst.uc b/Engine/Classes/CameraAnimInst.uc new file mode 100644 index 0000000..35fe69f --- /dev/null +++ b/Engine/Classes/CameraAnimInst.uc @@ -0,0 +1,119 @@ + +/** + * CameraAnim: defines a pre-packaged animation to be played on a camera. + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class CameraAnimInst extends Object + notplaceable + native(Camera); + +/** which CameraAnim this is an instance of */ +var CameraAnim CamAnim; + +/** the InterpGroupInst used to do the interpolation */ +var protected instanced InterpGroupInst InterpGroupInst; + +/** Current time for the animation */ +var protected transient float CurTime; +/** True if the animation should loop, false otherwise. */ +var protected transient bool bLooping; +/** True if the animation has finished, false otherwise. */ +var transient bool bFinished; +/** True if it's ok for the system to auto-release this instance upon completion. */ +var transient bool bAutoReleaseWhenFinished; + +/** Time to interpolate in from zero, for smooth starts. */ +var protected float BlendInTime; +/** Time to interpolate out to zero, for smooth finishes. */ +var protected float BlendOutTime; +/** True if currently blending in. */ +var protected transient bool bBlendingIn; +/** True if currently blending out. */ +var protected transient bool bBlendingOut; +/** Current time for the blend-in. I.e. how long we have been blending. */ +var protected transient float CurBlendInTime; +/** Current time for the blend-out. I.e. how long we have been blending. */ +var protected transient float CurBlendOutTime; + +/** Multiplier for playback rate. 1.0 = normal. */ +var protected float PlayRate; + +/** "Intensity" scalar. This is the scale at which the anim was first played. */ +var float BasePlayScale; +/** A supplemental scale factor, allowing external systems to scale this anim as necessary. This is reset to 1.f each frame. */ +var float TransientScaleModifier; + + +/* Number in range [0..1], controlling how much this influence this instance should have. */ +var float CurrentBlendWeight; + +/** How much longer to play the anim, if a specific duration is desired. Has no effect if 0. */ +var protected transient float RemainingTime; + +/** cached movement track from the currently playing anim so we don't have to go find it every frame */ +var transient InterpTrackMove MoveTrack; +var transient InterpTrackInstMove MoveInst; + +/** Ref to the AnimNodeSequence that's instigating this anim. Can be None. */ +var protected transient AnimNodeSequence SourceAnimNode; + +var protectedwrite ECameraAnimPlaySpace PlaySpace; +/** The user-defined space for CAPS_UserDefined */ +var transient matrix UserPlaySpaceMatrix; + +/** PP settings stored for this inst, to be applied at the proper time */ +var transient PostProcessSettings LastPPSettings; +var transient float LastPPSettingsAlpha; + +/** Camera Anim debug variable to trace back to previous location **/ +var transient vector LastCameraLoc; + +cpptext +{ + void RegisterAnimNode(class UAnimNodeSequence* AnimNode); +}; + +/** + * Starts this instance playing the specified CameraAnim. + * + * CamAnim: The animation that should play on this instance. + * CamActor: The Actor that will be modified by this animation. + * InRate: How fast to play the animation. 1.f is normal. + * InScale: How intense to play the animation. 1.f is normal. + * InBlendInTime: Time over which to linearly ramp in. + * InBlendInTime: Time over which to linearly ramp out. + * bInLoop: Whether or not to loop the animation. + * bRandomStartTime: Whether or not to choose a random time to start playing. Only really makes sense for bLoop = TRUE; + * Duration: optional specific playtime for this animation. This is total time, including blends. + */ +native final function Play(CameraAnim Anim, Actor CamActor, float InRate, float InScale, float InBlendInTime, float InBlendOutTime, bool bInLoop, bool bRandomStartTime, optional float Duration); + +/** Update this instance with new parameters. */ +native final function Update(float NewRate, float NewScale, float NewBlendInTime, float NewBlendOutTime, optional float NewDuration); + +/** advances the animation by the specified time - updates any modified interp properties, moves the group actor, etc */ +native final function AdvanceAnim(float DeltaTime, bool bJump); + +/** Stops this instance playing whatever animation it is playing. */ +native final function Stop(optional bool bImmediate); + +/** Applies given scaling factor to the playing animation for the next update only. */ +native final function ApplyTransientScaling(float Scalar); + +/** Sets this anim to play in an alternate playspace */ +native final function SetPlaySpace(ECameraAnimPlaySpace NewSpace, optional rotator UserPlaySpace); + + +defaultproperties +{ + bFinished=true + bAutoReleaseWhenFinished=true + PlayRate=1.f + TransientScaleModifier=1.f + + PlaySpace=CAPS_CameraLocal + + Begin Object Class=InterpGroupInst Name=InterpGroupInst0 + End Object + InterpGroupInst=InterpGroupInst0 +} diff --git a/Engine/Classes/CameraConeComponent.uc b/Engine/Classes/CameraConeComponent.uc new file mode 100644 index 0000000..fe568e8 --- /dev/null +++ b/Engine/Classes/CameraConeComponent.uc @@ -0,0 +1,11 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class CameraConeComponent extends PrimitiveComponent + native + noexport; + +defaultproperties +{ + AbsoluteScale=TRUE +} diff --git a/Engine/Classes/CameraModifier.uc b/Engine/Classes/CameraModifier.uc new file mode 100644 index 0000000..093db3a --- /dev/null +++ b/Engine/Classes/CameraModifier.uc @@ -0,0 +1,250 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class CameraModifier extends Object + native(Camera); + +/* Interface class for all camera modifiers applied to + a player camera actor. Sub classes responsible for + implementing declared functions. +*/ + +/* Do not apply this modifier */ +var protected bool bDisabled; +/* This modifier is still being applied and will disable itself */ +var bool bPendingDisable; + +/** Camera this object is attached to */ +var Camera CameraOwner; + +/** + * Priority of this modifier - determines where it is added in the modifier list. + * 0 = highest priority, 255 = lowest + */ +var protected byte Priority; +/** This modifier can only be used exclusively - no modifiers of same priority allowed */ +var protected bool bExclusive; +/** When blending in, alpha proceeds from 0 to 1 over this time */ +var protected float AlphaInTime; +/** When blending out, alpha proceeds from 1 to 0 over this time */ +var protected float AlphaOutTime; + +/** Current blend alpha */ +var protected transient float Alpha; +/** Desired alpha we are interpolating towards. */ +var protected transient float TargetAlpha; + + +//debug +var(Debug) bool bDebug; + +cpptext +{ +protected: + virtual FLOAT GetTargetAlpha(class ACamera* Camera); +public: + virtual void GetDebugText(TArray& Lines) {}; +}; + +/** Allow anything to happen right after creation */ +function Init(); + + +/** + * Directly modifies variables in the camera actor + * + * @param Camera reference to camera actor we are modifying + * @param DeltaTime Change in time since last update + * @param OutPOV current Point of View, to be updated. + * @return bool TRUE if should STOP looping the chain, FALSE otherwise + */ +native function bool ModifyCamera +( + Camera Camera, + float DeltaTime, + out TPOV OutPOV +); + +/** Accessor function to check if modifier is inactive */ +native function bool IsDisabled() const; + +/** + * Camera modifier evaluates itself vs the given camera's modifier list + * and decides whether to add itself or not. Handles adding by priority and avoiding + * adding the same modifier twice. + * + * @param Camera - reference to camera actor we want add this modifier to + * @return bool - TRUE if modifier added to camera's modifier list, FALSE otherwise + */ +function bool AddCameraModifier( Camera Camera ) +{ + local int BestIdx, ModifierIdx; + local CameraModifier Modifier; + + // Make sure we don't already have this modifier in the list + for( ModifierIdx = 0; ModifierIdx < Camera.ModifierList.Length; ModifierIdx++ ) + { + if ( Camera.ModifierList[ModifierIdx] == Self ) + { + return false; + } + } + + // Make sure we don't already have a modifier of this type + for( ModifierIdx = 0; ModifierIdx < Camera.ModifierList.Length; ModifierIdx++ ) + { + if ( Camera.ModifierList[ModifierIdx].Class == Class ) + { + `log("AddCameraModifier found existing modifier in list, replacing with new one" @ self); + + // hack replace old by new (delete??) + Camera.ModifierList[ModifierIdx] = Self; + + // Save camera + CameraOwner = Camera; + + return true; + } + } + + // Look through current modifier list and find slot for this priority + BestIdx = 0; + + for( ModifierIdx = 0; ModifierIdx < Camera.ModifierList.Length; ModifierIdx++ ) + { + Modifier = Camera.ModifierList[ModifierIdx]; + if( Modifier == None ) { + continue; + } + + // If priority of current index has passed or equaled ours - we have the insert location + if( Priority <= Modifier.Priority ) + { + // Disallow addition of exclusive modifier if priority is already occupied + if( bExclusive && Priority == Modifier.Priority ) + { + return false; + } + + break; + } + + // Update best index + BestIdx++; + } + + // Insert self into best index + Camera.ModifierList.Insert( BestIdx, 1 ); + Camera.ModifierList[BestIdx] = self; + + // Save camera + CameraOwner = Camera; + +`if(`notdefined(FINAL_RELEASE)) + //debug + if( bDebug ) + { + `log( "AddModifier"@BestIdx@self ); + for( ModifierIdx = 0; ModifierIdx < Camera.ModifierList.Length; ModifierIdx++ ) + { + `log( Camera.ModifierList[ModifierIdx]@"Idx"@ModifierIdx@"Pri"@Camera.ModifierList[ModifierIdx].Priority); + } + `log( "****************" ); + } +`endif + + return true; +} + + +/** + * Camera modifier removes itself from given camera's modifier list + * + * @param Camera - reference to camara actor we want to remove this modifier from + * @return bool - TRUE if modifier removed successfully, FALSE otherwise + */ +function bool RemoveCameraModifier( Camera Camera ) +{ + local int ModifierIdx; + + //debug + `Log( self@"RemoveModifier", bDebug ); + + // Loop through each modifier in camera + for( ModifierIdx = 0; ModifierIdx < Camera.ModifierList.Length; ModifierIdx++ ) + { + // If we found ourselves, remove ourselves from the list and return + if( Camera.ModifierList[ModifierIdx] == self ) + { + Camera.ModifierList.Remove(ModifierIdx, 1); + return true; + } + } + + // Didn't find ourselves in the list + return false; +} + +/** + * Accessor functions for changing disable flag + * + * @param bImmediate - TRUE to disable with no blend out, FALSE (default) to allow blend out + * */ +event DisableModifier(optional bool bImmediate) +{ + //debug + `Log( self@"DisableModifier"@bImmediate, bDebug ); + + if (bImmediate) + { + bDisabled = true; + bPendingDisable = false; + } + else if (!bDisabled) + { + bPendingDisable = true; + } + +} +function EnableModifier() +{ + //debug + `Log( self@"EnableModifier", bDebug ); + + bDisabled = false; + bPendingDisable = false; +} +function ToggleModifier() +{ + //debug + `Log( self@"ToggleModifier", bDebug ); + + if( bDisabled ) + { + EnableModifier(); + } + else + { + DisableModifier(); + } +} +/** + * Allow this modifier a chance to change view rotation and deltarot + * Default just returns ViewRotation unchanged + * @return bool - TRUE if should stop looping modifiers to adjust rotation, FALSE otherwise + */ +simulated function bool ProcessViewRotation( Actor ViewTarget, float DeltaTime, out Rotator out_ViewRotation, out Rotator out_DeltaRot ); + +/** + * Responsible for updating alpha blend value. + * + * @param Camera - Camera that is being updated + * @param DeltaTime - Amount of time since last update + */ +native function UpdateAlpha( Camera Camera, float DeltaTime ); + + +defaultproperties +{ + Priority=127 +} diff --git a/Engine/Classes/CameraModifier_CameraShake.uc b/Engine/Classes/CameraModifier_CameraShake.uc new file mode 100644 index 0000000..ef6750a --- /dev/null +++ b/Engine/Classes/CameraModifier_CameraShake.uc @@ -0,0 +1,291 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * Camera modifier that provides support for code-based oscillating camera shakes. + */ +class CameraModifier_CameraShake extends CameraModifier + native(Camera) + dependson(CameraShake) + config(Camera); + + +struct native CameraShakeInstance +{ + /** source shake */ + var CameraShake SourceShake; + + /** Used to identify shakes when single instances are desired */ + var name SourceShakeName; + + /** <0.f means play infinitely. */ + var float OscillatorTimeRemaining; + + /** blend vars */ + var bool bBlendingIn; + var float CurrentBlendInTime; + var bool bBlendingOut; + var float CurrentBlendOutTime; + + /** Current offsets. */ + var vector LocSinOffset; + var vector RotSinOffset; + var float FOVSinOffset; + + var float Scale; + + var CameraAnimInst AnimInst; + + /** What space to play the shake in before applying to the camera. Affects Anim and Oscillation both. */ + var ECameraAnimPlaySpace PlaySpace; + /** Matrix defining the playspace, used when PlaySpace == CAPS_UserDefined */ + var matrix UserPlaySpaceMatrix; +}; + + + +/** Active CameraShakes array */ +var Array ActiveShakes; + +/** Always active ScreenShake for testing purposes */ +//var() CameraShake TestShake; + +/** Scalar applied to all camera shakes in splitscreen. Normally used to dampen, since shakes feel more intense in a smaller viewport. */ +var() protected const float SplitScreenShakeScale; + +cpptext +{ +protected: + /** For situational scaling of individual shakes. */ + virtual FLOAT GetShakeScale(FCameraShakeInstance const& ShakeInst) const; +public: +}; + + +static protected function float InitializeOffset( const out FOscillator Param ) +{ + Switch( Param.InitialOffset ) + { + case EOO_OffsetRandom : return FRand() * 2 * Pi; break; + case EOO_OffsetZero : return 0; break; + } + + return 0; +} + + +function protected ReinitShake(int ActiveShakeIdx, float Scale) +{ + local CameraShake SourceShake; + local float Duration; + local bool bRandomStart, bLoop; + + if (class'Engine'.static.IsSplitScreen()) + { + Scale *= SplitScreenShakeScale; + } + ActiveShakes[ActiveShakeIdx].Scale = Scale; + + SourceShake = ActiveShakes[ActiveShakeIdx].SourceShake; + + if (SourceShake.OscillationDuration != 0.f) + { + ActiveShakes[ActiveShakeIdx].OscillatorTimeRemaining = SourceShake.OscillationDuration; + + if (ActiveShakes[ActiveShakeIdx].bBlendingOut) + { + ActiveShakes[ActiveShakeIdx].bBlendingOut = FALSE; + ActiveShakes[ActiveShakeIdx].CurrentBlendOutTime = 0.f; + + // stop any blendout and reverse it to a blendin + ActiveShakes[ActiveShakeIdx].bBlendingIn = TRUE; + ActiveShakes[ActiveShakeIdx].CurrentBlendInTime = ActiveShakes[ActiveShakeIdx].SourceShake.OscillationBlendInTime * (1.f - ActiveShakes[ActiveShakeIdx].CurrentBlendOutTime / ActiveShakes[ActiveShakeIdx].SourceShake.OscillationBlendOutTime); + } + } + + if (SourceShake.Anim != None) + { + if (SourceShake.bRandomAnimSegment) + { + bLoop = TRUE; + bRandomStart = TRUE; + Duration = SourceShake.RandomAnimSegmentDuration; + } + + ActiveShakes[ActiveShakeIdx].AnimInst = CameraOwner.PlayCameraAnim(SourceShake.Anim, + SourceShake.AnimPlayRate, + Scale, + SourceShake.AnimBlendInTime, + SourceShake.AnimBlendOutTime, + bLoop, + bRandomStart, + Duration, + TRUE); + } + +} + +/** Initialize camera shake structure */ +function protected CameraShakeInstance InitializeShake(CameraShake NewShake, float Scale, ECameraAnimPlaySpace PlaySpace, optional rotator UserPlaySpaceRot) +{ + local CameraShakeInstance Inst; + local float Duration; + local bool bRandomStart, bLoop; + + Inst.SourceShakeName = NewShake.Name; + + // Create a copy of NewShake. + // Keeping the reference to NewShake can sometimes cause problems during GC, if NewShake lives in the level. + Inst.SourceShake = new(self) NewShake.Class(); + Inst.SourceShake.OscillationDuration = NewShake.OscillationDuration; + Inst.SourceShake.OscillationBlendInTime = NewShake.OscillationBlendInTime; + Inst.SourceShake.OscillationBlendOutTime = NewShake.OscillationBlendOutTime; + Inst.SourceShake.RotOscillation = NewShake.RotOscillation; + Inst.SourceShake.LocOscillation = NewShake.LocOscillation; + Inst.SourceShake.FOVOscillation = NewShake.FOVOscillation; + Inst.SourceShake.Anim = NewShake.Anim; + Inst.SourceShake.AnimPlayRate = NewShake.AnimPlayRate; + Inst.SourceShake.AnimBlendInTime = NewShake.AnimBlendInTime; + Inst.SourceShake.AnimBlendOutTime = NewShake.AnimBlendOutTime; + Inst.SourceShake.bRandomAnimSegment = NewShake.bRandomAnimSegment; + Inst.SourceShake.RandomAnimSegmentDuration = NewShake.RandomAnimSegmentDuration; + + Inst.Scale = Scale; + if (class'Engine'.static.IsSplitScreen()) + { + Scale *= SplitScreenShakeScale; + } + + // init oscillations + if ( NewShake.OscillationDuration != 0.f ) + { + Inst.RotSinOffset.X = InitializeOffset( NewShake.RotOscillation.Pitch ); + Inst.RotSinOffset.Y = InitializeOffset( NewShake.RotOscillation.Yaw ); + Inst.RotSinOffset.Z = InitializeOffset( NewShake.RotOscillation.Roll ); + + Inst.LocSinOffset.X = InitializeOffset( NewShake.LocOscillation.X ); + Inst.LocSinOffset.Y = InitializeOffset( NewShake.LocOscillation.Y ); + Inst.LocSinOffset.Z = InitializeOffset( NewShake.LocOscillation.Z ); + + Inst.FOVSinOffset = InitializeOffset( NewShake.FOVOscillation ); + + Inst.OscillatorTimeRemaining = NewShake.OscillationDuration; + + if (NewShake.OscillationBlendInTime > 0.f) + { + Inst.bBlendingIn = TRUE; + Inst.CurrentBlendInTime = 0.f; + } + } + + // init anims + if (NewShake.Anim != None) + { + if (NewShake.bRandomAnimSegment) + { + bLoop = TRUE; + bRandomStart = TRUE; + Duration = NewShake.RandomAnimSegmentDuration; + } + + if (Scale > 0.f) + { + Inst.AnimInst = CameraOwner.PlayCameraAnim(NewShake.Anim, NewShake.AnimPlayRate, Scale, NewShake.AnimBlendInTime, NewShake.AnimBlendOutTime, bLoop, bRandomStart, Duration, NewShake.bSingleInstance); + if (PlaySpace != CAPS_CameraLocal && Inst.AnimInst != None) + { + Inst.AnimInst.SetPlaySpace(PlaySpace, UserPlaySpaceRot); + } + + } + } + + Inst.PlaySpace = PlaySpace; + if (Inst.PlaySpace == CAPS_UserDefined) + { + Inst.UserPlaySpaceMatrix = MakeRotationMatrix(UserPlaySpaceRot); + } + + return Inst; +} + +/** Add a new screen shake to the list */ +function AddCameraShake( CameraShake NewShake, float Scale, optional ECameraAnimPlaySpace PlaySpace=CAPS_CameraLocal, optional rotator UserPlaySpaceRot ) +{ + local int ShakeIdx, NumShakes; + + if (NewShake != None) + { + if (NewShake.bSingleInstance) + { + ShakeIdx = ActiveShakes.Find('SourceShakeName', NewShake.Name); + if (ShakeIdx != INDEX_NONE) + { + ReinitShake(ShakeIdx, Scale); + return; + } + } + + NumShakes = ActiveShakes.Length; + + // Initialize new shake and add it to the list of active shakes + ActiveShakes[NumShakes] = InitializeShake(NewShake, Scale, PlaySpace, UserPlaySpaceRot); + } +} + + +function RemoveCameraShake(CameraShake Shake) +{ + local int Idx; + local CameraAnimInst AnimInst; + + Idx = ActiveShakes.Find('SourceShakeName', Shake.Name); + + if (Idx != INDEX_NONE) + { + AnimInst = ActiveShakes[Idx].AnimInst; + if ( (AnimInst != None) && !AnimInst.bFinished ) + { + CameraOwner.StopCameraAnim(AnimInst, true); + } + + ActiveShakes.Remove(Idx,1); + } +} + +function RemoveAllCameraShakes() +{ + local int Idx; + local CameraAnimInst AnimInst; + + // clean up any active camera shake anims + for (Idx=0; Idx; +var(Oscillation) float OscillationBlendOutTime; + +/** Rotational oscillation */ +var(Oscillation) ROscillator RotOscillation; +/** Positional oscillation */ +var(Oscillation) VOscillator LocOscillation; +/** FOV oscillation */ +var(Oscillation) FOscillator FOVOscillation; + + + +/************************************************************ + * Parameters for defining CameraAnim-driven camera shakes + ************************************************************/ + +var(AnimShake) CameraAnim Anim; + +/** Scalar defining how fast to play the anim. */ +var(AnimShake) float AnimPlayRate; +/** Scalar defining how "intense" to play the anim. */ +var(AnimShake) float AnimScale; +/** Linear blend-in time. */ +var(AnimShake) float AnimBlendInTime; +/** Linear blend-out time. */ +var(AnimShake) float AnimBlendOutTime; + +/** + * If TRUE, play a random snippet of the animation of length Duration. Implies bLoop and bRandomStartTime = TRUE for the CameraAnim. + * If FALSE, play the full anim once, non-looped. + */ +var(AnimShake) bool bRandomAnimSegment; +/** When bRandomAnimSegment=true, this defines how long the anim should play. */ +var(AnimShake) float RandomAnimSegmentDuration; + + +simulated function float GetRotOscillationMagnitude() +{ + local vector V; + V.X = RotOscillation.Pitch.Amplitude; + V.Y = RotOscillation.Yaw.Amplitude; + V.Z = RotOscillation.Roll.Amplitude; + return VSize(V); +} +simulated function float GetLocOscillationMagnitude() +{ + local vector V; + V.X = LocOscillation.X.Amplitude; + V.Y = LocOscillation.Y.Amplitude; + V.Z = LocOscillation.Z.Amplitude; + return VSize(V); +} + + +defaultproperties +{ + AnimPlayRate=1.f + AnimScale=1.f + AnimBlendInTime=0.2f + AnimBlendOutTime=0.2f + OscillationBlendInTime=0.1f + OscillationBlendOutTime=0.2f +} diff --git a/Engine/Classes/Canvas.uc b/Engine/Classes/Canvas.uc new file mode 100644 index 0000000..ec9eab7 --- /dev/null +++ b/Engine/Classes/Canvas.uc @@ -0,0 +1,764 @@ +//============================================================================= +// Canvas: A drawing canvas. +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class Canvas extends Object + native + transient; + +/** + * Holds texture information with UV coordinates as well. + */ +struct native CanvasIcon +{ + /** Source texture */ + var() Texture Texture; + /** UV coords */ + var() float U, V, UL, VL; +}; + + +enum ECanvasBlendMode +{ + BLEND_CANVAS_Opaque, + BLEND_CANVAS_Masked, + BLEND_CANVAS_Translucent, + BLEND_CANVAS_Additive, + BLEND_CANVAS_Modulate, + BLEND_CANVAS_ModulateAndAdd, + BLEND_CANVAS_SoftMasked, + BLEND_CANVAS_AlphaComposite, + BLEND_CANVAS_DitheredTranslucent, + BLEND_CANVAS_AlphaOnly, +}; + +/** info for glow when using depth field rendering */ +struct native DepthFieldGlowInfo +{ + /** whether to turn on the outline glow (depth field fonts only) */ + var bool bEnableGlow; + /** base color to use for the glow */ + var LinearColor GlowColor; + /** if bEnableGlow, outline glow outer radius (0 to 1, 0.5 is edge of character silhouette) + * glow influence will be 0 at GlowOuterRadius.X and 1 at GlowOuterRadius.Y + */ + var vector2d GlowOuterRadius; + /** if bEnableGlow, outline glow inner radius (0 to 1, 0.5 is edge of character silhouette) + * glow influence will be 1 at GlowInnerRadius.X and 0 at GlowInnerRadius.Y + */ + var vector2d GlowInnerRadius; + + structcpptext + { + FDepthFieldGlowInfo() + {} + FDepthFieldGlowInfo(EEventParm) + { + appMemzero(this, sizeof(FDepthFieldGlowInfo)); + } + UBOOL operator==(const FDepthFieldGlowInfo& Other) const + { + if (Other.bEnableGlow != bEnableGlow) + { + return false; + } + else if (!bEnableGlow) + { + // if the glow is disabled on both, the other values don't matter + return true; + } + else + { + return (Other.GlowColor == GlowColor && Other.GlowOuterRadius == GlowOuterRadius && Other.GlowInnerRadius == GlowInnerRadius); + } + } + UBOOL operator!=(const FDepthFieldGlowInfo& Other) const + { + return !(*this == Other); + } + } +}; + + +struct native MobileDistanceFieldParams +{ + /** Gamma value for distance field shader */ + var float Gamma; + /** Alpha value to cull out*/ + var float AlphaRefVal; + /** Width */ + var float SmoothWidth; + /** Whether to shadow the font*/ + var BOOL EnableShadow; + /** Which screen-space direction the shadows are in*/ + var vector2d ShadowDirection; + /** Color of the font shadow*/ + var LinearColor ShadowColor; + /** Shadow width*/ + var float ShadowSmoothWidth; + /** Glow information structure*/ + var native DepthFieldGlowInfo GlowInfo; + /** Blend mode*/ + var INT BlendMode; + + structcpptext + { + /** Constructors */ + FMobileDistanceFieldParams( + FLOAT InGamma, + FLOAT InAlphaRefVal, + FLOAT InSmoothWidth, + UBOOL InEnableShadow, + FVector2D& InShadowDirection, + FLinearColor& InShadowColor, + FLOAT InShadowSmoothWidth, + const FDepthFieldGlowInfo& InGlowInfo, + INT InBlendMode + ) + : Gamma(InGamma) + , AlphaRefVal(InAlphaRefVal) + , SmoothWidth(InSmoothWidth) + , EnableShadow(InEnableShadow) + , ShadowDirection(InShadowDirection) + , ShadowColor(InShadowColor) + , ShadowSmoothWidth(InShadowSmoothWidth) + , GlowInfo(InGlowInfo) + , BlendMode(InBlendMode) + { + } + } +}; + +/** information used in font rendering */ +struct native FontRenderInfo +{ + /** whether to clip text */ + var bool bClipText; + /** whether to turn on shadowing */ + var bool bEnableShadow; + /** depth field glow parameters (only usable if font was imported with a depth field) */ + var DepthFieldGlowInfo GlowInfo; +}; + +/** Simple 2d triangle with UVs */ +struct native CanvasUVTri +{ + /** Position of first vertex */ + var() vector2d V0_Pos; + /** UV of first vertex */ + var() vector2d V0_UV; + + /** Position of second vertex */ + var() vector2d V1_Pos; + /** UV of second vertex */ + var() vector2d V1_UV; + + /** Position of third vertex */ + var() vector2d V2_Pos; + /** UV of third vertex */ + var() vector2d V2_UV; +}; + +// Modifiable properties. +var font Font; // Font for DrawText. +var float OrgX, OrgY; // Origin for drawing. +var float ClipX, ClipY; // Bottom right clipping region. +var const float CurX, CurY, CurZ;// Current position for drawing. Always use SetPos to set these +var float CurYL; // Largest Y size since DrawText. +var color DrawColor; // Color for drawing. +var bool bCenter; // Whether to center the text. +var bool bNoSmooth; // Don't bilinear filter. +var const int SizeX, SizeY; // Zero-based actual dimensions. + +// Internal. +var native const pointer Canvas{FCanvas}; +var native const pointer SceneView{FSceneView}; + +var Plane ColorModulate; +var Texture2D DefaultTexture; + +`if(`__TW_) +var bool bStencilEnabled; +`endif + +/** + * General purpose data structure for grouping all parameters needed when sizing or wrapping a string + */ +struct native transient TextSizingParameters +{ + /** a pixel value representing the horizontal screen location to begin rendering the string */ + var float DrawX; + + /** a pixel value representing the vertical screen location to begin rendering the string */ + var float DrawY; + + /** a pixel value representing the width of the area available for rendering the string */ + var float DrawXL; + + /** a pixel value representing the height of the area available for rendering the string */ + var float DrawYL; + + /** + * A value between 0.0 and 1.0, which represents how much the width/height should be scaled, + * where 1.0 represents 100% scaling. + */ + var Vector2D Scaling; + + /** the font to use for sizing/wrapping the string */ + var Font DrawFont; + + /** Horizontal spacing adjustment between characters and vertical spacing adjustment between wrapped lines */ + var Vector2D SpacingAdjust; + + /** the current height of the viewport; needed to support multifont */ + var float ViewportHeight; + + + structcpptext + { + FTextSizingParameters( FLOAT inDrawX, FLOAT inDrawY, FLOAT inDrawXL, FLOAT inDrawYL, UFont* inFont=NULL, FLOAT InViewportHeight=0.f ) + : DrawX(inDrawX), DrawY(inDrawY), DrawXL(inDrawXL), DrawYL(inDrawYL) + , Scaling(1.f,1.f), DrawFont(inFont) + , SpacingAdjust( 0.0f, 0.0f ), ViewportHeight(InViewportHeight) + { + } + + FTextSizingParameters( UFont* inFont, FLOAT ScaleX, FLOAT ScaleY, FLOAT InViewportHeight=0.f ) + : DrawX(0.f), DrawY(0.f), DrawXL(0.f), DrawYL(0.f) + , Scaling(ScaleX,ScaleY), DrawFont(inFont) + , SpacingAdjust( 0.0f, 0.0f ), ViewportHeight(InViewportHeight) + { + } + } +}; + + +/** + * Used by UUIString::WrapString to track information about each line that is generated as the result of wrapping. + */ +struct native transient WrappedStringElement +{ + /** the string associated with this line */ + var string Value; + + /** the size (in pixels) that it will take to render this string */ + var Vector2D LineExtent; + + structcpptext + { + /** Constructor */ + FWrappedStringElement( const TCHAR* InValue, FLOAT Width, FLOAT Height ) + : Value(InValue), LineExtent(Width,Height) + {} + } +}; + +cpptext +{ + // UCanvas interface. + void Init(); + void Update(); + + void DrawTile(UTexture* Tex, FLOAT X, FLOAT Y, FLOAT Z, FLOAT XL, FLOAT YL, FLOAT U, FLOAT V, FLOAT UL, FLOAT VL, const FLinearColor& Color,ECanvasBlendMode BlendMode); + void DrawTile(UTexture* Tex, FLOAT X, FLOAT Y, FLOAT Z, FLOAT XL, FLOAT YL, FLOAT U, FLOAT V, FLOAT UL, FLOAT VL, const FLinearColor& Color,EBlendMode BlendMode=BLEND_Translucent); + void DrawMaterialTile(UMaterialInterface* Tex, FLOAT X, FLOAT Y, FLOAT Z, FLOAT XL, FLOAT YL, FLOAT U, FLOAT V, FLOAT UL, FLOAT VL); + static void ClippedStrLen(UFont* Font, FLOAT ScaleX, FLOAT ScaleY, INT& XL, INT& YL, const TCHAR* Text); + void VARARGS WrappedStrLenf(UFont* Font, FLOAT ScaleX, FLOAT ScaleY, INT& XL, INT& YL, const TCHAR* Fmt, ...); + INT WrappedPrint(UBOOL Draw, INT& XL, INT& YL, UFont* Font, FLOAT ScaleX, FLOAT ScaleY, UBOOL Center, const TCHAR* Text, const FFontRenderInfo& RenderInfo = FFontRenderInfo(EC_EventParm)); + void DrawText(const FString& Text); + void DrawTileStretched(UTexture* Tex, FLOAT Left, FLOAT Top, FLOAT Depth, FLOAT AWidth, FLOAT AHeight, FLOAT U, FLOAT V, FLOAT UL, FLOAT VL, FLinearColor DrawColor,UBOOL bStretchHorizontally=1,UBOOL bStretchVertically=1,FLOAT ScalingFactor=1.0); + void DrawTimer(UTexture* Tex, FLOAT StartTime, FLOAT TotalTime, FLOAT X, FLOAT Y, FLOAT Z, FLOAT XL, FLOAT YL, FLOAT U, FLOAT V, FLOAT UL, FLOAT VL, const FLinearColor& Color,EBlendMode BlendMode=BLEND_Translucent); + + /** + * Calculates the size of the specified string. + * + * @param Parameters Used for various purposes + * DrawXL: [out] will be set to the width of the string + * DrawYL: [out] will be set to the height of the string + * DrawFont: [in] specifies the font to use for retrieving the size of the characters in the string + * Scale: [out] specifies the amount of scaling to apply to the string + * @param pText the string to calculate the size for + * @param EOL a pointer to a single character that is used as the end-of-line marker in this string + * @param bStripTrailingCharSpace + * whether the inter-character spacing following the last character should be included in the calculated width of the result string + */ + static void CanvasStringSize( FTextSizingParameters& Parameters, const TCHAR* pText, const TCHAR* EOL=NULL, UBOOL bStripTrailingCharSpace=TRUE ); + + + /** + * Parses a single string into an array of strings that will fit inside the specified bounding region. + * + * @param Parameters Used for various purposes: + * DrawX: [in] specifies the pixel location of the start of the horizontal bounding region that should be used for wrapping. + * DrawY: [in] specifies the Y origin of the bounding region. This should normally be set to 0, as this will be + * used as the base value for DrawYL. + * [out] Will be set to the Y position (+YL) of the last line, i.e. the total height of all wrapped lines relative to the start of the bounding region + * DrawXL: [in] specifies the pixel location of the end of the horizontal bounding region that should be used for wrapping + * DrawYL: [in] specifies the height of the bounding region, in pixels. A input value of 0 indicates that + * the bounding region height should not be considered. Once the total height of lines reaches this + * value, the function returns and no further processing occurs. + * DrawFont: [in] specifies the font to use for retrieving the size of the characters in the string + * Scale: [in] specifies the amount of scaling to apply to the string + * @param CurX specifies the pixel location to begin the wrapping; usually equal to the X pos of the bounding region, unless wrapping is initiated + * in the middle of the bounding region (i.e. indentation) + * @param pText the text that should be wrapped + * @param out_Lines [out] will contain an array of strings which fit inside the bounding region specified. Does + * not clear the array first. + * @param EOL a pointer to a single character that is used as the end-of-line marker in this string + * @param MaxLines the maximum number of lines that can be created. + */ + static void WrapString( FTextSizingParameters& Parameters, FLOAT CurX, const TCHAR* pText, TArray& out_Lines, const TCHAR* EOL = NULL, INT MaxLines = MAXINT); +} + +/** + * Draws a texture to an axis-aligned quad at CurX,CurY. + * + * @param Tex - The texture to render. + * @param XL - The width of the quad in pixels. + * @param YL - The height of the quad in pixels. + * @param U - The U coordinate of the quad's upper left corner, in normalized coordinates. + * @param V - The V coordinate of the quad's upper left corner, in normalized coordinates. + * @param UL - The range of U coordinates which is mapped to the quad. + * @param VL - The range of V coordinates which is mapped to the quad. + * @param LColor - Color to colorize this texture. + * @param bClipTile - Whether to clip the texture (FALSE by default). + */ +native noexport final function DrawTile(Texture Tex, float XL, float YL, float U, float V, float UL, float VL, optional LinearColor LColor, optional bool ClipTile, optional EBlendMode Blend); + + +/** + * Optimization call to pre-allocate vertices and triangles for future DrawTile() calls. + * NOTE: Num is number of subsequent DrawTile() calls that will be made in a row with the + * same Texture and Blend settings. If other draws (Text, different textures, etc) are + * done before the Num DrawTile calls, the optimization will not work and will only waste memory. + * + * @param Num - The number of DrawTile calls that will follow this function call + * @param Tex - The texture that will be used to render tiles. + * @param Blend - The blend mode that will be used for tiles. + */ +native noexport final function PreOptimizeDrawTiles(INT Num, Texture Tex, optional EBlendMode Blend); + +/** + * Draws the emissive channel of a material to an axis-aligned quad at CurX,CurY. + * + * @param Mat - The material which contains the emissive expression to render. + * @param XL - The width of the quad in pixels. + * @param YL - The height of the quad in pixels. + * @param U - The U coordinate of the quad's upper left corner, in normalized coordinates. + * @param V - The V coordinate of the quad's upper left corner, in normalized coordinates. + * @param UL - The range of U coordinates which is mapped to the quad. + * @param VL - The range of V coordinates which is mapped to the quad. + * @param bClipTile - Whether to clip the texture (FALSE by default). + */ +native noexport final function DrawMaterialTile +( + MaterialInterface Mat, + float XL, + float YL, + optional float U, + optional float V, + optional float UL, + optional float VL, + optional bool bClipTile +); + +native final function DrawRotatedTile( Texture Tex, rotator Rotation, float XL, float YL, float U, float V,float UL, float VL, + optional float AnchorX=0.5f, optional float AnchorY=0.5f); + +native final function DrawRotatedMaterialTile( MaterialInterface Mat, rotator Rotation, float XL, float YL, optional float U=0.f, optional float V=0.f, + optional float UL=0.f, optional float VL=0.f, optional float AnchorX=0.5f, optional float AnchorY=0.5f); + +/** +* Draws Draw a circular percentage of a texture - like drawing a pizza with slices missing. +* +* @param Tex - The texture to render. +* @param StartTime - 0 -> 12:00, 0.25 = 3:00, 0.5 = 6:00, 0.75 = 9:00. (negative goes other way) +* @param TotalTime - % of circle to draw (positive is clockwise, neg is counter clockwise) +* @param XL - The width of the quad in pixels. +* @param YL - The height of the quad in pixels. +* @param U - The U coordinate of the quad's upper left corner, in normalized coordinates. +* @param V - The V coordinate of the quad's upper left corner, in normalized coordinates. +* @param UL - The range of U coordinates which is mapped to the quad. +* @param VL - The range of V coordinates which is mapped to the quad. +* @param LColor - Color to colorize this texture. +* @param Blend - The blend mode that will be used for tiles. +*/ +native noexport final function DrawTimer(Texture Tex, float StartTime, float TotalTime, float XL, float YL, float U, float V, float UL, float VL, optional LinearColor LColor, optional EBlendMode Blend); + +native noexport final function DrawTileStretched(Texture Tex, float XL, float YL, float U, float V, float UL, float VL, optional LinearColor LColor/* = DrawColor*/, optional bool bStretchHorizontally/* = true*/, optional bool bStretchVertically/* = true*/, optional float ScalingFactor/* = 1.0*/); + +/** + * Draw a number of triangles on the canvas + * @param Tex Texture to apply to triangles + * @param Triangles Array of triangles to render + */ +native final function DrawTris( Texture Tex, array Triangles, Color InColor ); + +/** constructor for FontRenderInfo */ +static final function FontRenderInfo CreateFontRenderInfo(optional bool bClipText, optional bool bEnableShadow, optional LinearColor GlowColor, optional vector2D GlowOuterRadius, optional vector2D GlowInnerRadius) +{ + local FontRenderInfo Result; + + Result.bClipText = bClipText; + Result.bEnableShadow = bEnableShadow; + Result.GlowInfo.bEnableGlow = (GlowColor.A != 0.0); + if (Result.GlowInfo.bEnableGlow) + { + Result.GlowInfo.GlowOuterRadius = GlowOuterRadius; + Result.GlowInfo.GlowInnerRadius = GlowInnerRadius; + } + return Result; +} + +native noexport final function StrLen(coerce string String, out float XL, out float YL); // Wrapped! +native noexport final function TextSize(coerce string String, out float XL, out float YL, optional float XScale = 1.0, optional float YScale = 1.0); // Clipped! + +native noexport final function DrawText(coerce string Text, optional bool CR = true, optional float XScale = 1.0, optional float YScale = 1.0, optional const out FontRenderInfo RenderInfo); + +/** Convert a 3D vector to a 2D screen coords. */ +native noexport final function vector Project(vector location); + +/** transforms 2D screen coordinates into a 3D world-space origin and direction + * @param ScreenPos - screen coordinates in pixels + * @param WorldOrigin (out) - world-space origin vector + * @param WorldDirection (out) - world-space direction vector + */ +native noexport final function DeProject(vector2D ScreenPos, out vector WorldOrigin, out vector WorldDirection); + +/** + * Pushes a translation matrix onto the canvas. + * + * @param TranslationVector Translation vector to use to create the translation matrix. + */ +native noexport final function PushTranslationMatrix(vector TranslationVector); + +/** Pops the topmost matrix from the canvas transform stack. */ +native noexport final function PopTransform(); + +// UnrealScript functions. +event Reset(optional bool bKeepOrigin) +{ + Font = GetDefaultCanvasFont(); + + if ( !bKeepOrigin ) + { + OrgX = Default.OrgX; + OrgY = Default.OrgY; + } + SetPos(Default.CurX, Default.CurY); + DrawColor = Default.DrawColor; + CurYL = Default.CurYL; + bCenter = false; + bNoSmooth = false; +} + +/** + * Override this function to change the default font used by the canvas + * + * @return the Font to use for this scene + */ +function Font GetDefaultCanvasFont() +{ + return class'Engine'.Static.GetSmallFont(); +} + + +native final function SetPos(float PosX, float PosY, float PosZ=0.0); + +final function SetOrigin(float X, float Y) +{ + OrgX = X; + OrgY = Y; +} + +final function SetClip(float X, float Y) +{ + ClipX = X; + ClipY = Y; +} + +native noexport final function PushMaskRegion(float X, float Y, float XL, float YL); +native noexport final function PopMaskRegion(); + +final function DrawTexture(Texture Tex, float Scale) +{ + if (Tex != None) + { + DrawTile(Tex, Tex.GetSurfaceWidth()*Scale, Tex.GetSurfaceHeight()*Scale, 0, 0, Tex.GetSurfaceWidth(), Tex.GetSurfaceHeight()); + } +} + +/** + * Draw a texture to the canvas using one of the special Canvas blend modes + * + * @param Tex The texture to draw onto the canvas + * @param XL/YL Size on canvas (starting pos is CurX/CurY) + * @param U/V/UL/VL Texture coordinates + * @param Blend The ECanvasBlendMode to use for drawing the Texture + * + **/ +native final function DrawBlendedTile(Texture Tex, float XL, float YL, float U, float V, float UL, float VL, ECanvasBlendMode Blend); + +/** + * Fake CanvasIcon constructor. + */ +final function CanvasIcon MakeIcon(Texture Texture, optional float U, optional float V, optional float UL, optional float VL) +{ + local CanvasIcon Icon; + if (Texture != None) + { + Icon.Texture = Texture; + Icon.U = U; + Icon.V = V; + Icon.UL = (UL != 0.f ? UL : Texture.GetSurfaceWidth()); + Icon.VL = (VL != 0.f ? VL : Texture.GetSurfaceHeight()); + } + return Icon; +} + +/** + * Draw a CanvasIcon at the desired canvas position. + */ +final function DrawScaledIcon(CanvasIcon Icon, float X, float Y, Vector Scale) +{ + if (Icon.Texture != None) + { + // verify properties are valid + if (VSize(Scale) <= 0.f) + { + Scale.X = 1.f; + Scale.Y = 1.f; + } + if (Icon.UL == 0.f) + { + Icon.UL = Icon.Texture.GetSurfaceWidth(); + } + if (Icon.VL == 0.f) + { + Icon.VL = Icon.Texture.GetSurfaceHeight(); + } + // set the canvas position + SetPos(CurX, Cury); + // and draw the texture + DrawTile(Icon.Texture, Abs(Icon.UL) * Scale.X, Abs(Icon.VL) * Scale.Y, Icon.U, Icon.V, Icon.UL, Icon.VL); + } +} + +/** + * Draw a CanvasIcon at the desired canvas position. + */ +final function DrawIcon(CanvasIcon Icon, float X, float Y, optional float Scale) +{ + if (Icon.Texture != None) + { + // verify properties are valid + if (Scale <= 0.f) + { + Scale = 1.f; + } + if (Icon.UL == 0.f) + { + Icon.UL = Icon.Texture.GetSurfaceWidth(); + } + if (Icon.VL == 0.f) + { + Icon.VL = Icon.Texture.GetSurfaceHeight(); + } + // set the canvas position + SetPos(X, Y); + // and draw the texture + DrawTile(Icon.Texture, Abs(Icon.UL) * Scale, Abs(Icon.VL) * Scale, Icon.U, Icon.V, Icon.UL, Icon.VL); + } +} + +final function DrawRect(float RectX, float RectY, optional Texture Tex = DefaultTexture) +{ + DrawTile(Tex, RectX, RectY, 0, 0, Tex.GetSurfaceWidth(), Tex.GetSurfaceHeight()); +} + +final simulated function DrawBox(float width, float height) +{ + local int X, Y; + + X = CurX; + Y = CurY; + + // normalize CurX, CurY (eliminate float precision errors) + SetPos(X, Y); + + // draw the left side + DrawRect(2, height); + // then move cursor to top-right + SetPos(X + width - 2, Y); + + // draw the right face + DrawRect(2, height); + // then move the cursor to the top-left (+2 to account for the line we already drew for the left-face) + SetPos(X + 2, Y); + + // draw the top face + DrawRect(width - 4, 2); + // then move the cursor to the bottom-left (+2 to account for the line we already drew for the left-face) + SetPos(X + 2, Y + height - 2); + + // draw the bottom face + DrawRect(width - 4, 2); + // move the cursor back to its original position + SetPos(X, Y); +} + +native final function SetDrawColor(byte R, byte G, byte B, optional byte A = 255); + +`if(`__TW_) +native final function EnableStencilTest(bool bEnable); +`endif + +/** Set the draw color using a color struct */ +final function SetDrawColorStruct(color C) +{ + SetDrawColor(C.R, C.G, C.B, C.A); +} + +native noexport final function Draw2DLine(float X1, float Y1, float X2, float Y2, color LineColor); + +native final function DrawTextureLine(vector StartPoint, vector EndPoint, float Perc, float Width, color LineColor, Texture LineTexture, float U, float V, float UL, float VL ); +native final function DrawTextureDoubleLine(vector StartPoint, vector EndPoint, float Perc, float Spacing, float Width, color LineColor, color AltLineColor, Texture Tex, float U, float V, float UL, float VL); + + +/** + * Draws a graph comparing 2 variables. Useful for visual debugging and tweaking. + * + * @param Title Label to draw on the graph, or "" for none + * @param ValueX X-axis value of the point to plot + * @param ValueY Y-axis value of the point to plot + * @param UL_X X screen coord of the upper-left corner of the graph + * @param UL_Y Y screen coord of the upper-left corner of the graph + * @param W Width of the graph, in pixels + * @param H Height of the graph, in pixels + * @param RangeX Range of values expressed by the X axis of the graph + * @param RangeY Range of values expressed by the Y axis of the graph + */ +function DrawDebugGraph(coerce string Title, float ValueX, float ValueY, float UL_X, float UL_Y, float W, float H, vector2d RangeX, vector2d RangeY) +{ + `define GRAPH_ICONSIZE 8 + + local int X, Y; + + // draw graph box + SetDrawColor(255, 255, 255, 255); + SetPos(UL_X, UL_Y); + DrawBox(W, H); + + // plot point + SetDrawColor(255, 255, 0, 255); + X = UL_X + GetRangePctByValue(RangeX, ValueX) * W - `GRAPH_ICONSIZE/2; + Y = UL_Y + GetRangePctByValue(RangeY, ValueY) * H - `GRAPH_ICONSIZE/2; + SetPos(X, Y); + DrawRect(`GRAPH_ICONSIZE, `GRAPH_ICONSIZE); + + // plot lines + SetDrawColor(128, 128, 0, 128); + Draw2DLine(UL_X, Y, UL_X+W, Y, DrawColor); // horiz + Draw2DLine(X, UL_Y, X, UL_Y+H, DrawColor); // vert + + // x value at bottom + SetDrawColor(255, 255, 0, 255); + SetPos(X, UL_Y+H+16); + DrawText(ValueX); + + // y value on right + SetPos(UL_X+W+8, Y); + DrawText(ValueY); + + // title + if (Title != "") + { + SetPos(UL_X, UL_Y-16); + DrawText(Title); + } +} + + +`if(`__TW_) +/** + * Draws the background for a graph. Useful for visual debugging and tweaking. + * + * @param Title Label to draw on the graph, or "" for none + * @param UL_X X screen coord of the upper-left corner of the graph + * @param UL_Y Y screen coord of the upper-left corner of the graph + * @param W Width of the graph, in pixels + * @param H Height of the graph, in pixels + */ +function DrawDebugGraphBackground(coerce string Title, float UL_X, float UL_Y, float W, float H) +{ + // draw graph box + SetDrawColor(255, 255, 255, 255); + SetPos(UL_X, UL_Y); + DrawBox(W, H); + + // title + if (Title != "") + { + SetPos(UL_X, UL_Y-16); + DrawText(Title); + } +} + +/** + * Draws an element of a line graph for debugging + * + * @param Points An array of X and Y values that represents the points on the line to draw + * @param UL_X X screen coord of the upper-left corner of the graph + * @param UL_Y Y screen coord of the upper-left corner of the graph + * @param W Width of the graph, in pixels + * @param H Height of the graph, in pixels + * @param RangeX Range of values expressed by the X axis of the graph + * @param RangeY Range of values expressed by the Y axis of the graph + * @param Color The color to use to represent this element on the graph + * @param Title Label to draw on for the key for this element, or "" for none + * @param KeyXOffset Offset in the X axis for the position of drawing the key for this element + */ +function DrawDebugGraphElement(array Points, float UL_X, float UL_Y, float W, float H, vector2d RangeX, vector2d RangeY, Color ElementColor, coerce string KeyString, float KeyXOffset, coerce string LineValue) +{ + local int X1, Y1, X2, Y2; + local int i; + + SetPos(UL_X, UL_Y); + SetDrawColor(ElementColor.R,ElementColor.G, ElementColor.B, ElementColor.A); + + for( i = 0; i < (Points.Length - 1); i++ ) + { + // Draw each line element + X1 = UL_X + GetRangePctByValue(RangeX, Points[i].X) * W; + Y1 = UL_Y + GetRangePctByValue(RangeY, Points[i].Y) * H; + X2 = UL_X + GetRangePctByValue(RangeX, Points[i+1].X) * W; + Y2 = UL_Y + GetRangePctByValue(RangeY, Points[i+1].Y) * H; + + Draw2DLine(X1, Y1, X2, Y2, ElementColor); + } + + // Draw the current value for the element + if (LineValue != "") + { + SetPos(UL_X+W+8, Y2); + DrawText(LineValue); + } + + // Key + if (KeyString != "") + { + SetPos(UL_X+KeyXOffset, UL_Y+H+4); + DrawText(KeyString); + } +} +`endif + +defaultproperties +{ + DrawColor=(R=127,G=127,B=127,A=255) + ColorModulate=(X=1,Y=1,Z=1,W=1) + DefaultTexture="EngineResources.WhiteSquareTexture" +`if(`__TW_) + bStencilEnabled=false +`endif +} diff --git a/Engine/Classes/CeilingReachSpec.uc b/Engine/Classes/CeilingReachSpec.uc new file mode 100644 index 0000000..b2cc11e --- /dev/null +++ b/Engine/Classes/CeilingReachSpec.uc @@ -0,0 +1,26 @@ +/** + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + + +class CeilingReachSpec extends ReachSpec + native; + +cpptext +{ + virtual INT CostFor( APawn* P ); + virtual INT AdjustedCostFor( APawn* P, const FVector& StartToGoalDir, ANavigationPoint* Goal, INT Cost ); +#if __TW_PATHFINDING_ + virtual FPlane PathColor() + { + return FPlane( 0.89f, 0.565f, 0.294f, 1.f ); + } +#endif +} + + + +defaultproperties +{ +} diff --git a/Engine/Classes/CheatManager.uc b/Engine/Classes/CheatManager.uc new file mode 100644 index 0000000..61cf1a6 --- /dev/null +++ b/Engine/Classes/CheatManager.uc @@ -0,0 +1,1429 @@ +//============================================================================= +// CheatManager +// Object within playercontroller that manages "cheat" commands +// only spawned in single player mode +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= + +class CheatManager extends Object within PlayerController + dependson(AppNotificationsBase) + native; + +var localized string ViewingFrom; +var localized string OwnCamera; + +/** + * Finds the nearest pawn of the given class (excluding the owner's pawn) and + * plays the specified FaceFX animation. + */ +exec function FXPlay(class aClass, string FXAnimPath) +{ + local Pawn P, ClosestPawn; + local float ThisDistance, ClosestPawnDistance; + local string FxAnimGroup; + local string FxAnimName; + local int dotPos; + + if ( WorldInfo.NetMode == NM_Standalone ) + { + ClosestPawn = None; + ClosestPawnDistance = 10000000.0; + ForEach DynamicActors(class'Pawn', P) + { + if( ClassIsChildOf(P.class, aClass) && (P != PlayerController(Owner).Pawn) ) + { + ThisDistance = VSize(P.Location - PlayerController(Owner).Pawn.Location); + if(ThisDistance < ClosestPawnDistance) + { + ClosestPawn = P; + ClosestPawnDistance = ThisDistance; + } + } + } + + if( ClosestPawn.Mesh != none ) + { + dotPos = InStr(FXAnimPath, "."); + if( dotPos != -1 ) + { + FXAnimGroup = Left(FXAnimPath, dotPos); + FXAnimName = Right(FXAnimPath, Len(FXAnimPath) - dotPos - 1); +// WWISEMODIF_START, alessard, nov-28-2008, WwiseAudioIntegration + ClosestPawn.Mesh.PlayFaceFXAnim(None, FXAnimName, FXAnimGroup, none, none); +// WWISEMODIF_END + } + } + } +} + +/** + * Finds the nearest pawn of the given class (excluding the owner's pawn) and + * stops any currently playing FaceFX animation. + */ +exec function FXStop(class aClass) +{ + local Pawn P, ClosestPawn; + local float ThisDistance, ClosestPawnDistance; + + if ( WorldInfo.NetMode == NM_StandAlone ) + { + ClosestPawn = None; + ClosestPawnDistance = 10000000.0; + ForEach DynamicActors(class'Pawn', P) + { + if( ClassIsChildOf(P.class, aClass) && (P != PlayerController(Owner).Pawn) ) + { + ThisDistance = VSize(P.Location - PlayerController(Owner).Pawn.Location); + if(ThisDistance < ClosestPawnDistance) + { + ClosestPawn = P; + ClosestPawnDistance = ThisDistance; + } + } + } + + if( ClosestPawn.Mesh != none ) + { + ClosestPawn.Mesh.StopFaceFXAnim(); + } + } +} + +exec function DebugAI(optional coerce name Category); + +exec function EditAIByTrace() +{ + local Vector CamLoc; + local Rotator CamRot; + local Vector HitLocation, HitNormal; + local Pawn HitPawn; + local Controller C; + + GetPlayerViewPoint( CamLoc, CamRot ); + HitPawn = Pawn(Trace( HitLocation, HitNormal, CamLoc + Vector(CamRot) * 10000, CamLoc, TRUE, vect(10,10,10) )); + if( HitPawn != None ) + { + C = HitPawn.Controller; + if( C == None && HitPawn.DrivenVehicle != None ) + { + C = HitPawn.DrivenVehicle.Controller; + } + + if( C != None ) + { + ConsoleCommand( "EDITACTOR NAME="$C.Name, TRUE ); + } + } +} + +/** Dumps the pause state of the game */ +exec function DebugPause() +{ + WorldInfo.Game.DebugPause(); +} + +exec function ListDynamicActors() +{ +`if(`notdefined(FINAL_RELEASE)) + local Actor A; + local int i; + + ForEach DynamicActors(class'Actor',A) + { + i++; + `log(i@A); + } + `log("Num dynamic actors: "$i); +`endif +} + +exec function FreezeFrame(float delay) +{ + WorldInfo.Game.SetPause(Outer,Outer.CanUnpause); + WorldInfo.PauseDelay = WorldInfo.TimeSeconds + delay; +} + +exec function WriteToLog( string Param ) +{ + `log("NOW! "$Param); +} + +exec function KillViewedActor() +{ + if ( ViewTarget != None ) + { + if ( (Pawn(ViewTarget) != None) && (Pawn(ViewTarget).Controller != None) ) + Pawn(ViewTarget).Controller.Destroy(); + ViewTarget.Destroy(); + SetViewTarget(None); + } +} + +/* Teleport() +Teleport to surface player is looking at +*/ +exec function Teleport() +{ + local Actor HitActor; + local vector HitNormal, HitLocation; + local vector ViewLocation; + local rotator ViewRotation; + + GetPlayerViewPoint( ViewLocation, ViewRotation ); + + HitActor = Trace(HitLocation, HitNormal, ViewLocation + 1000000 * vector(ViewRotation), ViewLocation, true); + if ( HitActor != None) + HitLocation += HitNormal * 4.0; + + ViewTarget.SetLocation( HitLocation ); +} + +/* +Scale the player's size to be F * default size +*/ +exec function ChangeSize( float F ) +{ + Pawn.CylinderComponent.SetCylinderSize( Pawn.Default.CylinderComponent.CollisionRadius * F, Pawn.Default.CylinderComponent.CollisionHeight * F ); + Pawn.SetDrawScale(F); + Pawn.SetLocation(Pawn.Location); +} + +/* Stop interpolation +*/ +exec function EndPath() +{ +} + +exec function Amphibious() +{ + Pawn.UnderwaterTime = +999999.0; +} + +exec function Fly() +{ + if ( (Pawn != None) && Pawn.CheatFly() ) + { + ClientMessage("You feel much lighter"); + bCheatFlying = true; + Outer.GotoState('PlayerFlying'); + } +} + +exec function Walk() +{ + bCheatFlying = false; + if (Pawn != None && Pawn.CheatWalk()) + { + Restart(false); + } +} + +exec function Ghost() +{ + if ( (Pawn != None) && Pawn.CheatGhost() ) + { + bCheatFlying = true; + Outer.GotoState('PlayerFlying'); + } + else + { + bCollideWorld = false; + } + + ClientMessage("You feel ethereal"); +} + +/* AllAmmo + Sets maximum ammo on all weapons +*/ +exec function AllAmmo(); + +exec function God() +{ + if ( bGodMode ) + { + bGodMode = false; + ClientMessage("God mode off"); + return; + } + + bGodMode = true; + ClientMessage("God Mode on"); +} + +exec function Slomo( float T ) +{ + WorldInfo.Game.SetGameSpeed(T); +} + +exec function SetJumpZ( float F ) +{ + Pawn.JumpZ = F; +} + +exec function SetGravity( float F ) +{ + WorldInfo.WorldGravityZ = F; +} + +exec function SetSpeed( float F ) +{ + Pawn.GroundSpeed = Pawn.Default.GroundSpeed * f; + Pawn.WaterSpeed = Pawn.Default.WaterSpeed * f; +} + +exec function KillAll(class aClass) +{ + local Actor A; +`if(`notdefined(FINAL_RELEASE)) + local PlayerController PC; + + foreach WorldInfo.AllControllers(class'PlayerController', PC) + { + PC.ClientMessage("Killed all "$string(aClass)); + } +`endif + + if ( ClassIsChildOf(aClass, class'Pawn') ) + { + KillAllPawns(class(aClass)); + return; + } + ForEach DynamicActors(class 'Actor', A) + if ( ClassIsChildOf(A.class, aClass) ) + A.Destroy(); +} + +// Kill non-player pawns and their controllers +function KillAllPawns(class aClass) +{ + local Pawn P; + + ForEach DynamicActors(class'Pawn', P) + if ( ClassIsChildOf(P.Class, aClass) + && !P.IsPlayerPawn() ) + { + if ( P.Controller != None ) + P.Controller.Destroy(); + P.Destroy(); + } +} + +exec function KillPawns() +{ + KillAllPawns(class'Pawn'); +} + +/** + * Possess a pawn of the requested class + */ +exec function Avatar( name ClassName ) +{ + local Pawn P, TargetPawn, FirstPawn, OldPawn; + local bool bPickNextPawn; + + Foreach DynamicActors(class'Pawn', P) + { + if( P == Pawn ) + { + bPickNextPawn = TRUE; + } + else if( P.IsA(ClassName) ) + { + if( FirstPawn == None ) + { + FirstPawn = P; + } + + if( bPickNextPawn ) + { + TargetPawn = P; + break; + } + } + } + + // if we went through the list without choosing a pawn, pick first available choice (loop) + if( TargetPawn == None ) + { + TargetPawn = FirstPawn; + } + + if( TargetPawn != None ) + { + // detach TargetPawn from its controller and kill its controller. + TargetPawn.DetachFromController( TRUE ); + + // detach player from current pawn and possess targetpawn + if( Pawn != None ) + { + OldPawn = Pawn; + Pawn.DetachFromController(); + } + + Possess(TargetPawn, FALSE); + + // Spawn default controller for our ex-pawn (AI) + if( OldPawn != None ) + { + OldPawn.SpawnDefaultController(); + } + } + else + { + `log("Avatar: Couldn't find any Pawn to possess of class '" $ ClassName $ "'"); + } +} + +exec function Summon( string ClassName ) +{ + local class NewClass; + local vector SpawnLoc; + + `log( "Fabricate " $ ClassName ); + NewClass = class( DynamicLoadObject( ClassName, class'Class' ) ); + if( NewClass!=None ) + { + if ( Pawn != None ) + SpawnLoc = Pawn.Location; + else + SpawnLoc = Location; + Spawn( NewClass,,,SpawnLoc + 72 * Vector(Rotation) + vect(0,0,1) * 15 ); + } +} + +/** + * Give a specified weapon to the Pawn. + * If weapon is not carried by player, then it is created. + * Weapon given is returned as the function's return parmater. + */ +exec function Weapon GiveWeapon( String WeaponClassStr ) +{ + Local Weapon Weap; + local class WeaponClass; + + WeaponClass = class(DynamicLoadObject(WeaponClassStr, class'Class')); + Weap = Weapon(Pawn.FindInventoryType(WeaponClass)); + if( Weap != None ) + { + return Weap; + } + return Weapon(Pawn.CreateInventory( WeaponClass )); +} + +exec function PlayersOnly() +{ + if (WorldInfo.bPlayersOnly || WorldInfo.bPlayersOnlyPending) + { + WorldInfo.bPlayersOnly = false; + WorldInfo.bPlayersOnlyPending = false; + } + else + { + WorldInfo.bPlayersOnlyPending = !WorldInfo.bPlayersOnlyPending; + // WorldInfo.bPlayersOnly is set after next tick of UWorld::Tick + } +} + +exec function SuspendAI() +{ + WorldInfo.bSuspendAI = !WorldInfo.bSuspendAI; +} + +/** Util for fracturing meshes within an area of the player. */ +exec function DestroyFractures(optional float Radius) +{ + local FracturedStaticMeshActor FracActor; + + if(Radius == 0.0) + { + Radius = 256.0; + } + + foreach CollidingActors(class'FracturedStaticMeshActor', FracActor, Radius, Pawn.Location, TRUE) + { + if(FracActor.Physics == PHYS_None) + { + // Make sure the impacted fractured mesh is visually relevant + FracActor.BreakOffPartsInRadius(Pawn.Location, Radius, 500.0, TRUE); + } + } +} + +/** Util for ensuring at least one piece is broken of each FSM in level */ +exec function FractureAllMeshes() +{ + local FracturedStaticMeshActor FracActor; + + foreach AllActors(class'FracturedStaticMeshActor', FracActor) + { + FracActor.HideOneFragment(); + } +} + +/** This will break all Fractured meshes in the map in a way to maximize memory usage **/ +exec function FractureAllMeshesToMaximizeMemoryUsage() +{ + local FracturedStaticMeshActor FracActor; + + foreach AllActors(class'FracturedStaticMeshActor', FracActor) + { + FracActor.HideFragmentsToMaximizeMemoryUsage(); + } +} + + + +// *********************************************************** +// Navigation Aids (for testing) + +// remember spot for path testing (display path using ShowDebug) +exec function RememberSpot() +{ + if ( Pawn != None ) + SetDestinationPosition( Pawn.Location ); + else + SetDestinationPosition( Location ); +} + +// *********************************************************** +// Changing viewtarget + +exec function ViewSelf(optional bool bQuiet) +{ + Outer.ResetCameraMode(); + if ( Pawn != None ) + SetViewTarget(Pawn); + else + SetViewtarget(outer); + if (!bQuiet ) + ClientMessage(OwnCamera, 'Event'); + + FixFOV(); +} + +exec function ViewPlayer( string S ) +{ + local Controller P; + + foreach WorldInfo.AllControllers(class'Controller', P) + { + if ( P.bIsPlayer && (P.PlayerReplicationInfo.PlayerName ~= S ) ) + { + break; + } + } + + if ( P.Pawn != None ) + { + ClientMessage(ViewingFrom@P.PlayerReplicationInfo.PlayerName, 'Event'); + SetViewTarget(P.Pawn); + } +} + +exec function ViewActor( name ActorName) +{ + local Actor A; + + ForEach AllActors(class'Actor', A) + if ( A.Name == ActorName ) + { + SetViewTarget(A); + SetCameraMode('ThirdPerson'); + return; + } +} + +exec function ViewBot() +{ + local actor first; + local bool bFound; + local AIController C; + + foreach WorldInfo.AllControllers(class'AIController', C) + { + if (C.Pawn != None && C.PlayerReplicationInfo != None) + { + if (bFound || first == None) + { + first = C; + if (bFound) + { + break; + } + } + if (C.PlayerReplicationInfo == RealViewTarget) + { + bFound = true; + } + } + } + + if ( first != None ) + { + `log("view "$first); + SetViewTarget(first); + SetCameraMode( 'ThirdPerson' ); + FixFOV(); + } + else + ViewSelf(true); +} + +exec function ViewClass( class aClass ) +{ + local actor other, first; + local bool bFound; + + first = None; + + ForEach AllActors( aClass, other ) + { + if ( bFound || (first == None) ) + { + first = other; + if ( bFound ) + break; + } + if ( other == ViewTarget ) + bFound = true; + } + + if ( first != None ) + { + if ( Pawn(first) != None ) + ClientMessage(ViewingFrom@First.GetHumanReadableName(), 'Event'); + else + ClientMessage(ViewingFrom@first, 'Event'); + SetViewTarget(first); + FixFOV(); + } + else + ViewSelf(false); +} + +exec function Loaded() +{ + if( WorldInfo.Netmode!=NM_Standalone ) + return; + + AllWeapons(); + AllAmmo(); +} + +/* AllWeapons + Give player all available weapons +*/ +exec function AllWeapons() +{ + // subclass me +} + +/** streaming level debugging */ + +function SetLevelStreamingStatus(name PackageName, bool bShouldBeLoaded, bool bShouldBeVisible) +{ + local PlayerController PC; + local int i; + + if (PackageName != 'All') + { + foreach WorldInfo.AllControllers(class'PlayerController', PC) + { + PC.ClientUpdateLevelStreamingStatus(PackageName, bShouldBeLoaded, bShouldBeVisible, FALSE ); + } + } + else + { + foreach WorldInfo.AllControllers(class'PlayerController', PC) + { + for (i = 0; i < WorldInfo.StreamingLevels.length; i++) + { + PC.ClientUpdateLevelStreamingStatus(WorldInfo.StreamingLevels[i].PackageName, bShouldBeLoaded, bShouldBeVisible, FALSE ); + } + } + } +} + +exec function StreamLevelIn(name PackageName) +{ + SetLevelStreamingStatus(PackageName, true, true); +} + +exec function OnlyLoadLevel(name PackageName) +{ + SetLevelStreamingStatus(PackageName, true, false); +} + +exec function StreamLevelOut(name PackageName) +{ + SetLevelStreamingStatus(PackageName, false, false); +} + +exec function TestLevel() +{ + local Actor A, Found; + local bool bFoundErrors; + + ForEach AllActors(class'Actor', A) + { + bFoundErrors = bFoundErrors || A.CheckForErrors(); + if ( bFoundErrors && (Found == None) ) + Found = A; + } + + if ( bFoundErrors ) + { + `log("Found problem with "$Found); + assert(false); + } +} + +`if(`notdefined(FINAL_RELEASE)) +/** + * Logs the current session state for the game type and online layer + */ +exec function DumpOnlineSessionState() +{ + local int PlayerIndex; + + if (WorldInfo.NetMode != NM_Client) + { + `Log(""); + `Log("GameInfo state"); + `Log("-------------------------------------------------------------"); + `Log(""); + // Log game info data + `Log("Class: "$WorldInfo.Game.Class.Name); + // Log player count information + `Log(" MaxPlayersAllowed: "$WorldInfo.Game.MaxPlayersAllowed); + `Log(" MaxPlayers: "$WorldInfo.Game.MaxPlayers); + `Log(" NumPlayers: "$WorldInfo.Game.NumPlayers); + `Log(" MaxSpectatorsAllowed: "$WorldInfo.Game.MaxSpectatorsAllowed); + `Log(" MaxSpectators: "$WorldInfo.Game.MaxSpectators); + `Log(" NumSpectators: "$WorldInfo.Game.NumSpectators); + `Log(" NumBots: "$WorldInfo.Game.NumBots); + + `Log(" bUseSeamlessTravel: "$WorldInfo.Game.bUseSeamlessTravel); + `Log(" bRequiresPushToTalk: "$WorldInfo.Game.bRequiresPushToTalk); + `Log(" bHasNetworkError: "$WorldInfo.Game.bHasNetworkError); + + `Log(" OnlineGameSettingsClass: "$WorldInfo.Game.OnlineGameSettingsClass); + `Log(" OnlineStatsWriteClass: "$WorldInfo.Game.OnlineStatsWriteClass); + + `Log(" bUsingArbitration: "$WorldInfo.Game.bUsingArbitration); + if (WorldInfo.Game.bUsingArbitration) + { + `Log(" bHasArbitratedHandshakeBegun: "$WorldInfo.Game.bHasArbitratedHandshakeBegun); + `Log(" bNeedsEndGameHandshake: "$WorldInfo.Game.bNeedsEndGameHandshake); + `Log(" bIsEndGameHandshakeComplete: "$WorldInfo.Game.bIsEndGameHandshakeComplete); + `Log(" bHasEndGameHandshakeBegun: "$WorldInfo.Game.bHasEndGameHandshakeBegun); + `Log(" ArbitrationHandshakeTimeout: "$WorldInfo.Game.ArbitrationHandshakeTimeout); + `Log(" Number of pending arbitration PCs: "$WorldInfo.Game.PendingArbitrationPCs.Length); + // List who we are waiting of for arbitration + for (PlayerIndex = 0; PlayerIndex < WorldInfo.Game.PendingArbitrationPCs.Length; PlayerIndex++) + { + `Log(" Player: "$WorldInfo.Game.PendingArbitrationPCs[PlayerIndex].PlayerReplicationInfo.PlayerName$" PC ("$WorldInfo.Game.PendingArbitrationPCs[PlayerIndex].Name$")"); + } + `Log(" Number of arbitration PCs: "$WorldInfo.Game.ArbitrationPCs.Length); + // List all of the players that have completed arbitration + for (PlayerIndex = 0; PlayerIndex < WorldInfo.Game.ArbitrationPCs.Length; PlayerIndex++) + { + `Log(" Player: "$WorldInfo.Game.ArbitrationPCs[PlayerIndex].PlayerReplicationInfo.PlayerName$" PC ("$WorldInfo.Game.ArbitrationPCs[PlayerIndex].Name$")"); + } + } + } + // Log PRI player info + DebugLogPRIs(); + // Log the online session state + if (OnlineSub != None) + { + OnlineSub.DumpSessionState(); + } +} +`endif + +/** + * Changes the OS specific logging level + * + * @param DebugLevel the new debug level to use + */ +exec function SetOnlineDebugLevel(int DebugLevel) +{ + if (OnlineSub != None) + { + OnlineSub.SetDebugSpewLevel(DebugLevel); + } +} + +/** + * tries to path from the player's current position to the position the player is looking at + * + */ +exec function TestNavMeshPath(optional bool bDrawPath=TRUE) +{ + local actor HitActor; + local vector HitLoc,HitNorm, Start, End; + local rotator Rot; + + if(NavigationHandle == none) + { + NavigationHandle = new(outer) class'NavigationHandle'; + } + + GetPlayerViewPoint(Start,Rot); + End = Start + vector(rot) * 10000; + + HitActor = Trace(HitLoc,HitNorm,End,Start,false); + if(HitActor != none) + { + class'NavmeshPath_Toward'.static.TowardPoint(NavigationHandle,HitLoc); + class'NavMeshGoal_At'.static.AtLocation(NavigationHandle,HitLoc); + + NavigationHandle.bDebugConstraintsAndGoalEvals=true; + NavigationHandle.bUltraVerbosePathDebugging=TRUE; + if(NavigationHandle.FindPath()) + { + DrawDebugLine(HitLoc,Start,0,255,0,TRUE); + DrawDebugCoordinateSystem(HitLoc,rot(0,0,0),25.f,TRUE); + if(bDrawPath) + { + NavigationHandle.DrawPathCache(,true); + } + } + else + { + DrawDebugLine(HitLoc,Start,255,0,0,TRUE); + DrawDebugCoordinateSystem(HitLoc,rot(0,0,0),25.f,TRUE); + DrawDebugBox(Pawn.Location,Pawn.GetCollisionExtent(),255,0,0,TRUE); + } + } +} + +exec function TestPylonConnectivity() +{ + local Pylon Py; + foreach AllActors(class'Pylon',Py) + { + PY.VerifyTopLevelConnections(); + } +} + +exec function VerbosePathDebug() +{ + local vector HitLoc,HitNorm, Start, End; + local rotator Rot; + local Pawn P; + + GetPlayerViewPoint(Start,Rot); + End = Start + vector(rot) * 10000; + + foreach TraceActors(class'Pawn',P,HitLoc,HitNorm,End,Start,vect(1,1,1)) + { + Pawn.MessagePlayer("Verbosepathdebug trace hit"@P); + if(P != none && P.Controller != none) + { + P.Controller.NavigationHandle.bUltraVerbosePathDebugging=!P.Controller.NavigationHandle.bUltraVerbosePathDebugging; + } + } +} + +/** This is not an actor, so we need a stand in for PostBeginPlay */ +function InitCheatManager(); + + +/** + * This will have all PlaySound function calls emit a warnf so you can see that name of + * the soundcue being played. + **/ +exec native function LogPlaySoundCalls( bool bShouldLog ); + + +/** +* This will have all ActivateSystem function calls emit a warnf so you can see that name of +* the particlesystem being played. +**/ +exec native function LogParticleActivateSystemCalls( bool bShouldLog ); + +/** + * debug command, verifies that all path objects and path obstacls are valid + * (E.G.) that they haven't been deleted, but left registered + */ +exec native function VerifyNavMeshObjects(); + +/** + * debug command, will draw all edges that are not supported for the passed pawn class + */ +exec native function DrawUnsupportingEdges(coerce string PawnClassName); + +/** + * enables a timer to do periodic navmesh verification + */ +exec function NavMeshVerification(float interval=0.5) +{ + if(interval < 0) + { + ClearTimer(nameof(VerifyNavMeshObjects),outer); + } + else + { + SetTimer(interval,true,nameof(VerifyNavMeshObjects),outer); + } +} + +/** + * debug command, prints all navmesh pathobject edges + */ +exec native function PrintAllPathObjectEdges(); + +/** + * debug command, prints all active navmesh obstaces + */ +exec native function PrintNavMeshObstacles(); + +/** + * debug command, verifies all cover references + */ +exec native function VerifyNavMeshCoverRefs(); + +/** + * toggles AI logging + */ +exec function ToggleAILogging() +{ + local Engine Eng; + Eng = class'Engine'.static.GetEngine(); + if(Pawn != none) + { + if( Eng.bDisableAILogging ) + { + Pawn.MessagePlayer("OK! AI logging is now ON"); + } + else + { + Pawn.MessagePlayer("OK! AI logging is now OFF"); + } + } + + Eng.bDisableAILogging = !Eng.bDisableAILogging; + +} + +exec function DebugIniLocPatcher() +{ + if (OnlineSub != None && + OnlineSub.Patcher != None) + { + OnlineSub.Patcher.DownloadFiles(); + } +} + +exec function DebugDownloadTitleFile(string Filename, optional bool bFromCache) +{ + if (OnlineSub != None) + { + if (bFromCache) + { + if (OnlineSub.TitleFileCacheInterface != None) + { + `Log(`location @ "starting file load for"@Filename); + + OnlineSub.TitleFileCacheInterface.AddLoadTitleFileCompleteDelegate(OnLoadComplete); + OnlineSub.TitleFileCacheInterface.LoadTitleFile(Filename); + } + else + { + `Log(`location @ "OnlineTitleFileCacheInterface not supported"); + } + } + else + { + if (OnlineSub.TitleFileInterface != None) + { + `Log(`location @ "starting file download request for"@Filename); + + OnlineSub.TitleFileInterface.AddReadTitleFileCompleteDelegate(OnDownloadComplete); + OnlineSub.TitleFileInterface.ReadTitleFile(Filename); + } + else + { + `Log(`location @ "OnlineTitleFileInterface not supported"); + } + } + } +} +function OnDownloadComplete(bool bWasSuccessful,string Filename) +{ + OnlineSub.TitleFileInterface.ClearReadTitleFileCompleteDelegate(OnDownloadComplete); + + `Log(`location @ "download completed" + @"bWasSuccessful="$bWasSuccessful + @"FileName="$Filename); + + if (bWasSuccessful) + { + DebugSaveTitleFile(Filename); + } +} +function OnLoadComplete(bool bWasSuccessful,string FileName) +{ + OnlineSub.TitleFileCacheInterface.ClearLoadTitleFileCompleteDelegate(OnLoadComplete); + + `Log(`location @ "load completed" + @"bWasSuccessful="$bWasSuccessful + @"FileName="$Filename); + + DebugDownloadTitleFile(FileName,false); +} + +exec function DebugSaveTitleFile(string Filename) +{ + local array FileContents; + + if (OnlineSub != None) + { + if (OnlineSub.TitleFileInterface != None) + { + if (OnlineSub.TitleFileInterface.GetTitleFileContents(Filename, FileContents)) + { + `Log(`location @ "found file in download cache. using file contents from download cache:"@Filename); + } + else + { + `Log(`location @ "couldn't find file in download cache:"@Filename); + } + } + else + { + `Log(`location @ "OnlineTitleFileInterface not supported"); + } + + if (OnlineSub.TitleFileCacheInterface != None) + { + `Log(`location @ "starting file save for"@Filename); + + OnlineSub.TitleFileCacheInterface.AddSaveTitleFileCompleteDelegate(OnSaveComplete); + OnlineSub.TitleFileCacheInterface.SaveTitleFile(Filename, "TestName.ini", FileContents); + } + else + { + `Log(`location @ "OnlineTitleFileCacheInterface not supported"); + } + } +} +function OnSaveComplete(bool bWasSuccessful,string FileName) +{ + OnlineSub.TitleFileCacheInterface.ClearSaveTitleFileCompleteDelegate(OnSaveComplete); + + `Log(`location @ "save completed" + @"bWasSuccessful="$bWasSuccessful + @"FileName="$Filename); +} + +exec function DebugDeleteTitleFiles() +{ + if (OnlineSub != None) + { + if (OnlineSub.TitleFileCacheInterface != None) + { + `Log(`location @ "deleting all title files in cache dir"); + if (OnlineSub.TitleFileCacheInterface.DeleteTitleFiles(0)) + { + `Log(`location @ "delete succeeded"); + } + else + { + `Log(`location @ "cant delete. file ops in progress"); + } + } + else + { + `Log(`location @ "OnlineTitleFileCacheInterface not supported"); + } + } +} + +exec function DebugEmsDownload() +{ + if (OnlineSub != None && + OnlineSub.Patcher != None) + { + OnlineSub.Patcher.DownloadFiles(); + } +} + +/** + * debug command which prints out stats about memory usage by covernodes + */ +exec native function DumpCoverStats(); + +exec function DrawLocation(vector Loc) +{ + DrawDebugCoordinateSystem(Loc,rot(0,0,0),50.f,TRUE); +} + +exec function DrawLocationXYZ(float X, Float Y, float Z) +{ + local vector DrawSpot; + + DrawSpot.X = X; + DrawSpot.y = y; + DrawSpot.z = z; + DrawDebugCoordinateSystem(DrawSpot,rot(0,0,0),150.f,TRUE); +} + +/** + * Debug exec for scheduling a push notification + * + * @param MessageBody string to display in message box of notification + * @param SecondsFromNow seconds to elapse before triggering the notification + */ +exec function DebugNotification(string MessageBody, int SecondsFromNow) +{ + local AppNotificationsBase AppNotification; + local NotificationInfo NotificationInfo; + local NotificationMessageInfo MessageInfo; + + AppNotification = class'PlatformInterfaceBase'.static.GetAppNotificationsInterface(); + if (AppNotification != None) + { + NotificationInfo.BadgeNumber = 1; + NotificationInfo.MessageBody = MessageBody; + + MessageInfo.Key = "test key 1"; + MessageInfo.Value = "test val 1"; + NotificationInfo.MessageInfo.AddItem(MessageInfo); + + MessageInfo.Key = "test key 2"; + MessageInfo.Value = "test val 2"; + NotificationInfo.MessageInfo.AddItem(MessageInfo); + + `log(`location@"" + @" MessageBody="$MessageBody + @" SecondsFromNow="$SecondsFromNow); + + AppNotification.OnReceivedLocalNotification = OnReceivedLocalNotificationDebug; + AppNotification.ScheduleLocalNotification(NotificationInfo,SecondsFromNow); + } +} +/** + * Debug params from a local notification that was processed + */ +private function OnReceivedLocalNotificationDebug(const out NotificationInfo Notification, bool bWasAppActive) +{ + `log(`location@"bWasAppActive="$bWasAppActive); + class'PlatformInterfaceBase'.static.GetAppNotificationsInterface().DebugLogNotification(Notification); +} + +exec function DebugQueryUserFiles(string UserId) +{ + if (OnlineSub != None && + OnlineSub.UserCloudInterface != None) + { + OnlineSub.UserCloudInterface.AddEnumerateUserFileCompleteDelegate(OnEnumerateUserFilesComplete); + OnlineSub.UserCloudInterface.EnumerateUserFiles(UserId); + } +} + +private function OnEnumerateUserFilesComplete(bool bWasSuccessful,string UserId) +{ + OnlineSub.UserCloudInterface.ClearEnumerateUserFileCompleteDelegate(OnEnumerateUserFilesComplete); + + ConsoleCommand("obj dump" @OnlineSub.UserCloudInterface.Name); + + `log(`location@"" + $" bWasSuccessful="$bWasSuccessful + $" UserId="$UserId); +} + +exec function DebugWriteUserFile(string UserId, string FileName) +{ + local int Idx; + local array FileContents; + + if (OnlineSub != None && + OnlineSub.UserCloudInterface != None) + { + for (Idx=0; Idx < 1000; Idx++) + { + FileContents[Idx]=Idx; + } + OnlineSub.UserCloudInterface.AddWriteUserFileCompleteDelegate(OnWriteUserFileComplete); + OnlineSub.UserCloudInterface.WriteUserFile(UserId,FileName,FileContents); + } +} + +private function OnWriteUserFileComplete(bool bWasSuccessful,string UserId,string FileName) +{ + OnlineSub.UserCloudInterface.ClearWriteUserFileCompleteDelegate(OnWriteUserFileComplete); + + ConsoleCommand("obj dump" @OnlineSub.UserCloudInterface.Name); + + `log(`location@"" + $" bWasSuccessful="$bWasSuccessful + $" UserId="$UserId + $" FileName="$FileName); +} + +exec function DebugReadUserFile(string UserId, string FileName) +{ + if (OnlineSub != None && + OnlineSub.UserCloudInterface != None) + { + OnlineSub.UserCloudInterface.AddReadUserFileCompleteDelegate(OnReadUserFileComplete); + OnlineSub.UserCloudInterface.ReadUserFile(UserId,FileName); + } +} + +private function OnReadUserFileComplete(bool bWasSuccessful,string UserId,string FileName) +{ + local array FileContents; + + OnlineSub.UserCloudInterface.ClearReadUserFileCompleteDelegate(OnReadUserFileComplete); + OnlineSub.UserCloudInterface.GetFileContents(UserId,FileName,FileContents); + + ConsoleCommand("obj dump" @OnlineSub.UserCloudInterface.Name); + + `log(`location@"" + $" bWasSuccessful="$bWasSuccessful + $" UserId="$UserId + $" FileName="$FileName + $" FileContents="$FileContents.Length); +} + +exec function DebugDeleteUserFile(string UserId, string FileName) +{ + if (OnlineSub != None && + OnlineSub.UserCloudInterface != None) + { + OnlineSub.UserCloudInterface.AddDeleteUserFileCompleteDelegate(OnDeleteUserFileComplete); + OnlineSub.UserCloudInterface.DeleteUserFile(UserId,FileName,true,true); + } +} + +private function OnDeleteUserFileComplete(bool bWasSuccessful,string UserId,string FileName) +{ + OnlineSub.UserCloudInterface.ClearDeleteUserFileCompleteDelegate(OnDeleteUserFileComplete); + + ConsoleCommand("obj dump" @OnlineSub.UserCloudInterface.Name); + + `log(`location@"" + $" bWasSuccessful="$bWasSuccessful + $" UserId="$UserId + $" FileName="$FileName); +} + +defaultproperties +{ +} + +/** + * Simple function to illustrate the use of the HttpRequest system. + */ +exec function TestHttp(string Verb, string Payload, string URL, optional bool bSendParallelRequest) +{ + local HttpRequestInterface R; + + // create the request instance using the factory (which handles + // determining the proper type to create based on config). + R = class'HttpFactory'.static.CreateRequest(); + // always set a delegate instance to handle the response. + R.OnProcessRequestComplete = OnRequestComplete; + `log("Created request"); + // you can make many requests from one request object. + R.SetURL(URL); + // Default verb is GET + if (Len(Verb) > 0) + { + R.SetVerb(Verb); + } + else + { + `log("No Verb given, using the defaults."); + } + // Default Payload is empty + if (Len(Payload) > 0) + { + R.SetContentAsString(Payload); + } + else + { + `log("No payload given."); + } + `log("Creating request for URL:"@URL); + + // there is currently no way to distinguish keys that are empty from keys that aren't there. + `log("Key1 ="@R.GetURLParameter("Key1")); + `log("Key2 ="@R.GetURLParameter("Key2")); + `log("Key3NoValue ="@R.GetURLParameter("Key3NoValue")); + `log("NonexistentKey ="@R.GetURLParameter("NonexistentKey")); + // A header will not necessarily be present if you don't set one. Platform implementations + // may add things like Content-Length when you send the request, but won't necessarily + // be available in the Header. + `log("NonExistentHeader ="@R.GetHeader("NonExistentHeader")); + `log("CustomHeaderName ="@R.GetHeader("CustomHeaderName")); + `log("ContentType ="@R.GetContentType()); + `log("ContentLength ="@R.GetContentLength()); + `log("URL ="@R.GetURL()); + `log("Verb ="@R.GetVerb()); + + // multiple ProcessRequest calls can be made from the same instance if desired. + if (!R.ProcessRequest()) + { + `log("ProcessRequest failed. Unsuppress DevHttpRequest to see more details."); + } + else + { + `log("Request sent"); + } + // send off a parallel request for testing. + if (bSendParallelRequest) + { + if (!class'HttpFactory'.static.CreateRequest() + .SetURL("http://www.epicgames.com") + .SetVerb("GET") + .SetHeader("Test", "Value") + .SetProcessRequestCompleteDelegate(OnRequestComplete) + .ProcessRequest()) + { + `log("ProcessRequest for parallel request failed. Unsuppress DevHttpRequest to see more details."); + } + else + { + `log("Parallel Request sent"); + } + } +} + + +/** Delegate to use for HttpResponses. */ +function OnRequestComplete(HttpRequestInterface OriginalRequest, HttpResponseInterface Response, bool bDidSucceed) +{ + local array Headers; + local String Header; + local String Payload; + local int PayloadIndex; + + `log("Got response!!!!!!! Succeeded="@bDidSucceed); + `log("URL="@OriginalRequest.GetURL()); + // if we didn't succeed, we can't really trust the payload, so you should always really check this. + if (Response != None) + { + `log("ResponseURL="@Response.GetURL()); + `log("Response Code="@Response.GetResponseCode()); + Headers = Response.GetHeaders(); + foreach Headers(Header) + { + `log("Header:"@Header); + } + // GetContentAsString will make a copy of the payload to add the NULL terminator, + // then copy it again to convert it to TCHAR, so this could be fairly inefficient. + // This call also assumes the payload is UTF8 right now, as truly determining the encoding + // is content-type dependent. + // You also can't trust the content-length as you don't always get one. You should instead + // always trust the length of the content payload you receive. + Payload = Response.GetContentAsString(); + if (Len(Payload) > 1024) + { + PayloadIndex = 0; + `log("Payload:"); + while (PayloadIndex < Len(Payload)) + { + `log(" "@Mid(Payload, PayloadIndex, 1024)); + PayloadIndex = PayloadIndex + 1024; + } + } + else + { + `log("Payload:"@Payload); + } + } +} + +/** + * Debug function to send an arbitrary analytics event. + */ +exec function SendAnalyticsEvent(string EventName, optional string AttributeName, optional string AttributeValue) +{ + local AnalyticEventsBase Analytics; + + Analytics = class'PlatformInterfaceBase'.static.GetAnalyticEventsInterface(); + if (Len(AttributeName) > 0) + { + Analytics.LogStringEventParam(EventName, AttributeName, AttributeValue, false); + } + else + { + Analytics.LogStringEvent(EventName, false); + } +} + +/** + * Debug function to test analytic user events + */ +exec function SendAnalyticsUserAttributeEvent(string AttributeName, string AttributeValue) +{ + class'PlatformInterfaceBase'.static.GetAnalyticEventsInterface().LogUserAttributeUpdate(AttributeName, AttributeValue); +} + +/** + * Debug function to test analytic events + */ +exec function SendAnalyticsItemPurchaseEvent(string ItemId, string Currency, int PerItemCost, int ItemQuantity) +{ + class'PlatformInterfaceBase'.static.GetAnalyticEventsInterface().LogItemPurchaseEvent(ItemId, Currency, PerItemCost, ItemQuantity); +} + +/** + * Debug function to test analytic events + */ +exec function SendAnalyticsCurrencyPurchaseEvent(string GameCurrencyType, int GameCurrencyAmount, string RealCurrencyType, float RealMoneyCost, string PaymentProvider) +{ + class'PlatformInterfaceBase'.static.GetAnalyticEventsInterface().LogCurrencyPurchaseEvent(GameCurrencyType, GameCurrencyAmount, RealCurrencyType, RealMoneyCost, PaymentProvider); +} + +/** + * Debug function to test analytic events + */ +exec function SendAnalyticsCurrencyGivenEvent(string GameCurrencyType, int GameCurrencyAmount) +{ + class'PlatformInterfaceBase'.static.GetAnalyticEventsInterface().LogCurrencyGivenEvent(GameCurrencyType, GameCurrencyAmount); +} + +/** + * Debug function to test analytic events + */ +exec function SendAnalyticsCachedEvents() +{ + class'PlatformInterfaceBase'.static.GetAnalyticEventsInterface().SendCachedEvents(); +} + +/** + * Debug function to test analytic events + */ +exec function SetAnalyticsUserId(string UserId) +{ + class'PlatformInterfaceBase'.static.GetAnalyticEventsInterface().SetUserId(UserId); + `log("Analytics UserId set to:"@UserId); +} + +/** + * Debug function to test analytic events + */ +exec native function GetAnalyticsUserId(); + +/** + * Debug function to test analytic events + */ +exec function AnalyticsStartSession() +{ + class'PlatformInterfaceBase'.static.GetAnalyticEventsInterface().StartSession(); +} + +/** + * Debug function to test analytic events + */ +exec function AnalyticsEndSession() +{ + class'PlatformInterfaceBase'.static.GetAnalyticEventsInterface().EndSession(); +} diff --git a/Engine/Classes/ClipPadEntry.uc b/Engine/Classes/ClipPadEntry.uc new file mode 100644 index 0000000..98ccd8e --- /dev/null +++ b/Engine/Classes/ClipPadEntry.uc @@ -0,0 +1,24 @@ +/* epic =============================================== +* class ClipPadEntry +* +* A block of text that can be pasted into the level. + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ClipPadEntry extends Object + native + hidecategories(Object); + +/** User specified name */ +var() string Title; + +/** The text copied/pasted */ +var() string Text; + +cpptext +{ +} + +defaultproperties +{ + Title="Untitled" +} diff --git a/Engine/Classes/CloudSaveSystem.uc b/Engine/Classes/CloudSaveSystem.uc new file mode 100644 index 0000000..e60535f --- /dev/null +++ b/Engine/Classes/CloudSaveSystem.uc @@ -0,0 +1,654 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * An encapsulated system which utilizes CloudStorageBase to manage save data. + */ +class CloudSaveSystem extends Object + native; + +cpptext +{ +public: + void SerializeObject(class UObject* ObjectToSerialize, FMemoryWriter& MemoryWriter, int VersionNumber); + UObject* DeserializeObject(class UClass* ObjectClass, FMemoryReader MemoryReader, BYTE VersionSupport, int VersionNumber); +}; +//============================================================================== +const NUM_SAVE_SLOTS_KEY = "NumSaveSlots"; +const DATA_STORE_ID_KEY = "DataStoreID"; +const SAVE_DATA_BLOB_NAME_KEY = "DataBlobName"; +const SAVE_SYSTEM_VERSION_KEY = "CloudSaveSystemVersion"; +const COMMON_DATA_SAVE_SLOT_INDEX = -1; + +const GET_SAVE_SLOT_ERROR =-2; +const GET_SAVE_SLOT_INVALID = -1; + +enum SaveDataVersionSupport +{ + SaveDataVersionSupportLessThenEqual, + SaveDataVersionSupportEqual, + SaveDataVersionSupportAny, +}; + +//============================================================================== +var private transient CloudSaveSystemKVSInterface KeyValueStore; +var private transient CloudSaveSystemDataBlobStoreInterface DataBlobStore; +//============================================================================== +struct native GetSaveDataCallbackStruct +{ + var int SlotIndex; + var delegate Callback; +}; +var private transient array OnGetSaveDataCallbacks; + +struct native SetSaveDataCallbackStruct +{ + var int SlotIndex; + var delegate Callback; +}; +var private transient array OnSetSaveDataCallbacks; + +var private transient delegate DeleteSaveDataCallback; +var private transient int ActiveSlotForDelete; + +enum SaveSlotOperationEnum +{ + SSO_SET, + SSO_GET, + SSO_DELETE +}; +struct native SaveSlotOperation +{ + var int SlotIndex; + var SaveSlotOperationEnum SlotOperation; +}; +var private transient array ActiveSaveSlotOperations; + +//============================================================================== +delegate OnGetSaveDataCallback(bool bWasSuccessful, int SaveSlot, out array DataBlob, string Error); +delegate SaveSystemCallback(bool bWasSuccessful, int SaveSlot, string Error); +//============================================================================== + +//============================================================================== +//Utility Functions +//============================================================================== +//Returns the number of save slots. +final function bool GetNumberOfSaveSlots(out int NumSaveSlots) +{ + local PlatformInterfaceDelegateResult KVRes; + local bool RValue; + + RValue = false; + if (KeyValueStore != None && DataBlobStore != None) + { + //NumSaveSlots is slot agnostic so save to slot 0 for default name generation + KeyValueStore.ReadKeyValue(COMMON_DATA_SAVE_SLOT_INDEX, NUM_SAVE_SLOTS_KEY, PIDT_Int, KVRes); + if (KVRes.bSuccessful) + { + RValue = true; + NumSaveSlots = KVRes.Data.IntValue; + } + } + + return RValue; +} + +//Returns -1 on no match, slot index on match and -2 on error. +final function private int DoesSaveSlotKeyValueDataAlreadyExist(string DataStoreID, string DataBlobName) +{ + local int SaveSlotScan; + local int NumSaveSlots; + local string CompareDataStoreID; + local string CompareDataBlobName; + local int RValue; + + RValue = GET_SAVE_SLOT_INVALID; + + if (KeyValueStore != None && DataBlobStore != None && GetNumberOfSaveSlots(NumSaveSlots)) + { + for (SaveSlotScan = 0; SaveSlotScan < NumSaveSlots; ++SaveSlotScan) + { + if (GetDataStoreIDAndBlobNameForSaveSlot(SaveSlotScan, CompareDataStoreID, CompareDataBlobName)) + { + if (DataStoreID == CompareDataStoreID && DataBlobName == CompareDataBlobName) + { + RValue = SaveSlotScan; + break; + } + } + else + { + //Set error code + RValue = GET_SAVE_SLOT_ERROR; + } + } + + } + else + { + //Set error code + RValue = GET_SAVE_SLOT_ERROR; + } + + return RValue; +} + +final private function bool WriteNumSaveSlots(int NumSaveSlots) +{ + local PlatformInterfaceData KVSet; + + KVSet.IntValue = NumSaveSlots; + KVSet.Type = PIDT_Int; + if (KeyValueStore.WriteKeyValue(COMMON_DATA_SAVE_SLOT_INDEX, NUM_SAVE_SLOTS_KEY, KVSet)) + { + return true; + } + + return false; +} + +final function bool IsOperationActiveForSlot(int SlotIndex) +{ + local int Index; + Index = ActiveSaveSlotOperations.Find('SlotIndex', SlotIndex); + if (Index == INDEX_NONE) + { + return false; + } + else + { + return true; + } +} + +final function bool IsDeleteOperationActive() +{ + if (ActiveSlotForDelete == -1) + { + return false; + } + else + { + return true; + } +} + +final function bool AreAnySlotOperationsActive() +{ + if (ActiveSaveSlotOperations.Length > 0) + { + return true; + } + else + { + return false; + } +} + +//============================================================================== +//Native Functions +//============================================================================== +native final function SerializeObject(Object ObjectToSerialize, out array Data, int DataVersion); +//Will return none if the version of the data isn't supported +native final function Object DeserializeObject(class ObjectClass, out array Data, SaveDataVersionSupport VersionSupport, int DataVersion); + +//============================================================================== +//Init Functions +//============================================================================== + +//Initializes the CloudSaveSystem into a usable state +final function Init(CloudSaveSystemKVSInterface InKeyValueStore, CloudSaveSystemDataBlobStoreInterface InDataBlobStore, int VersionNumber) +{ + local PlatformInterfaceDelegateResult SaveSystemVersionNumber; + local PlatformInterfaceData SaveSystemVersionNumberSet; + + KeyValueStore = InKeyValueStore; + DataBlobStore = InDataBlobStore; + + GetKeyValue(COMMON_DATA_SAVE_SLOT_INDEX, SAVE_SYSTEM_VERSION_KEY, PIDT_Int, SaveSystemVersionNumber); + if (!SaveSystemVersionNumber.bSuccessful || SaveSystemVersionNumber.Data.IntValue != VersionNumber) + { + SaveSystemVersionNumberSet.IntValue = VersionNumber; + SaveSystemVersionNumberSet.Type = PIDT_Int; + SetKeyValue(COMMON_DATA_SAVE_SLOT_INDEX, SAVE_SYSTEM_VERSION_KEY, SaveSystemVersionNumberSet); + + WriteNumSaveSlots(0); + } +} + +//============================================================================== +//Data Retrieval +//============================================================================== +//Starts an async request that retrieves the save data blob for the given save slot. +//Save slot indexing is zero based. +final function GetSaveData(int SaveSlot, delegate OnGetSaveDataCallback) +{ + local string DataStoreID; + local GetSaveDataCallbackStruct CallbackStruct; + local SaveSlotOperation SlotOperation; + local array EmptyBuffer; + local string BlobName; + local bool ErrorOccured; + local string Error; + + ErrorOccured = true; + + if (KeyValueStore == None) + { + Error="GetSaveData::KeyValueStore instance cannot be None"; + } + else if (DataBlobStore == None) + { + Error="GetSaveData::DataBlobStore instance cannot be None"; + } + else if (OnGetSaveDataCallbacks.Find('SlotIndex', SaveSlot) != INDEX_NONE) + { + Error="GetSaveData::OnGetSaveDataCallback already present for save slot"; + } + else if (ActiveSaveSlotOperations.Find('SlotIndex', SaveSlot) != INDEX_NONE) + { + Error="GetSaveData::Save System operation already active for save slot"; + } + else if (IsDeleteOperationActive()) + { + Error="GetSaveData::Delete Operation active cannot GetSaveData"; + } + else if (!GetDataStoreIDAndBlobNameForSaveSlot(SaveSlot, DataStoreID, BlobName)) + { + Error="GetSaveData::Failed to get store id and data blob name for save slot"; + } + else + { + CallbackStruct.SlotIndex = SaveSlot; + CallbackStruct.Callback = OnGetSaveDataCallback; + OnGetSaveDataCallbacks.AddItem(CallbackStruct); + + SlotOperation.SlotIndex = SaveSlot; + SlotOperation.SlotOperation = SSO_GET; + ActiveSaveSlotOperations.AddItem(SlotOperation); + + DataBlobStore.GetDataBlob(DataStoreID, BlobName, OnGetSaveDataComplete); + + ErrorOccured = false; + } + + + if (ErrorOccured && OnGetSaveDataCallback != None) + { + OnGetSaveDataCallback(false/*bWasSuccessful*/, SaveSlot, EmptyBuffer, Error); + } +} + +final function private OnGetSaveDataComplete(bool bWasSuccessful, string StorageID, string BlobName, out array DataBlob, string Error) +{ + local int SaveSlotIndex; + local int Index; + local delegate LocalCallback; + + SaveSlotIndex = DoesSaveSlotKeyValueDataAlreadyExist(StorageID, BlobName); + if (SaveSlotIndex >= 0) + { + + //---------------------------------------------------------------------- + Index = ActiveSaveSlotOperations.Find('SlotIndex', SaveSlotIndex); + if (Index != INDEX_NONE) + { + if(ActiveSaveSlotOperations[Index].SlotOperation != SSO_GET) + { + bWasSuccessful = false; + Error = "CloudSaveSystem in corrupt stat GetSaveData request finished but active slot operation should have been"@ActiveSaveSlotOperations[Index].SlotOperation; + } + ActiveSaveSlotOperations.Remove(Index, 1); + } + else + { + bWasSuccessful = false; + Error = "CloudSaveSystem in corrupt state GetData request finished but was not correctly internally tracked."; + } + + Index = OnGetSaveDataCallbacks.Find('SlotIndex', SaveSlotIndex); + if (Index != INDEX_NONE) + { + LocalCallback = OnGetSaveDataCallbacks[Index].Callback; + LocalCallback(bWasSuccessful, SaveSlotIndex, DataBlob, "Unknown Error loading data blob from Cloud"); + OnGetSaveDataCallbacks.Remove(Index, 1); + } + } + else + { + `warn("CloudSaveSystem in corrupt sate. save slot index does not exist for ID:"@StorageID@"BlobName:"@BlobName); + } +} + +//============================================================================== +//Data Saving +//============================================================================== +//Sets the save data blob for the given save slot. Save slot indexing is zero based. +final function SetSaveData(int SaveSlot, delegate InSetSaveDataCallback, const out array SaveDataBlob) +{ + local SetSaveDataCallbackStruct CallbackStruct; + local SaveSlotOperation SlotOperation; + local string DataStoreID; + local string BlobName; + local bool ErrorOccured; + local string Error; + + + ErrorOccured = true; + if (KeyValueStore == None) + { + Error="SetSaveData::KeyValueStore instance cannot be None"; + } + else if (DataBlobStore == None) + { + Error="SetSaveData::DataBlobStore instance cannot be None"; + } + else if (OnSetSaveDataCallbacks.Find('SlotIndex', SaveSlot) != INDEX_NONE) + { + Error="SetSaveData::OnSetSaveDataCallback already present for save slot"; + } + else if (ActiveSaveSlotOperations.Find('SlotIndex', SaveSlot) != INDEX_NONE) + { + Error="SetSaveData::Save System operation already active for save slot"; + } + else if (IsDeleteOperationActive()) + { + Error="SetSaveData::Delete Operation active cannot SetSaveData"; + } + else if (!GetDataStoreIDAndBlobNameForSaveSlot(SaveSlot, DataStoreID, BlobName)) + { + Error="SetSaveData::Failed to get store id and data blob name for save slot"; + } + else + { + CallbackStruct.SlotIndex = SaveSlot; + CallbackStruct.Callback = InSetSaveDataCallback; + OnSetSaveDataCallbacks.AddItem(CallbackStruct); + + SlotOperation.SlotIndex = SaveSlot; + SlotOperation.SlotOperation = SSO_SET; + ActiveSaveSlotOperations.AddItem(SlotOperation); + + ErrorOccured = false; + + DataBlobStore.SetDataBlob(DataStoreID, BlobName, SaveDataBlob, OnSetSaveDataComplete); + } + + if (ErrorOccured && InSetSaveDataCallback != None) + { + InSetSaveDataCallback(false/*bWasSuccesfful*/, SaveSlot, Error); + } +} + +final function private OnSetSaveDataComplete(bool bWasSucessfull, string StorageID, string BlobName, string Error) +{ + local int SaveSlotIndex; + local int Index; + local delegate LocalCallback; + + SaveSlotIndex = DoesSaveSlotKeyValueDataAlreadyExist(StorageID, BlobName); + if (SaveSlotIndex >= 0) + { + //---------------------------------------------------------------------- + Index = ActiveSaveSlotOperations.Find('SlotIndex', SaveSlotIndex); + if (Index != INDEX_NONE) + { + if(ActiveSaveSlotOperations[Index].SlotOperation != SSO_SET) + { + Error = "CloudSaveSystem in corrupt stat Set Data request finished but active slot operation should have been"@ActiveSaveSlotOperations[Index].SlotOperation; + bWasSucessfull = false; + } + ActiveSaveSlotOperations.Remove(Index, 1); + } + else + { + bWasSucessfull = false; + Error = "CloudSaveSystem in corrupt state Set Data request finished but was not correctly internally tracked."; + } + + //---------------------------------------------------------------------- + Index = OnSetSaveDataCallbacks.Find('SlotIndex', SaveSlotIndex); + if (Index != INDEX_NONE) + { + LocalCallback = OnSetSaveDataCallbacks[Index].Callback; + LocalCallback(bWasSucessfull, SaveSlotIndex, Error); + OnSetSaveDataCallbacks.Remove(Index, 1); + } + } + else + { + `warn("CloudSaveSystem in corrupt sate. Save slot index does not exist for ID:"@StorageID@"BlobName:"@BlobName); + } +} + +//============================================================================== +//Data Deletion +//============================================================================== +final function bool DeleteSaveData(int SaveSlot, delegate InDeleteSaveDataCallback ) +{ + local string DataStoreID; + local string BlobName; + local SaveSlotOperation SlotOperation; + local bool RValue; + + RValue = false; + if (KeyValueStore != None && DataBlobStore != None + && DeleteSaveDataCallback == None + && !AreAnySlotOperationsActive() + && !IsDeleteOperationActive()) + { + if(GetDataStoreIDAndBlobNameForSaveSlot(SaveSlot, DataStoreID, BlobName)) + { + RValue = DataBlobStore.DeleteDataBlob(DataStoreID, BlobName,OnDeleteSaveDataComplete); + if (RValue) + { + DeleteSaveDataCallback = InDeleteSaveDataCallback; + ActiveSlotForDelete = SaveSlot; + + SlotOperation.SlotIndex = SaveSlot; + SlotOperation.SlotOperation = SSO_DELETE; + ActiveSaveSlotOperations.AddItem(SlotOperation); + } + } + } + + return RValue; +} + +final function OnDeleteSaveDataComplete(bool bWasSucessfull, string StorageID, string BlobName, string Error) +{ + local delegate Callback; + local int Scan; + local int Index; + local int SlotDeleted; + local int NumSaveSlots; + + local string DataStoreID; + local string DataBlobName; + + if (bWasSucessfull) + { + if(!GetNumberOfSaveSlots(NumSaveSlots)) + { + bWasSucessfull = false; + Error = "Could not retrieve number of save slots during slot deletion. Save system in corrupt state."; + } + else + { + for (Scan = ActiveSlotForDelete+1; Scan < NumSaveSlots && bWasSucessfull; ++Scan) + { + if(!GetDataStoreIDAndBlobNameForSaveSlot(Scan, DataStoreID, DataBlobName)) + { + bWasSucessfull = false; + Error = "Error retrieving DataStoreID and DataBlobName during slot deletion. Save system in corrupt state."; + } + else if (!InternalSetSaveSlotKeyValues(Scan-1, DataStoreID, DataBlobName)) + { + bWasSucessfull = false; + Error = "Error migrating DataStoreID and DataBlobName to new slot during slot deletion. Save system in corrupt state."; + } + } + if (bWasSucessfull) + { + NumSaveSlots--; + if(!WriteNumSaveSlots(NumSaveSlots)) + { + bWasSucessfull = false; + Error = "Error writing number of save slot to Cloud KVS"; + } + } + } + } + + //-------------------------------------------------------------------------- + SlotDeleted = ActiveSlotForDelete; + ActiveSlotForDelete = -1; + + //-------------------------------------------------------------------------- + Index = ActiveSaveSlotOperations.Find('SlotIndex', SlotDeleted); + if (Index != INDEX_NONE) + { + if(ActiveSaveSlotOperations[Index].SlotOperation != SSO_DELETE) + { + `warn("CloudSaveSystem in corrupt stat DeleteSaveData request finished but active slot operation should have been"@ActiveSaveSlotOperations[Index].SlotOperation); + } + ActiveSaveSlotOperations.Remove(Index, 1); + } + else + { + `warn("CloudSaveSystem in corrupt state DeleteSaveData request finished but was not correctly internally tracked."); + } + + //-------------------------------------------------------------------------- + if (DeleteSaveDataCallback != None) + { + Callback = DeleteSaveDataCallback; + DeleteSaveDataCallback = None; + Callback(bWasSucessfull, SlotDeleted, Error); + } + +} +//============================================================================== +//Key Value Sets +//============================================================================== +//Sets the key values for a given save slot. If the save slot exists the data will be +//overwritten, otherwise a new slot will be created +final function bool SetSaveSlotKeyValues(string DataStoreID, string SaveDataBlobName, out int SaveSlot) +{ + local bool RValue; + local int NumSaveSlots; + local bool IncSlotCount; + + RValue = false; + IncSlotCount = false; + + if (KeyValueStore != None && DataBlobStore != None && GetNumberOfSaveSlots(NumSaveSlots)) + { + + SaveSlot = DoesSaveSlotKeyValueDataAlreadyExist(DataStoreID, SaveDataBlobName); + //Error retrieving result do not change stored data + if (SaveSlot == GET_SAVE_SLOT_ERROR) + { + return false; + } + else if (SaveSlot == GET_SAVE_SLOT_INVALID) + { + //No matching data found + SaveSlot = NumSaveSlots; + IncSlotCount = true; + } + + if(InternalSetSaveSlotKeyValues(SaveSlot, DataStoreID, SaveDataBlobName)) + { + if (IncSlotCount) + { + NumSaveSlots++; + if (WriteNumSaveSlots(NumSaveSlots)) + { + RValue = true; + } + } + else + { + RValue = true; + } + } + } + + return RValue; +} + +final private function bool InternalSetSaveSlotKeyValues(int SaveSlot, string DataStoreID, string SaveDataBlobName) +{ + local PlatformInterfaceData KVSet; + local bool RValue; + + RValue = false; + + KVSet.StringValue = DataStoreID; + KVSet.Type = PIDT_String; + if(KeyValueStore.WriteKeyValue(SaveSlot, DATA_STORE_ID_KEY, KVSet)) + { + KVSet.StringValue = SaveDataBlobName; + KVSet.Type = PIDT_String; + if(KeyValueStore.WriteKeyValue(SaveSlot, SAVE_DATA_BLOB_NAME_KEY, KVSet)) + { + RValue = true; + } + } + + return RValue; +} + +final function bool SetKeyValue(int SaveSlot, string KeyName, const out PlatformInterfaceData Value) +{ + if (KeyValueStore == None) + { + return false; + } + + return KeyValueStore.WriteKeyValue(SaveSlot, KeyName, Value); +} + +//============================================================================== +//Key Value Gets +//============================================================================== +//Populates DataStoreID and DataBlobName with the data stored in the Key Value Store +final function private bool GetDataStoreIDAndBlobNameForSaveSlot(int SaveSlot, out string DataStoreID, out string DataBlobName) +{ + + local PlatformInterfaceDelegateResult KVRes; + local bool RValue; + + RValue = false; + if (KeyValueStore != None || DataBlobStore != None) + { + KeyValueStore.ReadKeyValue(SaveSlot, DATA_STORE_ID_KEY, PIDT_String, KVRes); + if (KVRes.bSuccessful) + { + DataStoreID = KVRes.Data.StringValue; + KeyValueStore.ReadKeyValue(SaveSlot, SAVE_DATA_BLOB_NAME_KEY, PIDT_String, KVRes); + if (KVRes.bSuccessful) + { + DataBlobName = KVRes.Data.StringValue; + RValue = true; + } + } + } + + return RValue; +} + +final function bool GetKeyValue(int SaveSlot, string KeyName, EPlatformInterfaceDataType Type, out PlatformInterfaceDelegateResult Value) +{ + if (KeyValueStore == None) + { + return false; + } + + return KeyValueStore.ReadKeyValue(SaveSlot, KeyName, Type, Value); +} + +DefaultProperties +{ + ActiveSlotForDelete = -1 +} \ No newline at end of file diff --git a/Engine/Classes/CloudSaveSystemDataBlobStoreInterface.uc b/Engine/Classes/CloudSaveSystemDataBlobStoreInterface.uc new file mode 100644 index 0000000..b2c7862 --- /dev/null +++ b/Engine/Classes/CloudSaveSystemDataBlobStoreInterface.uc @@ -0,0 +1,37 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * An interface for data blog storing withing the context of the CloudSaveSystem + */ +interface CloudSaveSystemDataBlobStoreInterface; + +/** +*Delegate signature for callback on GetDataBlob requests. +*/ +delegate GetDataBlobCallbackDelegate(bool bWasSuccessful, string StorageID, string BlobName, const out array DataBlob, string Error); + +/** +*Starts an Async request to get a data blob. All delegates set by SetGetDataBlobCompleteDelegate will be notified on completion +* +**/ +function GetDataBlob(string StorageID, string BlobName, delegate OnGetDataBlobComplete); + +/** +*Delegate signature for callback on SetDataBlob requests. +*/ +delegate SetDataBlobCallbackDelegate(bool bWasSucessfull, string StorageID, string BlobName, string Error); + +/** +*Starts an Async request to set blob data. All delegates set by SetSetDataBlobCompleteDelegate will be notified on completion +*/ +function SetDataBlob(string StorageID, string BlobName, const out array DataBlob, delegate InSetDataBlobCallback); + +/** +*Delegate signature for callback on SetDataBlob requests. +*/ +private delegate DeleteDataBlobCallbackDelegate(bool bWasSucessfull, string StorageID, string BlobName, string Error); + +/** +*Starts an Async delete of the data blob +*/ +function bool DeleteDataBlob(string StorageID, string BlobName, delegate InDeleteDataBlobCallback); diff --git a/Engine/Classes/CloudSaveSystemKVSInterface.uc b/Engine/Classes/CloudSaveSystemKVSInterface.uc new file mode 100644 index 0000000..06c86aa --- /dev/null +++ b/Engine/Classes/CloudSaveSystemKVSInterface.uc @@ -0,0 +1,12 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * An interface for a Key Value Store system within the context of the CloudSaveSystem + */ +interface CloudSaveSystemKVSInterface; + +/**Reads a value from the KVS. KeyNames can overlap across save slots*/ +function bool ReadKeyValue(int SaveSlotIndex, string KeyName, EPlatformInterfaceDataType Type, out PlatformInterfaceDelegateResult Value); + +/**Writes a value to the KVS. KeyNames can overlap across save slots*/ +function bool WriteKeyValue(int SaveSlotIndex, string KeyName, const out PlatformInterfaceData Value); \ No newline at end of file diff --git a/Engine/Classes/CloudStorageBase.uc b/Engine/Classes/CloudStorageBase.uc new file mode 100644 index 0000000..2f3d736 --- /dev/null +++ b/Engine/Classes/CloudStorageBase.uc @@ -0,0 +1,244 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * This is the base class for the various platform interface classes + */ + +class CloudStorageBase extends PlatformInterfaceBase + native(PlatformInterface); + + +/** All the types of delegate callbacks that a CloudStorage subclass may receive from C++ */ +enum ECloudStorageDelegate +{ + // @todo: Fill in the result descriptions for these guys (and the other PI subclasses) + CSD_KeyValueReadComplete, + CSD_KeyValueWriteComplete, + CSD_ValueChanged, + CSD_DocumentQueryComplete, + CSD_DocumentReadComplete, + CSD_DocumentWriteComplete, + + // Data:Document index that has the conflict + // Type:Int + // Desc:Called when multiple machines have + // updated the document, and script needs to determine which one to use, via the Resolve* + // functions + CSD_DocumentConflictDetected, +}; + +/** When using local storage (aka "cloud emulation"), this maintains a list of the file paths */ +var array LocalCloudFiles; + +/** If TRUE, delegate callbacks should be skipped */ +var bool bSuppressDelegateCalls; + +/** + * Perform any initialization + */ +native event Init(); + +/** + * @return True if we are actually using local cloud storage emulation + */ +native function bool IsUsingLocalStorage(); + +/** + * Initiate reading a key/value pair from cloud storage. + * + * @param KeyName String name of the key to retrieve + * @param Type Type of data to retrieve + * @param Result The resulting value of the key we just read (supports multiple types of value) + * + * @return True if successful + */ +native event bool ReadKeyValue(string KeyName, EPlatformInterfaceDataType Type, out PlatformInterfaceDelegateResult Value); + +/** +* Reads a key/value pair from the local backup of the cloud KVS storage +* to aid in conflict resolution +* +* @param KeyName String name of the key to retrieve +* @param Type Type of data to retrieve +* @param Result The resulting value of the key we just read (supports multiple types of value) +* +* @return True if successful +*/ +native event bool ReadKeyValueFromLocalStore(string KeyName, EPlatformInterfaceDataType Type, out PlatformInterfaceDelegateResult Value); + +/** + * Write a key/value pair to the cloud. + * + * @param KeyName String name of the key to write + * @param Value The type and value to write + * + * @return True if successful + */ +native event bool WriteKeyValue(string KeyName, const out PlatformInterfaceData Value); + + +/** + * Kick off an async query of documents that exist in the cloud. If any documents have + * already been retrieved, this will flush those documents, and refresh the set. A + * CSD_DocumentQueryComplete delegate will be called when it completes (if this + * function returns true). Then use GetNumCloudDocuments() and GetCloudDocumentName() + * to get the information about any existing documents. + * + * @return True if successful + */ +native event bool QueryForCloudDocuments(); + +/** + * @return the number of documents that are known to exist in the cloud + */ +native event int GetNumCloudDocuments(optional bool bIsForConflict); + +/** + * @return the name of the given cloud by index (up to GetNumCloudDocuments() - 1) + */ +native event string GetCloudDocumentName(int Index); + +/** + * Create a new document in the cloud (uninitialized, unsaved, use the Write/Save functions) + * + * @param Filename Filename for the cloud document (with any extension you want) + * + * @return Index of the new document, or -1 on failure + */ +native event int CreateCloudDocument(string Filename); + +/** + * Removes all of the files in the LocalCloudFiles array. + */ +native event DeleteAllCloudDocuments(); + +/** + * Reads a document into memory (or whatever is needed so that the ParseDocumentAs* functions + * operate synchronously without stalling the game). A CSD_DocumentReadComplete delegate + * will be called (if this function returns true). + * + * @param Index index of the document to read + * + * @param True if successful + */ +native event bool ReadCloudDocument(int Index, optional bool bIsForConflict); + +/** + * Once a document has been read in, use this to return a string representing the + * entire document. This should only be used if SaveDocumentWithString was used to + * generate the document. + * + * @param Index index of the document to read + * + * @return The document as a string. It will be empty if anything went wrong. + */ +native event string ParseDocumentAsString(int Index, optional bool bIsForConflict); + +/** + * Once a document has been read in, use this to return a string representing the + * entire document. This should only be used if SaveDocumentWithString was used to + * generate the document. + * + * @param Index index of the document to read + * @param ByteData The array of bytes to be filled out. It will be empty if anything went wrong + */ +native event ParseDocumentAsBytes(int Index, out array ByteData, optional bool bIsForConflict); + +/** + * Once a document has been read in, use this to return a string representing the + * entire document. This should only be used if SaveDocumentWithString was used to + * generate the document. + * + * @param Index index of the document to read + * @param ExpectedVersion Version number expected to be in the save data. If this doesn't match what's there, this function will return NULL + * @param ObjectClass The class of the object to create + * + * @return The object deserialized from the document. It will be none if anything went wrongs + */ +native event object ParseDocumentAsObject(int Index, class ObjectClass, int ExpectedVersion, optional bool bIsForConflict); + + + + +/** + * Writes a document that has been already "saved" using the SaveDocumentWith* functions. + * A CSD_DocumentWriteComplete delegate will be called (if this function returns true). + * + * @param Index index of the document to read + * + * @param True if successful + */ +native event bool WriteCloudDocument(int Index); + +/** + * Prepare a document for writing to the cloud with a string as input data. This is + * synchronous + * + * @param Index index of the document to save + * @param StringData The data to put into the document + * + * @param True if successful + */ +native event bool SaveDocumentWithString(int Index, string StringData); + +/** + * Prepare a document for writing to the cloud with an array of bytes as input data. This is + * synchronous + * + * @param Index index of the document to save + * @param ByteData The array of generic bytes to put into the document + * + * @param True if successful + */ +native event bool SaveDocumentWithBytes(int Index, array ByteData); + +/** + * Prepare a document for writing to the cloud with an object as input data. This is + * synchronous + * + * @param Index index of the document to save + * @param ObjectData The object to serialize to bytes and put into the document + * + * @param True if successful + */ +native event bool SaveDocumentWithObject(int Index, object ObjectData, int SaveVersion); + + +/** + * Checks whether there are any pending writes. + * Sometimes cloud services can get frazzled if you call ReadCloudDocument while still writing. + */ +native event bool IsStillWritingFiles(); + +/** + * Checks whether there are any pending writes. + * Sometimes cloud services can get frazzled if you call ReadCloudDocument while still writing. + */ +native event bool WaitForWritesToFinish(optional float MaxTimeSeconds); + +/** + * If there was a conflict notification, this will simply tell the cloud interface + * to choose the most recently modified version, and toss any others + */ +native event bool ResolveConflictWithNewestDocument(); + +/** + * If there was a conflict notification, this will tell the cloud interface + * to choose the version with a given Index to be the master version, and to + * toss any others + * + * @param Index Conflict version index + */ +native event bool ResolveConflictWithVersionIndex(int Index); + + + +/** + * Check if there are local files on disk. These would come from systems that allow both + * cloud files and local files (e.g. iOS users not signed into iCloud). + * HandleLocalDocument() will be called for each file this function finds, which you can + * override to handle each document. + * + * @return True if there were any documents + */ +native event bool UpgradeLocalStorageToCloud(CloudStorageUpgradeHelper UpgradeHelper, optional bool bForceSearchAgain); diff --git a/Engine/Classes/CloudStorageBaseCloudSaveSystemKVS.uc b/Engine/Classes/CloudStorageBaseCloudSaveSystemKVS.uc new file mode 100644 index 0000000..aadc6fd --- /dev/null +++ b/Engine/Classes/CloudStorageBaseCloudSaveSystemKVS.uc @@ -0,0 +1,61 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * A Cloud Save System KVS that utilizes the CloudStorageBase implementation. + */ + class CloudStorageBaseCloudSaveSystemKVS extends Object + implements(CloudSaveSystemKVSInterface) + dependson(CloudStorageBase); + + /*Instance of the cloud storage that this Save System KVS will utilize*/ + var transient private CloudStorageBase CloudStorage; + +/* +*Initializes the KVS system for use. +* +*@param InCloudStorage the instance of ClousStorageBase to use for KVS. +*@param List of all keys that will be utilized with this +*/ +final function Init(CloudStorageBase InCloudStorage) +{ + CloudStorage = InCloudStorage; +} + +/* +*Reads a key value for the given save slot +*/ +function bool ReadKeyValue(int SaveSlotIndex, string KeyName, EPlatformInterfaceDataType Type, out PlatformInterfaceDelegateResult Value) +{ + local string SaveSlotKeyName; + + if (CloudStorage == None) + { + return false; + } + + SaveSlotKeyName = GenerateKeyNameForSaveSlot(SaveSlotIndex, KeyName); + + return CloudStorage.ReadKeyValue(SaveSlotKeyName, Type, Value); +} + +/* +*Writes a key value for the given slot +*/ +function bool WriteKeyValue(int SaveSlotIndex, string KeyName, const out PlatformInterfaceData Value) +{ + local string SaveSlotKeyName; + + if (CloudStorage == None) + { + return false; + } + + SaveSlotKeyName = GenerateKeyNameForSaveSlot(SaveSlotIndex, KeyName); + + return CloudStorage.WriteKeyValue(SaveSlotKeyName, Value); +} + +final function private string GenerateKeyNameForSaveSlot(int SaveSlotIndex, string KeyName) +{ + return SaveSlotIndex$KeyName; +} \ No newline at end of file diff --git a/Engine/Classes/CloudStorageUpgradeHelper.uc b/Engine/Classes/CloudStorageUpgradeHelper.uc new file mode 100644 index 0000000..328c8e3 --- /dev/null +++ b/Engine/Classes/CloudStorageUpgradeHelper.uc @@ -0,0 +1,26 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +interface CloudStorageUpgradeHelper + native(PlatformInterface) + dependson(PlatformInterfaceBase); + +/** + * Handle each local document found by UpgradeLocalStorageToCloud(). By default it will move + * each doc to the cloud with its current name. + */ +event HandleLocalDocument(out string DocName, out int bShouldMoveToCloud, out int bShouldDeleteLocalFile); + +/** + * Handle each local key/value found by UpgradeLocalStorageToCloud(). By default it will move + * each value to the cloud with its current name. + */ +event HandleLocalKeyValue(out string CloudKeyName, out PlatformInterfaceData CloudValue, out int bShouldMoveToCloud, out int bShouldDeleteLocalKey); + +/** + * Fill an array of all the Keys you want to transfer to the cloud when upgrading from local storage. + * This will already have been filled with any values in IPhoneDrv.CloudUpgradeKeys in Engine.ini. + * Each entry in the array should have the format "(KeyName=XXX,KeyType=PIDT_XXX)" + */ +event GetCloudUpgradeKeys(out array CloudKeys); \ No newline at end of file diff --git a/Engine/Classes/CodecMovie.uc b/Engine/Classes/CodecMovie.uc new file mode 100644 index 0000000..57fd835 --- /dev/null +++ b/Engine/Classes/CodecMovie.uc @@ -0,0 +1,113 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class CodecMovie extends Object + abstract + transient + native; + +/** Cached script accessible playback duration of movie. */ +var const transient float PlaybackDuration; + +cpptext +{ + // Can't have pure virtual functions in classes declared in *Classes.h due to DECLARE_CLASS macro being used. + + // CodecMovie interface + + /** + * Not all codec implementations are available + * + * @return TRUE if the current codec is supported + */ + virtual UBOOL IsSupported() { return FALSE; } + + /** + * Returns the movie width. + * + * @return width of movie. + */ + virtual UINT GetSizeX() { return 0; } + /** + * Returns the movie height. + * + * @return height of movie. + */ + virtual UINT GetSizeY() { return 0; } + /** + * Returns the movie format. + * + * @return format of movie. + */ + virtual EPixelFormat GetFormat(); + /** + * Returns the framerate the movie was encoded at. + * + * @return framerate the movie was encoded at. + */ + virtual FLOAT GetFrameRate() { return 0; } + + /** + * Initializes the decoder to stream from disk. + * + * @param Filename Filename of compressed media. + * @param Offset Offset into file to look for the beginning of the compressed data. + * @param Size Size of compressed data. + * + * @return TRUE if initialization was successful, FALSE otherwise. + */ + virtual UBOOL Open( const FString& Filename, DWORD Offset, DWORD Size ) { return FALSE; } + /** + * Initializes the decoder to stream from memory. + * + * @param Source Beginning of memory block holding compressed data. + * @param Size Size of memory block. + * + * @return TRUE if initialization was successful, FALSE otherwise. + */ + virtual UBOOL Open( void* Source, DWORD Size ) { return FALSE; } + /** + * Tears down stream. + */ + virtual void Close() {} + + /** + * Resets the stream to its initial state so it can be played again from the beginning. + */ + virtual void ResetStream() {} + /** + * Queues the request to retrieve the next frame. + * + * @param InTextureMovieResource - output from movie decoding is written to this resource + */ + virtual void GetFrame( class FTextureMovieResource* InTextureMovieResource ) {} + /** + * Returns the playback time of the movie. + * + * @return playback duration of movie. + */ + virtual FLOAT GetDuration() { return PlaybackDuration; } + /** + * Begin playback of the movie stream + * + * @param bLooping - if TRUE then the movie loops back to the start when finished + * @param bOneFrameOnly - if TRUE then the decoding is paused after the first frame is processed + * @param bResetOnLastFrame - if TRUE then the movie frame is set to 0 when playback finishes + */ + virtual void Play(UBOOL bLooping, UBOOL bOneFrameOnly, UBOOL bResetOnLastFrame) {} + /** + * Pause or resume the movie playback. + * + * @param bPause - if TRUE then decoding will be paused otherwise it resumes + */ + virtual void Pause(UBOOL bPause) {} + /** + * Stop playback from the movie stream + */ + virtual void Stop() {} + + /** + * Release any dynamic rendering resources created by this codec + */ + virtual void ReleaseDynamicResources() {} +} diff --git a/Engine/Classes/CodecMovieFallback.uc b/Engine/Classes/CodecMovieFallback.uc new file mode 100644 index 0000000..9b2946e --- /dev/null +++ b/Engine/Classes/CodecMovieFallback.uc @@ -0,0 +1,72 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class CodecMovieFallback extends CodecMovie + native; + +/** seconds since start of playback */ +var const transient float CurrentTime; + +cpptext +{ + // CodecMovie interface + + /** + * Not all codec implementations are available + * @return TRUE if the current codec is supported + */ + virtual UBOOL IsSupported(); + /** + * Returns the movie width. + * + * @return width of movie. + */ + virtual UINT GetSizeX(); + /** + * Returns the movie height. + * + * @return height of movie. + */ + virtual UINT GetSizeY(); + /** + * Returns the movie format. + * + * @return format of movie. + */ + virtual EPixelFormat GetFormat(); + /** + * Returns the framerate the movie was encoded at. + * + * @return framerate the movie was encoded at. + */ + virtual FLOAT GetFrameRate(); + /** + * Initializes the decoder to stream from disk. + * + * @param Filename Filename of compressed media. + * @param Offset Offset into file to look for the beginning of the compressed data. + * @param Size Size of compressed data. + * + * @return TRUE if initialization was successful, FALSE otherwise. + */ + virtual UBOOL Open( const FString& Filename, DWORD Offset, DWORD Size ); + /** + * Initializes the decoder to stream from memory. + * + * @param Source Beginning of memory block holding compressed data. + * @param Size Size of memory block. + * + * @return TRUE if initialization was successful, FALSE otherwise. + */ + virtual UBOOL Open( void* Source, DWORD Size ); + /** + * Resets the stream to its initial state so it can be played again from the beginning. + */ + virtual void ResetStream(); + /** + * Queues the request to retrieve the next frame. + * + * @param InTextureMovieResource - output from movie decoding is written to this resource + */ + virtual void GetFrame( class FTextureMovieResource* InTextureMovieResource ); +} diff --git a/Engine/Classes/ColorScaleVolume.uc b/Engine/Classes/ColorScaleVolume.uc new file mode 100644 index 0000000..aea92fb --- /dev/null +++ b/Engine/Classes/ColorScaleVolume.uc @@ -0,0 +1,81 @@ +/** + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + + +class ColorScaleVolume extends Volume + hidecategories(Collision,Brush,Attachment,Volume) + placeable; + +/** Desired color scale upon entering volume */ +var() vector ColorScale; +/** Interpolation time for the color scale */ +var() float InterpTime; + +event Touch(Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal) +{ + local Pawn P; + local PlayerController PC; + Super.Touch(Other,OtherComp,HitLocation,HitNormal); + // check to see if we're touching a player controlled pawn + P = Pawn(Other); + if (P != None) + { + PC = PlayerController(P.Controller); + // with a valid camera + if (PC != None && PC.PlayerCamera != None) + { + // apply the entry scale + PC.PlayerCamera.SetDesiredColorScale(ColorScale,InterpTime); + } + } +} + +event UnTouch(Actor Other) +{ + local Pawn P; + local PlayerController PC; + local vector DesiredColorScale; + local float DesiredInterpTime; + local int Idx; + local ColorScaleVolume CSV; + Super.UnTouch(Other); + // check to see if we're touching a player controlled pawn + P = Pawn(Other); + if (P != None) + { + PC = PlayerController(P.Controller); + // with a valid camera + if (PC != None && PC.PlayerCamera != None) + { + // defult to the level color scale + DesiredColorScale = WorldInfo.DefaultColorScale; + DesiredInterpTime = 1.f; + if (P.Touching.Length > 0) + { + // look for any other color scale volumes + for (Idx = P.Touching.Length; Idx >= 0; --Idx) + { + CSV = ColorScaleVolume(P.Touching[Idx]); + if (CSV != None && CSV != self) + { + // set the desired values based on the CSV's + DesiredColorScale = CSV.ColorScale; + DesiredInterpTime = CSV.InterpTime; + // and stop looking + break; + } + } + } + // apply the exit scale + PC.PlayerCamera.SetDesiredColorScale(DesiredColorScale,DesiredInterpTime); + } + } +} + +defaultproperties +{ + ColorScale=(X=1.f,Y=1.f,Z=1.f) + InterpTime=1.f +} diff --git a/Engine/Classes/Console.uc b/Engine/Classes/Console.uc new file mode 100644 index 0000000..191a447 --- /dev/null +++ b/Engine/Classes/Console.uc @@ -0,0 +1,1295 @@ +//============================================================================= +// Console - A quick little command line console that accepts most commands. +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class Console extends Interaction + within GameViewportClient + transient + config(Input) + native(UserInterface); + +// Constants. +const MaxHistory=16; // # of command history to remember. + +/** The player which the next console command should be executed in the context of. If NULL, execute in the viewport. */ +var LocalPlayer ConsoleTargetPlayer; + +var Texture2D DefaultTexture_Black; +var Texture2D DefaultTexture_White; + +/** The key which opens the console. */ +var globalconfig name ConsoleKey; + +/** The key which opens the typing bar. */ +var globalconfig name TypeKey; + +/** Visible Console stuff */ +var globalconfig int MaxScrollbackSize; + +/** Holds the scrollback buffer */ +var array Scrollback; + +/** Where in the scrollback buffer are we */ +var int SBHead, SBPos; + +/** index into the History array for the latest command that was entered */ +var config int HistoryTop; + +/** index into the History array for the earliest command that was entered */ +var config int HistoryBot; + +/** the index of the current position in the History array */ +var config int HistoryCur; + +/** tracks previously entered console commands */ +var config string History[MaxHistory]; + +/** tracks whether the user is using arrows keys to navigate the history, so that auto-complete doesn't override */ +var transient bool bNavigatingHistory; + +/** The command the user is currently typing. */ +var string TypedStr; + +var int TypedStrPos; //Current position in TypedStr + +/** + * Indicates that InputChar events should be captured to prevent them from being passed on to other interactions. Reset + * when the another keydown event is received. + */ +var transient bool bCaptureKeyInput; + +/** True while a control key is pressed. */ +var bool bCtrl; + +var config bool bEnableUI; + +struct native AutoCompleteCommand +{ + var string Command; + var string Desc; +}; + +/** Manual list of auto-complete commands and info specified in BaseInput.ini */ +var config array ManualAutoCompleteList; +/** Full list of auto-complete commands and info */ +var transient array AutoCompleteList; +/** Is the current auto-complete selection locked */ +var transient bool bAutoCompleteLocked; +/** Currently selected auto complete index */ +var transient int AutoCompleteIndex; +/** Should the user be required to hold ctrl to use the up/down arrows when navigating auto-complete */ +var config bool bRequireCtrlToNavigateAutoComplete; +/** Do we need to rebuild auto complete? */ +var transient bool bIsRuntimeAutoCompleteUpToDate; + +/** Node for storing an auto-complete tree based on each char in the command */ +struct native AutoCompleteNode +{ + /** Char for node in the tree */ + var int IndexChar; + /** Indicies into AutoCompleteList for commands that match to this level */ + var init array AutoCompleteListIndices; + /** Children for further matching */ + var init array ChildNodes{FAutoCompleteNode}; + +structcpptext +{ + FAutoCompleteNode() + { + IndexChar = INDEX_NONE; + } + FAutoCompleteNode(INT NewChar) + { + IndexChar = NewChar; + } + ~FAutoCompleteNode() + { + for (INT Idx = 0; Idx < ChildNodes.Num(); Idx++) + { + FAutoCompleteNode *Node = ChildNodes(Idx); + delete Node; + } + ChildNodes.Empty(); + } +} +}; +var native transient AutoCompleteNode AutoCompleteTree; + +/** Current list of matching commands for auto-complete, @see UpdateCompleteIndices() */ +var transient array AutoCompleteIndices; + +/** + * Called when the Console is added to the GameViewportClient's Interactions array. + */ +function Initialized() +{ + Super.Initialized(); +} + +function SetInputText( string Text ) +{ + TypedStr = Text; +} + +function SetCursorPos( int Position ) +{ + TypedStrPos = Position; +} + +/** +* Searches console command history and removes any entries matching the specified command. +* @param Command - The command to search for and purge from the history. +*/ +function PurgeCommandFromHistory(string Command) +{ + local int HistoryIdx, Idx, NextIdx; + + if ( (HistoryTop >= 0) && (HistoryTop < MaxHistory) ) + { + for (HistoryIdx=0; HistoryIdx>>" @ Command @ "<<<"); + + if(ConsoleTargetPlayer != None) + { + // If there is a console target player, execute the command in the player's context. + ConsoleTargetPlayer.Actor.ConsoleCommand(Command); + } + else if(GamePlayers.Length > 0 && GamePlayers[0].Actor != None) + { + // If there are any players, execute the command in the first players context. + GamePlayers[0].Actor.ConsoleCommand(Command); + } + else + { + // Otherwise, execute the command in the context of the viewport. + Outer.ConsoleCommand(Command); + } +} + +/** + * Clears the console output buffer. + */ +function ClearOutput() +{ + SBHead = 0; + ScrollBack.Remove(0,ScrollBack.Length); +} + +/** + * Prints a single line of text to the console. + * @param Text - A line of text to display on the console. + */ +function OutputTextLine(coerce string Text) +{ + // If we are full, delete the first line + if (ScrollBack.Length > MaxScrollbackSize) + { + ScrollBack.Remove(0,1); + SBHead = MaxScrollBackSize-1; + } + else + SBHead++; + + // Add the line + ScrollBack.Length = ScrollBack.Length+1; + ScrollBack[SBHead] = Text; +} + +/** + * Prints a (potentially multi-line) string of text to the console. + * The text is split into separate lines and passed to OutputTextLine. + * @param Text - Text to display on the console. + */ +event OutputText(coerce string Text) +{ + local string RemainingText; + local int StringLength; + local int LineLength; + + RemainingText = Text; + StringLength = Len(Text); + while(StringLength > 0) + { + // Find the number of characters in the next line of text. + LineLength = InStr(RemainingText,"\n"); + if(LineLength == -1) + { + // There aren't any more newlines in the string, assume there's a newline at the end of the string. + LineLength = StringLength; + } + + // Output the line to the console. + OutputTextLine(Left(RemainingText,LineLength)); + + // Remove the line from the string. + RemainingText = Mid(RemainingText,LineLength + 1); + StringLength -= LineLength + 1; + }; +} + +/** + * Opens the typing bar with text already entered. + * @param Text - The text to enter in the typing bar. + */ +function StartTyping(coerce string Text) +{ + GotoState('Typing'); + SetInputText(Text); + SetCursorPos(Len(Text)); +} + +function PostRender_Console(Canvas Canvas); + +/** + * Process an input key event routed through unrealscript from another object. This method is assigned as the value for the + * OnRecievedNativeInputKey delegate so that native input events are routed to this unrealscript function. + * + * @param ControllerId the controller that generated this input key event + * @param Key the name of the key which an event occured for (KEY_Up, KEY_Down, etc.) + * @param EventType the type of event which occured (pressed, released, etc.) + * @param AmountDepressed for analog keys, the depression percent. + * + * @return true to consume the key event, false to pass it on. + */ +function bool InputKey( int ControllerId, name Key, EInputEvent Event, float AmountDepressed = 1.f, bool bGamepad = FALSE ) +{ + local PlayerController PC; + if ( Event == IE_Pressed ) + { + + bCaptureKeyInput = false; + +`if(`__TW_) + if(Key == 'F10') + { + foreach class'Engine'.static.GetCurrentWorldInfo().LocalPlayerControllers(class'PlayerController', PC) + { + PC.ForceDisconnect(); + } + } +`endif + + if ( Key == ConsoleKey ) + { + GotoState('Open'); + bCaptureKeyInput = true; + return true; + } + else if ( Key == TypeKey ) + { + GotoState('Typing'); + bCaptureKeyInput = true; + return true; + } + } + + return bCaptureKeyInput; +} + +`if(`__TW_) +function AttempDisconnect() +{ + +} +`endif + +/** + * Process a character input event (typing) routed through unrealscript from another object. This method is assigned as the value for the + * OnRecievedNativeInputKey delegate so that native input events are routed to this unrealscript function. + * + * @param ControllerId the controller that generated this character input event + * @param Unicode the character that was typed + * + * @return True to consume the character, false to pass it on. + */ +function bool InputChar( int ControllerId, string Unicode ) +{ + return bCaptureKeyInput; +} + +/** + * Clears out all pressed keys from the player's input object. + */ +function FlushPlayerInput() +{ + local PlayerController PC; + + if(ConsoleTargetPlayer != None) + { + PC = ConsoleTargetPlayer.Actor; + } + else if(GamePlayers.Length > 0 && GamePlayers[0].Actor != None) + { + // If there are any players, execute the command in the first players context. + PC = GamePlayers[0].Actor; + } + + if ( PC != None && PC.PlayerInput != None ) + { + PC.PlayerInput.ResetInput(); + } +} + +/** looks for Control key presses and the copy/paste combination that apply to both the console bar and the full open console */ +function bool ProcessControlKey(name Key, EInputEvent Event) +{ + if (Key == 'LeftControl' || Key == 'RightControl') + { + if (Event == IE_Released) + { + bCtrl = false; + } + else if (Event == IE_Pressed) + { + bCtrl = true; + } + + return true; + } + else if (bCtrl && Event == IE_Pressed && GamePlayers.length > 0 && GamePlayers[0].Actor != None) + { + if (Key == 'v') + { + // paste + AppendInputText(GamePlayers[0].Actor.PasteFromClipboard()); + return true; + } + else if (Key == 'c') + { + // copy + GamePlayers[0].Actor.CopyToClipboard(TypedStr); + return true; + } + else if (Key == 'x') + { + // cut + if (TypedStr != "") + { + GamePlayers[0].Actor.CopyToClipboard(TypedStr); + SetInputText(""); + SetCursorPos(0); + } + return true; + } + } + + return false; +} + +/** appends the specified text to the string of typed text */ +function AppendInputText(string Text) +{ + local int Character; + + while (Len(Text) > 0) + { + Character = Asc(Left(Text, 1)); + Text = Mid(Text, 1); + + if (Character >= 0x20 && Character < 0x100) + { + SetInputText(Left(TypedStr, TypedStrPos) $ Chr(Character) $ Right(TypedStr, Len(TypedStr) - TypedStrPos)); + SetCursorPos(TypedStrPos + 1); + } + }; + UpdateCompleteIndices(); +} + +final native function BuildRuntimeAutoCompleteList(optional bool bForce); + +native function UpdateCompleteIndices(); + +/** + * This state is used when the typing bar is open. + */ +state Typing +{ + /** + * Process a character input event (typing) routed through unrealscript from another object. This method is assigned as the value for the + * OnRecievedNativeInputKey delegate so that native input events are routed to this unrealscript function. + * + * @param ControllerId the controller that generated this character input event + * @param Unicode the character that was typed + * + * @return True to consume the character, false to pass it on. + */ + function bool InputChar( int ControllerId, string Unicode ) + { + if ( bCaptureKeyInput ) + { + return true; + } + + AppendInputText(Unicode); + + return true; + } + + /** + * Process an input key event routed through unrealscript from another object. This method is assigned as the value for the + * OnRecievedNativeInputKey delegate so that native input events are routed to this unrealscript function. + * + * @param ControllerId the controller that generated this input key event + * @param Key the name of the key which an event occured for (KEY_Up, KEY_Down, etc.) + * @param EventType the type of event which occured (pressed, released, etc.) + * @param AmountDepressed for analog keys, the depression percent. + * + * @return true to consume the key event, false to pass it on. + */ + function bool InputKey( int ControllerId, name Key, EInputEvent Event, float AmountDepressed = 1.f, bool bGamepad = FALSE ) + { + local string Temp; + local int NewPos, SpacePos, PeriodPos; + + //`log(`location@`showvar(Key)); + + if ( Event == IE_Pressed ) + { + bCaptureKeyInput = false; + } + + if (ProcessControlKey(Key, Event)) + { + return true; + } + else if( bGamepad ) + { + return FALSE; + } + else if( Key == 'Escape' && Event == IE_Released ) + { + if( TypedStr!="" ) + { + SetInputText(""); + SetCursorPos(0); + HistoryCur = HistoryTop; + return true; + } + else + { + GotoState( '' ); + } + + return true; + } + else if ( Key==ConsoleKey && Event == IE_Pressed ) + { + GotoState('Open'); + bCaptureKeyInput = true; + return true; + } + else if(Key == TypeKey && Event == IE_Pressed) + { + if (AutoCompleteIndices.Length > 0 && !bAutoCompleteLocked) + { + TypedStr = AutoCompleteList[AutoCompleteIndices[AutoCompleteIndex]].Command; + SetCursorPos(Len(TypedStr)); + bAutoCompleteLocked = TRUE; +`if(`__TW_) + // Prevent TypeKey from appending onto auto complete + bCaptureKeyInput = true; +`endif + } + else + { + GotoState(''); + bCaptureKeyInput = true; + } + return true; + } + else if( Key=='Enter' && Event == IE_Released ) + { + if( TypedStr!="" ) + { + // Make a local copy of the string. + Temp=TypedStr; + + SetInputText(""); + SetCursorPos(0); + + ConsoleCommand(Temp); + + //OutputText( Localize("Errors","Exec","Core") ); + + OutputText( "" ); + GotoState(''); + + UpdateCompleteIndices(); + } + else + { + GotoState(''); + } + + return true; + } + else if( Global.InputKey( ControllerId, Key, Event, AmountDepressed, bGamepad ) ) + { + return true; + } + else if( Event != IE_Pressed && Event != IE_Repeat ) + { + if( !bGamepad ) + { + return Key != 'LeftMouseButton' + && Key != 'MiddleMouseButton' + && Key != 'RightMouseButton'; + } + return FALSE; + } + else if( Key=='up' ) + { + if (!bNavigatingHistory && ((bRequireCtrlToNavigateAutoComplete && bCtrl) || (!bRequireCtrlToNavigateAutoComplete && !bCtrl && AutoCompleteIndices.Length > 1))) + { + if (++AutoCompleteIndex == AutoCompleteIndices.Length) + { + AutoCompleteIndex = 0; + } + } + else + if ( HistoryBot >= 0 ) + { + if (HistoryCur == HistoryBot) + HistoryCur = HistoryTop; + else + { + HistoryCur--; + if (HistoryCur<0) + HistoryCur = MaxHistory-1; + } + + SetInputText(History[HistoryCur]); + SetCursorPos(Len(History[HistoryCur])); + UpdateCompleteIndices(); + bNavigatingHistory = TRUE; + } + return True; + } + else if( Key=='down' ) + { + if (!bNavigatingHistory && ((bRequireCtrlToNavigateAutoComplete && bCtrl) || (!bRequireCtrlToNavigateAutoComplete && !bCtrl && AutoCompleteIndices.Length > 1))) + { + if (--AutoCompleteIndex < 0) + { + AutoCompleteIndex = AutoCompleteIndices.Length - 1; + } + bAutoCompleteLocked = FALSE; + } + else + if ( HistoryBot >= 0 ) + { + if (HistoryCur == HistoryTop) + HistoryCur = HistoryBot; + else + HistoryCur = (HistoryCur+1) % MaxHistory; + + SetInputText(History[HistoryCur]); + SetCursorPos(Len(History[HistoryCur])); + UpdateCompleteIndices(); + bNavigatingHistory = TRUE; + } + + } + else if( Key=='backspace' ) + { + if( TypedStrPos>0 ) + { + SetInputText(Left(TypedStr,TypedStrPos-1) $ Right(TypedStr, Len(TypedStr) - TypedStrPos)); + SetCursorPos(TypedStrPos-1); + // unlock auto-complete (@todo - track the lock position so we don't bother unlocking under bogus cases) + bAutoCompleteLocked = FALSE; + } + + return true; + } + else if ( Key=='delete' ) + { + if ( TypedStrPos < Len(TypedStr) ) + { + SetInputText(Left(TypedStr,TypedStrPos) $ Right(TypedStr, Len(TypedStr) - TypedStrPos - 1)); + } + return true; + } + else if ( Key=='left' ) + { + if (bCtrl) + { + // find the nearest '.' or ' ' + NewPos = Max(InStr(TypedStr,".",TRUE,FALSE,TypedStrPos),InStr(TypedStr," ",TRUE,FALSE,TypedStrPos)); + SetCursorPos(Max(0,NewPos)); + } + else + { + SetCursorPos(Max(0, TypedStrPos - 1)); + } + return true; + } + else if ( Key=='right' ) + { + if (bCtrl) + { + // find the nearest '.' or ' ' + SpacePos = InStr(TypedStr," ",FALSE,FALSE,TypedStrPos+1); + PeriodPos = InStr(TypedStr,".",FALSE,FALSE,TypedStrPos+1); + // pick the closest valid index + NewPos = SpacePos < 0 ? PeriodPos : (PeriodPos < 0 ? SpacePos : Min(SpacePos,PeriodPos)); + // jump to end if nothing in between + if (NewPos == INDEX_NONE) + { + NewPos = Len(TypedStr); + } + SetCursorPos(Min(Len(TypedStr),Max(TypedStrPos,NewPos))); + } + else + { + SetCursorPos(Min(Len(TypedStr), TypedStrPos + 1)); + } + return true; + } + else if ( Key=='home' ) + { + SetCursorPos(0); + return true; + } + else if ( Key=='end' ) + { + SetCursorPos(Len(TypedStr)); + return true; + } + + return TRUE; + } + + event PostRender_Console(Canvas Canvas) + { + local float y, xl, yl, info_xl, info_yl, ClipX, ClipY, LeftPos; + local string OutStr; + local int MatchIdx, Idx, StartIdx; + + Global.PostRender_Console(Canvas); + + // Blank out a space + + // use the smallest font + Canvas.Font = class'Engine'.Static.GetSmallFont(); + // determine the position for the cursor + OutStr = "(>"@TypedStr; + Canvas.Strlen(OutStr,xl,yl); + + ClipX = Canvas.ClipX; + ClipY = Canvas.ClipY; + LeftPos = 0; + + if (Class'WorldInfo'.Static.IsConsoleBuild()) + { + ClipX -= 32; + ClipY -= 32; + LeftPos = 32; + } + + // start at the bottom of the screen, then come up 6 pixels more than the height of the font + Canvas.SetPos(LeftPos,ClipY-6-yl); + // draw the background texture + Canvas.DrawTile( DefaultTexture_Black, ClipX, yl+6,0,0,32,32); + + Canvas.SetPos(LeftPos,ClipY-6-yl); + + // change the draw color to green + Canvas.SetDrawColor(0,255,0); + + // draw the top border of the typing region + Canvas.DrawTile( DefaultTexture_White, ClipX, 2,0,0,32,32); + + // center the text between the bottom of the screen and the bottom of the border line + Canvas.SetPos(LeftPos,ClipY-3-yl); + Canvas.bCenter = False; + Canvas.DrawText( OutStr, false ); + + // draw the remaining text for matching auto-complete + if (AutoCompleteIndices.Length > 0) + { + Idx = AutoCompleteIndices[AutoCompleteIndex]; + //Canvas.StrLen(OutStr,xl,yl); + Canvas.SetPos(LeftPos+xl,ClipY-3-yl); + Canvas.SetDrawColor(87,148,87); + Canvas.DrawText(Right(AutoCompleteList[Idx].Command,Len(AutoCompleteList[Idx].Command) - Len(TypedStr)),FALSE); + Canvas.StrLen("(>",xl,yl); + + StartIdx = AutoCompleteIndex - 5; + if (StartIdx < 0) + { + StartIdx = Max(0,AutoCompleteIndices.Length + StartIdx); + } + Idx = StartIdx; + y = ClipY - 6 - (yl * 2); + for (MatchIdx = 0; MatchIdx < 10; MatchIdx++) + { + OutStr = AutoCompleteList[AutoCompleteIndices[Idx]].Desc; + Canvas.StrLen(OutStr, info_xl, info_yl); + y -= info_yl - yl; + Canvas.SetPos(LeftPos + xl, y); + Canvas.SetDrawColor(0, 0, 0); + Canvas.DrawTile(DefaultTexture_White, info_xl, info_yl, 0, 0, 32, 32); + Canvas.SetPos(LeftPos + xl, y); + if (Idx == AutoCompleteIndex) + { + Canvas.SetDrawColor(0,255,0); + } + else + { + Canvas.SetDrawColor(0,150,0); + } + Canvas.DrawText(OutStr,false); + if (++Idx >= AutoCompleteIndices.Length) + { + Idx = 0; + } + y -= yl; + // break out if we loop on lists < 10 + if (Idx == StartIdx) + { + break; + } + } + if (AutoCompleteIndices.Length >= 10) + { + OutStr = "[" $ (AutoCompleteIndices.Length - 10 + 1) @ "more matches]"; + Canvas.StrLen(OutStr, info_xl, info_yl); + Canvas.SetPos(LeftPos + xl, y); + Canvas.SetDrawColor(0, 0, 0); + Canvas.DrawTile(DefaultTexture_White, info_xl, info_yl, 0, 0, 32, 32); + Canvas.SetPos(LeftPos + xl, y); + Canvas.SetDrawColor(0, 255, 0); + Canvas.DrawText(OutStr, false); + } + } + + // determine the cursor position + OutStr = "(>"@Left(TypedStr,TypedStrPos); + Canvas.StrLen(OutStr,xl,yl); + + // move the pen to that position + Canvas.SetPos(LeftPos + xl,ClipY-1-yl); + + // draw the cursor + Canvas.DrawText("_"); + } + + event BeginState(Name PreviousStateName) + { + if ( PreviousStateName == '' ) + { + FlushPlayerInput(); + } + bCaptureKeyInput = true; + HistoryCur = HistoryTop; + } + + event EndState( Name NextStateName ) + { + bAutoCompleteLocked = FALSE; + } +} + +/** + * This state is used when the console is open. + */ +state Open +{ + function bool InputChar( int ControllerId, string Unicode ) + { + if ( bCaptureKeyInput ) + { + return true; + } + + AppendInputText(Unicode); + + return true; + } + +//@HSL_BEGIN_XBOX + function KeyboardInputComplete(bool bWasSuccessful) + { + local string Temp; + local byte bWasCancelled; + local OnlineSubsystem OnlineSub; + + OnlineSub = Class'GameEngine'.static.GetOnlineSubsystem(); + TypedStr = OnlineSub.PlayerInterface.GetKeyboardInputResults(bWasCancelled); + + if( TypedStr!="" ) + { + // Make a local copy of the string. + Temp=TypedStr; + SetInputText(""); + SetCursorPos(0); + + if (Temp~="cls") + { + ClearOutput(); + } + else + { + ConsoleCommand(Temp); + } + + UpdateCompleteIndices(); + } + + GotoState(''); + } +//@HSL_END_XBOX + + /** + * Process an input key event routed through unrealscript from another object. This method is assigned as the value for the + * OnRecievedNativeInputKey delegate so that native input events are routed to this unrealscript function. + * + * @param ControllerId the controller that generated this input key event + * @param Key the name of the key which an event occured for (KEY_Up, KEY_Down, etc.) + * @param EventType the type of event which occured (pressed, released, etc.) + * @param AmountDepressed for analog keys, the depression percent. + * + * @return true to consume the key event, false to pass it on. + */ + function bool InputKey( int ControllerId, name Key, EInputEvent Event, float AmountDepressed = 1.f, bool bGamepad = FALSE ) + { + local string Temp; + + if (Event == IE_Pressed) + { + bCaptureKeyInput=false; + } + + if (ProcessControlKey(Key, Event)) + { + return true; + } + else if( bGamepad ) + { + return FALSE; + } + else if( Key == 'Escape' && Event == IE_Released ) + { + if( TypedStr!="" ) + { + SetInputText(""); + SetCursorPos(0); + HistoryCur = HistoryTop; + return true; + } + else + { + GotoState( '' ); + } + } + else if( Key==ConsoleKey && Event == IE_Pressed ) + { + GotoState(''); + bCaptureKeyInput = true; + return true; + } + else if(Key == TypeKey && Event == IE_Pressed) + { + if (AutoCompleteIndices.Length > 0 && !bAutoCompleteLocked) + { + TypedStr = AutoCompleteList[AutoCompleteIndices[0]].Command; + SetCursorPos(Len(TypedStr)); + bAutoCompleteLocked = TRUE; +`if(`__TW_) + // Prevent TypeKey from appending onto auto complete + bCaptureKeyInput = true; +`endif + } + else + { + GotoState(''); + bCaptureKeyInput = true; + } + return true; + } + else if( Key=='Enter' && Event == IE_Released ) + { + if( TypedStr!="" ) + { + // Make a local copy of the string. + Temp=TypedStr; + SetInputText(""); + SetCursorPos(0); + + if (Temp~="cls") + { + ClearOutput(); + } + else + { + ConsoleCommand(Temp); + } + + UpdateCompleteIndices(); + } + + return true; + } + else if( Global.InputKey( ControllerId, Key, Event, AmountDepressed, bGamepad ) ) + { + return true; + } + else if( Event != IE_Pressed && Event != IE_Repeat ) + { + if( !bGamepad ) + { + return Key != 'LeftMouseButton' + && Key != 'MiddleMouseButton' + && Key != 'RightMouseButton'; + } + return FALSE; + } + else if( Key=='up' ) + { + + if (!bCtrl) + { + + if ( HistoryBot >= 0 ) + { + if (HistoryCur == HistoryBot) + HistoryCur = HistoryTop; + else + { + HistoryCur--; + if (HistoryCur<0) + HistoryCur = MaxHistory-1; + } + + SetInputText(History[HistoryCur]); + SetCursorPos(Len(History[HistoryCur])); + } + } + else + { + if (SBPos=ScrollBack.Length) + SBPos = ScrollBack.Length-1; + } + } + return True; + } + else if( Key=='down' ) + { + if (!bCtrl) + { + if ( HistoryBot >= 0 ) + { + if (HistoryCur == HistoryTop) + HistoryCur = HistoryBot; + else + HistoryCur = (HistoryCur+1) % MaxHistory; + + SetInputText(History[HistoryCur]); + SetCursorPos(Len(History[HistoryCur])); + } + } + else + { + if (SBPos>0) + { + SBPos--; + if (SBPos<0) + SBPos = 0; + } + + } + return true; + } + else if( Key=='backspace' ) + { + if( TypedStrPos>0 ) + { + SetInputText(Left(TypedStr,TypedStrPos-1) $ Right(TypedStr, Len(TypedStr) - TypedStrPos)); + SetCursorPos(TypedStrPos-1); + // unlock auto-complete (@todo - track the lock position so we don't bother unlocking under bogus cases) + bAutoCompleteLocked = FALSE; + } + + return true; + } + else if ( Key=='delete' ) + { + if ( TypedStrPos < Len(TypedStr) ) + { + SetInputText(Left(TypedStr,TypedStrPos) $ Right(TypedStr, Len(TypedStr) - TypedStrPos - 1)); + } + return true; + } + else if ( Key=='left' ) + { + SetCursorPos(Max(0, TypedStrPos - 1)); + return true; + } + else if ( Key=='right' ) + { + SetCursorPos(Min(Len(TypedStr), TypedStrPos + 1)); + return true; + } + else if (bCtrl && Key=='home') + { + SBPos=0; + } + else if ( Key=='home' ) + { + SetCursorPos(0); + return true; + } + else if (bCtrl && Key=='end') + { + SBPos = ScrollBack.Length-1; + } + else if ( Key=='end' ) + { + SetCursorPos(Len(TypedStr)); + return true; + } + + else if ( Key=='pageup' || Key=='mousescrollup') + { + if (SBPos=ScrollBack.Length) + SBPos = ScrollBack.Length-1; + } + + return true; + } + else if ( Key=='pagedown' || Key=='mousescrolldown') + { + if (SBPos>0) + { + if (bCtrl) + SBPos-=5; + else + SBPos--; + + if (SBPos<0) + SBPos = 0; + } + + return true; + } + + + return TRUE; + } + + event PostRender_Console(Canvas Canvas) + { + + local float Height; + local float xl, yl, y, ScrollLineXL, ScrollLineYL, info_xl, info_yl; + local string OutStr; + local int idx, MatchIdx; + + // render the buffer + + // Blank out a space + Canvas.Font = class'Engine'.Static.GetSmallFont(); + + // the height of the buffer will be 75% of the height of the screen + Height = Canvas.ClipY * 0.75; + + // change the draw color to white + Canvas.SetDrawColor(255,255,255,255); + + // move the pen to the top-left pixel + Canvas.SetPos(0,0); + + // draw the black background tile + Canvas.DrawTile( DefaultTexture_Black, Canvas.ClipX, Height,0,0,32,32); + + // now render the typing region + OutStr = "(>"@TypedStr; + + // determine the height of the text + Canvas.Strlen(OutStr,xl,yl); + + // move the pen up + 12 pixels of buffer (for the green borders and some space) + Canvas.SetPos(0,Height-12-yl); + + // change the draw color to green + Canvas.SetDrawColor(0,255,0); + + // draw the top typing region border + Canvas.DrawTile( DefaultTexture_White, Canvas.ClipX, 2,0,0,32,32); + + // move the pen to the bottom of the console buffer area + Canvas.SetPos(0,Height); + + // draw the bottom typing region border + Canvas.DrawTile( DefaultTexture_White, Canvas.ClipX, 2,0,0,32,32); + + // center the pen between the two borders + Canvas.SetPos(0,Height-5-yl); + Canvas.bCenter = False; + + // render the text that is being typed + Canvas.DrawText( OutStr, false ); + + // draw the remaining text for matching auto-complete + if (AutoCompleteIndices.Length > 0) + { + Idx = AutoCompleteIndices[0]; + //Canvas.StrLen(OutStr,xl,yl); + Canvas.SetPos(0+xl,Height-5-yl); + Canvas.SetDrawColor(87,148,87); + Canvas.DrawText(Right(AutoCompleteList[Idx].Command,Len(AutoCompleteList[Idx].Command) - Len(TypedStr)),FALSE); + + Canvas.StrLen("(>", xl, yl); + y = Height + 5; + for (MatchIdx = 0; MatchIdx < AutoCompleteIndices.Length && MatchIdx < 10; MatchIdx++) + { + Idx = AutoCompleteIndices[MatchIdx]; + Canvas.SetPos(0 + xl, y); + Canvas.StrLen(AutoCompleteList[Idx].Desc, info_xl, info_yl); + Canvas.SetDrawColor(0, 0, 0); + Canvas.DrawTile(DefaultTexture_White, info_xl, info_yl, 0, 0, 32, 32); + Canvas.SetPos(0 + xl, y); + Canvas.SetDrawColor(0, 255, 0); + Canvas.DrawText(AutoCompleteList[Idx].Desc, false); + y += info_yl; + } + } + + OutStr = "(>"@Left(TypedStr,TypedStrPos); + + // position the pen at the cursor position + Canvas.StrLen(OutStr,xl,yl); + Canvas.SetPos(xl,Height-3-yl); + + // render the cursor + Canvas.DrawText("_"); + + // figure out which element of the scrollback buffer to should appear first (at the top of the screen) + idx = SBHead - SBPos; + y = Height-16-(yl*2); + + if (ScrollBack.Length==0) + return; + + // change the draw color to white + Canvas.SetDrawColor(255,255,255,255); + + // while we have enough room to draw another line and there are more lines to draw + while (y>yl && idx>=0) + { + // move the pen to the correct position + Canvas.SetPos(0, y); + + // adjust the location for any word wrapping due to long text lines + Canvas.StrLen(ScrollBack[idx], ScrollLineXL, ScrollLineYL); + if (ScrollLineYL > yl) + { + y -= (ScrollLineYL - yl); + Canvas.SetPos(Canvas.CurX, y, Canvas.CurZ); + } + + // draw the next line down in the buffer + Canvas.DrawText(Scrollback[idx],false); + idx--; + y-=yl; + } + } + + event BeginState(Name PreviousStateName) + { +//@HSL_BEGIN_XBOX + local OnlineSubsystem OnlineSub; + + bCaptureKeyInput = true; + HistoryCur = HistoryTop; + + SBPos = 0; + bCtrl = false; + + OnlineSub = Class'GameEngine'.static.GetOnlineSubsystem(); + OnlineSub.PlayerInterface.AddKeyboardInputDoneDelegate(KeyboardInputComplete); + + OnlineSub.PlayerInterface.ShowKeyboardUI(0, "Console Input", "Input console commands"); + + if ( PreviousStateName == '' ) + { + FlushPlayerInput(); + } + } + + event EndState( Name NextStateName ) + { + local OnlineSubsystem OnlineSub; + + OnlineSub = Class'GameEngine'.static.GetOnlineSubsystem(); + + OnlineSub.PlayerInterface.HideKeyboardUI(0); + OnlineSub.PlayerInterface.ClearKeyboardInputDoneDelegate(KeyboardInputComplete); + } +//@HSL_END_XBOX +} + +defaultproperties +{ + OnReceivedNativeInputKey=InputKey + OnReceivedNativeInputChar=InputChar + + DefaultTexture_Black=Texture2D'EngineResources.Black' + DefaultTexture_White=Texture2D'EngineResources.WhiteSquareTexture' +} diff --git a/Engine/Classes/Controller.uc b/Engine/Classes/Controller.uc new file mode 100644 index 0000000..cfbd6ee --- /dev/null +++ b/Engine/Classes/Controller.uc @@ -0,0 +1,1972 @@ +//============================================================================= +// Controller, the base class of players or AI. +// +// Controllers are non-physical actors that can be attached to a pawn to control +// its actions. PlayerControllers are used by human players to control pawns, while +// AIControFllers implement the artificial intelligence for the pawns they control. +// Controllers take control of a pawn using their Possess() method, and relinquish +// control of the pawn by calling UnPossess(). +// +// Controllers receive notifications for many of the events occuring for the Pawn they +// are controlling. This gives the controller the opportunity to implement the behavior +// in response to this event, intercepting the event and superceding the Pawn's default +// behavior. +// +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class Controller extends Actor + native(Controller) + nativereplication + implements(Interface_NavigationHandle) + abstract; + +//============================================================================= +// BASE VARIABLES + +/** Pawn currently being controlled by this controller. Use Pawn.Possess() to take control of a pawn */ +var editinline repnotify Pawn Pawn; + +/** PlayerReplicationInfo containing replicated information about the player using this controller (only exists if bIsPlayer is true). */ +var editinline repnotify PlayerReplicationInfo PlayerReplicationInfo; + +var const int PlayerNum; // The player number - per-match player number. +var const private Controller NextController; // chained Controller list + +var bool bIsPlayer; // Pawn is a player or a player-bot. +var bool bGodMode; // cheat - when true, can't be killed or hurt + +`if(`__TW_) +var bool bDemiGodMode; /** It forces the pawn to not be able to die */ +`endif + +var bool bSoaking; // pause and focus on pawn controlled by this controller if it encounters a problem +var bool bSlowerZAcquire; // AI acquires targets above or below more slowly than at same height + + +// Input buttons. +var input byte bFire; + +/** If true, the controlled pawn will attempt to alt fire */ +var input byte bAltFire; + +//============================================================================= +// PHYSICS VARIABLES + +var bool bNotifyPostLanded; // if true, event NotifyPostLanded() after pawn lands after falling. +var bool bNotifyApex; // if true, event NotifyJumpApex() when at apex of jump +var float MinHitWall; // Minimum HitNormal dot Velocity.Normal to get a HitWall event from the physics + + +//============================================================================= +// NAVIGATION VARIABLES + +/** Navigation handle used for pathing when using NavMesh */ +var class NavigationHandleClass; +var editinline NavigationHandle NavigationHandle; +/** Override search start position for navhandle path cache info */ +var bool bOverrideSearchStart; +var Vector OverrideSearchStart; + +var bool bAdvancedTactics; // serpentine movement between pathnodes +var bool bCanDoSpecial; // are we able to traverse R_SPECIAL reach specs? +var bool bAdjusting; // adjusting around obstacle +var bool bPreparingMove; // set true while pawn sets up for a latent move + +/** Used by AI, set true to force AI to use serpentine/strafing movement when possible. */ +var bool bForceStrafe; + +var float MoveTimer; // internal timer for latent moves, useful for setting a max duration +var Actor MoveTarget; // actor being moved toward +var BasedPosition DestinationPosition; // destination controlled pawn is moving toward +var BasedPosition FocalPosition; // position controlled pawn is looking at +var Actor Focus; // actor being looked at +var Actor GoalList[4]; // used by navigation AI - list of intermediate goals +var BasedPosition AdjustPosition; // intermediate destination used while adjusting around obstacle (bAdjusting is true) +var NavigationPoint StartSpot; // where player started the match + +/** Cached list of nodes filled in by the last call to FindPathXXX */ +var array RouteCache; + +var ReachSpec CurrentPath; // Current path being moved along +var ReachSpec NextRoutePath; // Next path in route to destination +var vector CurrentPathDir; // direction vector of current path +var Actor RouteGoal; // final destination for current route +var float RouteDist; // total distance for current route +var float LastRouteFind; // time at which last route finding occured +var InterpActor PendingMover; // InterpActor that controller is currently waiting on (e.g. door or lift) + +/** used for discovering navigation failures */ +var Actor FailedMoveTarget; +var int MoveFailureCount; + +var float GroundPitchTime; + +var Pawn ShotTarget; // Target most recently aimed at +var const Actor LastFailedReach; // cache to avoid trying failed actorreachable more than once per frame +var const float FailedReachTime; +var const vector FailedReachLocation; + +const LATENT_MOVETOWARD = 503; // LatentAction number for Movetoward() latent function + +//============================================================================= +// AI VARIABLES + +var const bool bLOSflag; // used for alternating LineOfSight traces +var bool bSkipExtraLOSChecks; // Skip viewport nudging checks for LOS +var bool bNotifyFallingHitWall; // If true, controller gets NotifyFallingHitWall() when pawn hits wall while falling +var float SightCounter; // Used to keep track of when to check player visibility +var float SightCounterInterval; // how often player visibility is checked +var bool bEarlyOutOfSighTestsForSameType;// when an AI already has an enemy of this type, early out from sight tests to me +`if(`__TW_) +var bool bReachedLatentMoveGoal; // Used by APawn::MoveToward() & AKFPawn::MoveToward() +var NavigationPoint LastNavGoalReached; // Last NavigationPoint reached via MoveToward() +var bool bAdjustFromWalls; // Moved down from AIController to avoid casting +`endif + +/** multiplier to cost of NavigationPoints that another Pawn is currently anchored to */ +var float InUseNodeCostMultiplier; + +/** additive modifier to cost of NavigationPoints that require high jumping */ +var int HighJumpNodeCostModifier; + +/** Max time when moving toward a pawn target before latent movetoward returns (allowing reassessment of movement) */ +var float MaxMoveTowardPawnTargetTime; + +// Enemy information +var Pawn Enemy; + +/** Forces all velocity to be directed towards reaching Destination */ +var bool bPreciseDestination; + +/** Do visibility checks, call SeePlayer events() for pawns on same team as self. Setting to true will result in a lot more AI visibility line checks. */ +var bool bSeeFriendly; + +/** List of destinations whose source portals are visible to this Controller */ +struct native VisiblePortalInfo +{ + /** source actor of portal */ + var Actor Source; + /** destination actor of portal */ + var Actor Destination; + + structcpptext + { + FVisiblePortalInfo() + {} + FVisiblePortalInfo(EEventParm) + { + appMemzero(this, sizeof(FVisiblePortalInfo)); + } + FVisiblePortalInfo(AActor* InSource, AActor* InDest) + : Source(InSource), Destination(InDest) + {} + + UBOOL operator==(const FVisiblePortalInfo& Other) + { + return Other.Source == Source && Other.Destination == Destination; + } + } +}; +var array VisiblePortals; + +/** indicates that the AI is within a lane in its CurrentPath (like a road) + * to avoid ramming other Pawns also using that path + * set by MoveToward() when it detects multiple AI pawns using the same path + * when this is true, serpentine movement and cutting corners are disabled + */ +var bool bUsingPathLanes; + +/** the offset from the center of CurrentPath to the center of the lane in use (the Pawn's CollisionRadius defines the extent) + * positive values are to the Pawn's right, negative to the Pawn's left + */ +var float LaneOffset; + +/** Used for reversing rejected mover base movement */ +var const rotator OldBasedRotation; + +/** allows easy modification of the search extent provided by setuppathfindingparams() */ +var vector NavMeshPath_SearchExtent_Modifier; + +cpptext +{ + INT* GetOptimizedRepList( BYTE* InDefault, FPropertyRetirement* Retire, INT* Ptr, UPackageMap* Map, UActorChannel* Channel ); + UBOOL Tick( FLOAT DeltaTime, enum ELevelTick TickType ); + virtual void Spawned(); + virtual void BeginDestroy(); + + virtual UBOOL IsPlayerOwned() + { + return IsPlayerOwner(); + } + + virtual UBOOL IsPlayerOwner() + { + return bIsPlayer; + } + virtual AController* GetAController() { return this; } + + // Seeing and hearing checks + virtual UBOOL CanHear(const FVector& NoiseLoc, FLOAT Loudness, AActor *Other); + virtual void ShowSelf(); + virtual UBOOL ShouldCheckVisibilityOf(AController* C); + virtual DWORD SeePawn(APawn *Other, UBOOL bMaySkipChecks = TRUE); + virtual DWORD LineOfSightTo(const AActor* Other, INT bUseLOSFlag=0, const FVector* chkLocation = NULL, UBOOL bTryAlternateTargetLoc = FALSE); + void CheckEnemyVisible(); + virtual void HearNoise(AActor* NoiseMaker, FLOAT Loudness, FName NoiseType); + + AActor* HandleSpecial(AActor *bestPath); + virtual INT AcceptNearbyPath(AActor* goal); + virtual UReachSpec* PrepareForMove( ANavigationPoint *NavGoal, UReachSpec* Path ); + UReachSpec* GetNextRoutePath( ANavigationPoint *NavGoal ); + virtual void AdjustFromWall(FVector HitNormal, AActor* HitActor); + void SetRouteCache( ANavigationPoint *EndPath, FLOAT StartDist, FLOAT EndDist ); + AActor* FindPath(const FVector& Point, AActor* Goal, UBOOL bWeightDetours, INT MaxPathLength, UBOOL bReturnPartial); + /** given the passed in goal for pathfinding, set bTransientEndPoint on all NavigationPoints that are acceptable + * destinations on the path network + * @param EndAnchor the Anchor for the goal on the navigation network + * @param Goal the goal actor we're pathfinding toward (may be NULL) + * @param GoalLocation the goal world location we're pathfinding toward + */ + virtual void MarkEndPoints(ANavigationPoint* EndAnchor, AActor* Goal, const FVector& GoalLocation); + /** gives the Controller a chance to pre-empt pathfinding with its own result (if a cached path is still valid, for example) + * called just before navigation network traversal, after Anchor determination and NavigationPoint transient properties are set up + * only called when using the 'FindEndPoint' node evaluator + * @param EndAnchor - Anchor for Goal on the path network + * @param Goal - Destination Actor we're trying to path to (may be NULL) + * @param GoalLocation - the goal world location we're pathfinding toward + * @param bWeightDetours - whether we should consider short detours for pickups and such + * @param BestWeight - weighting value for best node on path - if this function returns true, findPathToward() will return this value + * @return whether the normal pathfinding should be skipped + */ + virtual UBOOL OverridePathTo(ANavigationPoint* EndAnchor, AActor* Goal, const FVector& GoalLocation, UBOOL bWeightDetours, FLOAT& BestWeight) + { + return FALSE; + } + AActor* SetPath(INT bInitialPath=1); + virtual UBOOL WantsLedgeCheck(); + virtual UBOOL StopAtLedge(); + virtual void PrePollMove() + {} + virtual void PostPollMove() + {} + virtual void PollMoveComplete(); + virtual AActor* GetViewTarget(); + virtual void UpdateEnemyInfo(APawn* AcquiredEnemy) {}; +#if __TW_ + virtual void JumpOverWall(FVector WallNormal, AActor* Wall); +#else + virtual void JumpOverWall(FVector WallNormal); +#endif + virtual void UpdatePawnRotation(); + virtual UBOOL ForceReached(ANavigationPoint *Nav, const FVector& TestPosition); + virtual FRotator SetRotationRate(FLOAT deltaTime); + virtual FVector DesiredDirection(); + /** activates path lanes for this Controller's current movement and adjusts its destination accordingly + * @param DesiredLaneOffset the offset from the center of the Controller's CurrentPath that is desired + * the Controller sets its LaneOffset as close as it can get to it without + * allowing any part of the Pawn's cylinder outside of the CurrentPath + */ +#if __TW_PATHFINDING_ + virtual void SetPathLane(FLOAT InPathOffset); +#else + void SetPathLane(FLOAT InPathOffset); +#endif + +#if __TW_AIDEBUGGING_ + virtual void FailMove( const FString& Reason ); +#else + virtual void FailMove(); +#endif + // falling physics AI hooks + virtual void PreAirSteering(FLOAT DeltaTime) {}; + virtual void PostAirSteering(FLOAT DeltaTime) {}; + virtual void PostPhysFalling(FLOAT DeltaTime) {}; + virtual void PostPhysWalking(FLOAT DeltaTime) {}; + virtual void PostPhysSpider(FLOAT DeltaTime) {}; + virtual UBOOL AirControlFromWall(float DeltaTime, FVector& RealAcceleration) { return FALSE; }; + virtual void NotifyJumpApex(); + + virtual void PostBeginPlay(); + virtual void PostScriptDestroyed(); + + virtual void ClearCrossLevelPaths(ULevel *Level); + + // Natives. + DECLARE_FUNCTION(execPollWaitForLanding); + virtual DECLARE_FUNCTION(execPollMoveTo); + virtual DECLARE_FUNCTION(execPollMoveToward); + DECLARE_FUNCTION(execPollFinishRotation); + + virtual UBOOL ShouldOffsetCorners() { return TRUE; } + virtual UBOOL ShouldUsePathLanes() { return TRUE; } + virtual UBOOL ShouldIgnoreNavigationBlockingFor(const AActor* Other){ return !Other->bBlocksNavigation; } + + // AnimControl Matinee Track support + + /** Used to provide information on the slots that this Actor provides for animation to Matinee. */ + virtual void GetAnimControlSlotDesc(TArray& OutSlotDescs); + + /** + * Called by Matinee when we open it to start controlling animation on this Actor. + * Is also called again when the GroupAnimSets array changes in Matinee, so must support multiple calls. + */ + virtual void PreviewBeginAnimControl(class UInterpGroup* InInterpGroup); + + /** Called each frame by Matinee to update the desired sequence by name and position within it. */ + virtual void PreviewSetAnimPosition(FName SlotName, INT ChannelIndex, FName InAnimSeqName, FLOAT InPosition, UBOOL bLooping, UBOOL bFireNotifies, UBOOL bEnableRootMotion, FLOAT DeltaTime); + + /** Called each frame by Matinee to update the desired animation channel weights for this Actor. */ + virtual void PreviewSetAnimWeights(TArray& SlotInfos); + + /** Called by Matinee when we close it after we have been controlling animation on this Actor. */ + virtual void PreviewFinishAnimControl(class UInterpGroup* InInterpGroup); + + /** Function used to control FaceFX animation in the editor (Matinee). */ + virtual void PreviewUpdateFaceFX(UBOOL bForceAnim, const FString& GroupName, const FString& SeqName, FLOAT InPosition); + + /** Used by Matinee playback to start a FaceFX animation playing. */ +// WWISEMODIF_START + virtual void PreviewActorPlayFaceFX(const FString& GroupName, const FString& SeqName, UAkBaseSoundObject* InSoundCue); +// WWISEMODIF_END + + /** Used by Matinee to stop current FaceFX animation playing. */ + virtual void PreviewActorStopFaceFX(); + + /** Used in Matinee to get the AudioComponent we should play facial animation audio on. */ + virtual UAudioComponent* PreviewGetFaceFXAudioComponent(); + + /** Get the UFaceFXAsset that is currently being used by this Actor when playing facial animations. */ + virtual class UFaceFXAsset* PreviewGetActorFaceFXAsset(); + + /** Called each frame by Matinee to update the weight of a particular MorphNodeWeight. */ + virtual void PreviewSetMorphWeight(FName MorphNodeName, FLOAT MorphWeight); + + /** Called each frame by Matinee to update the scaling on a SkelControl. */ + virtual void PreviewSetSkelControlScale(FName SkelControlName, FLOAT Scale); + + /** Called each frame by Matinee to update the controlstrength on a SkelControl. */ + virtual void SetSkelControlStrength(FName SkelControlName, FLOAT ControlStrength); + + /** Called each from while the Matinee action is running, to set the animation weights for the actor. */ + virtual void SetAnimWeights( const TArray& SlotInfos ); + + /** base function called to kick off moveto latent action (called from execMoveTo and execMoveToDirectNonPathPos) */ + virtual void MoveTo(const FVector& Dest, AActor* ViewFocus, FLOAT DesiredOffset, UBOOL bShouldWalk); + + /** base function called to kick off movetoward latent action (called from execMoveToward) */ + virtual void MoveToward(AActor* goal, AActor* viewfocus, FLOAT DesiredOffset, UBOOL bStrafe, UBOOL bShouldWalk); + + + /** IMPLEMENT Interface_NavigationHandle */ + virtual UBOOL CanCoverSlip(ACoverLink* Link, INT SlotIdx); + virtual void SetupPathfindingParams( FNavMeshPathParams& out_ParamCache ); + virtual void InitForPathfinding() {} + virtual INT ExtraEdgeCostToAddWhenActive(FNavMeshEdgeBase* Edge) { return 0; } + virtual FVector GetEdgeZAdjust(FNavMeshEdgeBase* Edge); + /** END */ + + virtual FLOAT GetMaxDropHeight(); +} + + +replication +{ + if (bNetDirty && Role==ROLE_Authority) + PlayerReplicationInfo, Pawn; +} + +/** returns whether this Controller is a locally controlled PlayerController + * @note not valid until the Controller is completely spawned (i.e, unusable in Pre/PostBeginPlay()) + */ +native function bool IsLocalPlayerController(); + +/** returns whether this controller is a local controller. + * @RETURN true always for non-playercontroller + */ +native function bool IsLocalController(); + +/** Route Cache Operations + * Allows operations on nodes in the route while modifying route (ie before emptying the cache) + * Should override in subclasses as needed + */ +native function RouteCache_Empty(); +native function RouteCache_AddItem( NavigationPoint Nav ); +native function RouteCache_InsertItem( NavigationPoint Nav, int Idx=0 ); +native function RouteCache_RemoveItem( NavigationPoint Nav ); +native function RouteCache_RemoveIndex( int InIndex, int Count=1 ); + +/** Set FocalPoint as absolute position or offset from base */ +native final function SetFocalPoint( Vector FP, optional bool bOffsetFromBase ); +/** Retrive the final position that controller should be looking at */ +native final function Vector GetFocalPoint(); + +/** Set Destination as absolute position or offset from base */ +native final function SetDestinationPosition( Vector Dest, optional bool bOffsetFromBase ); +/** Retrive the final position that controller should be moving to */ +native final function Vector GetDestinationPosition(); + +native final virtual function SetAdjustLocation( Vector NewLoc, bool bAdjust, optional bool bOffsetFromBase ); +native final function Vector GetAdjustLocation(); + +/** + * this event is called when an edge is deleted that this controller's handle is actively using + */ +event NotifyPathChanged(); + +`if(`__TW_PATHFINDING_) +event FailedToFindAnchor(); +event JumpedOverWall( vector WallHitNormal, optional actor Wall ); +event NotifyFailMove( string Reason ); +event AILog_Internal( coerce string LogText, optional Name LogCategory, optional bool bForce, optional bool BugIt, optional bool bSkipExtraInfo ); +event PauseAndShowMsg( optional string MsgTxt, optional vector TeleportToLocation ); +`endif + +/** Called when we start an AnimControl track operating on this Actor. Supplied is the set of AnimSets we are going to want to play from. */ +simulated event BeginAnimControl(InterpGroup InInterpGroup) +{ + Pawn.BeginAnimControl(InInterpGroup); +} + +/** Called each from while the Matinee action is running, with the desired sequence name and position we want to be at. */ +simulated event SetAnimPosition(name SlotName, int ChannelIndex, name InAnimSeqName, float InPosition, bool bFireNotifies, bool bLooping, bool bEnableRootMotion) +{ + Pawn.SetAnimPosition(SlotName, ChannelIndex, InAnimSeqName, InPosition, bFireNotifies, bLooping, bEnableRootMotion); +} + +/** Called when we are done with the AnimControl track. */ +simulated event FinishAnimControl(InterpGroup InInterpGroup) +{ + Pawn.FinishAnimControl(InInterpGroup); +} + +/** + * Play FaceFX animations on this Actor. + * Returns TRUE if succeeded, if failed, a log warning will be issued. + */ +// WWISEMODIF_START +event bool PlayActorFaceFXAnim(FaceFXAnimSet AnimSet, String GroupName, String SeqName, SoundCue SoundCueToPlay, AkEvent AkEventToPlay) +{ + return Pawn.PlayActorFaceFXAnim(AnimSet, GroupName, SeqName, SoundCueToPlay, AkEventToPlay); +} +// WWISEMODIF_END + +/** Stop any matinee FaceFX animations on this Actor. */ +event StopActorFaceFXAnim() +{ + Pawn.StopActorFaceFXAnim(); +} + +/** Called each frame by Matinee to update the weight of a particular MorphNodeWeight. */ +event SetMorphWeight(name MorphNodeName, float MorphWeight) +{ + Pawn.SetMorphweight(MorphNodeName, MorphWeight); +} + +/** Called each frame by Matinee to update the scaling on a SkelControl. */ +event SetSkelControlScale(name SkelControlName, float Scale) +{ + Pawn.SetSkelControlScale(SkelControlName, Scale); +} +/* epic =============================================== +* ::PostBeginPlay +* +* Overridden to create the player replication info and +* perform other mundane initialization tasks. +* +* ===================================================== +*/ +event PostBeginPlay() +{ + Super.PostBeginPlay(); + + if ( !bDeleteMe && (WorldInfo.NetMode != NM_Client) ) + { + if( bIsPlayer ) + { + // create a new player replication info + InitPlayerReplicationInfo(); + } + InitNavigationHandle(); + } + // randomly offset the sight counter to avoid hitches + SightCounter = SightCounterInterval * FRand(); +} + +/* epic =============================================== +* ::Reset +* +* Resets various properties to their default state, used +* for round resetting, etc. +* +* ===================================================== +*/ +function Reset() +{ + super.Reset(); + Enemy = None; + StartSpot = None; + bAdjusting = false; + bPreparingMove = false; + MoveTimer = -1; + MoveTarget = None; + CurrentPath = None; + RouteGoal = None; +} + +/* epic =============================================== +* ::ClientSetLocation +* +* Replicated function to set the pawn location and +* rotation, allowing server to force (ex. teleports). +* +* ===================================================== +*/ +reliable client function ClientSetLocation( vector NewLocation, rotator NewRotation ) +{ + SetRotation(NewRotation); + if ( Pawn != None ) + { + if ( (Rotation.Pitch > Pawn.MaxPitchLimit) + && (Rotation.Pitch < 65536 - Pawn.MaxPitchLimit) ) + { + If (Rotation.Pitch < 32768) + NewRotation.Pitch = Pawn.MaxPitchLimit; + else + NewRotation.Pitch = 65536 - Pawn.MaxPitchLimit; + } + NewRotation.Roll = 0; + Pawn.SetRotation( NewRotation ); + Pawn.SetLocation( NewLocation ); + } +} + +/* epic =============================================== +* ::ClientSetRotation +* +* Replicated function to set the pawn rotation, allowing +* the server to force. +* +* ===================================================== +*/ +reliable client function ClientSetRotation( rotator NewRotation, optional bool bResetCamera ) +{ + SetRotation(NewRotation); + if ( Pawn != None ) + { + NewRotation.Pitch = 0; + NewRotation.Roll = 0; + Pawn.SetRotation( NewRotation ); + } +} + +/* epic =============================================== +* ::ReplicatedEvent +* +* Called when a variable with the property flag "RepNotify" is replicated +* +* ===================================================== +*/ +simulated event ReplicatedEvent(name VarName) +{ + if (VarName == 'PlayerReplicationInfo') + { + if (PlayerReplicationInfo != None) + { + PlayerReplicationInfo.ClientInitialize(self); + } + } + else + { + Super.ReplicatedEvent(VarName); + } +} + +/** Kismet Action to possess a Pawn or a vehicle */ +function OnPossess(SeqAct_Possess inAction) +{ + local Pawn OldPawn; + local Vehicle V; + + // if we're driving a vehicle, and we should try to get out first. + V = Vehicle(Pawn); + if( inAction.bTryToLeaveVehicle && + V != None ) + { + V.DriverLeave( TRUE ); + } + + if( inAction.PawnToPossess != None ) + { + V = Vehicle(inAction.PawnToPossess); + if( Pawn!= None && V != None ) + { + V.TryToDrive( Pawn ); + } + else + { + OldPawn = Pawn; + UnPossess(); + Possess( inAction.PawnToPossess, FALSE ); + + if( inAction.bKillOldPawn && OldPawn != None ) + { + OldPawn.Destroy(); + } + } + } +} + + +/* epic =============================================== +* ::Possess +* +* Handles attaching this controller to the specified +* pawn. +* +* ===================================================== +*/ +event Possess(Pawn inPawn, bool bVehicleTransition) +{ + if (inPawn.Controller != None) + { + inPawn.Controller.UnPossess(); + } + + inPawn.PossessedBy(self, bVehicleTransition); + Pawn = inPawn; + + // preserve Pawn's rotation initially for placed Pawns + SetFocalPoint( Pawn.Location + 512*vector(Pawn.Rotation), TRUE ); + Restart(bVehicleTransition); + + if( Pawn.Weapon == None ) + { + ClientSwitchToBestWeapon(); + } +} + +/* epic =============================================== +* ::UnPossess +* +* Called to unpossess our pawn for any reason that is not death +* (death handled by PawnDied()) +* +* ===================================================== +*/ +event UnPossess() +{ + if ( Pawn != None ) + { + Pawn.UnPossessed(); + Pawn = None; + } +} + +/* epic =============================================== +* ::PawnDied +* +* Called to unpossess our pawn because it has died +* (other unpossession handled by UnPossess()) +* +* ===================================================== +*/ +function PawnDied(Pawn inPawn) +{ + local int idx; + + if ( inPawn != Pawn ) + { // if that's not our current pawn, leave + return; + } + + // abort any latent actions + TriggerEventClass(class'SeqEvent_Death',self); + for (idx = 0; idx < LatentActions.Length; idx++) + { + if (LatentActions[idx] != None) + { + LatentActions[idx].AbortFor(self); + } + } + LatentActions.Length = 0; + + if ( Pawn != None ) + { + SetLocation(Pawn.Location); + Pawn.UnPossessed(); + } + Pawn = None; + + // if we are a player, transition to the dead state + if ( bIsPlayer ) + { + // only if the game hasn't ended, + if ( !GamePlayEndedState() ) + { + // so that we can respawn + GotoState('Dead'); + } + } + // otherwise destroy this controller + else + { + Destroy(); + } +} + +function bool GamePlayEndedState() +{ + return false; +} + +/* epic =============================================== +* ::NotifyPostLanded +* +* Called after pawn lands after falling if bNotifyPostLanded is true +* +* ===================================================== +*/ +event NotifyPostLanded(); + +/* epic =============================================== +* ::Destroyed +* +* Called once this controller has been deleted, overridden +* to cleanup any lingering references, etc. +* +* ===================================================== +*/ +event Destroyed() +{ + if (Role == ROLE_Authority) + { + // if we are a player, log out + if ( bIsPlayer && (WorldInfo.Game != None) ) + { + WorldInfo.Game.logout(self); + } + if ( PlayerReplicationInfo != None ) + { + // remove from team if applicable + if ( !PlayerReplicationInfo.bOnlySpectator && + PlayerReplicationInfo.Team != None ) + { + PlayerReplicationInfo.Team.RemoveFromTeam(self); + } + CleanupPRI(); + } + } + Super.Destroyed(); +} + +/* epic =============================================== +* ::CleanupPRI +* +* Called from Destroyed(). Cleans up PlayerReplicationInfo. +* +* ===================================================== +*/ +function CleanupPRI() +{ + PlayerReplicationInfo.Destroy(); + PlayerReplicationInfo = None; +} + +/* epic =============================================== +* ::Restart +* +* Called upon possessing a new pawn, perform any specific +* cleanup/initialization here. +* +* ===================================================== +*/ +function Restart(bool bVehicleTransition) +{ + Pawn.Restart(); + if ( !bVehicleTransition ) + { + Enemy = None; + } + + // if not vehicle transition, clear controller information + if ( bVehicleTransition == FALSE && Pawn.InvManager != None ) + { + Pawn.InvManager.UpdateController(); + } +} + +/* epic =============================================== +* ::BeyondFogDistance +* +* Returns true if OtherPoint is occluded by fog when viewed from ViewPoint. +* +* ===================================================== +*/ +final native function bool BeyondFogDistance(vector ViewPoint, vector OtherPoint); + +/* epic =============================================== +* ::EnemyJustTeleported +* +* Notification that Enemy just went through a teleporter. +* +* ===================================================== +*/ +function EnemyJustTeleported() +{ + LineOfSightTo(Enemy); +} + +/* epic =============================================== +* ::NotifyTakeHit +* +* Notification from pawn that it has received damage +* via TakeDamage(). +* +* ===================================================== +*/ +function NotifyTakeHit(Controller InstigatedBy, vector HitLocation, int Damage, class damageType, vector Momentum); + +/** spawns and initializes the PlayerReplicationInfo for this Controller */ +function InitPlayerReplicationInfo() +{ + PlayerReplicationInfo = Spawn(WorldInfo.Game.PlayerReplicationInfoClass, self,, vect(0,0,0),rot(0,0,0)); + // force a default player name if necessary + if (PlayerReplicationInfo.PlayerName == "") + { + // don't call SetPlayerName() as that will broadcast entry messages but the GameInfo hasn't had a chance + // to potentionally apply a player/bot name yet + PlayerReplicationInfo.PlayerName = class'GameInfo'.default.DefaultPlayerName; + } +} + +/* + * Queries the PRI and returns our current team index. + */ +simulated native function byte GetTeamNum(); + +/* epic =============================================== +* ::ServerRestartPlayer +* +* Attempts to restart this player, generally called from +* the client upon respawn request. +* +* ===================================================== +*/ +reliable server function ServerRestartPlayer() +{ + if (WorldInfo.NetMode != NM_Client && + Pawn != None) + { + ServerGivePawn(); + } +} + +/* epic =============================================== +* ::ServerGivePawn +* +* Requests a pawn from the server for this controller, +* as part of the respawn process. +* +* ===================================================== +*/ +function ServerGivePawn(); + +/* epic =============================================== +* ::SetCharacter +* +* Sets the character for this controller for future +* pawn spawns. +* +* ===================================================== +*/ +function SetCharacter(string inCharacter); + +/* epic =============================================== +* ::GameHasEnded +* +* Called from game info upon end of the game, used to +* transition to proper state. +* +* ===================================================== +*/ +function GameHasEnded(optional Actor EndGameFocus, optional bool bIsWinner) +{ + // and transition to the game ended state + GotoState('RoundEnded'); +} + +/* epic =============================================== +* ::NotifyKilled +* +* Notification from game that a pawn has been killed. +* +* ===================================================== +*/ +function NotifyKilled(Controller Killer, Controller Killed, pawn KilledPawn, class damageTyp) +{ + if( Pawn != None ) + { + Pawn.TriggerEventClass( class'SeqEvent_SeeDeath', KilledPawn ); + } + + if (Enemy == KilledPawn) + { + Enemy = None; + } +} + +function NotifyProjLanded( Projectile Proj ) +{ + if( Proj != None && Pawn != None ) + { + Pawn.TriggerEventClass( class'SeqEvent_ProjectileLanded', Proj ); + } +} + +/** + * Notification from given projectil that it is about to explode + */ +function WarnProjExplode( Projectile Proj ); + +//============================================================================= +// INVENTORY FUNCTIONS + +/* epic =============================================== +* ::RatePickup +* +* Callback from PickupFactory that allows players to +* additionally weight certain pickups. +* +* ===================================================== +*/ +event float RatePickup(Actor PickupHolder, class inPickup); + +/* epic =============================================== +* ::FireWeaponAt +* +* Should cause this player to fire a weapon at the given +* actor. +* +* ===================================================== +*/ +function bool FireWeaponAt(Actor inActor); + +/* epic =============================================== +* ::StopFiring +* +* Stop firing of our current weapon. +* +* ===================================================== +*/ +event StopFiring() +{ + bFire = 0; + if ( Pawn != None ) + Pawn.StopFiring(); +} + +/* epic =============================================== +* ::RoundHasEnded +* +* +* ===================================================== +*/ +function RoundHasEnded(optional Actor EndRoundFocus) +{ + GotoState('RoundEnded'); +} + +/* epic =============================================== +* ::HandlePickup +* +* Called whenever our pawn runs over a new pickup. +* +* ===================================================== +*/ +function HandlePickup(Inventory Inv); + +/** + * Adjusts weapon aiming direction. + * Gives controller a chance to modify the aiming of the pawn. For example aim error, auto aiming, adhesion, AI help... + * Requested by weapon prior to firing. +* + * @param W, weapon about to fire + * @param StartFireLoc, world location of weapon fire start trace, or projectile spawn loc. + */ +function Rotator GetAdjustedAimFor( Weapon W, vector StartFireLoc ) +{ + // by default, return Rotation. This is the standard aim for controllers + // see implementation for PlayerController. + if ( Pawn != None ) + { + return Pawn.GetBaseAimRotation(); + } + return Rotation; +} + +/* epic =============================================== +* ::InstantWarnTarget +* +* Warn a target it is about to be shot at with an instant hit +* weapon. +* +* ===================================================== +*/ +function InstantWarnTarget(Actor InTarget, Weapon FiredWeapon, vector FireDir) +{ + local Pawn P; + + P = Pawn(InTarget); + if (P != None && P.Controller != None) + { + P.Controller.ReceiveWarning(Pawn, -1, FireDir); + } +} + +/* epic =============================================== +* ::ReceiveWarning +* +* Notification that the pawn is about to be shot by a +* trace hit weapon. +* +* ===================================================== +*/ +function ReceiveWarning(Pawn shooter, float projSpeed, vector FireDir); + +/* epic =============================================== +* ::ReceiveProjectileWarning +* +* Notification that the pawn is about to be shot by a +* projectile. +* +* ===================================================== +*/ +function ReceiveProjectileWarning(Projectile Proj); + +/* epic =============================================== +* ::SwitchToBestWeapon +* +* Rates the pawn's weapon loadout and chooses the best +* weapon, bringing it up as the active weapon. +* +* ===================================================== +*/ + +exec function SwitchToBestWeapon(optional bool bForceNewWeapon) +{ + if ( Pawn == None || Pawn.InvManager == None ) + return; + + Pawn.InvManager.SwitchToBestWeapon(bForceNewWeapon); +} + +/* epic =============================================== +* ::ClientSwitchToBestWeapon +* +* Forces the client to switch to a new weapon, allowing +* the server control. +* +* ===================================================== +*/ +reliable client function ClientSwitchToBestWeapon(optional bool bForceNewWeapon) +{ + SwitchToBestWeapon(bForceNewWeapon); +} + +/* epic =============================================== +* ::NotifyChangedWeapon +* +* Notification from pawn that the current weapon has +* changed. +* Network: LocalPlayer +* ===================================================== +*/ +function NotifyChangedWeapon( Weapon PrevWeapon, Weapon NewWeapon ); + +//============================================================================= +// AI FUNCTIONS + +/* epic =============================================== +* ::LineOfSightTo +* +* Returns true if the specified actor has line of sight +* to our pawn. +* +* NOTE: No FOV is accounted for, use CanSee(). +* +* ===================================================== +*/ +native(514) noexport final function bool LineOfSightTo(Actor Other, optional vector chkLocation, optional bool bTryAlternateTargetLoc); + +/* epic =============================================== +* ::CanSee +* +* Returns true if the specified pawn is visible within +* our peripheral vision. If the pawn is not our current +* enemy then LineOfSightTo() will be called instead. +* +* ===================================================== +*/ +native(533) final function bool CanSee(Pawn Other); + +/* epic =============================================== +* ::CanSee +* +* Returns true if the test location is visible within +* our peripheral vision (from view location). +* +* ===================================================== +*/ +native(537) final function bool CanSeeByPoints( Vector ViewLocation, Vector TestLocation, Rotator ViewRotation ); + +/* epic =============================================== +* ::PickTarget +* +* Evaluates pawns in the local area and returns the +* one that is closest to the specified FireDir. +* +* ===================================================== +*/ +`if(`__TW_) +native(531) final function Pawn PickTarget(class TargetClass, out float bestAim, out float bestDist, vector FireDir, vector projStart, float MaxRange, optional bool bTargetTeammates = False); +`else +native(531) final function Pawn PickTarget(class TargetClass, out float bestAim, out float bestDist, vector FireDir, vector projStart, float MaxRange); +`endif + +/* epic =============================================== +* ::HearNoise +* +* Counterpart to the Actor::MakeNoise() function, called +* whenever this player is within range of a given noise. +* Used as AI audio cues, instead of processing actual +* sounds. +* +* ===================================================== +*/ +event HearNoise( float Loudness, Actor NoiseMaker, optional Name NoiseType ); + +/* epic =============================================== +* ::SeePlayer +* +* Called whenever Seen is within of our line of sight +* if Seen.bIsPlayer==true. +* +* ===================================================== +*/ +event SeePlayer( Pawn Seen ); + +/* epic =============================================== +* ::SeeMonster +* +* Called whenever Seen is within of our line of sight +* if Seen.bIsPlayer==false. +* +* ===================================================== +*/ +event SeeMonster( Pawn Seen ); + +/* epic =============================================== +* ::EnemyNotVisible +* +* Called whenever Enemy is no longer within of our line +* of sight. +* +* ===================================================== +*/ +event EnemyNotVisible(); + +//============================================================================= +// NAVIGATION FUNCTIONS + +/* epic =============================================== +* ::MoveTo +* +* Latently moves our pawn to the desired location, which +* is cached in Destination. +* +* ===================================================== +*/ +native(500) noexport final latent function MoveTo(vector NewDestination, optional Actor ViewFocus, optional float DestinationOffset, optional bool bShouldWalk = (Pawn != None) ? Pawn.bIsWalking : false); + +/* epic =============================================== +* ::MoveToDirectNonPathPos +* +* Latently moves our pawn to the desired location, which +* is cached in Destination. +* NOTE: this function should be used only when moving directly to a final goal (e.g. not following a path) +* it will properly set the final destination on the navhandle (and ensure things are cleared out which would normally be set by GetNextMoveLocation) +* @Param NewDestination - destination to move to +* @param ViewFocus - actor to look at while moving +* @param DestinationOffset - distance from goal we would like to get within +* @param bShouldWalk - should the AI walk for this move? +* ===================================================== +*/ +native noexport final latent function MoveToDirectNonPathPos(vector NewDestination, optional Actor ViewFocus, optional float DestinationOffset, optional bool bShouldWalk = (Pawn != None) ? Pawn.bIsWalking : false); + +/* epic =============================================== +* ::MoveToward +* +* Latently moves our pawn to the desired actor, which +* is cached in MoveTarget. Takes advantage of the +* navigation network anchors when moving to other Pawn +* and Inventory actors. +* +* ===================================================== +*/ +native(502) noexport final latent function MoveToward(Actor NewTarget, optional Actor ViewFocus, optional float DestinationOffset, optional bool bUseStrafing, optional bool bShouldWalk = (Pawn != None) ? Pawn.bIsWalking : false); + +/* epic =============================================== +* ::SetupSpecialPathAbilities +* +* Called before path finding to allow setup of transient +* navigation flags. +* +* ===================================================== +*/ +event SetupSpecialPathAbilities(); + +/* epic =============================================== +* ::FinishRotation +* +* Latently waits for our pawn's rotation to match the +* pawn's DesiredRotation. +* +* ===================================================== +*/ +native(508) final latent function FinishRotation(); + +/* epic =============================================== +* ::FindPathTo +* +* Searches the navigation network for a path to the +* node closest to the given point. +* +* ===================================================== +*/ +native(518) final function Actor FindPathTo( Vector aPoint, optional int MaxPathLength, optional bool bReturnPartial ); + +/* epic =============================================== +* ::FindPathToward +* +* Searches the navigation network for a path to the +* node closest to the given actor. +* +* ===================================================== +*/ +native(517) final function Actor FindPathToward( Actor anActor, optional bool bWeightDetours, optional int MaxPathLength, optional bool bReturnPartial ); + +/* epic =============================================== +* ::FindPathTowardNearest +* +* Searches the navigation network for a path to the +* closest node of the specified type. +* +* ===================================================== +*/ +native final function Actor FindPathTowardNearest(class GoalClass, optional bool bWeightDetours, optional int MaxPathLength, optional bool bReturnPartial ); + +/* epic =============================================== +* ::FindRandomDest +* +* Returns a random node on the network. +* +* ===================================================== +*/ +native(525) final function NavigationPoint FindRandomDest(); + +native final function Actor FindPathToIntercept(Pawn P, Actor InRouteGoal, optional bool bWeightDetours, optional int MaxPathLength, optional bool bReturnPartial ); + +/* epic =============================================== +* ::PointReachable +* +* Returns true if the given point is directly reachable +* given our pawn's current movement capabilities. +* +* NOTE: This function is potentially expensive and should +* be used sparingly. If at all possible, use ActorReachable() +* instead, since that has more possible optimizations +* over PointReachable(). +* +* ===================================================== +*/ +native(521) final function bool PointReachable(vector aPoint); + +/* epic =============================================== +* ::ActorReachable +* +* Returns true if the given actor is directly reachable +* given our pawn's current movement capabilities. Takes +* advantage of the navigation network anchors when +* possible. +* +* NOTE: This function is potentially expensive and should +* be used sparingly. +* +* ===================================================== +*/ +native(520) final function bool ActorReachable(actor anActor); + +/** + * Called by APawn::moveToward when the point is unreachable + * due to obstruction or height differences. + */ +event MoveUnreachable(vector AttemptedDest, Actor AttemptedTarget) +{ +} + +/* epic =============================================== +* ::PickWallAdjust +* +* Checks if we could jump over obstruction (if within +* knee height), or attempts to move to either side of +* the obstruction. +* +* ===================================================== +*/ +native(526) final function bool PickWallAdjust(vector HitNormal); + +/* epic =============================================== +* ::WaitForLanding +* +* Latently waits until the pawn has landed. Only valid +* with PHYS_Falling. Optionally specify the max amount +* of time to wait, which defaults to 4 seconds. +* +* NOTE: If the pawn hasn't landed before the duration +* is exceeded, it will abort and call LongFall(). +* +* ===================================================== +*/ +native(527) noexport final latent function WaitForLanding(optional float waitDuration); + +/* epic =============================================== +* ::LongFall +* +* Called once the duration for WaitForLanding has been +* exceeded without hitting ground. +* +* ===================================================== +*/ +event LongFall(); + +/* epic =============================================== +* ::EndClimbLadder +* +* Aborts a latent move action if the MoveTarget is +* currently a ladder. +* +* ===================================================== +*/ +native function EndClimbLadder(); + +/* epic =============================================== +* ::MayFall +* +* Called when a pawn is about to fall off a ledge, and +* allows the controller to prevent a fall by toggling +* bCanJump. +* This event is also passed if a floor is found over the edge, and the normal of the floor if so. +* +* ===================================================== +*/ +event MayFall(bool bFloor, vector FloorNormal); + +/* epic =============================================== +* ::AllowDetourTo +* +* Return true to allow a detour to a given point, or +* false to avoid it. Called during any sort of path +* finding (FindPathXXX() functions). +* +* ===================================================== +*/ +event bool AllowDetourTo(NavigationPoint N) +{ + return true; +} + +/* epic =============================================== +* ::WaitForMover +* +* Used to notify AI controller that it needs to wait +* at its current position for an interpActor to +* become properly positioned. +* +* ===================================================== +*/ +function WaitForMover(InterpActor M) +{ + PendingMover = M; + M.bMonitorMover = true; + bPreparingMove = true; + Pawn.Acceleration = vect(0,0,0); +} + +/* epic =============================================== +* ::MoverFinished +* +* Called by InterpActor when it stops +* if this controller has it set as its PendingMover +* +* ===================================================== +*/ +event bool MoverFinished() +{ + if (Pawn == None || PendingMover.MyMarker == None || PendingMover.MyMarker.ProceedWithMove(Pawn)) + { + PendingMover = None; + bPreparingMove = false; + return true; + } + return false; +} + +/** Called when the this Controller's Pawn gets hit by an InterpActor interpolating downward while this Controller has Lift + * set as its PendingMover + * @param Lift the LiftCenter associated with the InterpActor that hit the Pawn + */ +function UnderLift(LiftCenter Lift); + +/** called when a ReachSpec the AI wants to use is blocked by a dynamic obstruction + * gives the AI an opportunity to do something to get rid of it instead of trying to find another path + * @note MoveTarget is the actor the AI wants to move toward, CurrentPath the ReachSpec it wants to use + * @param BlockedBy the object blocking the path + * @return true if the AI did something about the obstruction and should use the path anyway, false if the path + * is unusable and the bot must find some other way to go + */ +event bool HandlePathObstruction(Actor BlockedBy); + +//============================================================================= +// CAMERA FUNCTIONS + +/** + * Returns Player's Point of View + * For the AI this means the Pawn's 'Eyes' ViewPoint + * For a Human player, this means the Camera's ViewPoint +* + * @output out_Location, view location of player + * @output out_rotation, view rotation of player +*/ +simulated event GetPlayerViewPoint( out vector out_Location, out Rotator out_rotation ) +{ + out_Location = Location; + out_Rotation = Rotation; +} + +/** + * returns the point of view of the actor. + * note that this doesn't mean the camera, but the 'eyes' of the actor. + * For example, for a Pawn, this would define the eye height location, + * and view rotation (which is different from the pawn rotation which has a zeroed pitch component). + * A camera first person view will typically use this view point. Most traces (weapon, AI) will be done from this view point. +* + * @output out_Location, location of view point + * @output out_Rotation, view rotation of actor. +*/ +simulated event GetActorEyesViewPoint( out vector out_Location, out Rotator out_Rotation ) +{ + // If we have a Pawn, this is our view point. + if ( Pawn != None ) + { + Pawn.GetActorEyesViewPoint( out_Location, out_Rotation ); + } + else + { // Otherwise controller location/rotation is our view point. + out_Location = Location; + out_Rotation = Rotation; + } +} + +/** + * This will return whether or not this controller is aiming at the passed in actor. + * We are defining AIMing to mean that you are attempting to target the actor. Not just looking in the + * direction of the actor. + * + **/ +simulated function bool IsAimingAt( Actor ATarget, float Epsilon ) +{ + local Vector Loc; + local Rotator Rot; + + // grab camera location/rotation for checking Dist + GetPlayerViewPoint( Loc, Rot ); + + // a decent epsilon value is 0.98f as that allows a for a little bit of slop + // NOTE: if you want to aim DIRECTLY at something then you would want ~= 1.0f + return ( (Normal(ATarget.Location - Loc) dot vector(Rot)) >= Epsilon ); +} + +/** LandingShake() +returns true if controller wants landing view shake +*/ +simulated function bool LandingShake() +{ + return false; +} + +//============================================================================= +// PHYSICS FUNCTIONS + +/* epic =============================================== +* ::NotifyPhysicsVolumeChange +* +* Called when our pawn enters a new physics volume. +* +* ===================================================== +*/ +event NotifyPhysicsVolumeChange(PhysicsVolume NewVolume); + +/* epic =============================================== +* ::NotifyHeadVolumeChange +* +* Called when our pawn's head enters a new physics +* volume. +* return true to prevent HeadVolumeChange() notification on the pawn. +* +* ===================================================== +*/ +event bool NotifyHeadVolumeChange(PhysicsVolume NewVolume); + +/* epic =============================================== +* ::NotifyLanded +* +* Called when our pawn has landed from a fall, return +* true to prevent Landed() notification on the pawn. +* +* ===================================================== +*/ +event bool NotifyLanded(vector HitNormal, Actor FloorActor); + +/* epic =============================================== +* ::NotifyHitWall +* +* Called when our pawn has collided with a blocking +* piece of world geometry, return true to prevent +* HitWall() notification on the pawn. +* +* ===================================================== +*/ +event bool NotifyHitWall(vector HitNormal, actor Wall); + +/* epic =============================================== +* ::NotifyFallingHitWall +* +* Called when our pawn has collided with a blocking +* piece of world geometry while falling, only called if +* bNotifyFallingHitWall is true +* ===================================================== +*/ +event NotifyFallingHitWall(vector HitNormal, actor Wall); + +/* epic =============================================== +* ::NotifyBump +* +* Called when our pawn has collided with a blocking player, +* return true to prevent Bump() notification on the pawn. +* +* ===================================================== +*/ +event bool NotifyBump(Actor Other, Vector HitNormal); + +/* epic =============================================== +* ::NotifyJumpApex +* +* Called when our pawn has reached the apex of a jump. +* +* ===================================================== +*/ +event NotifyJumpApex(); + +/* epic =============================================== +* ::NotifyMissedJump +* +* Called when our pawn misses a jump while performing +* latent movement (ie MoveToward()). +* +* ===================================================== +*/ +event NotifyMissedJump(); + +/** Called when our pawn reaches Controller.Destination after setting bPreciseDestination = TRUE */ +event ReachedPreciseDestination(); + +//============================================================================= +// MISC FUNCTIONS + +/* epic =============================================== +* ::InLatentExecution +* +* Returns true if currently in the specified latent +* action. +* +* ===================================================== +*/ +native final function bool InLatentExecution(int LatentActionNumber); + +/* epic =============================================== +* ::StopLatentExecution +* +* Stops any active latent action. +* +* ===================================================== +*/ +native final function StopLatentExecution(); + +/** + * list important Controller variables on canvas. HUD will call DisplayDebug() on the current ViewTarget when + * the ShowDebug exec is used + * + * @param HUD - HUD with canvas to draw on + * @input out_YL - Height of the current font + * @input out_YPos - Y position on Canvas. out_YPos += out_YL, gives position to draw text for next debug line. + */ +simulated function DisplayDebug(HUD HUD, out float out_YL, out float out_YPos) +{ + local Canvas Canvas; + + Canvas = HUD.Canvas; + + if ( Pawn == None ) + { + if ( PlayerReplicationInfo == None ) + { + Canvas.DrawText("NO PLAYERREPLICATIONINFO", false); + } + else + { + PlayerReplicationInfo.DisplayDebug(HUD,out_YL,out_YPos); + } + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + + super.DisplayDebug(HUD,out_YL,out_YPos); + return; + } + + Canvas.SetDrawColor(255,0,0); + Canvas.DrawText("CONTROLLER "$GetItemName(string(Self))$" Pawn "$GetItemName(string(Pawn))); + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + + Canvas.DrawText(" bPreciseDestination:" @ bPreciseDestination); + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + + if (HUD.ShouldDisplayDebug('AI')) + { + if ( Enemy != None ) + { + Canvas.DrawText(" STATE: "$GetStateName()$" Enemy "$Enemy.GetHumanReadableName(), false); + } + else + { + Canvas.DrawText(" STATE: "$GetStateName()$" NO Enemy ", false); + } + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + } +} + +/* epic =============================================== +* ::GetHumanReadableName +* +* Returns the PRI player name if available, or of this +* controller object. +* +* ===================================================== +*/ +simulated function String GetHumanReadableName() +{ + if ( PlayerReplicationInfo != None ) + { + return PlayerReplicationInfo.PlayerName; + } + else + { + return GetItemName(String(self)); + } +} + +//============================================================================= +// CONTROLLER STATES + +function bool IsDead(); + +/* epic =============================================== +* state Dead +* +* Base state entered upon pawn death, if bIsPlayer is +* set to true. +* +* ===================================================== +*/ +State Dead +{ +ignores SeePlayer, HearNoise, KilledBy; + + function bool IsDead() { return TRUE; } + + function PawnDied(Pawn P) + { + if ( WorldInfo.NetMode != NM_Client ) + { + `warn( Self @ "Pawndied while dead" ); + ScriptTrace(); + } + } + + /* epic =============================================== + * ::ServerRestartPlayer + * + * Attempts to restart the player if not a client. + * + * ===================================================== + */ + reliable server function ServerReStartPlayer() + { + if ( WorldInfo.NetMode == NM_Client ) + return; + + // If we're still attached to a Pawn, leave it + if ( Pawn != None ) + { + UnPossess(); + } + + WorldInfo.Game.RestartPlayer( Self ); + } +} + +/* epic =============================================== +* state RoundEnded +* +* Base state entered upon the end of a game round, instigated +* by the +* +* ===================================================== +*/ +state RoundEnded +{ +ignores SeePlayer, HearNoise, KilledBy, NotifyBump, HitWall, NotifyPhysicsVolumeChange, NotifyHeadVolumeChange, Falling, TakeDamage, ReceiveWarning; + + function bool GamePlayEndedState() + { + return true; + } + + event BeginState(Name PreviousStateName) + { + // if we still have a valid pawn, + if ( Pawn != None ) + { + // stop it in midair and detach + Pawn.TurnOff(); + StopFiring(); + if (!bIsPlayer) + { + Pawn.UnPossessed(); + Pawn = None; + } + } + if ( !bIsPlayer ) + { + Destroy(); + } + } +} + +/** + * Overridden to redirect to pawn, since teleporting the controller + * would be useless. + * If Action == None, this was called from the Pawn already + */ +simulated function OnTeleport(SeqAct_Teleport Action) +{ + if( Action != None ) + { + if (Pawn != None) + { + Pawn.OnTeleport(Action); + } + else + { + Super.OnTeleport(Action); + } + } +} + +function OnAttachToActor(SeqAct_AttachToActor Action) +{ + if (Pawn != None) + { + Pawn.OnAttachToActor(Action); + } + else + { + Super.OnAttachToActor(Action); + } +} + +/** + * Sets god mode based on the activated link. + */ +function OnToggleGodMode(SeqAct_ToggleGodMode inAction) +{ + if (inAction.InputLinks[0].bHasImpulse) + { + bGodMode = true; + } + else if (inAction.InputLinks[1].bHasImpulse) + { + bGodMode = false; + } + else + { + bGodMode = !bGodMode; + } +} + +/** Redirects SetPhysics kismet action to the pawn */ +simulated function OnSetPhysics(SeqAct_SetPhysics Action) +{ + if( Pawn != None ) + { + Pawn.OnSetPhysics(Action); + } + else + { + Super.OnSetPhysics(Action); + } +} + +/** Redirects SetVelocity kismet action to the pawn */ +simulated function OnSetVelocity( SeqAct_SetVelocity Action ) +{ + if( Pawn != None ) + { + Pawn.OnSetVelocity(Action); + } + else + { + Super.OnSetVelocity(Action); + } +} + + + +/** + * Called when a slot is disabled with this controller as the current owner. + */ +simulated function NotifyCoverDisabled( CoverLink Link, int SlotIdx, optional bool bAdjacentIdx ); + +/** + * Called when a slot is adjusted with this controller as the current owner. + */ +simulated event NotifyCoverAdjusted() +{ + // do nothing. intended to be overloaded, but needs a body because it's an event. +} + +/** + * Called when cover that AI had claimed is claimed forceably by someone else (usually a player) + */ +simulated function bool NotifyCoverClaimViolation( Controller NewClaim, CoverLink Link, int SlotIdx ); + +/** +* Redirect to pawn. +*/ +simulated function OnModifyHealth(SeqAct_ModifyHealth Action) +{ + if (Pawn != None) + { + Pawn.OnModifyHealth(Action); + } +} + +/** + * Called when an inventory item is given to our Pawn + * (owning client only) + * @param NewItem the Inventory item that was added + */ +function NotifyAddInventory(Inventory NewItem); + +/** + * Overridden to redirect to the pawn if available. + */ +simulated function OnToggleHidden(SeqAct_ToggleHidden Action) +{ + if (Pawn != None) + { + Pawn.OnToggleHidden(Action); + } +} + +/** Returns true if controller is spectating */ +event bool IsSpectating() +{ + return false; +} + +/** Returns if controller is in combat */ +event bool IsInCombat( optional bool bForceCheck ); + +/** + * Called when the level this controller is in is unloaded via streaming. + */ +event CurrentLevelUnloaded(); + +function SendMessage(PlayerReplicationInfo Recipient, name MessageType, float Wait, optional class DamageType); + +function ReadyForLift(); + +/** spawn and init Navigation Handle */ +simulated function InitNavigationHandle() +{ + if( NavigationHandleClass != None ) + { + NavigationHandle = new(self) NavigationHandleClass; + } +} + +simulated event InterpolationStarted(SeqAct_Interp InterpAction, InterpGroupInst GroupInst) +{ + if (Pawn!=none) + { + Pawn.InterpolationStarted(InterpAction, GroupInst); + } + + Super.InterpolationStarted( InterpAction, GroupInst ); +} + +/** called when a SeqAct_Interp action finished interpolating this Actor + * @note this function is called on clients for actors that are interpolated clientside via MatineeActor + * @param InterpAction the SeqAct_Interp that was affecting the Actor + */ +simulated event InterpolationFinished(SeqAct_Interp InterpAction) +{ + if (Pawn!=none) + { + Pawn.InterpolationFinished(InterpAction); + } + + Super.InterpolationFinished( InterpAction ); +} + +event bool GeneratePathToActor( Actor Goal, optional float WithinDistance, optional bool bAllowPartialPath ); +event bool GeneratePathToLocation( Vector Goal, optional float WithinDistance, optional bool bAllowPartialPath ); + +defaultproperties +{ + RotationRate=(Pitch=30000,Yaw=30000,Roll=2048) + bHidden=TRUE + bHiddenEd=TRUE + MinHitWall=-1.f + bSlowerZAcquire=TRUE + RemoteRole=ROLE_None + bOnlyRelevantToOwner=TRUE + + SightCounterInterval=0.2 + MaxMoveTowardPawnTargetTime=1.2 + + NavigationHandleClass=class'NavigationHandle' +} diff --git a/Engine/Classes/CoverGroup.uc b/Engine/Classes/CoverGroup.uc new file mode 100644 index 0000000..3b1d24d --- /dev/null +++ b/Engine/Classes/CoverGroup.uc @@ -0,0 +1,84 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class CoverGroup extends Info + native + placeable + ClassGroup(Cover) + dependson(CoverLink); + +/** + * Defines a group of cover links they can be acted on as a single unit + * (ie enable/disable) + */ +cpptext +{ + void AutoFillGroup( ECoverGroupFillAction CGFA, TArray& Links ); + + virtual void GetActorReferences(TArray &ActorRefs, UBOOL bIsRemovingLevel); + + virtual void PostLoad(); +#if WITH_EDITOR + virtual void EditorApplyScale(const FVector& DeltaScale, const FMatrix& ScaleMatrix, const FVector* PivotLocation, UBOOL bAltDown, UBOOL bShiftDown, UBOOL bCtrlDown); + virtual void CheckForErrors(); +#endif +} + +enum ECoverGroupFillAction +{ + CGFA_Overwrite, + CGFA_Add, + CGFA_Remove, + CGFA_Clear, + CGFA_Cylinder, +}; + +/** List of cover links in the group */ +var() array CoverLinkRefs; + +/** Radius around group actor to select nodes */ +var() float AutoSelectRadius; +/** Z distance below group actor to select nodes */ +var() float AutoSelectHeight; + +native function EnableGroup(); +native function DisableGroup(); +native function ToggleGroup(); + +simulated function OnToggle( SeqAct_Toggle Action ) +{ + // On + if( Action.InputLinks[0].bHasImpulse ) + { + EnableGroup(); + } + // Off + if( Action.InputLinks[1].bHasImpulse ) + { + DisableGroup(); + } + // Toggle + if( Action.InputLinks[2].bHasImpulse ) + { + ToggleGroup(); + } +} + +defaultproperties +{ + Begin Object NAME=Sprite + Sprite=Texture2D'EditorMaterials.CovergroupIcon' + SpriteCategoryName="Cover" + End Object + + Begin Object Class=CoverGroupRenderingComponent Name=CoverGroupRenderer + AlwaysLoadOnClient=False + AlwaysLoadOnServer=False + End Object + Components.Add(CoverGroupRenderer) + + AutoSelectRadius=0.f + AutoSelectHeight=0.f + + bStatic=TRUE +} diff --git a/Engine/Classes/CoverGroupRenderingComponent.uc b/Engine/Classes/CoverGroupRenderingComponent.uc new file mode 100644 index 0000000..d04fa95 --- /dev/null +++ b/Engine/Classes/CoverGroupRenderingComponent.uc @@ -0,0 +1,17 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class CoverGroupRenderingComponent extends PrimitiveComponent + native(AI); + +cpptext +{ + virtual FPrimitiveSceneProxy* CreateSceneProxy(); + virtual void UpdateBounds(); + virtual UBOOL ShouldRecreateProxyOnUpdateTransform() const; +}; + +defaultproperties +{ + HiddenGame=TRUE +} diff --git a/Engine/Classes/CoverLink.uc b/Engine/Classes/CoverLink.uc new file mode 100644 index 0000000..a58a5d7 --- /dev/null +++ b/Engine/Classes/CoverLink.uc @@ -0,0 +1,1417 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class CoverLink extends NavigationPoint + native + DependsOn(Pylon) + placeable + ClassGroup(Cover) + config(Game); + +/** + * Global flag: Whether coverlinks should create slot markers for navigation + * Should be FALSE if using navigation mesh, where cover navigation info will be built into the mesh + */ +var globalconfig bool GLOBAL_bUseSlotMarkers; + +// Initial flanking dot prod value +const COVERLINK_ExposureDot = 0.4f; +// Considered vulnerable at edge slot if past this dot prod +const COVERLINK_EdgeCheckDot = 0.25f; +const COVERLINK_EdgeExposureDot = 0.85f; +// Navigation points within this range are considered dangerous to travel through +const COVERLINK_DangerDist = 1536.f; + +struct immutablewhencooked native CoverReference extends ActorReference +{ + /** Slot referenced in the link */ + var() int SlotIdx; + structcpptext + { + friend FArchive& operator<<( FArchive& Ar, FCoverReference& T ); + } +}; + +cpptext +{ + struct FFireLinkInfo + { + class ACoverLink* Link; + INT SlotIdx; + FCoverSlot* Slot; + FVector SlotLocation; + FRotator SlotRotation; + FVector X, Y, Z; + TArray Types; + TArray Actions; + + INT* out_FireLinkIdx; + + FFireLinkInfo( ACoverLink* InLink, INT InSlotIdx, INT* InIdx = NULL ) + { + Link = InLink; + SlotIdx = InSlotIdx; + Slot = &Link->Slots(SlotIdx); + out_FireLinkIdx = InIdx; + + if( Slot->bLeanLeft ) + { + Actions.AddItem( CA_LeanLeft ); + } + if( Slot->bLeanRight ) + { + Actions.AddItem( CA_LeanRight ); + } + if( Slot->bCanPopUp && Slot->CoverType == CT_MidLevel ) + { + Actions.AddItem( CA_PopUp ); + } + + Types.AddItem( Slot->CoverType ); + if( Slot->CoverType == CT_Standing ) + { + Types.AddItem( CT_MidLevel ); + } + + SlotLocation = Link->GetSlotLocation(SlotIdx); + SlotRotation = Link->GetSlotRotation(SlotIdx); + FRotationMatrix(SlotRotation).GetAxes(X,Y,Z); + } + }; + + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual void BuildSlotInfo( INT SlotIdx, UBOOL bSeedPylon = FALSE, AScout* Scout = NULL); + virtual void BuildSlotInfoInternal( AScout* Scout, INT SlotIdx, UBOOL bSeedPylon = FALSE ); + + /**Sorts the CoverSlots + * @param LastSelectedSlot - the last coverslot the user has selected, the sort will update this value if passed in*/ + void SortSlots(FCoverSlot** LastSelectedSlot = NULL); + void BuildFireLinks( AScout* Scout ); + void BuildOtherLinks( AScout* Scout ); + UBOOL GetFireActions( FFireLinkInfo& SrcInfo, ACoverLink* TestLink, INT TestSlotIdx, UBOOL bFill = TRUE ); + UBOOL CanFireLinkHit( const FVector &ViewPt, const FVector &TargetLoc, UBOOL bDebugLines = FALSE ); + + UBOOL GetExposedInfo( ACoverLink* SrcLink, INT SrcSlotIdx, ACoverLink* DestLink, INT DestSlotIdx, FLOAT& out_ExposedScale ); + + virtual UBOOL GetFireLinkTo( INT SlotIdx, const FCoverInfo& ChkCover, BYTE ChkActin, BYTE ChkType, INT& out_FireLinkIdx, TArray& Items ); + virtual UBOOL HasFireLinkTo( INT SlotIdx, const FCoverInfo& ChkCover, UBOOL bAllowFallbackLinks = FALSE ); + FLOAT GetSlotHeight(INT SlotIdx); +#if WITH_EDITOR + /** Properly handles the mirroring of cover slots associated with this link */ + virtual void EditorApplyMirror(const FVector& MirrorScale, const FVector& PivotLocation); + + virtual void CheckForErrors(); + virtual INT AddMyMarker(AActor *S); +#endif + virtual UBOOL IsFireLinkValid( INT SlotIdx, INT FireLinkIdx, BYTE ArrayID = 0 ); + virtual void GetActorReferences(TArray &ActorRefs, UBOOL bIsRemovingLevel); + + UBOOL IsOverlapSlotClaimed( APawn *ChkClaim, INT SlotIdx, UBOOL bSkipTeamCheck ); + + static FCoverSlot* CoverInfoToSlotPtr( FCoverInfo& InSlot ); + static FCoverSlot* CoverRefToSlotPtr( FCoverReference& InRef ); + + UBOOL FindCoverEdges(const FVector& StartLoc, FVector AxisX, FVector AxisY, FVector AxisZ); + INT AddCoverSlot(FVector& SlotLocation, FRotator& SlotRotation, FCoverSlot Slot, INT SlotIdx = -1); + void EditorAutoSetup(FVector Direction,FVector *HitL = NULL, FVector *HitN = NULL); + void ClearExposedFireLinks(); + + // called during navmesh generation to link this coverlink into the mesh + virtual UBOOL LinkCoverSlotToNavigationMesh(INT SlotIdx, class UNavigationMeshBase* Mesh=NULL); + + virtual INT FindCoverReference( ACoverLink* TestLink, INT TestSlotIdx, UBOOL bAddIfNotFound = TRUE ); + virtual UBOOL GetCachedCoverInfo( INT RefIdx, FCoverInfo& out_Info ); + void FixupLevelCoverReferences(); + + static FORCEINLINE void FireLinkInteraction_PackSrcType( BYTE SrcType, BYTE& PackedByte ) + { + if( SrcType == CT_MidLevel ) { PackedByte |= (1<<0); } + } + static FORCEINLINE void FireLinkInteraction_PackSrcAction( BYTE SrcAction, BYTE& PackedByte ) + { + PackedByte |= (SrcAction == CA_LeanLeft ? (1<<1) : + SrcAction == CA_LeanRight ? (1<<2) : + SrcAction == CA_PopUp ? (1<<3) : + 0); + } + static FORCEINLINE void FireLinkInteraction_PackDestType( BYTE DestType, BYTE& PackedByte ) + { + if( DestType == CT_MidLevel ) { PackedByte |= (1<<4); } + } + static FORCEINLINE void FireLinkInteraction_PackDestAction( BYTE DestAction, BYTE& PackedByte ) + { + PackedByte |= (DestAction == CA_LeanLeft ? (1<<5) : + DestAction == CA_LeanRight ? (1<<6) : + DestAction == CA_PopUp ? (1<<7) : + 0); + } + + static FORCEINLINE BYTE FireLinkInteraction_UnpackSrcType( const BYTE PackedByte ) + { + return (PackedByte & (1<<0)) ? CT_MidLevel : CT_Standing; + } + static FORCEINLINE BYTE FireLinkInteraction_UnpackSrcAction( const BYTE PackedByte ) + { + return (PackedByte & (1<<1)) ? CA_LeanLeft : + (PackedByte & (1<<2)) ? CA_LeanRight : + (PackedByte & (1<<3)) ? CA_PopUp : + CA_Default; + } + static FORCEINLINE BYTE FireLinkInteraction_UnpackDestType( const BYTE PackedByte ) + { + return (PackedByte & (1<<4)) ? CT_MidLevel : CT_Standing; + } + static FORCEINLINE BYTE FireLinkInteraction_UnpackDestAction( const BYTE PackedByte ) + { + return (PackedByte & (1<<5)) ? CA_LeanLeft : + (PackedByte & (1<<6)) ? CA_LeanRight : + (PackedByte & (1<<7)) ? CA_PopUp : + CA_Default; + } +}; + +/** Utility struct for referencing cover link slots. */ +struct immutablewhencooked native CoverInfo +{ + var() editconst CoverLink Link; + var() editconst int SlotIdx; + + structcpptext + { + FCoverInfo() + { + Link = NULL; + SlotIdx = 0; + } + FCoverInfo(EEventParm) + { + appMemzero(this, sizeof(FCoverInfo)); + } + FCoverInfo(class ACoverLink* inLink, INT inSlotIdx) + { + Link = inLink; + SlotIdx = inSlotIdx; + } + UBOOL operator==(const FCoverInfo &Other) const + { + return (this->Link == Other.Link && this->SlotIdx == Other.SlotIdx); + } + FString ToString() const; + } +}; + +/** Utility struct to reference a position in cover */ +struct immutablewhencooked native CovPosInfo +{ + /** CoverLink holding cover position */ + var CoverLink Link; + /** Index of left bounding slot */ + var int LtSlotIdx; + /** Index of right bounding slot */ + var int RtSlotIdx; + /** Pct of distance Location is, between left and right slots */ + var float LtToRtPct; + /** Location in cover */ + var vector Location; + /** Normal vector, used to define direction. Pointing from Location away from Wall. */ + var vector Normal; + /** Tangent vector, gives alignement of cover. With multiple slots cover, this gives the direction from Left to Right slots. */ + var vector Tangent; + + structdefaultproperties + { + LtSlotIdx=-1 + RtSlotIdx=-1 + LtToRtPct=+0.f + } +}; + + +/** + * Represents the current action this pawn is performing at the + * current cover node. + */ +enum ECoverAction +{ + /** Default no action */ + CA_Default, + /** Blindfiring to the left */ + CA_BlindLeft, + /** Blindfiring to the right */ + CA_BlindRight, + /** Leaning to the left */ + CA_LeanLeft, + /** Leaning to the right */ + CA_LeanRight, + /** Pop up, out of cover */ + CA_PopUp, + /** Blind fire up */ + CA_BlindUp, + + /** AI Peek from cover options */ + CA_PeekLeft, + CA_PeekRight, + CA_PeekUp, +}; + +/** + * Represents a direction associated with cover, for use with movement/camera/etc. + */ +enum ECoverDirection +{ + CD_Default, + CD_Left, + CD_Right, + CD_Up, +}; + +/** + * Represents what type of cover this node provides. + */ +enum ECoverType +{ + /** Default, no cover */ + CT_None, + /** Full standing cover */ + CT_Standing, + /** Mid-level crouch cover, stand to fire */ + CT_MidLevel, +}; + +/** Descriptive tags for a particular cover location. Could be used for custom dialogue, for instance. */ +enum ECoverLocationDescription +{ + CoverDesc_None, + CoverDesc_InWindow, + CoverDesc_InDoorway, + CoverDesc_BehindCar, + CoverDesc_BehindTruck, + CoverDesc_OnTruck, + CoverDesc_BehindBarrier, + CoverDesc_BehindColumn, + CoverDesc_BehindCrate, + CoverDesc_BehindWall, + CoverDesc_BehindStatue, + CoverDesc_BehindSandbags, + // new entries go here at the end +}; + +enum EFireLinkID +{ + FLI_FireLink, + FLI_RejectedFireLink, + // new entries go here at the end +}; + +/** Contains specific links between SOURCE actions/postures to DEST actions/postures */ +struct immutablewhencooked native FireLinkItem +{ + /** CT_Standing/CT_MidLevel for source */ + var ECoverType SrcType; + /** Action for source */ + var ECoverAction SrcAction; + /** CT_Standing/CT_MidLevel for source */ + var ECoverType DestType; + /** Action for source */ + var ECoverAction DestAction; +}; + +/** + * Contains information about what other cover nodes this node is + * capable of firing on. + */ +struct immutablewhencooked native FireLink +{ +// var deprecated editconst const CoverReference TargetActor; +// var deprecated array Items; + + /** List of fire link interactions */ + var array Interactions; + + /** + * Packed properties + * CoverRefIdx (Bits 0 - 15) - Index into Levels CoverIndexPairs array + * DynamicLinkInfoIndex (Bits 16 - 31) - Index into this CoverLinks DynamicLinkInfos array + */ + var private const int PackedProperties_CoverPairRefAndDynamicInfo; + + /** Is this link considered a fallback link? (Shouldn't be desired, but is acceptable) */ + var private bool bFallbackLink; + /** Whether DynamicLinkInfoIndex has been initialized */ + var private bool bDynamicIndexInited; + + structcpptext + { + /** + * Updated DynamicLinkInfos array if source or destination is dynamic + */ + void UpdateDynamicLinkInfoFor(ACoverLink* MyLink, ACoverLink* TestLink, INT InSlotIdx, const FVector& LastSrcLocation); + + FVector GetLastTargetLocation(ACoverLink *MyLink); + FVector GetLastSrcLocation(ACoverLink *MyLink); + + FORCEINLINE void SetFallbackLink( UBOOL bSet ) + { + bFallbackLink = bSet; + } + + FORCEINLINE UBOOL IsFallbackLink() + { + return bFallbackLink; + } + + FORCEINLINE void SetDynamicIndexInited( UBOOL bSet ) + { + bDynamicIndexInited = bSet; + } + + FORCEINLINE UBOOL IsDynamicIndexInited() + { + return bDynamicIndexInited; + } + + FORCEINLINE void SetCoverRefIdx( INT Val ) + { + Val &= 0x0000FFFF; + PackedProperties_CoverPairRefAndDynamicInfo &= ~(0x0000FFFF); + PackedProperties_CoverPairRefAndDynamicInfo |= Val; + } + FORCEINLINE DWORD GetCoverRefIdx() + { + return (PackedProperties_CoverPairRefAndDynamicInfo & (0x0000FFFF)); + } + + FORCEINLINE void SetDynamicLinkInfoIndex( INT Val ) + { + Val &= 0xFFFF0000; + PackedProperties_CoverPairRefAndDynamicInfo &= ~(0xFFFF0000); + PackedProperties_CoverPairRefAndDynamicInfo |= (Val << 16); + } + FORCEINLINE DWORD GetDynamicLinkInfoIndex() + { + return ((PackedProperties_CoverPairRefAndDynamicInfo & (0xFFFF0000)) >> 16); + } + } +}; + +struct immutablewhencooked native DynamicLinkInfo +{ + /** Location of the target when this FireLink was created/updated (Used for tracking CoverLink_Dynamic) */ + var Vector LastTargetLocation; + + /** Location of the src when this FireLink was created/updated (Used for tracking CoverLink_Dynamic) */ + var Vector LastSrcLocation; +}; + +/** + * Contains information about other cover nodes this node is exposed to + * (ie flanked by) + */ +struct immutablewhencooked native ExposedLink +{ + /** Slot that is dangerous to this link */ + var() editconst const CoverReference TargetActor; + + /** Scale of how dangerous this exposure is + (0,255] -- ~0 = not very dangerous, 255 = extremely dangerous */ + var() byte ExposedScale; +}; + +struct immutablewhencooked native SlotMoveRef +{ + var() PolyReference Poly; + var() BasedPosition Dest; + var() int Direction; + + structcpptext + { + void Clear() + { + Poly.Clear(); + Dest.Clear(); + Direction = 0; + } + } +}; + +/** Contains information for a cover slot that a player can occupy */ +struct immutablewhencooked native CoverSlot +{ + /** Slot marker to allow the slot to exist on the navigation network */ +// var deprecated editconst Actor SlotMarker; +// var deprecated array ForcedFireLinks; +// var deprecated array ExposedFireLinks; +// var deprecated editconst array OverlapClaims; +// var deprecated array TurnTarget; + + /** Current owner of this slot */ + var Pawn SlotOwner; + + /** Slot is invalid until world.timeseconds is >= this value (allows temporary disabling of slots) */ + var transient float SlotValidAfterTime; + + /** Gives LDs ability to force the type - CT_None == auto find*/ + var() ECoverType ForceCoverType; + /** Type of cover this slot provides */ + var(Auto) editconst ECoverType CoverType; + /** Per-slot description tag. If _None, fall back to the description in the CoverLink. */ + var() ECoverLocationDescription LocationDescription; + + + /** Offset from node location for this slot */ + var vector LocationOffset; + + /** Offset from node rotation for this slot */ + var rotator RotationOffset; + + /** List of actions possible from this slot */ + var array Actions; + + /** List of all attackable nodes */ + var() editconst array FireLinks; + + /** List of coverlinks/slots that couldn't be shot at - used by COVERLINK_DYNAMIC */ + var() editconst transient array RejectedFireLinks; + + /** + * ExposedCover Packed Properties + * CoverRefIdx (Bits 0 - 15) - Index into Levels CoverIndexPairs array + * ExposedScale (Bits 16 - 23) - Scale of how dangerous this exposure is + * (0,255] -- ~0 = not very dangerous, 255 = extremely dangerous + */ + var private array ExposedCoverPackedProperties; + + /** + * Link/slot info about where swat turn evade can move to + * Packs left/right index into Level CoverIndexPair + * left turn target into bits 0-15, right turn target into 16-31 + */ + var private int TurnTargetPackedProperties; + + /** Info about where cover slip can move to */ + var array SlipRefs; + + /** List of cover slots that should be claimed when this slot is claimed + because they are overlapping */ + var(Auto) editconst array OverlapClaimsList; + /** Can we lean left/right to shoot from this slot? */ + var(Auto) bool bLeanLeft, bLeanRight; + /** Can we popup? */ + var(Auto) bool bForceCanPopUp; + var(Auto) editconst bool bCanPopUp; + /** Can we mantle over this cover? */ + var(Auto) editconst bool bCanMantle; + /** Can we mantle up? */ + var(Auto) editconst bool bCanClimbUp; + /** Can cover slip at this slot? */ + var(Auto) bool bForceCanCoverSlip_Left, bForceCanCoverSlip_Right; + var(Auto) editconst bool bCanCoverSlip_Left, bCanCoverSlip_Right; + /** Can swat turn at this slot? */ + var(Auto) editconst bool bCanSwatTurn_Left, bCanSwatTurn_Right; + + /** Is this slot currently enabled? */ + var() bool bEnabled; + + /** Is popping up allowed for midlevel/crouching cover? */ + var() bool bAllowPopup; + /** Is mantling allowed here? */ + var() bool bAllowMantle; + /** Is cover slip allowed? */ + var() bool bAllowCoverSlip; + /** Is climbing up allowed here? */ + var() bool bAllowClimbUp; + /** Is swat turn allowed? */ + var() bool bAllowSwatTurn; + /** if this is on ground adjustments will be skipped */ + var() bool bForceNoGroundAdjust; + /** Slot can only be used by players, not AI */ + var() bool bPlayerOnly; + /** Override the default behavior of popup on target preffered over lean out */ + var() bool bPreferLeanOverPopup; + /** runtime only - whether this slot is on destructible cover (so AI can shoot it to get the enemy out) */ + var transient bool bDestructible; + + /** === Editor specific === */ + /** Is this slot currently selected for editing? */ + var transient bool bSelected; + + /** Map Error: Cover slot failed to find surface to align to */ + var() transient editconst bool bFailedToFindSurface; + + structdefaultproperties + { + bEnabled=TRUE + + bCanMantle=TRUE + bCanCoverSlip_Left=TRUE + bCanCoverSlip_Right=TRUE + bCanSwatTurn_Left=TRUE + bCanSwatTurn_Right=TRUE + bCanClimbUp=FALSE + + bAllowMantle=TRUE + bAllowCoverSlip=TRUE + bAllowPopup=TRUE + bAllowSwatTurn=TRUE + bAllowClimbUp=FALSE + + TurnTargetPackedProperties=4294967296 + } + + structcpptext + { + FORCEINLINE void SetExposedCoverRefIdx( INT Index, INT Val ) + { + Val &= 0x0000FFFF; + ExposedCoverPackedProperties(Index) &= ~(0x0000FFFF); + ExposedCoverPackedProperties(Index) |= Val; + } + FORCEINLINE DWORD GetExposedCoverRefIdx( INT Index ) + { + return (ExposedCoverPackedProperties(Index) & (0x0000FFFF)); + } + + FORCEINLINE void SetExposedScale( INT Index, INT Val ) + { + Val &= 0x000000FF; + ExposedCoverPackedProperties(Index) &= ~(0x00FF0000); + ExposedCoverPackedProperties(Index) |= (Val << 16); + } + FORCEINLINE BYTE GetExposedScale( INT Index ) + { + return ((ExposedCoverPackedProperties(Index) & (0x00FF0000)) >> 16); + } + + FORCEINLINE void SetLeftTurnTargetCoverRefIdx( INT Val ) + { + Val &= 0x0000FFFF; + TurnTargetPackedProperties &= ~(0x0000FFFF); + TurnTargetPackedProperties |= Val; + } + FORCEINLINE DWORD GetLeftTurnTargetCoverRefIdx() + { + return (TurnTargetPackedProperties & (0x0000FFFF)); + } + FORCEINLINE void SetRightTurnTargetCoverRefIdx( INT Val ) + { + Val &= 0x0000FFFF; + TurnTargetPackedProperties &= ~(0xFFFF0000); + TurnTargetPackedProperties |= (Val << 16); + } + FORCEINLINE DWORD GetRightTurnTargetCoverRefIdx() + { + return ((TurnTargetPackedProperties & (0xFFFF0000)) >> 16); + } + + FORCEINLINE FFireLink& GetFireLinkRef( INT FireLinkIdx, BYTE ArrayID = 0 ) + { + if( ArrayID == FLI_RejectedFireLink ) + { + return RejectedFireLinks(FireLinkIdx); + } + else + { + return FireLinks(FireLinkIdx); + } + } + } +}; + +/** How far auto adjust code traces forward from lean fire point + to determine if the lean has a valid fire line */ +var float LeanTraceDist; + + +/** All slots linked to this node */ +var() editinline array Slots; + +/** Array of src and target location for dynamic links */ +var array DynamicLinkInfos; + +/** List of all players using this cover */ +var array Claims; + +/** Whether cover link is disabled */ +var() bool bDisabled; + +/** Claim all slots when someone claims one - used for cover that needs more than one slot, but slots overlap */ +var() bool bClaimAllSlots; + +/** Allow auto-sorting of the Slots array */ +var() bool bAutoSort; + +/** Allow auto-adjusting of the Slots orientation/position and covertype? */ +var() bool bAutoAdjust; + +/** Is this circular cover? */ +var() bool bCircular; + +/** Cover is looped, first slot and last slot should be reachable direclty */ +var() bool bLooped; + +/** Is this cover restricted to player use? */ +var() bool bPlayerOnly; +/** This cover is dynamic */ +var bool bDynamicCover; +/** This cover fractures when it is interacted with */ +var() bool bFractureOnTouch; +/** Distance link must move to invalidate it's info */ +var() float InvalidateDistance; +/** Max trace dist for fire links to check */ +var() float MaxFireLinkDist; + +/** Origin for circular cover */ +var const vector CircularOrigin; + +/** Radius for circular cover */ +var const float CircularRadius; + +/** Distance used when aligning to nearby surfaces */ +var const float AlignDist; + +/** Minimum distance to place between non-essential cover slots when auto-generating a cover link */ +var const float AutoCoverSlotInterval; + +/** Min height for nearby geometry to categorize as standing cover */ +var const float StandHeight; + +/** Min height for nearby geometry to categorize as mid-level cover */ +var const float MidHeight; + +var const Vector StandingLeanOffset; +var const Vector CrouchLeanOffset; +var const Vector PopupOffset; + +/** Forward distance for checking cover slip links */ +var const float SlipDist; +/** Lateral distance for checking swat turn links */ +var const float TurnDist; +/** Scale applied to danger cost during path finding for slots of this link */ +var() float DangerScale; + +/** Used for the WorldInfo.CoverList linked list */ +var const CoverLink NextCoverLink; + +var(Debug) bool bDebug_FireLinks; +var(Debug) bool bDebug_ExposedLinks; +/** when enabled, extra info will be drawn and printed to the log related to generation of cover information for this link */ +var(Debug) bool bDebug_CoverGen; + +/** Description for the entire CoverLink. Can be overridden per-slot. */ +var() const ECoverLocationDescription LocationDescription; + +/** Should we automatically insert slots when there is too big of a gap? */ +var() bool bDoAutoSlotDensityFixup; + +simulated native function bool GetFireLinkTargetCoverInfo( int SlotIdx, int FireLinkIdx, out CoverInfo out_Info, optional EFireLinkID ArrayID ); + +/** + * Packs fire link item info into a single byte + * SrcType/DestType - only allow CT_Standing/CT_MidLevel + * SrcAction/DestAction - only allow CA_LeanLeft/CA_LeanRight/CA_PopUp/CA_Default(destonly) + */ +simulated static native function BYTE PackFireLinkInteractionInfo( ECoverType SrcType, ECoverAction SrcAction, ECoverType DestType, ECoverAction DestAction ); +simulated static native function UnPackFireLinkInteractionInfo( const BYTE PackedByte, out ECoverType SrcType, out ECoverAction SrcAction, out ECoverType DestType, out ECoverAction DestAction ); + +/** Returns the world location of the requested slot. */ +simulated native final function vector GetSlotLocation(int SlotIdx, optional bool bForceUseOffset); + +/** Returns the world rotation of the requested slot. */ +simulated native final function rotator GetSlotRotation(int SlotIdx, optional bool bForceUseOffset); + +/** Returns the world location of the default viewpoint for the specified slot. */ +simulated native final function vector GetSlotViewPoint( int SlotIdx, optional ECoverType Type, optional ECoverAction Action ); + +simulated native final function bool IsExposedTo( int SlotIdx, CoverInfo ChkSlot, out float out_ExposedScale ); + +simulated final event SetInvalidUntil(int SlotIdx, float TimeToBecomeValid) +{ + Slots[SlotIdx].SlotValidAfterTime = TimeToBecomeValid; + NotifySlotOwnerCoverDisabled( SlotIdx ); +} + +/** Asserts a claim on this link by the specified controller. */ +simulated final event bool Claim( Pawn NewClaim, int SlotIdx ) +{ + local int Idx; + local bool bResult, bDoClaim; + local PlayerController PC; + local Pawn PreviousOwner; + +`if (`notdefined(FINAL_RELEASE)) + local int NumClaims; + local array SlotList; + local String Str; + + //debug + if( bDebug ) + { + `log( self@"Claim Slot"@SlotIdx@"For"@NewClaim@"(All?)"@bClaimAllSlots ); + } +`endif + + // Make sure SlotIdx is valid + if( SlotIdx < 0 ) + { + return FALSE; + } + + bDoClaim = TRUE; + + + // If slot already claimed + if( Slots[SlotIdx].SlotOwner != None ) + { + // If we have already claimed it, nothing to do + // If we don't, fail claim + bResult = Slots[SlotIdx].SlotOwner == NewClaim; + bDoClaim = FALSE; + + // If claimer is different + if( !bResult ) + { + // If claimer is a player controller + PC = PlayerController( NewClaim.Controller ); + if( PC != None ) + { + PreviousOwner = Slots[SlotIdx].SlotOwner; + // Tell the previous owner that we are taking over + bDoClaim = TRUE; + } + } + } + + if( bDoClaim ) + { + // If all slots must be claimed + if( bClaimAllSlots ) + { + // Loop through each slot and set new claim as owner of all + for( Idx = 0; Idx < Slots.Length; Idx++ ) + { + if( Slots[Idx].SlotOwner == None ) + { + // Add entry to general claims list (will contain multiple entries if has multiple slots claimed) + Claims[Claims.Length] = NewClaim; + // Mark slot claim + Slots[Idx].SlotOwner = NewClaim; + bResult = TRUE; + } + } + } + else + { + // Add entry to general claims list (will contain multiple entries if has multiple slots claimed) + Claims[Claims.Length] = NewClaim; + // Mark slot claim + Slots[SlotIdx].SlotOwner = NewClaim; + + bResult = TRUE; + } + if (PreviousOwner != None && PreviousOwner.Controller != None) + { + PreviousOwner.Controller.NotifyCoverClaimViolation( NewClaim.Controller, self, SlotIdx ); + } + } + + //debug +`if (`notdefined(FINAL_RELEASE)) + if( bDebug ) + { + for( Idx = 0; Idx < Claims.Length; Idx++ ) + { + if( Claims[Idx] == NewClaim ) + { + NumClaims++; + } + } + for( Idx = 0; Idx < Slots.Length; Idx++ ) + { + if( Slots[Idx].SlotOwner == NewClaim ) + { + SlotList[SlotList.Length] = Idx; + } + } + if( SlotList.Length == 0 ) + { + Str = "None"; + } + else + { + for( Idx = 0; Idx < SlotList.Length; Idx++ ) + { + Str = Str@SlotList[Idx]; + } + } + + `log( self@"Claims from"@NewClaim@NumClaims@"Slots:"@Str ); + + ScriptTrace(); + } +`endif + + return bResult; +} + +/** Removes any claims the specified controller has on this link. */ +simulated final event bool UnClaim( Pawn OldClaim, int SlotIdx, bool bUnclaimAll ) +{ + local int Idx, NumReleased; + local bool bResult; + +`if (`notdefined(FINAL_RELEASE)) + //debug + local int NumClaims; + local array SlotList; + local String Str; + + //debug + if( bDebug ) + { + `log( self@"UnClaim"@`showvar(OldClaim)@`showvar(SlotIdx)@`showvar(bUnclaimAll)@`showvar(bClaimAllSlots) ); + } +`endif + + if( !bUnclaimAll && SlotIdx < 0) + { + return false; + } + + // If letting go of link completely + if( bUnclaimAll ) + { + // Clear the slot owner from all slots + for( Idx = 0; Idx < Slots.Length; Idx++ ) + { + if( Slots[Idx].SlotOwner == OldClaim ) + { + Slots[Idx].SlotOwner = None; + NumReleased++; + bResult = TRUE; + } + } + } + // Otherwise, if we want to let go of only one slot (and shouldn't always hold all of them) + else if( !bClaimAllSlots && Slots[SlotIdx].SlotOwner == OldClaim ) + { + // Release this slot + Slots[SlotIdx].SlotOwner = None; + NumReleased++; + bResult = TRUE; + } + + // For each slot released + while( NumReleased > 0 ) + { + // Find a claim in the list + Idx = Claims.Find(OldClaim); + if( Idx < 0 ) + { + break; + } + + // Clear on claim from the general claims list + Claims.Remove( Idx, 1 ); + NumReleased--; + } + + //debug +`if (`notdefined(FINAL_RELEASE)) + if( bDebug ) + { + for( Idx = 0; Idx < Claims.Length; Idx++ ) + { + if( Claims[Idx] == OldClaim ) + { + NumClaims++; + } + } + for( Idx = 0; Idx < Slots.Length; Idx++ ) + { + if( Slots[Idx].SlotOwner == OldClaim ) + { + SlotList[SlotList.Length] = Idx; + } + } + if( SlotList.Length == 0 ) + { + Str = "None"; + } + else + { + for( Idx = 0; Idx < SlotList.Length; Idx++ ) + { + Str = Str@SlotList[Idx]; + } + } + + `log( self@"Claims from"@`showvar(OldClaim)@`showvar(NumClaims)@"Slots:"@Str ); + + ScriptTrace(); + } +`endif + + return bResult; +} + +/** Returns true if the specified controller is able to claim the slot. */ +final native function bool IsValidClaim( Pawn ChkClaim, int SlotIdx, optional bool bSkipTeamCheck, optional bool bSkipOverlapCheck ); +final native function bool IsValidClaimBetween( Pawn ChkClaim, int StartSlotIdx, int EndSlotIdx, optional bool bSkipTeamCheck, optional bool bSkipOverlapCheck ); + +/** + * Checks to see if the specified slot support stationary cover actions. + */ +simulated final function bool IsStationarySlot(int SlotIdx) +{ + return (!bCircular && IsEdgeSlot(SlotIdx,FALSE)); +} + +/** + * Finds the current set of slots the specified point is between. Returns true + * if a valid slot set was found. + */ +simulated native final function bool FindSlots(vector CheckLocation, float MaxDistance, out int LeftSlotIdx, out int RightSlotIdx); + + +/** + * Return true if the specified slot is an edge, signifying "End Of Cover". + */ +simulated native final function bool IsEdgeSlot( int SlotIdx, optional bool bIgnoreLeans ); +simulated native final function bool IsLeftEdgeSlot( int SlotIdx, bool bIgnoreLeans ); +simulated native final function bool IsRightEdgeSlot( int SlotIdx, bool bIgnoreLeans ); + +simulated native final function int GetSlotIdxToLeft( int SlotIdx, optional int Cnt = 1 ); +simulated native final function int GetSlotIdxToRight( int SlotIdx, optional int Cnt = 1 ); + +simulated final function bool AllowRightTransition(int SlotIdx) +{ + local int NextSlotIdx; + + NextSlotIdx = GetSlotIdxToRight( SlotIdx ); + if( NextSlotIdx >= 0 ) + { + return Slots[NextSlotIdx].bEnabled; + } + return FALSE; +} + +simulated final function bool AllowLeftTransition(int SlotIdx) +{ + local int NextSlotIdx; + + NextSlotIdx = GetSlotIdxToLeft( SlotIdx ); + if( NextSlotIdx >= 0 ) + { + return Slots[NextSlotIdx].bEnabled; + } + return FALSE; +} + +/** + * Searches for a fire link to the specified cover/slot and returns the cover actions. + */ +native noexport function bool GetFireLinkTo( int SlotIdx, CoverInfo ChkCover, ECoverAction ChkAction, ECoverType ChkType, out int out_FireLinkIdx, out array out_Items ); + +/** + * Searches for a valid fire link to the specified cover/slot. + * NOTE: marked noexport until 'optional out int' is fixed in the exporter + */ +native noexport function bool HasFireLinkTo( int SlotIdx, CoverInfo ChkCover, optional bool bAllowFallbackLinks ); + +/** + * Returns a list of AI actions possible from this slot + */ +native final function GetSlotActions( int SlotIdx, out array Actions ); + +/** + * Enable/disable the entire CoverLink. + */ +simulated event SetDisabled(bool bNewDisabled) +{ + local int SlotIdx; + local CoverReplicator CoverReplicator; + + bDisabled = bNewDisabled; + + if( bDisabled ) + { + for( SlotIdx = 0; SlotIdx < Slots.Length; SlotIdx++ ) + { + NotifySlotOwnerCoverDisabled( SlotIdx ); + } + } + + // if on server, notify clients slot was disabled + if( Role == ROLE_Authority ) + { + CoverReplicator = WorldInfo.Game.GetCoverReplicator(); + if (CoverReplicator != None) + { + CoverReplicator.NotifyLinkDisabledStateChange(self); + } + } +} + +/** + * Enable/disable a particular cover slot. + */ +simulated event SetSlotEnabled(int SlotIdx, bool bEnable) +{ + Slots[SlotIdx].bEnabled = bEnable; + + if( !bEnable ) + { + NotifySlotOwnerCoverDisabled( SlotIdx ); + } +} + +simulated function NotifySlotOwnerCoverDisabled( int SlotIdx, optional bool bAIOnly ) +{ + local int LeftIdx, RightIdx; + + if( Slots[SlotIdx].SlotOwner != None && + Slots[SlotIdx].SlotOwner.Controller != None && + (!bAIOnly || PlayerController(Slots[SlotIdx].SlotOwner.Controller) == None) ) + { + // notify any owner that the slot is disabled + Slots[SlotIdx].SlotOwner.Controller.NotifyCoverDisabled( self, SlotIdx, FALSE ); + } + + // Notify any adjacent owners + LeftIdx = GetSlotIdxToLeft( SlotIdx ); + if( LeftIdx >= 0 && + Slots[LeftIdx].SlotOwner != None && + Slots[LeftIdx].SlotOwner.Controller != None && + (!bAIOnly || PlayerController(Slots[LeftIdx].SlotOwner.Controller) == None) ) + { + Slots[LeftIdx].SlotOwner.Controller.NotifyCoverDisabled( self, SlotIdx, TRUE ); + } + + RightIdx = GetSlotIdxToRight( SlotIdx ); + if( RightIdx >= 0 && + Slots[RightIdx].SlotOwner != None && + Slots[RightIdx].SlotOwner.Controller != None && + (!bAIOnly || PlayerController(Slots[RightIdx].SlotOwner.Controller) == None) ) + { + Slots[RightIdx].SlotOwner.Controller.NotifyCoverDisabled( self, SlotIdx, TRUE ); + } +} + +/** + * Enable/disable playersonly on a particular cover slot. + */ +simulated event SetSlotPlayerOnly(int SlotIdx, bool bInPlayerOnly ) +{ + Slots[SlotIdx].bPlayerOnly = bInPlayerOnly; + + if( Slots[SlotIdx].bPlayerOnly ) + { + NotifySlotOwnerCoverDisabled( SlotIdx, TRUE ); + } +} + + +/** + * Handle modify action by enabling/disabling the list of slots, or auto adjusting. + */ +function OnModifyCover(SeqAct_ModifyCover Action) +{ + local array SlotIndices; + local int Idx, SlotIdx; + local CoverReplicator CoverReplicator; + + // if the action has slots specified + if (Action.Slots.Length > 0) + { + // use only those indicies + SlotIndices = Action.Slots; + } + else + { + // otherwise use all the slots + for (Idx = 0; Idx < Slots.Length; Idx++) + { + SlotIndices[SlotIndices.Length] = Idx; + } + } + for (Idx = 0; Idx < SlotIndices.Length; Idx++) + { + SlotIdx = SlotIndices[Idx]; + if (SlotIdx >= 0 && SlotIdx < Slots.Length) + { + if (Action.InputLinks[0].bHasImpulse) + { + SetSlotEnabled(SlotIdx, TRUE); + } + else + if (Action.InputLinks[1].bHasImpulse) + { + SetSlotEnabled(SlotIdx, FALSE); + } + else + if (Action.InputLinks[2].bHasImpulse) + { + // update the slot + if (AutoAdjustSlot(SlotIdx,FALSE) && + Slots[SlotIdx].SlotOwner != None && Slots[SlotIdx].SlotOwner.Controller != None) + { + // and notify if it changed + Slots[SlotIdx].SlotOwner.Controller.NotifyCoverAdjusted(); + } + } + else + if (Action.InputLinks[3].bHasImpulse) + { + if( Action.ManualCoverType != CT_None ) + { + Slots[SlotIdx].CoverType = Action.ManualCoverType; + if (Slots[SlotIdx].SlotOwner != None && Slots[SlotIdx].SlotOwner.Controller != None) + { + // notify the owner of the change + Slots[SlotIdx].SlotOwner.Controller.NotifyCoverAdjusted(); + } + } + Slots[SlotIdx].bPlayerOnly = Action.bManualAdjustPlayersOnly; + } + } + } + + CoverReplicator = WorldInfo.Game.GetCoverReplicator(); + if (CoverReplicator != None) + { + if (Action.InputLinks[0].bHasImpulse) + { + CoverReplicator.NotifyEnabledSlots(self, SlotIndices); + } + else if (Action.InputLinks[1].bHasImpulse) + { + CoverReplicator.NotifyDisabledSlots(self, SlotIndices); + } + else if (Action.InputLinks[2].bHasImpulse) + { + CoverReplicator.NotifyAutoAdjustSlots(self, SlotIndices); + } + else if (Action.InputLinks[3].bHasImpulse) + { + CoverReplicator.NotifySetManualCoverTypeForSlots(self, SlotIndices, Action.ManualCoverType); + } + } +} + +/** + * Auto-adjusts the slot orientation/location to the nearest geometry, as well + * as determine leans and cover type. Returns TRUE if the cover type changed. + */ +native final function bool AutoAdjustSlot(int SlotIdx, bool bOnlyCheckLeans); +native final function bool IsEnabled(); + + +/** + * Overridden to disable all slots when toggled off. + */ +function OnToggle(SeqAct_Toggle inAction) +{ + local CoverReplicator CoverReplicator; + local int SlotIdx; + + Super.OnToggle( inAction ); + + if (inAction.InputLinks[0].bHasImpulse) + { + bDisabled = FALSE; + } + else if (inAction.InputLinks[1].bHasImpulse) + { + bDisabled = TRUE; + } + else + { + bDisabled = !bDisabled; + } + + // Call SetSlotEnabled() which notifies any Pawns using this cover + for (SlotIdx = 0; SlotIdx < Slots.Length; ++SlotIdx) + { + SetSlotEnabled(SlotIdx, !bDisabled); + } + + CoverReplicator = WorldInfo.Game.GetCoverReplicator(); + if (CoverReplicator != None) + { + CoverReplicator.NotifyLinkDisabledStateChange(self); + } +} + +function CreateCheckpointRecord(out CheckpointRecord Record) +{ + Super.CreateCheckpointRecord(Record); + Record.bDisabled = bDisabled; +} + +function ApplyCheckpointRecord(const out CheckpointRecord Record) +{ + local CoverReplicator CoverReplicator; + + Super.ApplyCheckpointRecord(Record); + + bDisabled = Record.bDisabled; + + CoverReplicator = WorldInfo.Game.GetCoverReplicator(); + if (CoverReplicator != None) + { + CoverReplicator.NotifyLinkDisabledStateChange(self); + } +} + +simulated event ShutDown() +{ + Super.ShutDown(); + + bDisabled = TRUE; +} + +simulated native function bool GetSwatTurnTarget( int SlotIdx, int Direction, out CoverInfo out_Info ); + +/** Applies an impulse to all nearby fractureable objects, if this coverlink is set to fracture on touch +* +* @param Origin - Origin of fracture pulse +* @param Radius - Radius around origin to apply the fracturable pulse. All parts in radius will fracture +* @param RBStrength - strength to apply to fractureable parts +* @param DamageType - DamageType to use as the fracturable pulse, potentially ignored by certain fractureable objects +*/ +simulated function BreakFracturedMeshes(vector Origin, float Radius, float RBStrength, class DamageType) +{ + local FracturedStaticMeshActor FracActor; + local byte bWantPhysChunksAndParticles; + + if (!bFractureOnTouch) + { + return; + } + + foreach CollidingActors(class'FracturedStaticMeshActor', FracActor, Radius, Origin, TRUE) + { + if((FracActor.Physics == PHYS_None) && FracActor.IsFracturedByDamageType(DamageType)) + { + // Make sure the impacted fractured mesh is visually relevant + if( FracActor.FractureEffectIsRelevant( FALSE, Instigator, bWantPhysChunksAndParticles ) ) + { + FracActor.BreakOffPartsInRadius(Origin, Radius, RBStrength, bWantPhysChunksAndParticles == 1 ? TRUE : FALSE); + } + } + } +} + +//debug +`if (`notdefined(FINAL_RELEASE)) +simulated event Tick( float DeltaTime ) +{ + local int SlotIdx; + local CoverSlot Slot; + local Vector OwnerLoc; + local byte R, G, B; + + // no super tick implemented + //super.Tick( DeltaTime ); + + if( bDebug ) + { + for( SlotIdx = 0; SlotIdx < Slots.Length; SlotIdx++ ) + { + Slot = Slots[SlotIdx]; + if( Slot.SlotOwner != None ) + { + if( Slot.SlotOwner != None ) + { + OwnerLoc = Slot.SlotOwner.Location; + R = 166; + G = 236; + B = 17; + } + else + { + OwnerLoc = vect(0,0,0); + R = 170; + G = 0; + B = 0; + } + + DrawDebugLine( GetSlotLocation(SlotIdx), OwnerLoc, R, G, B ); + } + } + } +} +`endif + +native final function int AddCoverSlot(vector SlotLocation, rotator SlotRotation, optional int SlotIdx = -1, optional bool bForceSlotUpdate, optional Scout Scout); + +simulated final event string GetDebugString(int SlotIdx) +{ + return "L:"$GetRightMost(self)@"S:"$SlotIdx; +} + +simulated native final function ECoverLocationDescription GetLocationDescription(int SlotIdx); + +simulated event string GetDebugAbbrev() +{ + return "CL"; +} + +defaultproperties +{ + Components.Remove(PathRenderer) + + Begin Object Name=CollisionCylinder + CollisionRadius=48.f + CollisionHeight=58.f + End Object + + Begin Object NAME=Sprite + Sprite=Texture2D'EditorMaterials.CoverIcons.CoverNodeNoneLocked' + SpriteCategoryName="Cover" + End Object + + Begin Object Class=CoverMeshComponent Name=CoverMesh + AlwaysLoadOnClient=False + AlwaysLoadOnServer=False + bUsePrecomputedShadows=False + End Object + Components.Add(CoverMesh) + // Don't show the navigation point arrow on cover links. + Components.Remove(Arrow) + Slots(0)=(LocationOffset=(X=64.f)) + + AlignDist=36.f + StandHeight=160.f + MidHeight=70.f + AutoCoverSlotInterval=175.f + + StandingLeanOffset=(X=0,Y=78,Z=69) + CrouchLeanOffset=(X=0,Y=70,Z=19) + PopupOffset=(X=0,Y=0,Z=70) + + SlipDist=60.f + TurnDist=512.f + + bAutoSort=TRUE + bAutoAdjust=TRUE + bSpecialMove=TRUE + bBuildLongPaths=FALSE + + MaxFireLinkDist=2048.f + InvalidateDistance=64.f + DangerScale=2.f + +//debug +// bDebug=TRUE +// bStatic=FALSE + + bDebug_FireLinks=FALSE + bDebug_ExposedLinks=FALSE + + bDestinationOnly=TRUE + + LeanTraceDist=64.f + + bDoAutoSlotDensityFixup=FALSE +} diff --git a/Engine/Classes/CoverMeshComponent.uc b/Engine/Classes/CoverMeshComponent.uc new file mode 100644 index 0000000..61cb56b --- /dev/null +++ b/Engine/Classes/CoverMeshComponent.uc @@ -0,0 +1,86 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class CoverMeshComponent extends StaticMeshComponent + native(AI); + +cpptext +{ + void UpdateBounds(); + virtual FPrimitiveSceneProxy* CreateSceneProxy(); + virtual UBOOL ShouldRecreateProxyOnUpdateTransform() const; + virtual void UpdateMeshes() {}; +}; + +struct native CoverMeshes +{ + var StaticMesh Base; + var StaticMesh LeanLeft, LeanRight; + var StaticMesh LeanLeftPref, LeanRightPref; + var StaticMesh Climb, Mantle; + var StaticMesh SlipLeft, SlipRight; + var StaticMesh SwatLeft, SwatRight; + var StaticMesh PopUp; + var StaticMesh PlayerOnly; +}; +var array Meshes; + +/** Base offset applied to all meshes */ +var vector LocationOffset; + +var StaticMesh AutoAdjustOn; +var StaticMesh AutoAdjustOff; +var StaticMesh Disabled; + +/** Allows the LDs to show all cover in a level without editing the cover */ +var editoronly transient bool bShowWhenNotSelected; + +defaultproperties +{ + HiddenGame=true + AlwaysLoadOnServer=FALSE + AlwaysLoadOnClient=FALSE + CollideActors=FALSE + BlockActors=FALSE + BlockZeroExtent=FALSE + BlockNonZeroExtent=FALSE + BlockRigidBody=FALSE + bAcceptsStaticDecals=FALSE + bAcceptsDynamicDecals=FALSE + bAcceptsLights=FALSE + CastShadow=FALSE + + StaticMesh=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy__BASE_TALL' + LocationOffset=(X=0,Y=0,Z=-60) + + Meshes(CT_None)=(Base=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy__BASE_TALL') + Meshes(CT_Standing)={( + Base=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy__BASE_TALL', + LeanLeft=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy_LeanLeftS', + LeanRight=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy_LeanRightS', + SlipLeft=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy_CoverSlipLeft', + SlipRight=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy_CoverSlipRight', + SwatLeft=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy_SwatLeft', + SwatRight=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy_SwatRight', + PlayerOnly=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy_PlayerOnlyS' + )} + Meshes(CT_MidLevel)={( + Base=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy__BASE_SHORT', + LeanLeft=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy_LeanLeftM', + LeanLeftPref=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy_LeanLeftMPref', + LeanRight=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy_LeanRightM', + LeanRightPref=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy_LeanRightMPref', + Climb=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy_Climb', + Mantle=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy_Mantle', + SlipLeft=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy_CoverSlipLeft', + SlipRight=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy_CoverSlipRight', + SwatLeft=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy_SwatLeft', + SwatRight=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy_SwatRight', + PopUp=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy_PopUp', + PlayerOnly=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy_PlayerOnlyM' + )} + + AutoAdjustOn=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy_AutoAdjust' + AutoAdjustOff=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy_AutoAdjustOff' + Disabled=StaticMesh'NodeBuddies.3D_Icons.NodeBuddy_Enabled' +} diff --git a/Engine/Classes/CoverReplicator.uc b/Engine/Classes/CoverReplicator.uc new file mode 100644 index 0000000..4cfebc9 --- /dev/null +++ b/Engine/Classes/CoverReplicator.uc @@ -0,0 +1,794 @@ +/** + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + + +/** this handles replicating cover changes to a client + * can't use variable replication on the CoverLinks because the slots list is a dynamic array + * also, that could potentially be a whole lot of channels if LDs mess with a lot of cover via Kismet, so this is more efficient + */ +class CoverReplicator extends ReplicationInfo; + +struct ManualCoverTypeInfo +{ + var byte SlotIndex; + var ECoverType ManualCoverType; +}; + +struct CoverReplicationInfo +{ + /** CoverLink that was changed */ + var CoverLink Link; + /** indices of slots that were enabled */ + var array SlotsEnabled; + /** indices of slots that were disabled */ + var array SlotsDisabled; + /** indices of slots that were adjusted */ + var array SlotsAdjusted; + /** slots that have had cover type manually set */ + var array SlotsCoverTypeChanged; +}; + +var array CoverReplicationData; + +/** removes entries that are no longer valid (i.e. the CoverLink has been streamed out) */ +function PurgeOldEntries() +{ + local int i; + + for (i = 0; i < CoverReplicationData.length; i++) + { + if (CoverReplicationData[i].Link == None) + { + CoverReplicationData.Remove(i--, 1); + } + } +} + +/** copies and starts replicating already changed cover info */ +function ReplicateInitialCoverInfo() +{ + local CoverReplicator CoverReplicatorBase; + + CoverReplicatorBase = WorldInfo.Game.GetCoverReplicator(); + // clean out old entries first + CoverReplicatorBase.PurgeOldEntries(); + // copy over data + CoverReplicationData = CoverReplicatorBase.CoverReplicationData; + if (PlayerController(Owner) != None) + { + //@HACK: bSkipActorPropertyReplication prevents Owner from being replicated. Should fix that eventually, but for now, force it by RPC + ClientSetOwner(PlayerController(Owner)); + + // start replicating it out + ServerSendInitialCoverReplicationInfo(0); + } +} + +//@HACK: bSkipActorPropertyReplication prevents Owner from being replicated. Should fix that eventually, but for now, force it by RPC +reliable client function ClientSetOwner(PlayerController PC) +{ + SetOwner(PC); +} + +/** sends info for one CoverReplicationData to the client */ +reliable server function ServerSendInitialCoverReplicationInfo(int Index) +{ + local byte SlotsArrayIndex, + NumSlotsEnabled, NumSlotsDisabled, NumSlotsAdjusted, NumCoverTypesChanged, + SlotsEnabled[8], SlotsDisabled[8], SlotsAdjusted[8]; + local ManualCoverTypeInfo SlotsCoverTypeChanged[8]; + local int i; + local bool bDone; + + // verify there's no None entries as the client assumes that means the data must be resent + while (Index < CoverReplicationData.length && CoverReplicationData[Index].Link == None) + { + CoverReplicationData.Remove(Index, 1); + } + + if (Index < CoverReplicationData.length) + { + SlotsArrayIndex = 0; + do + { + // figure out how many elements of each array to send + NumSlotsEnabled = Clamp(CoverReplicationData[Index].SlotsEnabled.length - SlotsArrayIndex, 0, 8); + NumSlotsDisabled = Clamp(CoverReplicationData[Index].SlotsDisabled.length - SlotsArrayIndex, 0, 8); + NumSlotsAdjusted = Clamp(CoverReplicationData[Index].SlotsAdjusted.length - SlotsArrayIndex, 0, 8); + NumCoverTypesChanged = Clamp(CoverReplicationData[Index].SlotsCoverTypeChanged.length - SlotsArrayIndex, 0, 8); + + // if we're sending nothing, make sure we zero the array so the netcode doesn't send that parameter at all + if (NumSlotsEnabled == 0) + { + for (i = 0; i < 8; i++) + { + SlotsEnabled[i] = 0; + } + } + else + { + // compose the data to send + // we don't bother with elements after NumSlotsEnabled as the netcode will send them regardless + for (i = 0; i < NumSlotsEnabled; i++) + { + SlotsEnabled[i] = CoverReplicationData[Index].SlotsEnabled[SlotsArrayIndex + i]; + } + } + + // do the same for the other three arrays + + if (NumSlotsDisabled == 0) + { + for (i = 0; i < 8; i++) + { + SlotsDisabled[i] = 0; + } + } + else + { + for (i = 0; i < NumSlotsDisabled; i++) + { + SlotsDisabled[i] = CoverReplicationData[Index].SlotsDisabled[SlotsArrayIndex + i]; + } + } + + if (NumSlotsAdjusted == 0) + { + for (i = 0; i < 8; i++) + { + SlotsAdjusted[i] = 0; + } + } + else + { + for (i = 0; i < NumSlotsAdjusted; i++) + { + SlotsAdjusted[i] = CoverReplicationData[Index].SlotsAdjusted[SlotsArrayIndex + i]; + } + } + + if (NumCoverTypesChanged == 0) + { + for (i = 0; i < 8; i++) + { + SlotsCoverTypeChanged[i].SlotIndex = 0; + SlotsCoverTypeChanged[i].ManualCoverType = CT_None; + } + } + else + { + for (i = 0; i < NumCoverTypesChanged; i++) + { + SlotsCoverTypeChanged[i] = CoverReplicationData[Index].SlotsCoverTypeChanged[SlotsArrayIndex + i]; + } + } + + // we're done if all of the arrays have 8 elements to send or less + bDone = ( CoverReplicationData[Index].SlotsEnabled.length - SlotsArrayIndex <= 8 && + CoverReplicationData[Index].SlotsDisabled.length - SlotsArrayIndex <= 8 && + CoverReplicationData[Index].SlotsAdjusted.length - SlotsArrayIndex <= 8 && + CoverReplicationData[Index].SlotsCoverTypeChanged.length - SlotsArrayIndex <= 8 ); + + // send out the data + ClientReceiveInitialCoverReplicationInfo( Index, CoverReplicationData[Index].Link, CoverReplicationData[Index].Link.bDisabled, + NumSlotsEnabled, SlotsEnabled, + NumSlotsDisabled, SlotsDisabled, + NumSlotsAdjusted, SlotsAdjusted, + NumCoverTypesChanged, SlotsCoverTypeChanged, + bDone ); + + // increment base array index + SlotsArrayIndex += 8; + + } until (bDone); + } +} + +/** replicates the information for one CoverReplicationData entry + * bDone indicates whether or not there is more data coming for this entry (because some arrays have more than 8 elements) + */ +reliable client function ClientReceiveInitialCoverReplicationInfo( int Index, CoverLink Link, bool bLinkDisabled, + byte NumSlotsEnabled, byte SlotsEnabled[8], + byte NumSlotsDisabled, byte SlotsDisabled[8], + byte NumSlotsAdjusted, byte SlotsAdjusted[8], + byte NumCoverTypesChanged, ManualCoverTypeInfo SlotsCoverTypeChanged[8], + bool bDone ) +{ + local int i; + + // if we received an invalid CoverLink, we might not have loaded that level yet, so ask for a resend + if (Link == None) + { + if (bDone) + { + ServerSendInitialCoverReplicationInfo(Index); + } + } + else + { + // process the data + Link.bDisabled = bLinkDisabled; + for (i = 0; i < NumSlotsEnabled; i++) + { + Link.SetSlotEnabled(SlotsEnabled[i], true); + } + for (i = 0; i < NumSlotsDisabled; i++) + { + Link.SetSlotEnabled(SlotsDisabled[i], false); + } + for (i = 0; i < NumSlotsAdjusted; i++) + { + if (Link.AutoAdjustSlot(SlotsAdjusted[i], false) && Link.Slots[SlotsAdjusted[i]].SlotOwner != None && Link.Slots[SlotsAdjusted[i]].SlotOwner.Controller != None) + { + Link.Slots[SlotsAdjusted[i]].SlotOwner.Controller.NotifyCoverAdjusted(); + } + } + for (i = 0; i < NumCoverTypesChanged; i++) + { + Link.Slots[SlotsCoverTypeChanged[i].SlotIndex].CoverType = SlotsCoverTypeChanged[i].ManualCoverType; + if (Link.Slots[SlotsCoverTypeChanged[i].SlotIndex].SlotOwner != None && Link.Slots[SlotsCoverTypeChanged[i].SlotIndex].SlotOwner.Controller != None) + { + Link.Slots[SlotsCoverTypeChanged[i].SlotIndex].SlotOwner.Controller.NotifyCoverAdjusted(); + } + } + + // ask for next + if (bDone) + { + ServerSendInitialCoverReplicationInfo(Index + 1); + } + } +} + +/** notification that slots on the given CoverLink have been enabled */ +function NotifyEnabledSlots(CoverLink Link, const out array SlotIndices) +{ + local int Index, SlotIndex; + local int i; + local PlayerController PC; + + Index = CoverReplicationData.Find('Link', Link); + if (Index == INDEX_NONE) + { + Index = CoverReplicationData.length; + CoverReplicationData.length = CoverReplicationData.length + 1; + CoverReplicationData[Index].Link = Link; + for (i = 0; i < SlotIndices.length; i++) + { + CoverReplicationData[Index].SlotsEnabled[i] = SlotIndices[i]; + } + } + else + { + for (i = 0; i < SlotIndices.length; i++) + { + // add to enabled list if not already there + SlotIndex = CoverReplicationData[Index].SlotsEnabled.Find(SlotIndices[i]); + if (SlotIndex == INDEX_NONE) + { + CoverReplicationData[Index].SlotsEnabled[CoverReplicationData[Index].SlotsEnabled.length] = SlotIndices[i]; + } + // remove from disabled list, if necessary + SlotIndex = CoverReplicationData[Index].SlotsDisabled.Find(SlotIndices[i]); + if (SlotIndex != INDEX_NONE) + { + CoverReplicationData[Index].SlotsDisabled.Remove(SlotIndex, 1); + } + } + } + + if (WorldInfo.Game.GetCoverReplicator() == self) + { + // we are the base info; inform players of the change now + foreach WorldInfo.AllControllers(class'PlayerController', PC) + { + if (PC.MyCoverReplicator == None) + { + PC.SpawnCoverReplicator(); + } + else + { + PC.MyCoverReplicator.NotifyEnabledSlots(Link, SlotIndices); + } + } + } + + if (PlayerController(Owner) != None) + { + // replicate the data for this action + ServerSendEnabledSlots(Index); + } +} + +/** send just the enabled slots for the CoverLink at the given index */ +reliable server function ServerSendEnabledSlots(int Index) +{ + local int SlotsArrayIndex; + local byte NumSlotsEnabled, SlotsEnabled[8]; + local int i; + local bool bDone; + + if (CoverReplicationData[Index].Link != None) + { + SlotsArrayIndex = 0; + do + { + NumSlotsEnabled = Clamp(CoverReplicationData[Index].SlotsEnabled.length - SlotsArrayIndex, 0, 8); + + // compose the data to send + // we don't bother with elements after NumSlotsEnabled as the netcode will send them regardless + for (i = 0; i < NumSlotsEnabled; i++) + { + SlotsEnabled[i] = CoverReplicationData[Index].SlotsEnabled[SlotsArrayIndex + i]; + } + + // we're done if the array has 8 elements to send or less + bDone = (CoverReplicationData[Index].SlotsEnabled.length - SlotsArrayIndex <= 8); + + // send out the data + ClientReceiveEnabledSlots(Index, CoverReplicationData[Index].Link, NumSlotsEnabled, SlotsEnabled, bDone); + + // increment base array index + SlotsArrayIndex += 8; + + } until (bDone); + } +} + +/** client receives just the enabled slots for the given CoverLink */ +reliable client function ClientReceiveEnabledSlots(int Index, CoverLink Link, byte NumSlotsEnabled, byte SlotsEnabled[8], bool bDone) +{ + local int i; + + // if we received an invalid CoverLink, we might not have loaded that level yet, so ask for a resend + if (Link == None) + { + if (bDone) + { + ServerSendEnabledSlots(Index); + } + } + else + { + // process the data + for (i = 0; i < NumSlotsEnabled; i++) + { + Link.SetSlotEnabled(SlotsEnabled[i], true); + } + } +} + +/** notification that the slots on the given CoverLink have been disabled */ +function NotifyDisabledSlots(CoverLink Link, const out array SlotIndices) +{ + local int Index, SlotIndex; + local int i; + local PlayerController PC; + + Index = CoverReplicationData.Find('Link', Link); + if (Index == INDEX_NONE) + { + Index = CoverReplicationData.length; + CoverReplicationData.length = CoverReplicationData.length + 1; + CoverReplicationData[Index].Link = Link; + for (i = 0; i < SlotIndices.length; i++) + { + CoverReplicationData[Index].SlotsDisabled[i] = SlotIndices[i]; + } + } + else + { + for (i = 0; i < SlotIndices.length; i++) + { + // add to disabled list if not already there + SlotIndex = CoverReplicationData[Index].SlotsDisabled.Find(SlotIndices[i]); + if (SlotIndex == INDEX_NONE) + { + CoverReplicationData[Index].SlotsDisabled[CoverReplicationData[Index].SlotsDisabled.length] = SlotIndices[i]; + } + // remove from enabled list, if necessary + SlotIndex = CoverReplicationData[Index].SlotsEnabled.Find(SlotIndices[i]); + if (SlotIndex != INDEX_NONE) + { + CoverReplicationData[Index].SlotsEnabled.Remove(SlotIndex, 1); + } + } + } + + if (WorldInfo.Game.GetCoverReplicator() == self) + { + // we are the base info; inform players of the change now + foreach WorldInfo.AllControllers(class'PlayerController', PC) + { + if (PC.MyCoverReplicator == None) + { + PC.SpawnCoverReplicator(); + } + else + { + PC.MyCoverReplicator.NotifyDisabledSlots(Link, SlotIndices); + } + } + } + + if (PlayerController(Owner) != None) + { + // replicate the data for this action + ServerSendDisabledSlots(Index); + } +} + +/** send just the disabled slots for the CoverLink at the given index */ +reliable server function ServerSendDisabledSlots(int Index) +{ + local int SlotsArrayIndex; + local byte NumSlotsDisabled, SlotsDisabled[8]; + local int i; + local bool bDone; + + if (CoverReplicationData[Index].Link != None) + { + SlotsArrayIndex = 0; + do + { + NumSlotsDisabled = Clamp(CoverReplicationData[Index].SlotsDisabled.length - SlotsArrayIndex, 0, 8); + + // compose the data to send + // we don't bother with elements after NumSlotsDisabled as the netcode will send them regardless + for (i = 0; i < NumSlotsDisabled; i++) + { + SlotsDisabled[i] = CoverReplicationData[Index].SlotsDisabled[SlotsArrayIndex + i]; + } + + // we're done if the array has 8 elements to send or less + bDone = (CoverReplicationData[Index].SlotsDisabled.length - SlotsArrayIndex <= 8); + + // send out the data + ClientReceiveDisabledSlots(Index, CoverReplicationData[Index].Link, NumSlotsDisabled, SlotsDisabled, bDone); + + // increment base array index + SlotsArrayIndex += 8; + + } until (bDone); + } +} + +/** client receives just the disabled slots for the given CoverLink */ +reliable client function ClientReceiveDisabledSlots(int Index, CoverLink Link, byte NumSlotsDisabled, byte SlotsDisabled[8], bool bDone) +{ + local int i; + + // if we received an invalid CoverLink, we might not have loaded that level yet, so ask for a resend + if (Link == None) + { + if (bDone) + { + ServerSendDisabledSlots(Index); + } + } + else + { + // process the data + for (i = 0; i < NumSlotsDisabled; i++) + { + Link.SetSlotEnabled(SlotsDisabled[i], false); + } + } +} + +/** notification that the slots on the given CoverLink have been auto-adjusted */ +function NotifyAutoAdjustSlots(CoverLink Link, const out array SlotIndices) +{ + local int Index, SlotIndex; + local int i; + local PlayerController PC; + + Index = CoverReplicationData.Find('Link', Link); + if (Index == INDEX_NONE) + { + Index = CoverReplicationData.length; + CoverReplicationData.length = CoverReplicationData.length + 1; + CoverReplicationData[Index].Link = Link; + for (i = 0; i < SlotIndices.length; i++) + { + CoverReplicationData[Index].SlotsAdjusted[i] = SlotIndices[i]; + } + } + else + { + for (i = 0; i < SlotIndices.length; i++) + { + // add to adjusted list if not already there + SlotIndex = CoverReplicationData[Index].SlotsAdjusted.Find(SlotIndices[i]); + if (SlotIndex == INDEX_NONE) + { + CoverReplicationData[Index].SlotsAdjusted[CoverReplicationData[Index].SlotsAdjusted.length] = SlotIndices[i]; + } + // remove from manual list, if necessary + SlotIndex = CoverReplicationData[Index].SlotsCoverTypeChanged.Find('SlotIndex', SlotIndices[i]); + if (SlotIndex != INDEX_NONE) + { + CoverReplicationData[Index].SlotsCoverTypeChanged.Remove(SlotIndex, 1); + } + } + } + + if (WorldInfo.Game.GetCoverReplicator() == self) + { + // we are the base info; inform players of the change now + foreach WorldInfo.AllControllers(class'PlayerController', PC) + { + if (PC.MyCoverReplicator == None) + { + PC.SpawnCoverReplicator(); + } + else + { + PC.MyCoverReplicator.NotifyAutoAdjustSlots(Link, SlotIndices); + } + } + } + + if (PlayerController(Owner) != None) + { + // replicate the data for this action + ServerSendAdjustedSlots(Index); + } +} + +/** send just the auto-adjusted slots for the CoverLink at the given index */ +reliable server function ServerSendAdjustedSlots(int Index) +{ + local int SlotsArrayIndex; + local byte NumSlotsAdjusted, SlotsAdjusted[8]; + local int i; + local bool bDone; + + if (CoverReplicationData[Index].Link != None) + { + SlotsArrayIndex = 0; + do + { + NumSlotsAdjusted = Clamp(CoverReplicationData[Index].SlotsAdjusted.length - SlotsArrayIndex, 0, 8); + + // compose the data to send + // we don't bother with elements after NumSlotsDisabled as the netcode will send them regardless + for (i = 0; i < NumSlotsAdjusted; i++) + { + SlotsAdjusted[i] = CoverReplicationData[Index].SlotsAdjusted[SlotsArrayIndex + i]; + } + + // we're done if the array has 8 elements to send or less + bDone = (CoverReplicationData[Index].SlotsAdjusted.length - SlotsArrayIndex <= 8); + + // send out the data + ClientReceiveAdjustedSlots(Index, CoverReplicationData[Index].Link, NumSlotsAdjusted, SlotsAdjusted, bDone); + + // increment base array index + SlotsArrayIndex += 8; + + } until (bDone); + } +} + +/** client receives just the auto-adjusted slots for the given CoverLink */ +reliable client function ClientReceiveAdjustedSlots(int Index, CoverLink Link, byte NumSlotsAdjusted, byte SlotsAdjusted[8], bool bDone) +{ + local int i; + + // if we received an invalid CoverLink, we might not have loaded that level yet, so ask for a resend + if (Link == None) + { + if (bDone) + { + ServerSendAdjustedSlots(Index); + } + } + else + { + // process the data + for (i = 0; i < NumSlotsAdjusted; i++) + { + if (Link.AutoAdjustSlot(SlotsAdjusted[i], true) && Link.Slots[SlotsAdjusted[i]].SlotOwner != None && Link.Slots[SlotsAdjusted[i]].SlotOwner.Controller != None) + { + Link.Slots[SlotsAdjusted[i]].SlotOwner.Controller.NotifyCoverAdjusted(); + } + } + } +} + +/** notification that the slots on the given CoverLink have been manually adjusted */ +function NotifySetManualCoverTypeForSlots(CoverLink Link, const out array SlotIndices, ECoverType NewCoverType) +{ + local int Index, SlotIndex; + local int i; + local PlayerController PC; + + Index = CoverReplicationData.Find('Link', Link); + if (Index == INDEX_NONE) + { + Index = CoverReplicationData.length; + CoverReplicationData.length = CoverReplicationData.length + 1; + CoverReplicationData[Index].Link = Link; + CoverReplicationData[Index].SlotsCoverTypeChanged.length = SlotIndices.length; + for (i = 0; i < SlotIndices.length; i++) + { + CoverReplicationData[Index].SlotsCoverTypeChanged[i].SlotIndex = SlotIndices[i]; + CoverReplicationData[Index].SlotsCoverTypeChanged[i].ManualCoverType = NewCoverType; + } + } + else + { + for (i = 0; i < SlotIndices.length; i++) + { + // add to adjusted list if not already there + SlotIndex = CoverReplicationData[Index].SlotsCoverTypeChanged.Find('SlotIndex', SlotIndices[i]); + if (SlotIndex == INDEX_NONE) + { + SlotIndex = CoverReplicationData[Index].SlotsCoverTypeChanged.length; + CoverReplicationData[Index].SlotsCoverTypeChanged.length = CoverReplicationData[Index].SlotsCoverTypeChanged.length + 1; + CoverReplicationData[Index].SlotsCoverTypeChanged[SlotIndex].SlotIndex = SlotIndices[i]; + } + CoverReplicationData[Index].SlotsCoverTypeChanged[SlotIndex].ManualCoverType = NewCoverType; + // remove from auto list, if necessary + SlotIndex = CoverReplicationData[Index].SlotsAdjusted.Find(SlotIndices[i]); + if (SlotIndex != INDEX_NONE) + { + CoverReplicationData[Index].SlotsAdjusted.Remove(SlotIndex, 1); + } + } + } + + if (WorldInfo.Game.GetCoverReplicator() == self) + { + // we are the base info; inform players of the change now + foreach WorldInfo.AllControllers(class'PlayerController', PC) + { + if (PC.MyCoverReplicator == None) + { + PC.SpawnCoverReplicator(); + } + else + { + PC.MyCoverReplicator.NotifySetManualCoverTypeForSlots(Link, SlotIndices, NewCoverType); + } + } + } + + if (PlayerController(Owner) != None) + { + // replicate the data for this action + ServerSendManualCoverTypeSlots(Index); + } +} + +/** send just the manual adjusted slots for the CoverLink at the given index */ +reliable server function ServerSendManualCoverTypeSlots(int Index) +{ + local int SlotsArrayIndex; + local byte NumCoverTypesChanged; + local ManualCoverTypeInfo SlotsCoverTypeChanged[8]; + local int i; + local bool bDone; + + if (CoverReplicationData[Index].Link != None) + { + SlotsArrayIndex = 0; + do + { + NumCoverTypesChanged = Clamp(CoverReplicationData[Index].SlotsCoverTypeChanged.length - SlotsArrayIndex, 0, 8); + + // compose the data to send + // we don't bother with elements after NumSlotsDisabled as the netcode will send them regardless + for (i = 0; i < NumCoverTypesChanged; i++) + { + SlotsCoverTypeChanged[i] = CoverReplicationData[Index].SlotsCoverTypeChanged[SlotsArrayIndex + i]; + } + + // we're done if the array has 8 elements to send or less + bDone = (CoverReplicationData[Index].SlotsCoverTypeChanged.length - SlotsArrayIndex <= 8); + + // send out the data + ClientReceiveManualCoverTypeSlots(Index, CoverReplicationData[Index].Link, NumCoverTypesChanged, SlotsCoverTypeChanged, bDone); + + // increment base array index + SlotsArrayIndex += 8; + + } until (bDone); + } +} + +/** client receives just the manual adjusted slots for the given CoverLink */ +reliable client function ClientReceiveManualCoverTypeSlots( int Index, CoverLink Link, byte NumCoverTypesChanged, + ManualCoverTypeInfo SlotsCoverTypeChanged[8], bool bDone ) +{ + local int i; + + // if we received an invalid CoverLink, we might not have loaded that level yet, so ask for a resend + if (Link == None) + { + if (bDone) + { + ServerSendManualCoverTypeSlots(Index); + } + } + else + { + // process the data + for (i = 0; i < NumCoverTypesChanged; i++) + { + Link.Slots[SlotsCoverTypeChanged[i].SlotIndex].CoverType = SlotsCoverTypeChanged[i].ManualCoverType; + if (Link.Slots[SlotsCoverTypeChanged[i].SlotIndex].SlotOwner != None && Link.Slots[SlotsCoverTypeChanged[i].SlotIndex].SlotOwner.Controller != None) + { + Link.Slots[SlotsCoverTypeChanged[i].SlotIndex].SlotOwner.Controller.NotifyCoverAdjusted(); + } + } + } +} + +function NotifyLinkDisabledStateChange(CoverLink Link) +{ + local int Index; + local PlayerController PC; + + Index = CoverReplicationData.Find('Link', Link); + if (Index == INDEX_NONE) + { + Index = CoverReplicationData.length; + CoverReplicationData.length = CoverReplicationData.length + 1; + CoverReplicationData[Index].Link = Link; + } + + if (WorldInfo.Game.GetCoverReplicator() == self) + { + // we are the base info; inform players of the change now + foreach WorldInfo.AllControllers(class'PlayerController', PC) + { + if (PC.MyCoverReplicator == None) + { + PC.SpawnCoverReplicator(); + } + else + { + PC.MyCoverReplicator.NotifyLinkDisabledStateChange(Link); + } + } + } + + if (PlayerController(Owner) != None) + { + // replicate the data for this action + ServerSendLinkDisabledState(Index); + } +} + +reliable server function ServerSendLinkDisabledState(int Index) +{ + if (CoverReplicationData[Index].Link != None) + { + ClientReceiveLinkDisabledState(Index, CoverReplicationData[Index].Link, CoverReplicationData[Index].Link.bDisabled); + } +} + +reliable client function ClientReceiveLinkDisabledState(int Index, CoverLink Link, bool bLinkDisabled) +{ + // if we received an invalid CoverLink, we might not have loaded that level yet, so ask for a resend + if (Link == None) + { + ServerSendLinkDisabledState(Index); + } + else + { + Link.bDisabled = bLinkDisabled; + } +} + +defaultproperties +{ + bOnlyRelevantToOwner=true + bAlwaysRelevant=false + bOnlyDirtyReplication=true + NetUpdateFrequency=0.1 +} diff --git a/Engine/Classes/CoverSlipReachSpec.uc b/Engine/Classes/CoverSlipReachSpec.uc new file mode 100644 index 0000000..ff76b36 --- /dev/null +++ b/Engine/Classes/CoverSlipReachSpec.uc @@ -0,0 +1,19 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class CoverSlipReachSpec extends ForcedReachSpec + native; + +cpptext +{ + virtual INT CostFor(APawn* P); + virtual FVector GetForcedPathSize( class ANavigationPoint* Start, class ANavigationPoint* End, class AScout* Scout ); +} + +// Value CoverLink.ECoverDirection for movement direction along this spec +var() editconst Byte SpecDirection; + +defaultproperties +{ + bSkipPrune=TRUE +} diff --git a/Engine/Classes/CrowdAgentBase.uc b/Engine/Classes/CrowdAgentBase.uc new file mode 100644 index 0000000..1e0b2c4 --- /dev/null +++ b/Engine/Classes/CrowdAgentBase.uc @@ -0,0 +1,41 @@ +/** + * This is the base class for crowd agents. Allows us to interact with it in the Engine module. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class CrowdAgentBase extends Actor + abstract + native(AI) + implements( Interface_NavigationHandle ) + dependson( CoverLink ) + ClassGroup(Crowd); + + +cpptext +{ + virtual UBOOL CanCoverSlip(ACoverLink* Link, INT SlotIdx) { return FALSE; } + + /** + * returns the offset from the edge move point this entity should move toward (e.g. how high off the ground we should move to) + * @param Edge - the edge we're moving to + * @return - the offset to use + */ + virtual FVector GetEdgeZAdjust(FNavMeshEdgeBase* Edge) + { + return FVector(0.f,0.f,1.f); + } + + virtual void SetupPathfindingParams( FNavMeshPathParams& out_ParamCache ); + virtual void InitForPathfinding() {} + virtual INT ExtraEdgeCostToAddWhenActive(FNavMeshEdgeBase* Edge) { return 0; } +} + +// Interface_navigationhandle stub - called when path edge is deleted that this controller is using +event NotifyPathChanged(); + + + +defaultproperties +{ +} diff --git a/Engine/Classes/CrowdPopulationManagerBase.uc b/Engine/Classes/CrowdPopulationManagerBase.uc new file mode 100644 index 0000000..3838b86 --- /dev/null +++ b/Engine/Classes/CrowdPopulationManagerBase.uc @@ -0,0 +1,13 @@ +/** + * This is the base class for crowd population managers. Needed so can have a reference in the WorldInfo. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class CrowdPopulationManagerBase extends Actor + native(AI) + abstract; + +defaultproperties +{ +} diff --git a/Engine/Classes/CullDistanceVolume.uc b/Engine/Classes/CullDistanceVolume.uc new file mode 100644 index 0000000..dd42fd3 --- /dev/null +++ b/Engine/Classes/CullDistanceVolume.uc @@ -0,0 +1,77 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class CullDistanceVolume extends Volume + native + hidecategories(Advanced,Attachment,Collision,Volume) + placeable; + +/** + * Helper structure containing size and cull distance pair. + */ +struct native CullDistanceSizePair +{ + /** Size to associate with cull distance. */ + var() float Size; + /** Cull distance associated with size. */ + var() float CullDistance; +}; + +/** + * Array of size and cull distance pairs. The code will calculate the sphere diameter of a primitive's BB and look for a best + * fit in this array to determine which cull distance to use. + */ +var() array CullDistances; + +/** + * Whether the volume is currently enabled or not. + */ +var() bool bEnabled; + +cpptext +{ + /** + * Called after change has occured - used to force update of affected primitives. + */ + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + /** + * bFinished is FALSE while the actor is being continually moved, and becomes TRUE on the last call. + * This can be used to defer computationally intensive calculations to the final PostEditMove call of + * eg a drag operation. + */ + virtual void PostEditMove(UBOOL bFinished); + + /** + * Returns whether the passed in primitive can be affected by cull distance volumes. + * + * @param PrimitiveComponent Component to test + * @return TRUE if tested component can be affected, FALSE otherwise + */ + static UBOOL CanBeAffectedByVolumes( UPrimitiveComponent* PrimitiveComponent ); + + /** + * Get the set of primitives and new max draw distances defined by this volume. + */ + void GetPrimitiveMaxDrawDistances(TMap& OutCullDistances); +} + +defaultproperties +{ + Begin Object Name=BrushComponent0 + CollideActors=False + BlockActors=False + BlockZeroExtent=False + BlockNonZeroExtent=False + BlockRigidBody=False + End Object + + CullDistances(0)=(Size=0,CullDistance=0) + CullDistances(1)=(Size=10000,CullDistance=0) + bEnabled=TRUE + + bCollideActors=False + bBlockActors=False + bProjTarget=False + SupportedEvents.Empty +} diff --git a/Engine/Classes/CurveEdPresetCurve.uc b/Engine/Classes/CurveEdPresetCurve.uc new file mode 100644 index 0000000..c3a8248 --- /dev/null +++ b/Engine/Classes/CurveEdPresetCurve.uc @@ -0,0 +1,36 @@ +//============================================================================= +// CurveEdPresetCurve +// A preset curve data object +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class CurveEdPresetCurve extends object + native + hidecategories(Object) + editinlinenew + ; + +/** Preset Generated Point */ +struct native PresetGeneratedPoint +{ + var float KeyIn; + var float KeyOut; + var bool TangentsValid; + var float TangentIn; + var float TangentOut; + var EInterpCurveMode IntepMode; +}; + +/** Name of the curve */ +var() localized string CurveName; + +/** The points of the curve */ +var array Points; + +cpptext +{ + UBOOL StoreCurvePoints(INT CurveIndex, FCurveEdInterface* Distribution); +} + +defaultproperties +{ +} diff --git a/Engine/Classes/CustomPropertyItemHandler.uc b/Engine/Classes/CustomPropertyItemHandler.uc new file mode 100644 index 0000000..25ddddd --- /dev/null +++ b/Engine/Classes/CustomPropertyItemHandler.uc @@ -0,0 +1,41 @@ +/** + * Provides an interface for overriding the default behavior of routing and applying property values received + * from a custom editor property window item. + * + * Classes which implement this interface would also need to specify custom property item windows + * @see UnrealEd.CustomPropertyItemBindings + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +interface CustomPropertyItemHandler + native; + +cpptext +{ + /** + * Determines whether the specified property value matches the current value of the property. Called after the user + * has changed the value of a property handled by a custom property window item. Is used to determine whether Pre/PostEditChange + * should be called for the selected objects. + * + * @param InProperty the property whose value is being checked. + * @param NewPropertyValue the value to compare against the current value of the property. + * @param ArrayIndex the array index for the element being compared; only relevant for array properties + * + * @return TRUE if NewPropertyValue matches the current value of the property specified, indicating that no effective changes + * were actually made. + */ + virtual UBOOL IsCustomPropertyValueIdentical( UProperty* InProperty, const union UPropertyValue& NewPropertyValue, INT ArrayIndex=INDEX_NONE )=0; + + /** + * Method for overriding the default behavior of applying property values received from a custom editor property window item. + * + * @param InProperty the property that is being edited + * @param PropertyValue the value to assign to the property + * @param ArrayIndex the array index for the element being changed; only relevant for array properties + * + * @return TRUE if the property was handled by this object and the property value was successfully applied to the + * object's data. + */ + virtual UBOOL EditorSetPropertyValue( UProperty* InProperty, const union UPropertyValue& PropertyValue, INT ArrayIndex=INDEX_NONE )=0; +} + diff --git a/Engine/Classes/CylinderComponent.uc b/Engine/Classes/CylinderComponent.uc new file mode 100644 index 0000000..d73acda --- /dev/null +++ b/Engine/Classes/CylinderComponent.uc @@ -0,0 +1,43 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class CylinderComponent extends PrimitiveComponent + native + noexport + collapsecategories + editinlinenew; + +var() const export float CollisionHeight; +var() const export float CollisionRadius; + +/** Color used to draw the cylinder. */ +var() const color CylinderColor; + +/** Whether to draw the red bounding box for this cylinder. */ +var const bool bDrawBoundingBox; + +/** If TRUE, this cylinder will always draw when SHOW_Collision is on, even if CollideActors is FALSE. */ +var const bool bDrawNonColliding; + +/** If TRUE, this cylinder will always draw when the actor is selected. */ +var const bool bAlwaysRenderIfSelected; + +native final function SetCylinderSize(float NewRadius, float NewHeight); + +// The rotation part of the local-to-world transformation has no effect on the cylinder; it is always +// assumed to be aligned with the z-axis. The translation part is however taken into consideration. + +defaultproperties +{ + HiddenGame=TRUE + BlockZeroExtent=true + BlockNonZeroExtent=true + CollisionRadius=+00022.000000 + CollisionHeight=+00022.000000 + bAcceptsLights=false + bCastDynamicShadow=false + CylinderColor=(R=223,G=149,B=157,A=255) + bDrawBoundingBox=TRUE + bAlwaysRenderIfSelected=false + bAcceptsDynamicDecals=FALSE +} diff --git a/Engine/Classes/DOFAndBloomEffect.uc b/Engine/Classes/DOFAndBloomEffect.uc new file mode 100644 index 0000000..e281987 --- /dev/null +++ b/Engine/Classes/DOFAndBloomEffect.uc @@ -0,0 +1,134 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * Depth of Field post process effect + * + */ +class DOFAndBloomEffect extends DOFEffect + native; + +/** A scale applied to blooming colors. */ +var(Bloom) float BloomScale; + +/** Any component of a pixel's color must be larger than this to contribute bloom. */ +var(Bloom) float BloomThreshold; + +/** Multiplies against the bloom color. */ +var(Bloom) color BloomTint; + +/** + * Scene color luminance must be less than this to receive bloom. + * This behaves like Photoshop's screen blend mode and prevents over-saturation from adding bloom to already bright areas. + * The default value of 1 means that a pixel with a luminance of 1 won't receive any bloom, but a pixel with a luminance of .5 will receive half bloom. + */ +var(Bloom) float BloomScreenBlendThreshold; + +/** A multiplier applied to all reads of scene color. */ +var deprecated float SceneMultiplier; + +/** the radius of the bloom effect 0..64 */ +var(Bloom) float BlurBloomKernelSize; + +var deprecated bool bEnableReferenceDOF; + +`if(`__TW_HQ_BLOOM_) +/** Scales the final bloom color before applying to the scene */ +var(HQ_Bloom) float BloomIntensity; + +/** Width multiplier for the blur kernel. Larger values equal width bloom. */ +var(HQ_Bloom) float BloomWidth; + +/** During the bright-pass phase, the candidate color at each pixel is scaled by this + * value before applying the threshold. */ +var(HQ_Bloom) float Exposure; + +/** Threshold value for determining which pixels contribute to bloom. Pixel colors + * are scaled by Exposure before applying the threshold. */ +var(HQ_Bloom) float BloomThreshold2; +`endif + +/** + * Allows to specify the depth of field type. Choose depending on performance and quality needs. + * "SimpleDOF" blurs the out of focus content and recombines that with the unblurred scene (fast, almost constant speed). + * "ReferenceDOF" makes use of dynamic branching in the pixel shader and features circular Bokeh shape effects (slow for big Kernel Size). +`if(`__TW_POSTPROCESS_) + * "VariableWidthDOF" uses a summed area table for constant-time variable-width blur. +`endif + * "BokehDOF" allows to specify a Bokeh texture and a bigger radius (requires D3D11, slow when using a lot of out of focus content) + */ +var(DepthOfField) enum EDOFType +{ + DOFType_SimpleDOF, + DOFType_ReferenceDOF, + DOFType_BokehDOF, +`if(`__TW_POSTPROCESS_) + DOFType_VariableWidthDOF, +`endif +} DepthOfFieldType; + +/** + * Allows to specify the quality of the chose Depth of Field Type. + * This meaning depends heavily on the current implementation and that might change. + * If performance is important the lowest acceptable quality should be used. + */ +var(DepthOfField) enum EDOFQuality +{ + DOFQuality_Low, + DOFQuality_Medium, + DOFQuality_High, +} DepthOfFieldQuality; + +/** only used if BokehDOF is enabled */ +var(DepthOfField) Texture2D BokehTexture; + +cpptext +{ + // UPostProcessEffect interface + + /** + * Creates a proxy to represent the render info for a post process effect + * @param WorldSettings - The world's post process settings for the view. + * @return The proxy object. + */ + virtual class FPostProcessSceneProxy* CreateSceneProxy(const FPostProcessSettings* WorldSettings); + + /** + * @param View - current view + * @return TRUE if the effect should be rendered + */ + virtual UBOOL IsShown(const FSceneView* View) const; + + // UObject interface + + /** + * Called after this instance has been serialized. UberPostProcessEffect should only + * ever exists in the SDPG_PostProcess scene + */ + virtual void PostLoad(); + + /** + * This allows to print a warning when the effect is used. + */ + virtual void OnPostProcessWarning(FString& OutWarning) const + { + OutWarning = TEXT("Warning: DOFAndBloom should no longer be used, use Uberpostprocess instead."); + } +} + +defaultproperties +{ + BloomScale=1.0 + BloomThreshold=1.0 + BloomTint=(R=255,G=255,B=255) + BloomScreenBlendThreshold=10 + BlurKernelSize=16.0 + BlurBloomKernelSize=16.0 + bEnableReferenceDOF=false + +`if(`__TW_HQ_BLOOM_) + BloomIntensity=1.05 + BloomWidth=4 + Exposure=1.25 + BloomThreshold2=0.6 +`endif +} \ No newline at end of file diff --git a/Engine/Classes/DOFBloomMotionBlurEffect.uc b/Engine/Classes/DOFBloomMotionBlurEffect.uc new file mode 100644 index 0000000..395ddb1 --- /dev/null +++ b/Engine/Classes/DOFBloomMotionBlurEffect.uc @@ -0,0 +1,56 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DOFBloomMotionBlurEffect extends DOFAndBloomEffect + native; + +/** Maximum blur velocity amount. This is a clamp on the amount of blur. */ +var(MotionBlur) float MaxVelocity; + +/** This is a scale that could be considered as the "sensitivity" of the blur. */ +var(MotionBlur) float MotionBlurAmount; + +/** Whether everything (static/dynamic objects) should motion blur or not. If disabled, only moving objects may blur. */ +var(MotionBlur) bool FullMotionBlur; + +/** Threshhold for when to turn off motion blur when the camera rotates swiftly during a single frame (in degrees). */ +var(MotionBlur) float CameraRotationThreshold; + +/** Threshhold for when to turn off motion blur when the camera translates swiftly during a single frame (in world units). */ +var(MotionBlur) float CameraTranslationThreshold; + +cpptext +{ + // UPostProcessEffect interface + + /** + * Creates a proxy to represent the render info for a post process effect + * @param WorldSettings - The world's post process settings for the view. + * @return The proxy object. + */ + virtual class FPostProcessSceneProxy* CreateSceneProxy(const FPostProcessSettings* WorldSettings); + + /** + * @param View - current view + * @return TRUE if the effect should be rendered + */ + virtual UBOOL IsShown(const FSceneView* View) const; + + /** + * This allows to print a warning when the effect is used. + */ + virtual void OnPostProcessWarning(FString& OutWarning) const + { + OutWarning = TEXT("Warning: DOFAndBloomAndMotionBlur should no longer be used, use Uberpostprocess instead."); + } +} + +defaultproperties +{ + MotionBlurAmount = 0.5f; + MaxVelocity = 1.0f; + FullMotionBlur = true; + CameraRotationThreshold = 90.0f; + CameraTranslationThreshold = 10000.0f; + bShowInEditor = false; +} diff --git a/Engine/Classes/DOFEffect.uc b/Engine/Classes/DOFEffect.uc new file mode 100644 index 0000000..234b0d5 --- /dev/null +++ b/Engine/Classes/DOFEffect.uc @@ -0,0 +1,71 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * Depth of Field post process effect + * + */ +class DOFEffect extends PostProcessEffect + native + abstract; + +/** exponent to apply to blur amount after it has been normalized to [0,1] */ +var(DepthOfField) float FalloffExponent; +/** affects the radius of the DepthOfField bohek / how blurry the scene gets */ +var(DepthOfField) float BlurKernelSize; +/** [0,1] value for clamping how much blur to apply to items in front of the focus plane */ +var(DepthOfField, BlurAmount) float MaxNearBlurAmount; +/** [0,1] value for clamping how much blur to apply */ +var(DepthOfField, BlurAmount) float MinBlurAmount; +/** [0,1] value for clamping how much blur to apply to items behind the focus plane */ +var(DepthOfField, BlurAmount) float MaxFarBlurAmount; + +/** control how the focus point is determined */ +var(DepthOfField) enum EFocusType +{ + // use distance from the view + FOCUS_Distance, + // use a world space point + FOCUS_Position +} FocusType; +/** inner focus radius */ +var(DepthOfField) float FocusInnerRadius; +/** used when FOCUS_Distance is enabled */ +var(DepthOfField) float FocusDistance; +/** used when FOCUS_Position is enabled */ +var(DepthOfField) vector FocusPosition; + +cpptext +{ + // UPostProcessEffect interface + + /** + * Creates a proxy to represent the render info for a post process effect + * @param WorldSettings - The world's post process settings for the view. + * @return The proxy object. + */ + virtual class FPostProcessSceneProxy* CreateSceneProxy(const FPostProcessSettings* WorldSettings); + + /** + * @param View - current view + * @return TRUE if the effect should be rendered + */ + virtual UBOOL IsShown(const FSceneView* View) const; + + // UObject inteface + + /** callback for changed property */ + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); +} + +defaultproperties +{ + // typical settings + FocusType=FOCUS_Distance + FocusDistance=800 + FocusInnerRadius=400 + FalloffExponent=2 + BlurKernelSize=2 + MaxNearBlurAmount=1 + MinBlurAmount=0 + MaxFarBlurAmount=1 +} \ No newline at end of file diff --git a/Engine/Classes/DamageType.uc b/Engine/Classes/DamageType.uc new file mode 100644 index 0000000..5ab9b4f --- /dev/null +++ b/Engine/Classes/DamageType.uc @@ -0,0 +1,62 @@ +/** + * DamageType, the base class of all damagetypes. + * this and its subclasses are never spawned, just used as information holders + * + * NOTE: we can not do: HideDropDown on this class as we need to be able to use it in SeqEvent_TakeDamage for objects taking + * damage from any DamageType! + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + + +class DamageType extends object + native + abstract; + +var() bool bArmorStops; // does regular armor provide protection against this damage + +var bool bCausedByWorld; //this damage was caused by the world (falling off level, into lava, etc) +var bool bExtraMomentumZ; // Add extra Z to momentum on walking pawns to throw them up into the air + +/** Can break bits off FracturedStaticMeshActors. */ +var() bool bCausesFracture; + +var(RigidBody) float KDamageImpulse; // magnitude of impulse applied to KActor due to this damage type. +var(RigidBody) float KDeathVel; // How fast ragdoll moves upon death +var(RigidBody) float KDeathUpKick; // Amount of upwards kick ragdolls get when they die + +/** Size of impulse to apply when doing radial damage. */ +var(RigidBody) float RadialDamageImpulse; + +/** When applying radial impulses, whether to treat as impulse or velocity change. */ +var(RigidBody) bool bRadialDamageVelChange; + +/** multiply damage by this for vehicles */ +var float VehicleDamageScaling; + +/** multiply momentum by this for vehicles */ +var float VehicleMomentumScaling; + +/** The forcefeedback waveform to play when you take damage */ +var ForceFeedbackWaveform DamagedFFWaveform; + +/** The forcefeedback waveform to play when you are killed by this damage type */ +var ForceFeedbackWaveform KilledFFWaveform; + +/** Damage imparted by this damage type to fracturable meshes. Scaled by config WorldInfo.FracturedMeshWeaponDamage. */ +var float FracturedMeshDamage; + +static function float VehicleDamageScalingFor(Vehicle V) +{ + return Default.VehicleDamageScaling; +} + +defaultproperties +{ + bArmorStops=true + KDamageImpulse=800 + VehicleDamageScaling=+1.0 + VehicleMomentumScaling=+1.0 + bExtraMomentumZ=true + FracturedMeshDamage=1.0 +} diff --git a/Engine/Classes/DataStoreClient.uc b/Engine/Classes/DataStoreClient.uc new file mode 100644 index 0000000..499b9cc --- /dev/null +++ b/Engine/Classes/DataStoreClient.uc @@ -0,0 +1,231 @@ +/** + * Creates and manages all globally accessible persistent data stores. + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DataStoreClient extends UIRoot + native(inherit) + Config(Engine); + +/** + * Represents a collection of data stores that are linked to a specific player. + */ +struct native transient PlayerDataStoreGroup +{ + /** + * the player that this group is associated with. + */ + var const transient LocalPlayer PlayerOwner; + + /** + * the list of data stores registered for this player. + */ + var const transient array DataStores; +}; + +/** + * List of global data store class names to create when the data store client is created. + */ +var config array GlobalDataStoreClasses; + +/** + * The list of global persistent data stores. + */ +var const array GlobalDataStores; + +/** + * List of data store class names that should be loaded at initialization time, but not created. Instances of these data + * stores will be created as they are needed (i.e. PlayerOwner, etc.) + */ +var config array PlayerDataStoreClassNames; + +/** + * Stores the list of dynamic player data store classes that were loaded from PlayerDataStoreClassNames. + */ +var const private array > PlayerDataStoreClasses; + +/** + * the list of dynamic data stores that are created per-player. + */ +var const array PlayerDataStores; + +cpptext +{ + /** + * Loads each of the classes from the GlobalDataStoreClasses array, creates an instance of that class, and stores + * that instance in the GlobalDataStores array. + */ + virtual void InitializeDataStores(); +} + +/** + * Finds the data store indicated by DataStoreTag and returns a pointer to it. + * + * @param DataStoreTag A name corresponding to the 'Tag' property of a data store + * @param PlayerOwner used for resolving the correct data stores in split-screen games. + * + * @return a pointer to the data store that has a Tag corresponding to DataStoreTag, or NULL if no data + * were found with that tag. + */ +native final function UIDataStore FindDataStore( name DataStoreTag, optional LocalPlayer PlayerOwner ); + +/** + * Creates and initializes an instance of the data store class specified. + * + * @param DataStoreClass the data store class to create an instance of. DataStoreClass should be a child class + * of UUIDataStore + * + * @return a pointer to an instance of the data store class specified. + */ +native final function coerce UIDataStore CreateDataStore( class DataStoreClass ); + +/** + * Adds a new data store to the GlobalDataStores array. + * + * @param DataStore the data store to add + * @param PlayerOwner if specified, the data store will be added to the list of PlayerDataStores, rather than the list of global data stores + * + * @return TRUE if the data store was successfully added, or if the data store was already in the list. + */ +native final function bool RegisterDataStore( UIDataStore DataStore, optional LocalPlayer PlayerOwner ); + +/** + * Removes a data store from the GlobalDataStores array. + * + * @param DataStore the data store to remove + * + * @return TRUE if the data store was successfully removed, or if the data store wasn't in the list. + */ +native final function bool UnregisterDataStore( UIDataStore DataStore ); + +/** + * Finds the index into the PlayerDataStores array for the data stores associated with the specified player. + * + * @param PlayerOwner the player to search for associated data stores for. + */ +native final function int FindPlayerDataStoreIndex( LocalPlayer PlayerOwner ) const; + +/* === Unrealscript === */ +/** + * Accessor for grabbing the list of player data store classes. + */ +final function GetPlayerDataStoreClasses( out array > out_DataStoreClasses ) +{ + out_DataStoreClasses = PlayerDataStoreClasses; +} + +/** + * Searches the data store client's data store class arrays for a child of the specified meta class. + * + * @param RequiredMetaClass the data store base class to search for. + * + * @return a pointer to a child class of RequiredMetaClass that was specified in the ini. + */ +final function class FindDataStoreClass( class RequiredMetaClass ) +{ + local int i; + local class Result; + + // first, search through the global data stores array + for ( i = 0; i < GlobalDataStores.Length; i++ ) + { + // if this global data store is an instance of the class we're searching for, stop here + if ( GlobalDataStores[i].IsA(RequiredMetaClass.Name) ) + { + Result = GlobalDataStores[i].Class; + break; + } + } + + if ( Result == None ) + { + // search through the player data store class arrays + for ( i = 0; i < PlayerDataStoreClasses.Length; i++ ) + { + if ( ClassIsChildOf(PlayerDataStoreClasses[i], RequiredMetaClass) ) + { + Result = PlayerDataStoreClasses[i]; + break; + } + } + } + + return Result; +} + +/** + * Called when the current map is being unloaded. Cleans up any references which would prevent garbage collection. + */ +final event NotifyGameSessionEnded() +{ + local int i, DataStoreIndex; + local array DataStoreArray; + + DataStoreArray = GlobalDataStores; + + // notify all global data stores + for ( DataStoreIndex = 0; DataStoreIndex < DataStoreArray.Length; DataStoreIndex++ ) + { + if ( DataStoreArray[DataStoreIndex].NotifyGameSessionEnded() ) + { + UnregisterDataStore(DataStoreArray[DataStoreIndex]); + } + } + + // now notify all dynamic data stores + for ( i = PlayerDataStores.Length - 1; i >= 0; i-- ) + { + DataStoreArray = PlayerDataStores[i].DataStores; + for ( DataStoreIndex = 0; DataStoreIndex < DataStoreArray.Length; DataStoreIndex++ ) + { + DataStoreArray[DataStoreIndex].NotifyGameSessionEnded(); + UnregisterDataStore(DataStoreArray[DataStoreIndex]); + } + } +} + + +final function DebugDumpDataStoreInfo( bool bVerbose ) +{ +`if(`notdefined(FINAL_RELEASE)) + local int DataStoreIndex, PlayerDataStoreIndex; + local string PlayerName; + + local LocalPlayer PlayerOwner; + local array PlayerGroupDataStores; + + // first, search through the global data stores array + `log("GlobalDataStores: " $ GlobalDataStores.Length,,'DevDataStore'); + + for ( DataStoreIndex = 0; DataStoreIndex < GlobalDataStores.Length; DataStoreIndex++ ) + { + //@todo ronp - expose UUIDataStore::GetDataStoreId() as a native unrealscript function, rather than using the data store's tag directly + `log(" GlobalDataStore[" $ DataStoreIndex $ "]:" @ GlobalDataStores[DataStoreIndex].Tag @ "(" $ GlobalDataStores[DataStoreIndex] $ ")",,'DevDataStore'); + + //@todo ronp - call a function on the GlobalDataStore to allow it to log more detailed information + } + + `log(""); + `log("Player data store groups:" $ PlayerDataStores.Length,,'DevDataStore'); + for ( DataStoreIndex = 0; DataStoreIndex < PlayerDataStores.Length; DataStoreIndex++ ) + { + PlayerOwner = PlayerDataStores[DataStoreIndex].PlayerOwner; + PlayerGroupDataStores = PlayerDataStores[DataStoreIndex].DataStores; + + PlayerName = (PlayerOwner != None && PlayerOwner.Actor != None && PlayerOwner.Actor.PlayerReplicationInfo != None) ? PlayerOwner.Actor.PlayerReplicationInfo.PlayerName : "None"; + `log(" PlayerDataStores for player " $ DataStoreIndex $ ":" @ PlayerGroupDataStores.Length @ "(" $ Playername @ "-" @ PlayerOwner $ ")",,'DevDataStore'); + + for ( PlayerDataStoreIndex = 0; PlayerDataStoreIndex < PlayerGroupDataStores.Length; PlayerDataStoreIndex++ ) + { + //@todo ronp - expose UUIDataStore::GetDataStoreId() as a native unrealscript function, rather than using the data store's tag directly + `log(" PlayerDataStore[" $ PlayerDataStoreIndex $ "]:" @ PlayerGroupDataStores[PlayerDataStoreIndex].Tag @ "(" $ PlayerGroupDataStores[PlayerDataStoreIndex] $ ")",,'DevDataStore'); + + //@todo ronp - call a function on the GlobalDataStore to allow it to log more detailed information + } + } +`endif +} + +DefaultProperties +{ + +} diff --git a/Engine/Classes/DecalActor.uc b/Engine/Classes/DecalActor.uc new file mode 100644 index 0000000..7eb8455 --- /dev/null +++ b/Engine/Classes/DecalActor.uc @@ -0,0 +1,13 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class DecalActor extends DecalActorBase + native(Decal) + placeable; + +defaultproperties +{ + bStatic=true + bMovable=false +} diff --git a/Engine/Classes/DecalActorBase.uc b/Engine/Classes/DecalActorBase.uc new file mode 100644 index 0000000..e842f82 --- /dev/null +++ b/Engine/Classes/DecalActorBase.uc @@ -0,0 +1,65 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class DecalActorBase extends Actor + implements(EditorLinkSelectionInterface) + native(Decal) + ClassGroup(Decals) + abstract; + +var() editconst const DecalComponent Decal; + +cpptext +{ + // UObject interface. + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + // AActor interface. + virtual void PostEditMove(UBOOL bFinished); + + /** EditorLinkSelectionInterface */ + virtual void LinkSelection(USelection* SelectedActors); + virtual void UnLinkSelection(USelection* SelectedActors); + + /** + * Function that gets called from within Map_Check to allow this actor to check itself + * for any potential errors and register them with map check dialog. + */ +#if WITH_EDITOR + virtual void EditorApplyScale(const FVector& DeltaScale, const FMatrix& ScaleMatrix, const FVector* PivotLocation, UBOOL bAltDown, UBOOL bShiftDown, UBOOL bCtrlDown); + virtual void CheckForErrors(); +#endif +} + +defaultproperties +{ + TickGroup=TG_DuringAsyncWork + + Begin Object Class=DecalComponent Name=NewDecalComponent + DecalTransform=DecalTransform_OwnerAbsolute + bStaticDecal=TRUE + End Object + Decal=NewDecalComponent + Components.Add(NewDecalComponent) + + Begin Object Class=SpriteComponent Name=Sprite + Sprite=Texture2D'EditorResources.S_DecalActorIcon' + Scale=0.15 + HiddenGame=True + AlwaysLoadOnClient=False + AlwaysLoadOnServer=False + SpriteCategoryName="Decals" + End Object + Components.Add(Sprite) + + Begin Object Class=ArrowComponent Name=ArrowComponent0 + bTreatAsASprite=True + HiddenGame=true + SpriteCategoryName="Decals" + End Object + Components.Add(ArrowComponent0) + + bStatic=true + bMovable=false +} diff --git a/Engine/Classes/DecalActorMovable.uc b/Engine/Classes/DecalActorMovable.uc new file mode 100644 index 0000000..61825a8 --- /dev/null +++ b/Engine/Classes/DecalActorMovable.uc @@ -0,0 +1,19 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class DecalActorMovable extends DecalActorBase + native(Decal) + placeable; + +defaultproperties +{ + Begin Object Name=NewDecalComponent + bMovableDecal=TRUE + End Object + + bStatic=FALSE + bNoDelete=TRUE + bMovable=TRUE + bHardAttach=TRUE +} diff --git a/Engine/Classes/DecalComponent.uc b/Engine/Classes/DecalComponent.uc new file mode 100644 index 0000000..039a90b --- /dev/null +++ b/Engine/Classes/DecalComponent.uc @@ -0,0 +1,423 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class DecalComponent extends PrimitiveComponent + native(Decal) + editinlinenew + hidecategories(Collision,Object,Physics,PrimitiveComponent); + +/** Decal material. */ +var(Decal) private{private} const MaterialInterface DecalMaterial; + +/** Decal world space width. */ +var(Decal) float Width; + +/** Decal world space height. */ +var(Decal) float Height; + +/** Decal tiling along the tangent. */ +var(Decal) float TileX; + +/** Decal tiling along the binormal. */ +var(Decal) float TileY; + +/** Decal offset along the tangent. */ +var(Decal) float OffsetX; + +/** Decal offset along the binormal. */ +var(Decal) float OffsetY; + +/** Decal in-plane rotation, in degrees. */ +var(Decal) float DecalRotation; + +/** Horizontal field of view. */ +var float FieldOfView; + +/** Near plane clip distance. */ +var(Decal) float NearPlane; + +/** Far plane clip distance. */ +var(Decal) float FarPlane; + +/** Decal's frustum location, set in code or copied from DecalActor in UnrealEd. */ +var transient vector Location; + +/** Decal's frustum orientation, set in code or copied from DecalActor in UnrealEd. */ +var transient rotator Orientation; + +/** Decal's impact location, as computed by eg weapon trace. */ +var vector HitLocation; + +/** Decal's impact normal, as computed by eg weapon trace.*/ +var vector HitNormal; + +/** Decal's impact tangent, as computed by eg weapon trace.*/ +var vector HitTangent; + +/** Decal's impact binormal, as computed by eg weapon trace.*/ +var vector HitBinormal; + +/** + * If FALSE (the default), use precise clipping to compute the decal geometry. + * If TRUE, decal geometry generation is faster, but the decal material will have + * to use clamped texture coordinates. + */ +var(Decal) bool bNoClip; + +/** + * TRUE for decals created in the editor, FALSE for decals created at runtime. + */ +var const bool bStaticDecal; + +/** + * If non-NULL, consider HitComponent only when computing receivers. + */ +var transient PrimitiveComponent HitComponent; + +/** + * The name of hit bone. + */ +var transient name HitBone; + +/** If not -1, specifies the index of the BSP node that was hit. */ +var transient int HitNodeIndex; + +/** If not -1, specifies the level into the world's level array of the BSP node that was hit. */ +var transient int HitLevelIndex; + +/** If not -1, specifies the index of the FracturedStaticMeshComponent we hit */ +var transient int FracturedStaticMeshComponentIndex; + +/** Used to pass information of which BSP nodes where hit */ +var private const transient array HitNodeIndices; + +/** + * A decal receiver and its associated render data. + */ +struct native DecalReceiver +{ + var const PrimitiveComponent Component; + var native const pointer RenderData{class FDecalRenderData}; +}; + +/** List of receivers to which this decal is attached. */ +var private noimport duplicatetransient const array DecalReceivers; + +/** List of receivers for static decals. Empty if the decal has bStaticDecal=FALSE.*/ +var native private noimport transient duplicatetransient const array StaticReceivers{class FStaticReceiverData}; + +/** Command fence used to shut down properly. */ +var native const transient duplicatetransient pointer ReleaseResourcesFence{FRenderCommandFence}; + +/** Ortho planes. */ +var private transient array Planes; + +var(DecalRender) float DepthBias; +var(DecalRender) float SlopeScaleDepthBias; + +//@zombie_ps4_begin - TODO - Orbis has a different depth bias. We need a cleaner solution for this. +var(DecalRender) float OrbisDepthBias; +var(DecalRender) float OrbisSlopeScaleDepthBias; +//@zombie_ps4_end +/** Controls the order in which decal elements are rendered. Higher values draw later (on top). */ +var(DecalRender) int SortOrder; + +/** Dot product of the minimum angle that surfaces can make with the decal normal to be considered backfacing. */ +var(DecalRender) float BackfaceAngle; + +/** Start/End blend range specified as an angle in degrees. Controls where to start blending out the decal on a surface */ +var(DecalRender) Vector2D BlendRange; + +/** + * Allows artists to adjust the distance where textures using UV 0 are streamed in/out. + * 1.0 is the default, whereas a higher value increases the streamed-in resolution. + */ +var(DecalRender) const float StreamingDistanceMultiplier; + +enum EDecalTransform +{ + /** Location/Orientation are obtained from the owning actor's absolute world coordinates */ + DecalTransform_OwnerAbsolute, + /** Location/Orientation are transformed relative to the owning actor's coordinates */ + DecalTransform_OwnerRelative, + /** Location/Orientation are relative to the original spawn point in world coordinates */ + DecalTransform_SpawnRelative +}; +/** Determines how the Location/Orientation of the decal are used */ +var const EDecalTransform DecalTransform; + +/** + * Specifies how the decal application filter should be interpreted. + */ +enum EFilterMode +{ + /** Filter is ignored. */ + FM_None, + /** Filter specifies list of components to ignore. */ + FM_Ignore, + /** Filter specifies list of components to affect.*/ + FM_Affect +}; + +/** Current filter application mode. */ +var(DecalFilter) EFilterMode FilterMode; + +/** Component filter. */ +var(DecalFilter) array Filter; + +/** @hack: Gears hack to avoid an octree look-up for level-placed decals. To be replaced with receiver serialization after ship.*/ +var(DecalFilter) array ReceiverImages; + +/** If FALSE (the default), don't project decal onto back-facing polygons. */ +var(DecalFilter) bool bProjectOnBackfaces; + +/** If FALSE (the default), don't project decal onto hidden receivers. */ +var(DecalFilter) bool bProjectOnHidden; + +/** If FALSE, don't project decal onto BSP. */ +var(DecalFilter) bool bProjectOnBSP; + +/** If FALSE, don't project decal onto static meshes. */ +var(DecalFilter) bool bProjectOnStaticMeshes; + +/** If FALSE, don't project decal onto skeletal meshes. */ +var(DecalFilter) bool bProjectOnSkeletalMeshes; + +/** If FALSE, don't project decal onto terrain. */ +var(DecalFilter) bool bProjectOnTerrain; + +/** If TRUE, invert the direction considered to be backfacing receiver triangles. Set e.g. when decal actors are mirrored. */ +var bool bFlipBackfaceDirection; + +/** If TRUE, then the decal will recompute its receivers whenever its transform is updated. Allowing for dynamic movable decals */ +var bool bMovableDecal; + +`if(`__TW_) +/** If TRUE, it will recalculate the parent relative transform every tick. + PERFORMANCE WARNING + */ +var bool bTickParentRelativeTransform; +`endif + +/** TRUE if the decal has already been attached once. Allows for static decals to be reattached */ +var private transient bool bHasBeenAttached; + +/** Decal location relative to parent transform used with DecalTransform_OwnerRelative mode */ +var(DecalRender) vector ParentRelativeLocation; +/** Decal orientation vector relative to parent transform used with DecalTransform_OwnerRelative mode */ +var(DecalRender) rotator ParentRelativeOrientation; + +/** Decal location/orientation relative to parent transform when first attached */ +var const private transient matrix ParentRelLocRotMatrix; + +/** + * So for some DecalComponents (usually residing in GamePlay objects) we set the DecalMaterial from an Archetype or some other default property. + * For those decals we do not want to MapCheckForErrors on them. + **/ +var() bool bDecalMaterialSetAtRunTime; + + +/** detaches the component and resets the component's properties to the values of its template */ +native final function ResetToDefaults(); + +/** setting decal material on decal component. This will force the decal to reattach */ +native final function SetDecalMaterial(MaterialInterface NewDecalMaterial); +/** Accessor for decal material */ +native final function MaterialInterface GetDecalMaterial() const; + +/** Needed for proper synchronization of pooled decals */ +native final function bool IsWaitingForResetToDefaultsToComplete(); + +cpptext +{ +public: + /** + * Builds orthogonal planes from HitLocation, HitNormal, Width, Height and Depth. + */ + void UpdateOrthoPlanes(); + + /** + * @return TRUE if the decal is enabled as specified in GEngine, FALSE otherwise. + */ + UBOOL IsEnabled() const; + + /** + * If the decal is non-static, allocates a sort key and, if the decal is lit, a random + * depth bias to the decal. + */ + void AllocateSortKey(); + + /** + * Fills in the specified vertex list with the local-space decal frustum vertices. + */ + void GenerateDecalFrustumVerts(FVector Verts[8]) const; + + /** + * Fills in the specified decal state object with this decal's state. + */ + void CaptureDecalState(class FDecalState* DecalState) const; + + void AttachReceiver(UPrimitiveComponent* Receiver); + + /** + * Updates ortho planes, computes the receiver set, and connects to a decal manager. + */ + void ComputeReceivers(); + + /** + * Attaches the decal to static receivers, according to the data stored in StaticReceivers. + */ + void AttachToStaticReceivers(); + + /** + * Disconnects the decal from its manager and detaches receivers. + */ + void DetachFromReceivers(); + + /** + * Disconnects the decal from its manager and detaches receivers matching the given primitive component. + * This will also release the resources associated with the receiver component. + * + * @param Receiver The receiving primitive to detach decal render data for + */ + void DetachFromReceiver(UPrimitiveComponent* Receiver); + + /** + * @return TRUE if the application filter passes the specified component, FALSE otherwise. + */ + UBOOL FilterComponent(UPrimitiveComponent* Component) const; + + /** + * Frees any StaticReceivers data. + */ + void FreeStaticReceivers(); + + // PrimitiveComponent interface. + /** + * Sets the component's bounds based on the vertices of the decal frustum. + */ + virtual void UpdateBounds(); + + /** + * Enumerates the streaming textures used by the primitive. + * @param OutStreamingTextures - Upon return, contains a list of the streaming textures used by the primitive. + */ + virtual void GetStreamingTextureInfo(TArray& OutStreamingTextures) const; + + /** + * Retrieves the materials used in this component + * + * @param OutMaterials The list of used materials. + */ + virtual void GetUsedMaterials( TArray& OutMaterials ) const; + + /** + * Creates a FPrimitiveSceneProxy proxy to implement debug rendering of the decal in the rendering thread. + * + * @return A heap-allocated proxy rendering object corresponding to this decal component. + */ + virtual FPrimitiveSceneProxy* CreateSceneProxy(); + + /** + * @return TRUE if both IsEnabled() and Super::IsValidComponent() return TRUE. + */ + virtual UBOOL IsValidComponent() const; + + /** + * Determines whether the proxy for this primitive type needs to be recreated whenever the primitive moves. + * @return TRUE to recreate the proxy when UpdateTransform is called. + */ + virtual UBOOL ShouldRecreateProxyOnUpdateTransform() const; + + /** + * convert interval specified in degrees to clamped dot product range + * @return min,max range of blending decal + */ + virtual FVector2D CalcDecalDotProductBlendRange() const; + + virtual INT GetNumElements() const + { + return 1; // DecalMaterial + } + virtual UMaterialInterface* GetElementMaterial(INT ElementIndex) const + { + return (ElementIndex == 0) ? DecalMaterial : NULL; + } + virtual void SetElementMaterial(INT ElementIndex, UMaterialInterface* InMaterial) + { + if (ElementIndex == 0) + { + SetDecalMaterial(InMaterial); + } + } + + /** EditorLinkSelectionInterface */ + virtual UBOOL LinkSelection(USelection* SelectedActors); + virtual UBOOL UnLinkSelection(USelection* SelectedActors); + + // ActorComponent interface. +#if WITH_EDITOR + virtual void CheckForErrors(); +#endif + + // UObject interface; + virtual void BeginPlay(); + virtual void BeginDestroy(); + virtual UBOOL IsReadyForFinishDestroy(); + virtual void FinishDestroy(); + virtual void PreSave(); + virtual void Serialize(FArchive& Ar); + virtual INT GetResourceSize(void); + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual void AddReferencedObjects(TArray& ObjectArray); + +protected: + void ReleaseResources(UBOOL bBlockOnRelease, UPrimitiveComponent* Receiver=NULL); + + // ActorComponent interface. + virtual void Attach(); + virtual void SetParentToWorld(const FMatrix& ParentToWorld); + virtual void UpdateTransform(); + virtual void Detach( UBOOL bWillReattach = FALSE ); +} + +defaultproperties +{ + bAcceptsLights=FALSE + bAcceptsDynamicLights=FALSE + bCastDynamicShadow=FALSE + + bAcceptsStaticDecals=FALSE + bAcceptsDynamicDecals=FALSE + + bMovableDecal=FALSE + + Width=200 + Height=200 + TileX=1 + TileY=1 + NearPlane=0 + FarPlane=300 + FieldOfView=80 + HitNodeIndex=-1 + HitLevelIndex=-1 +//@zombie_ps4_begin - TODO - Orbis has a different depth bias. We need a cleaner solution for this. + OrbisDepthBias=-1.6 + OrbisSlopeScaleDepthBias=50.0 +//@zombie_ps4_end + DepthBias=-0.00006 + SlopeScaleDepthBias=0.0 + BackfaceAngle=0.001 // Corresponds to an angle of 89.94 degrees + + bProjectOnBSP=TRUE + bProjectOnSkeletalMeshes=TRUE + bProjectOnStaticMeshes=TRUE + bProjectOnTerrain=TRUE + + BlendRange=(X=89.5,Y=180) + + StreamingDistanceMultiplier=1.0 + + DecalTransform=DecalTransform_SpawnRelative +} diff --git a/Engine/Classes/DecalManager.uc b/Engine/Classes/DecalManager.uc new file mode 100644 index 0000000..d74f53b --- /dev/null +++ b/Engine/Classes/DecalManager.uc @@ -0,0 +1,293 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DecalManager extends Actor + native(Decal) + config(Game); + +/** template to base pool components off of - should not be used for decals or attached to anything */ +var protected DecalComponent DecalTemplate; +/** components currently in the pool */ +var array PoolDecals; +/** maximum allowed active components - if this is greater than 0 and is exceeded, the oldest active decal is taken */ +var int MaxActiveDecals; +/** default lifetime for decals */ +var globalconfig float DecalLifeSpan; +/** default depth bias offset */ +var float DecalDepthBias; +//@zombie_ps4_begin - TODO - Orbis has a different depth bias. We need a cleaner solution for this. +/** default depth bias offset */ +var float OrbisDecalDepthBias; +//@zombie_ps4_end +/** default decal blend range */ +var vector2D DecalBlendRange; + +/** components currently active in the world and how much longer they will be */ +struct native ActiveDecalInfo +{ + var DecalComponent Decal; + var float LifetimeRemaining; +}; +var array ActiveDecals; + +cpptext +{ + virtual void TickSpecial(FLOAT DeltaTime); +} + +/** @return whether dynamic decals are enabled */ +native static final function bool AreDynamicDecalsEnabled(); + +/** + * Called when the given decal's lifetime has run out + * @note: caller responsible for removing from ActiveDecals array (this is to prevent code iterating the array from having dependencies on this function) + */ +event DecalFinished(DecalComponent Decal) +{ + if (Decal != None) + { + // clear it and return it to the pool + Decal.ResetToDefaults(); + PoolDecals[PoolDecals.length] = Decal; + } +} + +/** @return whether spawning decals is allowed right now */ +function bool CanSpawnDecals() +{ + return AreDynamicDecalsEnabled(); +} + + +/** + * This will set all of the various decal parameters. This is the function that should be updated when there are new + * Decal Paramaters that exist that should be updated by game code + * + * @param InExistingDecal If you have an existing decal that you want to set all the params on. + * @param DecalMaterial the material to use for the decal + * @param Width decal width + * @param Height decal height + * @param Thickness decal thickness (used to calculate the nearplane/farplane values) + * @param bNoClip if true, use the bNoClip code path for decal generation (requires DecalMaterial to have clamped texture coordinates) + * @param DecalRotation rotation of the decal in degrees + * @param HitComponent if specified, will only project on this component (optimization) + * @param bProjectOnTerrain whether decal can project on terrain (default true) + * @param bProjectOnTerrain whether decal can project on skeletal meshes (default false) + * @param HitBone if HitComponent is a skeletal mesh, the bone that was hit + * @param HitNodeIndex if HitComponent is BSP, the node that was hit + * @param HitLevelIndex if HitComponent is BSP, the index of the level whose BSP was hit + * @param InFracturedStaticMeshComponentIndex The index of the FracturedMesh component. -1/INDEX_NONE if the decal should project onto both the shell and core of the FracturedMeshActor + * @param DepthBias depth bias offset to control z-fighting + * @param BlendRange Start/End blend range specified as an angle in degrees. Controls where to start blending out the decal on a surface + * + **/ +static final function SetDecalParameters( DecalComponent TheDecal, + MaterialInterface DecalMaterial, + vector DecalLocation, + rotator DecalOrientation, + float Width, + float Height, + float Thickness, + bool bNoClip, + float DecalRotation, + PrimitiveComponent HitComponent, + bool bProjectOnTerrain, + bool bProjectOnSkeletalMeshes, + name HitBone, + int HitNodeIndex, + int HitLevelIndex, + int InFracturedStaticMeshComponentIndex, + float DepthBias, +//@zombie_ps4_begin - TODO - Orbis has a different depth bias. We need a cleaner solution for this. + float OrbisDepthBias, +//@zombie_ps4_end + vector2D BlendRange + ) +{ + // set the decal's data + TheDecal.Location = DecalLocation; + TheDecal.Orientation = DecalOrientation; + TheDecal.DecalRotation = DecalRotation; + TheDecal.Width = Width; + TheDecal.Height = Height; + // the thickness is just divided in half to create the far/near plane + TheDecal.FarPlane = Thickness * 0.5; + TheDecal.NearPlane = -TheDecal.FarPlane; + TheDecal.bNoClip = bNoClip; + TheDecal.HitComponent = HitComponent; + TheDecal.HitBone = HitBone; + TheDecal.HitNodeIndex = HitNodeIndex; + TheDecal.HitLevelIndex = HitLevelIndex; + TheDecal.SetDecalMaterial(DecalMaterial); + TheDecal.bProjectOnTerrain = bProjectOnTerrain; + TheDecal.bProjectOnSkeletalMeshes = bProjectOnSkeletalMeshes; + TheDecal.FracturedStaticMeshComponentIndex = InFracturedStaticMeshComponentIndex; + TheDecal.DepthBias = DepthBias; +//@zombie_ps4_begin - TODO - Orbis has a different depth bias. We need a cleaner solution for this. + TheDecal.OrbisDepthBias = OrbisDepthBias; +//@zombie_ps4_end + TheDecal.BlendRange = BlendRange; +} + +/** @return a decal from the pool, or a new one if the pool was empty */ +protected function DecalComponent GetPooledComponent() +{ + local int i; + local DecalComponent Result; + + // try to grab one from the pool + while (PoolDecals.length > 0) + { + i = PoolDecals.length - 1; + Result = PoolDecals[i]; + PoolDecals.Remove(i, 1); + if (Result != None && !Result.IsPendingKill() && !Result.IsWaitingForResetToDefaultsToComplete()) + { + break; + } + else + { + Result = None; + } + } + + if (Result == None) + { + // if pool is empty, get started expiring something + if (MaxActiveDecals > 0 && ActiveDecals.length >= MaxActiveDecals) + { + // expire oldest decal + Result = ActiveDecals[0].Decal; + Result.ResetToDefaults(); + ActiveDecals.Remove(0, 1); + } + + Result = new(self) DecalTemplate.Class(DecalTemplate); + } + + return Result; +} + +/** + * Spawns a decal with the given parameters, taking a component from the pool or creating as necessary. + * + * @note: the component is returned so the caller can perform any additional modifications (parameters, etc), + * but it shouldn't keep the reference around as the component will be returned to the pool as soon as the lifetime runs out + * + * @param DecalMaterial the material to use for the decal + * @param Width decal width + * @param Height decal height + * @param Thickness decal thickness (used to calculate the nearplane/farplane values) + * @param bNoClip if true, use the bNoClip code path for decal generation (requires DecalMaterial to have clamped texture coordinates) + * @param DecalRotation (opt) rotation of the decal in degrees + * @param HitComponent (opt) if specified, will only project on this component (optimization) + * @param bProjectOnTerrain (opt) whether decal can project on terrain (default true) + * @param bProjectOnTerrain (opt) whether decal can project on skeletal meshes (default false) + * @param HitBone (opt) if HitComponent is a skeletal mesh, the bone that was hit + * @param HitNodeIndex (opt) if HitComponent is BSP, the node that was hit + * @param HitLevelIndex (opt) if HitComponent is BSP, the index of the level whose BSP was hit + * @param InDecalLifeSpan lifetime for the decal + * @param InFracturedStaticMeshComponentIndex The index of the FracturedMesh component. -1/INDEX_NONE if the decal should project onto both the shell and core of the FracturedMeshActor + * @param DepthBias depth bias offset to control z-fighting + * @param BlendRange Start/End blend range specified as an angle in degrees. Controls where to start blending out the decal on a surface + * @return the DecalComponent that will be used (may be None if dynamic decals are disabled) + */ +function DecalComponent SpawnDecal( MaterialInterface DecalMaterial, + vector DecalLocation, + rotator DecalOrientation, + float Width, + float Height, + float Thickness, + bool bNoClip, + optional float DecalRotation = (FRand() * 360.0), + optional PrimitiveComponent HitComponent, + optional bool bProjectOnTerrain = TRUE, + optional bool bProjectOnSkeletalMeshes, + optional name HitBone, + optional int HitNodeIndex = INDEX_NONE, + optional int HitLevelIndex = INDEX_NONE, + optional float InDecalLifeSpan = DecalLifeSpan, + optional int InFracturedStaticMeshComponentIndex = INDEX_NONE, + optional float InDepthBias = DecalDepthBias, +//@zombie_ps4_begin - TODO - Orbis has a different depth bias. We need a cleaner solution for this. + optional float InOrbisDepthBias = OrbisDecalDepthBias, +//@zombie_ps4_end + optional vector2D InBlendRange = DecalBlendRange + + ) +{ + local DecalComponent Result; + local ActiveDecalInfo DecalInfo; + + // do nothing if decals are disabled + if (!CanSpawnDecals()) + { + return None; + } + + Result = GetPooledComponent(); + + // set the decal's data + SetDecalParameters( + Result, + DecalMaterial, + DecalLocation, + DecalOrientation, + Width, + Height, + Thickness, + bNoClip, + DecalRotation, + HitComponent, + bProjectOnTerrain, + bProjectOnSkeletalMeshes, + HitBone, + HitNodeIndex, + HitLevelIndex, + INDEX_NONE, + InDepthBias, +//@zombie_ps4_begin - TODO - Orbis has a different depth bias. We need a cleaner solution for this. + InOrbisDepthBias, +//@zombie_ps4_end + InBlendRange + ); + + AttachComponent(Result); + + // add to list to tick lifetime + DecalInfo.Decal = Result; + DecalInfo.LifetimeRemaining = InDecalLifeSpan; + ActiveDecals.AddItem(DecalInfo); + + return Result; +} + +`if(`__TW_) +function Reset() +{ + local int i; + + // Returns all decals to the pool + for( i = 0; i < ActiveDecals.Length; ++i ) + { + DecalFinished( ActiveDecals[i].Decal ); + } + ActiveDecals.Length = 0; +} +`endif + +defaultproperties +{ + TickGroup=TG_DuringAsyncWork + + Begin Object Class=DecalComponent Name=BaseDecal + bIgnoreOwnerHidden=TRUE // this is needed a the owner of this decal is "hidden" as it is a global entity @see UDecalComponent::IsEnabled() + End Object + DecalTemplate=BaseDecal + +//@zombie_ps4_begin - TODO - Orbis has a different depth bias. We need a cleaner solution for this. + OrbisDecalDepthBias=-1.6 +//@zombie_ps4_end + DecalDepthBias=-0.00006 + DecalBlendRange=(X=89.5,Y=180) +} diff --git a/Engine/Classes/DecalMaterial.uc b/Engine/Classes/DecalMaterial.uc new file mode 100644 index 0000000..fe510c7 --- /dev/null +++ b/Engine/Classes/DecalMaterial.uc @@ -0,0 +1,27 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DecalMaterial extends Material + native(Decal); + +cpptext +{ + // UMaterial interface. + virtual FMaterialResource* AllocateResource(); + + // UObject interface. + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual void PreSave(); + virtual void PostLoad(); + virtual void Serialize(FArchive& Ar); +} + +defaultproperties +{ + bUsedWithStaticLighting=TRUE + bUsedWithSkeletalMesh=TRUE + bUsedWithMorphTargets=TRUE + bUsedWithDecals=TRUE + bUsedWithFluidSurfaces=TRUE + bUsedWithFracturedMeshes=TRUE +} diff --git a/Engine/Classes/DefaultPhysicsVolume.uc b/Engine/Classes/DefaultPhysicsVolume.uc new file mode 100644 index 0000000..f2fe741 --- /dev/null +++ b/Engine/Classes/DefaultPhysicsVolume.uc @@ -0,0 +1,24 @@ +//============================================================================= +// DefaultPhysicsVolume: the default physics volume for areas of the level with +// no physics volume specified +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class DefaultPhysicsVolume extends PhysicsVolume + native + notplaceable + transient; + +event Destroyed() +{ + `log(self$" destroyed!"); + assert(false); +} + +defaultproperties +{ + // Visual things should be ticked in parallel with physics + TickGroup=TG_DuringAsyncWork + + bStatic=false + bNoDelete=false +} diff --git a/Engine/Classes/DirectionalLight.uc b/Engine/Classes/DirectionalLight.uc new file mode 100644 index 0000000..b6a41d1 --- /dev/null +++ b/Engine/Classes/DirectionalLight.uc @@ -0,0 +1,60 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DirectionalLight extends Light + native(Light) + ClassGroup(Lights,DirectionalLights) + placeable; + +cpptext +{ +public: + /** + * This will determine which icon should be displayed for this light. + **/ + virtual void DetermineAndSetEditorIcon(); + + /** + * Called from within SpawnActor, setting up the default value for the Lightmass light source angle. + */ + virtual void Spawned(); + + virtual void PostLoad(); +} + + +defaultproperties +{ + Begin Object Name=Sprite + Sprite=Texture2D'EditorResources.LightIcons.Light_Directional_Stationary_DynamicsAndStatics' + End Object + + Begin Object Class=DirectionalLightComponent Name=DirectionalLightComponent0 + LightAffectsClassification=LAC_DYNAMIC_AND_STATIC_AFFECTING + + CastShadows=TRUE + CastStaticShadows=TRUE + CastDynamicShadows=TRUE + bForceDynamicLight=FALSE + UseDirectLightMap=TRUE +`if(`__TW_LIGHTING_MODIFICATIONS_) // Custom lighting channel implementation + LightingChannels=(Outdoor=TRUE,bInitialized=TRUE) +`else + LightingChannels=(BSP=TRUE,Static=TRUE,Dynamic=TRUE,bInitialized=TRUE) +`endif + End Object + LightComponent=DirectionalLightComponent0 + Components.Add(DirectionalLightComponent0) + + Begin Object Class=ArrowComponent Name=ArrowComponent0 + ArrowColor=(R=150,G=200,B=255) + bTreatAsASprite=True + AlwaysLoadOnClient=False + AlwaysLoadOnServer=False + SpriteCategoryName="Lighting" + End Object + Components.Add(ArrowComponent0) + + Rotation=(Pitch=-16384,Yaw=0,Roll=0) + RotationRate=(Pitch=0, Yaw=0, Roll=0) +} diff --git a/Engine/Classes/DirectionalLightComponent.uc b/Engine/Classes/DirectionalLightComponent.uc new file mode 100644 index 0000000..619b6f2 --- /dev/null +++ b/Engine/Classes/DirectionalLightComponent.uc @@ -0,0 +1,86 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DirectionalLightComponent extends LightComponent + native(Light) + hidecategories(Object) + dependson(EngineTypes) + editinlinenew; + +/** + * Trace distance for static lighting. Objects further than TraceDistance away from an object won't be taken into + * account for static shadowing applied to said object. This is used to work around floating point consistency + * issues in the collision code with regard to very long traces. The old default was WORLD_MAX. + */ +var(AdvancedLighting) float TraceDistance; + +/** + * Radius of the whole scene dynamic shadow centered on the viewer, which replaces the precomputed shadows based on distance from the camera. + * A Radius of 0 disables the dynamic shadow. This feature is currently only supported on dominant directional lights. + */ + `if(`__TW_) + var(CascadedShadowMaps) interp float WholeSceneDynamicShadowRadius; + `else +var(CascadedShadowMaps) interp float WholeSceneDynamicShadowRadius; +`endif + +/** + * Number of cascades to split the view frustum into for the whole scene dynamic shadow. + * More cascades result in better shadow resolution and allow WholeSceneDynamicShadowRadius to be further, but add rendering cost. + */ + `if(`__TW_) +var(CascadedShadowMaps) editconst const int NumWholeSceneDynamicShadowCascades; +`else +var(CascadedShadowMaps) editconst const int NumWholeSceneDynamicShadowCascades; +`endif + +/** + * Exponent that is applied to the cascade transition distances as a fraction of WholeSceneDynamicShadowRadius. + * An exponent of 1 means that cascade transitions will happen at a distance proportional to their resolution. + * A value greater than 1 brings transitions closer to the camera. + */ + `if(`__TW_) + var const float CascadeDistributionExponent; + `else +var(CascadedShadowMaps) const float CascadeDistributionExponent; +`endif + +/** The Lightmass settings for this object. */ +var(Lightmass) LightmassDirectionalLightSettings LightmassSettings ; + +cpptext +{ + virtual FLightSceneInfo* CreateSceneInfo() const; + virtual FVector4 GetPosition() const; + virtual ELightComponentType GetLightType() const; + + /** + * Called after property has changed via e.g. property window or set command. + * + * @param PropertyThatChanged UProperty that has been changed, NULL if unknown + */ + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); +} + +/** Called from matinee code when LightColor property changes. */ +function OnUpdatePropertyLightColor() +{ + UpdateColorAndBrightness(); +} + +/** Called from matinee code when Brightness property changes. */ +function OnUpdatePropertyBrightness() +{ + UpdateColorAndBrightness(); +} + +defaultproperties +{ + TraceDistance=100000 + NumWholeSceneDynamicShadowCascades=1 + CascadeDistributionExponent=4 +`if(`__TW_LIGHTING_MODIFICATIONS_) + WholeSceneDynamicShadowRadius=750 + bCastPerObjectShadows=TRUE +`endif +} diff --git a/Engine/Classes/DirectionalLightToggleable.uc b/Engine/Classes/DirectionalLightToggleable.uc new file mode 100644 index 0000000..dedeb12 --- /dev/null +++ b/Engine/Classes/DirectionalLightToggleable.uc @@ -0,0 +1,70 @@ +/** + * Toggleable version of DirectionalLight. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DirectionalLightToggleable extends DirectionalLight + native(Light) + ClassGroup(Lights, DirectionalLights) + placeable; + + +cpptext +{ +public: + /** + * This will determine which icon should be displayed for this light. + **/ + virtual void DetermineAndSetEditorIcon(); + + /** + * Static affecting Toggleables can't have UseDirectLightmaps=TRUE So even tho they are not "free" + * lightmapped data, they still are classified as static as it is the best they can be. + **/ + virtual void SetValuesForLight_StaticAffecting(); + + /** + * Returns true if the light supports being toggled off and on on-the-fly + * + * @return For 'toggleable' lights, returns true + **/ + virtual UBOOL IsToggleable() const + { + // DirectionalLightToggleable supports being toggled on the fly! + return TRUE; + } +} + + +defaultproperties +{ + // Visual things should be ticked in parallel with physics + TickGroup=TG_DuringAsyncWork + + Begin Object Name=Sprite + Sprite=Texture2D'EditorResources.LightIcons.Light_Directional_Toggleable_DynamicsAndStatics' + End Object + + // Light component. + Begin Object Name=DirectionalLightComponent0 + LightAffectsClassification=LAC_DYNAMIC_AND_STATIC_AFFECTING + + CastShadows=TRUE + CastStaticShadows=TRUE + CastDynamicShadows=TRUE + bForceDynamicLight=FALSE + UseDirectLightMap=FALSE +`if(`__TW_LIGHTING_MODIFICATIONS_) // Custom lighting channel implementation + LightingChannels=(Outdoor=TRUE,bInitialized=TRUE) +`else + LightingChannels=(BSP=TRUE,Static=TRUE,Dynamic=TRUE,bInitialized=TRUE) +`endif + // By default indirect light from toggleable lights won't be put into lightmaps, since it can't be toggled in-game + LightmassSettings=(IndirectLightingScale=0) + End Object + + + bMovable=FALSE + bStatic=FALSE + bHardAttach=TRUE +} diff --git a/Engine/Classes/DiscordRPCIntegration.uc b/Engine/Classes/DiscordRPCIntegration.uc new file mode 100644 index 0000000..11ff761 --- /dev/null +++ b/Engine/Classes/DiscordRPCIntegration.uc @@ -0,0 +1,42 @@ +//============================================================================= +// DiscordRPCIntegration +//============================================================================= +// Platform interface plugin for Discord's rich presence service. +//============================================================================= +// Killing Floor 2 +// Copyright (C) 2017 Tripwire Interactive LLC +//============================================================================= + +class DiscordRPCIntegration extends PlatformInterfaceBase + native(PlatformInterface); + +var bool bDiscordReady; + +//Delegate/Function pairs with callbacks into other areas +delegate JoinLobby(qword LobbyId); +native function InternalJoinLobby(qword LobbyId); + +/** +* Perform any initialization +*/ +native event Init(); + +/* + * Perform shutdown of the Discord lib + */ +native function Shutdown(); + +/** + * Called on PC tick to trigger any callbacks from the Discord DLL + */ +native function TickDiscord(); + + /** + * Create and send a presence object involving being in the main menu. + */ +native simulated function CreateMenuPresence(string PresenceString, qword LobbyId, int CurrentPlayers, int MaxPlayers); + +/** + * Create and send a presence object involving being in-game. + */ +native simulated function CreateGamePresence(string PresenceString, string DetailsString, string MapName, int CurrentPlayers, int MaxPlayers); \ No newline at end of file diff --git a/Engine/Classes/DistributionFloatConstant.uc b/Engine/Classes/DistributionFloatConstant.uc new file mode 100644 index 0000000..57a7ad9 --- /dev/null +++ b/Engine/Classes/DistributionFloatConstant.uc @@ -0,0 +1,46 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DistributionFloatConstant extends DistributionFloat + native + collapsecategories + hidecategories(Object) + editinlinenew; + +/** This float will be returned for all values of time. */ +var() float Constant; + +cpptext +{ + virtual FLOAT GetValue( FLOAT F = 0.f, UObject* Data = NULL, class FRandomStream* InRandomStream = NULL ); + + // FCurveEdInterface interface + virtual INT GetNumKeys(); + virtual INT GetNumSubCurves() const; + virtual FLOAT GetKeyIn(INT KeyIndex); + virtual FLOAT GetKeyOut(INT SubIndex, INT KeyIndex); + + /** + * Provides the color for the given key at the given sub-curve. + * + * @param SubIndex The index of the sub-curve + * @param KeyIndex The index of the key in the sub-curve + * @param[in] CurveColor The color of the curve + * @return The color that is associated the given key at the given sub-curve + */ + virtual FColor GetKeyColor(INT SubIndex, INT KeyIndex, const FColor& CurveColor); + + virtual void GetInRange(FLOAT& MinIn, FLOAT& MaxIn); + virtual void GetOutRange(FLOAT& MinOut, FLOAT& MaxOut); + virtual BYTE GetKeyInterpMode(INT KeyIndex); + virtual void GetTangents(INT SubIndex, INT KeyIndex, FLOAT& ArriveTangent, FLOAT& LeaveTangent); + virtual FLOAT EvalSub(INT SubIndex, FLOAT InVal); + + virtual INT CreateNewKey(FLOAT KeyIn); + virtual void DeleteKey(INT KeyIndex); + + virtual INT SetKeyIn(INT KeyIndex, FLOAT NewInVal); + virtual void SetKeyOut(INT SubIndex, INT KeyIndex, FLOAT NewOutVal); + virtual void SetKeyInterpMode(INT KeyIndex, EInterpCurveMode NewMode); + virtual void SetTangents(INT SubIndex, INT KeyIndex, FLOAT ArriveTangent, FLOAT LeaveTangent); +} diff --git a/Engine/Classes/DistributionFloatConstantCurve.uc b/Engine/Classes/DistributionFloatConstantCurve.uc new file mode 100644 index 0000000..9faae27 --- /dev/null +++ b/Engine/Classes/DistributionFloatConstantCurve.uc @@ -0,0 +1,53 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DistributionFloatConstantCurve extends DistributionFloat + native + collapsecategories + hidecategories(Object) + editinlinenew; + +/** Keyframe data for how output constant varies over time. */ +var() interpcurvefloat ConstantCurve; + +cpptext +{ + virtual FLOAT GetValue( FLOAT F = 0.f, UObject* Data = NULL, class FRandomStream* InRandomStream = NULL ); + + // FCurveEdInterface interface + virtual INT GetNumKeys(); + virtual INT GetNumSubCurves() const; + virtual FLOAT GetKeyIn(INT KeyIndex); + virtual FLOAT GetKeyOut(INT SubIndex, INT KeyIndex); + + /** + * Provides the color for the given key at the given sub-curve. + * + * @param SubIndex The index of the sub-curve + * @param KeyIndex The index of the key in the sub-curve + * @param[in] CurveColor The color of the curve + * @return The color that is associated the given key at the given sub-curve + */ + virtual FColor GetKeyColor(INT SubIndex, INT KeyIndex, const FColor& CurveColor); + + virtual void GetInRange(FLOAT& MinIn, FLOAT& MaxIn); + virtual void GetOutRange(FLOAT& MinOut, FLOAT& MaxOut); + virtual BYTE GetKeyInterpMode(INT KeyIndex); + virtual void GetTangents(INT SubIndex, INT KeyIndex, FLOAT& ArriveTangent, FLOAT& LeaveTangent); + virtual FLOAT EvalSub(INT SubIndex, FLOAT InVal); + + virtual INT CreateNewKey(FLOAT KeyIn); + virtual void DeleteKey(INT KeyIndex); + + virtual INT SetKeyIn(INT KeyIndex, FLOAT NewInVal); + virtual void SetKeyOut(INT SubIndex, INT KeyIndex, FLOAT NewOutVal); + virtual void SetKeyInterpMode(INT KeyIndex, EInterpCurveMode NewMode); + virtual void SetTangents(INT SubIndex, INT KeyIndex, FLOAT ArriveTangent, FLOAT LeaveTangent); + + /** Returns TRUE if this curve uses legacy tangent/interp algorithms and may be 'upgraded' */ + virtual UBOOL UsingLegacyInterpMethod() const; + + /** 'Upgrades' this curve to use the latest tangent/interp algorithms (usually, will 'bake' key tangents.) */ + virtual void UpgradeInterpMethod(); +} + diff --git a/Engine/Classes/DistributionFloatParameterBase.uc b/Engine/Classes/DistributionFloatParameterBase.uc new file mode 100644 index 0000000..b67dfba --- /dev/null +++ b/Engine/Classes/DistributionFloatParameterBase.uc @@ -0,0 +1,44 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DistributionFloatParameterBase extends DistributionFloatConstant + abstract + native + collapsecategories + hidecategories(Object) + editinlinenew; + +var() name ParameterName; +var() float MinInput; +var() float MaxInput; +var() float MinOutput; +var() float MaxOutput; + +enum DistributionParamMode +{ + DPM_Normal, + DPM_Abs, + DPM_Direct +}; + +var() DistributionParamMode ParamMode; + +cpptext +{ + virtual FLOAT GetValue( FLOAT F = 0.f, UObject* Data = NULL, class FRandomStream* InRandomStream = NULL ); + + virtual UBOOL GetParamValue(UObject* Data, FName ParamName, FLOAT& OutFloat) { return false; } + + virtual void GetOutRange(FLOAT& MinOut, FLOAT& MaxOut); + + /** + * Return whether or not this distribution can be baked into a FRawDistribution lookup table + */ + virtual UBOOL CanBeBaked() const { return FALSE; } +} + +defaultproperties +{ + MaxInput=1.0 + MaxOutput=1.0 +} diff --git a/Engine/Classes/DistributionFloatParticleParameter.uc b/Engine/Classes/DistributionFloatParticleParameter.uc new file mode 100644 index 0000000..318c8ad --- /dev/null +++ b/Engine/Classes/DistributionFloatParticleParameter.uc @@ -0,0 +1,13 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DistributionFloatParticleParameter extends DistributionFloatParameterBase + native(Particle) + collapsecategories + hidecategories(Object) + editinlinenew; + +cpptext +{ + virtual UBOOL GetParamValue(UObject* Data, FName ParamName, FLOAT& OutFloat); +} diff --git a/Engine/Classes/DistributionFloatSoundParameter.uc b/Engine/Classes/DistributionFloatSoundParameter.uc new file mode 100644 index 0000000..5d294d5 --- /dev/null +++ b/Engine/Classes/DistributionFloatSoundParameter.uc @@ -0,0 +1,13 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DistributionFloatSoundParameter extends DistributionFloatParameterBase + native(Sound) + collapsecategories + hidecategories(Object) + editinlinenew; + +cpptext +{ + virtual UBOOL GetParamValue(UObject* Data, FName ParamName, FLOAT& OutFloat); +} diff --git a/Engine/Classes/DistributionFloatUniform.uc b/Engine/Classes/DistributionFloatUniform.uc new file mode 100644 index 0000000..b30173e --- /dev/null +++ b/Engine/Classes/DistributionFloatUniform.uc @@ -0,0 +1,78 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DistributionFloatUniform extends DistributionFloat + native + collapsecategories + hidecategories(Object) + editinlinenew; + +/** Low end of output float distribution. */ +var() float Min; + +/** High end of output float distribution. */ +var() float Max; + +cpptext +{ + virtual void PostLoad(); + + virtual FLOAT GetValue( FLOAT F = 0.f, UObject* Data = NULL, class FRandomStream* InRandomStream = NULL ); + +#if !CONSOLE + /** + * Return the operation used at runtime to calculate the final value + */ + virtual ERawDistributionOperation GetOperation(); + + /** + * Fill out an array of floats and return the number of elements in the entry + * + * @param Time The time to evaluate the distribution + * @param Values An array of values to be filled out, guaranteed to be big enough for 4 floats + * @return The number of elements (values) set in the array + */ + virtual DWORD InitializeRawEntry(FLOAT Time, FLOAT* Values); +#endif + + // FCurveEdInterface interface + virtual INT GetNumKeys(); + virtual INT GetNumSubCurves() const; + + /** + * Provides the color for the sub-curve button that is present on the curve tab. + * + * @param SubCurveIndex The index of the sub-curve. Cannot be negative nor greater or equal to the number of sub-curves. + * @param bIsSubCurveHidden Is the curve hidden? + * @return The color associated to the given sub-curve index. + */ + virtual FColor GetSubCurveButtonColor(INT SubCurveIndex, UBOOL bIsSubCurveHidden) const; + + virtual FLOAT GetKeyIn(INT KeyIndex); + virtual FLOAT GetKeyOut(INT SubIndex, INT KeyIndex); + + /** + * Provides the color for the given key at the given sub-curve. + * + * @param SubIndex The index of the sub-curve + * @param KeyIndex The index of the key in the sub-curve + * @param[in] CurveColor The color of the curve + * @return The color that is associated the given key at the given sub-curve + */ + virtual FColor GetKeyColor(INT SubIndex, INT KeyIndex, const FColor& CurveColor); + + virtual void GetInRange(FLOAT& MinIn, FLOAT& MaxIn); + virtual void GetOutRange(FLOAT& MinOut, FLOAT& MaxOut); + virtual BYTE GetKeyInterpMode(INT KeyIndex); + virtual void GetTangents(INT SubIndex, INT KeyIndex, FLOAT& ArriveTangent, FLOAT& LeaveTangent); + virtual FLOAT EvalSub(INT SubIndex, FLOAT InVal); + + virtual INT CreateNewKey(FLOAT KeyIn); + virtual void DeleteKey(INT KeyIndex); + + virtual INT SetKeyIn(INT KeyIndex, FLOAT NewInVal); + virtual void SetKeyOut(INT SubIndex, INT KeyIndex, FLOAT NewOutVal); + virtual void SetKeyInterpMode(INT KeyIndex, EInterpCurveMode NewMode); + virtual void SetTangents(INT SubIndex, INT KeyIndex, FLOAT ArriveTangent, FLOAT LeaveTangent); +} + diff --git a/Engine/Classes/DistributionFloatUniformCurve.uc b/Engine/Classes/DistributionFloatUniformCurve.uc new file mode 100644 index 0000000..e652930 --- /dev/null +++ b/Engine/Classes/DistributionFloatUniformCurve.uc @@ -0,0 +1,83 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DistributionFloatUniformCurve extends DistributionFloat + native + collapsecategories + hidecategories(Object) + editinlinenew; + +/** Keyframe data for how output constant varies over time. */ +var() interpcurvevector2d ConstantCurve; + +cpptext +{ + virtual void PostLoad(); + + virtual FLOAT GetValue( FLOAT F = 0.f, UObject* Data = NULL, class FRandomStream* InRandomStream = NULL ); + +#if !CONSOLE + /** + * Return the operation used at runtime to calculate the final value + */ + virtual ERawDistributionOperation GetOperation(); + + /** + * Fill out an array of floats and return the number of elements in the entry + * + * @param Time The time to evaluate the distribution + * @param Values An array of values to be filled out, guaranteed to be big enough for 4 floats + * @return The number of elements (values) set in the array + */ + virtual DWORD InitializeRawEntry(FLOAT Time, FLOAT* Values); +#endif + + virtual FVector2D GetMinMaxValue(FLOAT F = 0.f, UObject* Data = NULL); + + // FCurveEdInterface interface + virtual INT GetNumKeys(); + virtual INT GetNumSubCurves() const; + + /** + * Provides the color for the sub-curve button that is present on the curve tab. + * + * @param SubCurveIndex The index of the sub-curve. Cannot be negative nor greater or equal to the number of sub-curves. + * @param bIsSubCurveHidden Is the curve hidden? + * @return The color associated to the given sub-curve index. + */ + virtual FColor GetSubCurveButtonColor(INT SubCurveIndex, UBOOL bIsSubCurveHidden) const; + + virtual FLOAT GetKeyIn(INT KeyIndex); + virtual FLOAT GetKeyOut(INT SubIndex, INT KeyIndex); + + /** + * Provides the color for the given key at the given sub-curve. + * + * @param SubIndex The index of the sub-curve + * @param KeyIndex The index of the key in the sub-curve + * @param[in] CurveColor The color of the curve + * @return The color that is associated the given key at the given sub-curve + */ + virtual FColor GetKeyColor(INT SubIndex, INT KeyIndex, const FColor& CurveColor); + + virtual void GetInRange(FLOAT& MinIn, FLOAT& MaxIn); + virtual void GetOutRange(FLOAT& MinOut, FLOAT& MaxOut); + virtual BYTE GetKeyInterpMode(INT KeyIndex); + virtual void GetTangents(INT SubIndex, INT KeyIndex, FLOAT& ArriveTangent, FLOAT& LeaveTangent); + virtual FLOAT EvalSub(INT SubIndex, FLOAT InVal); + + virtual INT CreateNewKey(FLOAT KeyIn); + virtual void DeleteKey(INT KeyIndex); + + virtual INT SetKeyIn(INT KeyIndex, FLOAT NewInVal); + virtual void SetKeyOut(INT SubIndex, INT KeyIndex, FLOAT NewOutVal); + virtual void SetKeyInterpMode(INT KeyIndex, EInterpCurveMode NewMode); + virtual void SetTangents(INT SubIndex, INT KeyIndex, FLOAT ArriveTangent, FLOAT LeaveTangent); + + /** Returns TRUE if this curve uses legacy tangent/interp algorithms and may be 'upgraded' */ + virtual UBOOL UsingLegacyInterpMethod() const; + + /** 'Upgrades' this curve to use the latest tangent/interp algorithms (usually, will 'bake' key tangents.) */ + virtual void UpgradeInterpMethod(); +} + diff --git a/Engine/Classes/DistributionFloatUniformRange.uc b/Engine/Classes/DistributionFloatUniformRange.uc new file mode 100644 index 0000000..52ba060 --- /dev/null +++ b/Engine/Classes/DistributionFloatUniformRange.uc @@ -0,0 +1,105 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DistributionFloatUniformRange extends DistributionFloat + native + collapsecategories + hidecategories(Object) + editinlinenew; + +/** + * High value of the maximum end of the output float distribution. + * Final value will be between [MinHigh..MinLow] or [MaxHigh..MaxLow] + */ +var() float MaxHigh; +/** + * Low value of the maximum end of the output float distribution. + * Final value will be between [MinHigh..MinLow] or [MaxHigh..MaxLow] + */ +var() float MaxLow; + +/** + * High value of the minimum end of the output float distribution. + * Final value will be between [MinHigh..MinLow] or [MaxHigh..MaxLow] + */ +var() float MinHigh; +/** + * Low value of the minimum end of the output float distribution. + * Final value will be between [MinHigh..MinLow] or [MaxHigh..MaxLow] + */ +var() float MinLow; + +/** + * If TRUE, mirror the MaxHigh, MinHigh values in the MaxLow, MinLow values + * ie, MinHigh = -MaxHigh; MinLow = -MaxLow + */ +var() bool bMirrorMaxMin; + +cpptext +{ + virtual void PostLoad(); + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + virtual FLOAT GetValue( FLOAT F = 0.f, UObject* Data = NULL, class FRandomStream* InRandomStream = NULL ); + +#if !CONSOLE + /** + * Return the operation used at runtime to calculate the final value + */ + virtual ERawDistributionOperation GetOperation(); + + /** + * Fill out an array of floats and return the number of elements in the entry + * + * @param Time The time to evaluate the distribution + * @param Values An array of values to be filled out, guaranteed to be big enough for 4 floats + * @return The number of elements (values) set in the array + */ + virtual DWORD InitializeRawEntry(FLOAT Time, FLOAT* Values); +#endif + + // FCurveEdInterface interface + virtual INT GetNumKeys(); + virtual INT GetNumSubCurves() const; + + /** + * Provides the color for the sub-curve button that is present on the curve tab. + * + * @param SubCurveIndex The index of the sub-curve. Cannot be negative nor greater or equal to the number of sub-curves. + * @param bIsSubCurveHidden Is the curve hidden? + * @return The color associated to the given sub-curve index. + */ + virtual FColor GetSubCurveButtonColor(INT SubCurveIndex, UBOOL bIsSubCurveHidden) const; + + virtual FLOAT GetKeyIn(INT KeyIndex); + virtual FLOAT GetKeyOut(INT SubIndex, INT KeyIndex); + + /** + * Provides the color for the given key at the given sub-curve. + * + * @param SubIndex The index of the sub-curve + * @param KeyIndex The index of the key in the sub-curve + * @param[in] CurveColor The color of the curve + * @return The color that is associated the given key at the given sub-curve + */ + virtual FColor GetKeyColor(INT SubIndex, INT KeyIndex, const FColor& CurveColor); + + virtual void GetInRange(FLOAT& MinIn, FLOAT& MaxIn); + virtual void GetOutRange(FLOAT& MinOut, FLOAT& MaxOut); + virtual BYTE GetKeyInterpMode(INT KeyIndex); + virtual void GetTangents(INT SubIndex, INT KeyIndex, FLOAT& ArriveTangent, FLOAT& LeaveTangent); + virtual FLOAT EvalSub(INT SubIndex, FLOAT InVal); + + virtual INT CreateNewKey(FLOAT KeyIn); + virtual void DeleteKey(INT KeyIndex); + + virtual INT SetKeyIn(INT KeyIndex, FLOAT NewInVal); + virtual void SetKeyOut(INT SubIndex, INT KeyIndex, FLOAT NewOutVal); + virtual void SetKeyInterpMode(INT KeyIndex, EInterpCurveMode NewMode); + virtual void SetTangents(INT SubIndex, INT KeyIndex, FLOAT ArriveTangent, FLOAT LeaveTangent); +} + +defaultproperties +{ + bCanBeBaked=false +} diff --git a/Engine/Classes/DistributionVectorConstant.uc b/Engine/Classes/DistributionVectorConstant.uc new file mode 100644 index 0000000..79bfd89 --- /dev/null +++ b/Engine/Classes/DistributionVectorConstant.uc @@ -0,0 +1,66 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DistributionVectorConstant extends DistributionVector + native + collapsecategories + hidecategories(Object) + editinlinenew; + +/** This vector will be returned for all input times. */ +var() vector Constant; + +/** If true, X == Y == Z ie. only one degree of freedom. If false, each axis is picked independently. */ +var bool bLockAxes; +var() EDistributionVectorLockFlags LockedAxes; + +cpptext +{ + virtual FVector GetValue( FLOAT F = 0.f, UObject* Data = NULL, INT LastExtreme = 0, class FRandomStream* InRandomStream = NULL ); + + // UObject interface + virtual void Serialize(FArchive& Ar); + + // FCurveEdInterface interface + virtual INT GetNumKeys(); + virtual INT GetNumSubCurves() const; + + /** + * Provides the color for the sub-curve button that is present on the curve tab. + * + * @param SubCurveIndex The index of the sub-curve. Cannot be negative nor greater or equal to the number of sub-curves. + * @param bIsSubCurveHidden Is the curve hidden? + * @return The color associated to the given sub-curve index. + */ + virtual FColor GetSubCurveButtonColor(INT SubCurveIndex, UBOOL bIsSubCurveHidden) const; + + virtual FLOAT GetKeyIn(INT KeyIndex); + virtual FLOAT GetKeyOut(INT SubIndex, INT KeyIndex); + + /** + * Provides the color for the given key at the given sub-curve. + * + * @param SubIndex The index of the sub-curve + * @param KeyIndex The index of the key in the sub-curve + * @param[in] CurveColor The color of the curve + * @return The color that is associated the given key at the given sub-curve + */ + virtual FColor GetKeyColor(INT SubIndex, INT KeyIndex, const FColor& CurveColor); + + virtual void GetInRange(FLOAT& MinIn, FLOAT& MaxIn); + virtual void GetOutRange(FLOAT& MinOut, FLOAT& MaxOut); + virtual BYTE GetKeyInterpMode(INT KeyIndex); + virtual void GetTangents(INT SubIndex, INT KeyIndex, FLOAT& ArriveTangent, FLOAT& LeaveTangent); + virtual FLOAT EvalSub(INT SubIndex, FLOAT InVal); + + virtual INT CreateNewKey(FLOAT KeyIn); + virtual void DeleteKey(INT KeyIndex); + + virtual INT SetKeyIn(INT KeyIndex, FLOAT NewInVal); + virtual void SetKeyOut(INT SubIndex, INT KeyIndex, FLOAT NewOutVal); + virtual void SetKeyInterpMode(INT KeyIndex, EInterpCurveMode NewMode); + virtual void SetTangents(INT SubIndex, INT KeyIndex, FLOAT ArriveTangent, FLOAT LeaveTangent); + + // DistributionVector interface + virtual void GetRange(FVector& OutMin, FVector& OutMax); +} diff --git a/Engine/Classes/DistributionVectorConstantCurve.uc b/Engine/Classes/DistributionVectorConstantCurve.uc new file mode 100644 index 0000000..e258d81 --- /dev/null +++ b/Engine/Classes/DistributionVectorConstantCurve.uc @@ -0,0 +1,72 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DistributionVectorConstantCurve extends DistributionVector + native + collapsecategories + hidecategories(Object) + editinlinenew; + +/** Keyframe data for each component (X,Y,Z) over time. */ +var() InterpCurveVector ConstantCurve; + +/** If true, X == Y == Z ie. only one degree of freedom. If false, each axis is picked independently. */ +var bool bLockAxes; +var() EDistributionVectorLockFlags LockedAxes; + +cpptext +{ + virtual FVector GetValue( FLOAT F = 0.f, UObject* Data = NULL, INT LastExtreme = 0, class FRandomStream* InRandomStream = NULL ); + + // UObject interface + virtual void Serialize(FArchive& Ar); + + // FCurveEdInterface interface + virtual INT GetNumKeys(); + virtual INT GetNumSubCurves() const; + + /** + * Provides the color for the sub-curve button that is present on the curve tab. + * + * @param SubCurveIndex The index of the sub-curve. Cannot be negative nor greater or equal to the number of sub-curves. + * @param bIsSubCurveHidden Is the curve hidden? + * @return The color associated to the given sub-curve index. + */ + virtual FColor GetSubCurveButtonColor(INT SubCurveIndex, UBOOL bIsSubCurveHidden) const; + + virtual FLOAT GetKeyIn(INT KeyIndex); + virtual FLOAT GetKeyOut(INT SubIndex, INT KeyIndex); + virtual void GetInRange(FLOAT& MinIn, FLOAT& MaxIn); + virtual void GetOutRange(FLOAT& MinOut, FLOAT& MaxOut); + + /** + * Provides the color for the given key at the given sub-curve. + * + * @param SubIndex The index of the sub-curve + * @param KeyIndex The index of the key in the sub-curve + * @param[in] CurveColor The color of the curve + * @return The color that is associated the given key at the given sub-curve + */ + virtual FColor GetKeyColor(INT SubIndex, INT KeyIndex, const FColor& CurveColor); + + virtual BYTE GetKeyInterpMode(INT KeyIndex); + virtual void GetTangents(INT SubIndex, INT KeyIndex, FLOAT& ArriveTangent, FLOAT& LeaveTangent); + virtual FLOAT EvalSub(INT SubIndex, FLOAT InVal); + + virtual INT CreateNewKey(FLOAT KeyIn); + virtual void DeleteKey(INT KeyIndex); + + virtual INT SetKeyIn(INT KeyIndex, FLOAT NewInVal); + virtual void SetKeyOut(INT SubIndex, INT KeyIndex, FLOAT NewOutVal); + virtual void SetKeyInterpMode(INT KeyIndex, EInterpCurveMode NewMode); + virtual void SetTangents(INT SubIndex, INT KeyIndex, FLOAT ArriveTangent, FLOAT LeaveTangent); + + /** Returns TRUE if this curve uses legacy tangent/interp algorithms and may be 'upgraded' */ + virtual UBOOL UsingLegacyInterpMethod() const; + + /** 'Upgrades' this curve to use the latest tangent/interp algorithms (usually, will 'bake' key tangents.) */ + virtual void UpgradeInterpMethod(); + + // DistributionVector interface + virtual void GetRange(FVector& OutMin, FVector& OutMax); +} diff --git a/Engine/Classes/DistributionVectorParameterBase.uc b/Engine/Classes/DistributionVectorParameterBase.uc new file mode 100644 index 0000000..489085f --- /dev/null +++ b/Engine/Classes/DistributionVectorParameterBase.uc @@ -0,0 +1,36 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DistributionVectorParameterBase extends DistributionVectorConstant + abstract + native + collapsecategories + hidecategories(Object) + editinlinenew; + +var() name ParameterName; +var() vector MinInput; +var() vector MaxInput; +var() vector MinOutput; +var() vector MaxOutput; +var() DistributionFloatParameterBase.DistributionParamMode ParamModes[3]; + +cpptext +{ + virtual FVector GetValue(FLOAT F = 0.f, UObject* Data = NULL, INT Extreme = 0, class FRandomStream* InRandomStream = NULL); + + virtual UBOOL GetParamValue(UObject* Data, FName ParamName, FVector& OutVector) { return false; } + + virtual void GetOutRange(FLOAT& MinOut, FLOAT& MaxOut); + + /** + * Return whether or not this distribution can be baked into a FRawDistribution lookup table + */ + virtual UBOOL CanBeBaked() const { return FALSE; } +} + +defaultproperties +{ + MaxInput=(X=1.0,Y=1.0,Z=1.0) + MaxOutput=(X=1.0,Y=1.0,Z=1.0) +} diff --git a/Engine/Classes/DistributionVectorParticleParameter.uc b/Engine/Classes/DistributionVectorParticleParameter.uc new file mode 100644 index 0000000..bacb7de --- /dev/null +++ b/Engine/Classes/DistributionVectorParticleParameter.uc @@ -0,0 +1,13 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DistributionVectorParticleParameter extends DistributionVectorParameterBase + native(Particle) + collapsecategories + hidecategories(Object) + editinlinenew; + +cpptext +{ + virtual UBOOL GetParamValue(UObject* Data, FName ParamName, FVector& OutVector); +} diff --git a/Engine/Classes/DistributionVectorUniform.uc b/Engine/Classes/DistributionVectorUniform.uc new file mode 100644 index 0000000..d7ce593 --- /dev/null +++ b/Engine/Classes/DistributionVectorUniform.uc @@ -0,0 +1,121 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DistributionVectorUniform extends DistributionVector + native + collapsecategories + hidecategories(Object) + editinlinenew; + +/** Upper end of vector magnitude range. */ +var() vector Max; +/** Lower end of vector magnitude range. */ +var() vector Min; + +/** If true, X == Y == Z ie. only one degree of freedom. If false, each axis is picked independently. */ +var bool bLockAxes; +var() EDistributionVectorLockFlags LockedAxes; +var() EDistributionVectorMirrorFlags MirrorFlags[3]; +var() bool bUseExtremes; + +cpptext +{ + virtual void PostLoad(); + + virtual FVector GetValue( FLOAT F = 0.f, UObject* Data = NULL, INT LastExtreme = 0, class FRandomStream* InRandomStream = NULL ); + +#if !CONSOLE + /** + * Return the operation used at runtime to calculate the final value + */ + virtual ERawDistributionOperation GetOperation(); + + /** + * Return the lock flags used at runtime to calculate the final value + */ + virtual ERawDistributionLockFlags GetLockFlags(INT InIndex) + { + if (InIndex != 0) + { + return RDL_None; + } + + switch (LockedAxes) + { + case EDVLF_XY: return RDL_XY; + case EDVLF_XZ: return RDL_XZ; + case EDVLF_YZ: return RDL_YZ; + case EDVLF_XYZ: return RDL_XYZ; + } + return RDL_None; + } + + /** + * Fill out an array of vectors and return the number of elements in the entry + * + * @param Time The time to evaluate the distribution + * @param Values An array of values to be filled out, guaranteed to be big enough for 2 vectors + * @return The number of elements (values) set in the array + */ + virtual DWORD InitializeRawEntry(FLOAT Time, FVector* Values); +#endif + + /** These two functions will retrieve the Min/Max values respecting the Locked and Mirror flags. */ + virtual FVector GetMinValue(); + virtual FVector GetMaxValue(); + + // UObject interface + virtual void Serialize(FArchive& Ar); + + // FCurveEdInterface interface + virtual INT GetNumKeys(); + virtual INT GetNumSubCurves() const; + + /** + * Provides the color for the sub-curve button that is present on the curve tab. + * + * @param SubCurveIndex The index of the sub-curve. Cannot be negative nor greater or equal to the number of sub-curves. + * @param bIsSubCurveHidden Is the curve hidden? + * @return The color associated to the given sub-curve index. + */ + virtual FColor GetSubCurveButtonColor(INT SubCurveIndex, UBOOL bIsSubCurveHidden) const; + + virtual FLOAT GetKeyIn(INT KeyIndex); + virtual FLOAT GetKeyOut(INT SubIndex, INT KeyIndex); + + /** + * Provides the color for the given key at the given sub-curve. + * + * @param SubIndex The index of the sub-curve + * @param KeyIndex The index of the key in the sub-curve + * @param[in] CurveColor The color of the curve + * @return The color that is associated the given key at the given sub-curve + */ + virtual FColor GetKeyColor(INT SubIndex, INT KeyIndex, const FColor& CurveColor); + + virtual void GetInRange(FLOAT& MinIn, FLOAT& MaxIn); + virtual void GetOutRange(FLOAT& MinOut, FLOAT& MaxOut); + virtual BYTE GetKeyInterpMode(INT KeyIndex); + virtual void GetTangents(INT SubIndex, INT KeyIndex, FLOAT& ArriveTangent, FLOAT& LeaveTangent); + virtual FLOAT EvalSub(INT SubIndex, FLOAT InVal); + + virtual INT CreateNewKey(FLOAT KeyIn); + virtual void DeleteKey(INT KeyIndex); + + virtual INT SetKeyIn(INT KeyIndex, FLOAT NewInVal); + virtual void SetKeyOut(INT SubIndex, INT KeyIndex, FLOAT NewOutVal); + virtual void SetKeyInterpMode(INT KeyIndex, EInterpCurveMode NewMode); + virtual void SetTangents(INT SubIndex, INT KeyIndex, FLOAT ArriveTangent, FLOAT LeaveTangent); + + // DistributionVector interface + virtual void GetRange(FVector& OutMin, FVector& OutMax); +} + +defaultproperties +{ + MirrorFlags[0] = EDVMF_Different + MirrorFlags[1] = EDVMF_Different + MirrorFlags[2] = EDVMF_Different + + bUseExtremes = false +} diff --git a/Engine/Classes/DistributionVectorUniformCurve.uc b/Engine/Classes/DistributionVectorUniformCurve.uc new file mode 100644 index 0000000..eee477a --- /dev/null +++ b/Engine/Classes/DistributionVectorUniformCurve.uc @@ -0,0 +1,135 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DistributionVectorUniformCurve extends DistributionVector + native + collapsecategories + hidecategories(Object) + editinlinenew; + +/** Keyframe data for how output constant varies over time. */ +var() interpcurvetwovectors ConstantCurve; + +/** If true, X == Y == Z ie. only one degree of freedom. If false, each axis is picked independently. */ +var bool bLockAxes1; +var bool bLockAxes2; +var() EDistributionVectorLockFlags LockedAxes[2]; +var() EDistributionVectorMirrorFlags MirrorFlags[3]; +var() bool bUseExtremes; + +cpptext +{ + virtual void PostLoad(); + + virtual FVector GetValue( FLOAT F = 0.f, UObject* Data = NULL, INT LastExtreme = 0, class FRandomStream* InRandomStream = NULL ); + +#if !CONSOLE + /** + * Return the operation used at runtime to calculate the final value + */ + virtual ERawDistributionOperation GetOperation(); + + /** + * Return the lock flags used at runtime to calculate the final value + */ + virtual ERawDistributionLockFlags GetLockFlags(INT InIndex) + { + if ((InIndex >= 0) && (InIndex <= 1)) + { + switch (LockedAxes[InIndex]) + { + case EDVLF_XY: return RDL_XY; + case EDVLF_XZ: return RDL_XZ; + case EDVLF_YZ: return RDL_YZ; + case EDVLF_XYZ: return RDL_XYZ; + } + } + return RDL_None; + } + + /** + * Return true if the distribution is a uniform curve + */ + virtual UBOOL IsUniformCurve() { return TRUE; } + + /** + * Fill out an array of vectors and return the number of elements in the entry + * + * @param Time The time to evaluate the distribution + * @param Values An array of values to be filled out, guaranteed to be big enough for 2 vectors + * @return The number of elements (values) set in the array + */ + virtual DWORD InitializeRawEntry(FLOAT Time, FVector* Values); +#endif + virtual FTwoVectors GetMinMaxValue(FLOAT F = 0.f, UObject* Data = NULL); + + /** These two functions will retrieve the Min/Max values respecting the Locked and Mirror flags. */ + virtual FVector GetMinValue(); + virtual FVector GetMaxValue(); + + // UObject interface + virtual void Serialize(FArchive& Ar); + + // FCurveEdInterface interface + virtual INT GetNumKeys(); + virtual INT GetNumSubCurves() const; + + /** + * Provides the color for the sub-curve button that is present on the curve tab. + * + * @param SubCurveIndex The index of the sub-curve. Cannot be negative nor greater or equal to the number of sub-curves. + * @param bIsSubCurveHidden Is the curve hidden? + * @return The color associated to the given sub-curve index. + */ + virtual FColor GetSubCurveButtonColor(INT SubCurveIndex, UBOOL bIsSubCurveHidden) const; + + virtual FLOAT GetKeyIn(INT KeyIndex); + virtual FLOAT GetKeyOut(INT SubIndex, INT KeyIndex); + + /** + * Provides the color for the given key at the given sub-curve. + * + * @param SubIndex The index of the sub-curve + * @param KeyIndex The index of the key in the sub-curve + * @param[in] CurveColor The color of the curve + * @return The color that is associated the given key at the given sub-curve + */ + virtual FColor GetKeyColor(INT SubIndex, INT KeyIndex, const FColor& CurveColor); + + virtual void GetInRange(FLOAT& MinIn, FLOAT& MaxIn); + virtual void GetOutRange(FLOAT& MinOut, FLOAT& MaxOut); + virtual BYTE GetKeyInterpMode(INT KeyIndex); + virtual void GetTangents(INT SubIndex, INT KeyIndex, FLOAT& ArriveTangent, FLOAT& LeaveTangent); + virtual FLOAT EvalSub(INT SubIndex, FLOAT InVal); + + virtual INT CreateNewKey(FLOAT KeyIn); + virtual void DeleteKey(INT KeyIndex); + + virtual INT SetKeyIn(INT KeyIndex, FLOAT NewInVal); + virtual void SetKeyOut(INT SubIndex, INT KeyIndex, FLOAT NewOutVal); + virtual void SetKeyInterpMode(INT KeyIndex, EInterpCurveMode NewMode); + virtual void SetTangents(INT SubIndex, INT KeyIndex, FLOAT ArriveTangent, FLOAT LeaveTangent); + + /** Returns TRUE if this curve uses legacy tangent/interp algorithms and may be 'upgraded' */ + virtual UBOOL UsingLegacyInterpMethod() const; + + /** 'Upgrades' this curve to use the latest tangent/interp algorithms (usually, will 'bake' key tangents.) */ + virtual void UpgradeInterpMethod(); + + virtual void LockAndMirror(FTwoVectors& Val); + + // DistributionVector interface + virtual void GetRange(FVector& OutMin, FVector& OutMax); +} + +defaultproperties +{ + bLockAxes1 = false + bLockAxes2 = false + LockedAxes[0] = EDVLF_None + LockedAxes[1] = EDVLF_None + MirrorFlags[0] = EDVMF_Different + MirrorFlags[1] = EDVMF_Different + MirrorFlags[2] = EDVMF_Different + bUseExtremes = false +} diff --git a/Engine/Classes/DistributionVectorUniformRange.uc b/Engine/Classes/DistributionVectorUniformRange.uc new file mode 100644 index 0000000..24c55de --- /dev/null +++ b/Engine/Classes/DistributionVectorUniformRange.uc @@ -0,0 +1,108 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DistributionVectorUniformRange extends DistributionVector + native + collapsecategories + hidecategories(Object) + editinlinenew; + +/** + * High value of the maximum end of the output distribution. + * Final value will be between [MinHigh..MinLow] or [MaxHigh..MaxLow] + */ +var() vector MaxHigh; +/** + * Low value of the maximum end of the output distribution. + * Final value will be between [MinHigh..MinLow] or [MaxHigh..MaxLow] + */ +var() vector MaxLow; +/** + * High value of the minimum end of the output distribution. + * Final value will be between [MinHigh..MinLow] or [MaxHigh..MaxLow] + */ +var() vector MinHigh; +/** + * Low value of the minimum end of the output distribution. + * Final value will be between [MinHigh..MinLow] or [MaxHigh..MaxLow] + */ +var() vector MinLow; + +cpptext +{ + virtual void PostLoad(); + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + virtual FVector GetValue( FLOAT F = 0.f, UObject* Data = NULL, INT LastExtreme = 0, class FRandomStream* InRandomStream = NULL ); + +#if !CONSOLE + /** + * Return the operation used at runtime to calculate the final value + */ + virtual ERawDistributionOperation GetOperation(); + + /** + * Fill out an array of vectors and return the number of elements in the entry + * + * @param Time The time to evaluate the distribution + * @param Values An array of values to be filled out, guaranteed to be big enough for 2 vectors + * @return The number of elements (values) set in the array + */ + virtual DWORD InitializeRawEntry(FLOAT Time, FVector* Values); +#endif + + /** These two functions will retrieve the Min/Max values respecting the Locked and Mirror flags. */ + virtual FVector GetMinValue(); + virtual FVector GetMaxValue(); + + // UObject interface + virtual void Serialize(FArchive& Ar); + + // FCurveEdInterface interface + virtual INT GetNumKeys(); + virtual INT GetNumSubCurves() const; + + /** + * Provides the color for the sub-curve button that is present on the curve tab. + * + * @param SubCurveIndex The index of the sub-curve. Cannot be negative nor greater or equal to the number of sub-curves. + * @param bIsSubCurveHidden Is the curve hidden? + * @return The color associated to the given sub-curve index. + */ + virtual FColor GetSubCurveButtonColor(INT SubCurveIndex, UBOOL bIsSubCurveHidden) const; + + virtual FLOAT GetKeyIn(INT KeyIndex); + virtual FLOAT GetKeyOut(INT SubIndex, INT KeyIndex); + + /** + * Provides the color for the given key at the given sub-curve. + * + * @param SubIndex The index of the sub-curve + * @param KeyIndex The index of the key in the sub-curve + * @param[in] CurveColor The color of the curve + * @return The color that is associated the given key at the given sub-curve + */ + virtual FColor GetKeyColor(INT SubIndex, INT KeyIndex, const FColor& CurveColor); + + virtual void GetInRange(FLOAT& MinIn, FLOAT& MaxIn); + virtual void GetOutRange(FLOAT& MinOut, FLOAT& MaxOut); + virtual BYTE GetKeyInterpMode(INT KeyIndex); + virtual void GetTangents(INT SubIndex, INT KeyIndex, FLOAT& ArriveTangent, FLOAT& LeaveTangent); + virtual FLOAT EvalSub(INT SubIndex, FLOAT InVal); + + virtual INT CreateNewKey(FLOAT KeyIn); + virtual void DeleteKey(INT KeyIndex); + + virtual INT SetKeyIn(INT KeyIndex, FLOAT NewInVal); + virtual void SetKeyOut(INT SubIndex, INT KeyIndex, FLOAT NewOutVal); + virtual void SetKeyInterpMode(INT KeyIndex, EInterpCurveMode NewMode); + virtual void SetTangents(INT SubIndex, INT KeyIndex, FLOAT ArriveTangent, FLOAT LeaveTangent); + + // DistributionVector interface + virtual void GetRange(FVector& OutMin, FVector& OutMax); +} + +defaultproperties +{ + bCanBeBaked=false +} diff --git a/Engine/Classes/DmgType_Crushed.uc b/Engine/Classes/DmgType_Crushed.uc new file mode 100644 index 0000000..f15dd64 --- /dev/null +++ b/Engine/Classes/DmgType_Crushed.uc @@ -0,0 +1,4 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DmgType_Crushed extends DamageType; diff --git a/Engine/Classes/DmgType_Fell.uc b/Engine/Classes/DmgType_Fell.uc new file mode 100644 index 0000000..a95f380 --- /dev/null +++ b/Engine/Classes/DmgType_Fell.uc @@ -0,0 +1,13 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DmgType_Fell extends DamageType + abstract; + +defaultproperties +{ + bCausedByWorld=true +`if(`__TW_) + bArmorStops=false +`endif +} diff --git a/Engine/Classes/DmgType_Suicided.uc b/Engine/Classes/DmgType_Suicided.uc new file mode 100644 index 0000000..f422acc --- /dev/null +++ b/Engine/Classes/DmgType_Suicided.uc @@ -0,0 +1,10 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DmgType_Suicided extends KillZDamageType + abstract; + +defaultproperties +{ + bArmorStops=false +} diff --git a/Engine/Classes/DmgType_Telefragged.uc b/Engine/Classes/DmgType_Telefragged.uc new file mode 100644 index 0000000..3632991 --- /dev/null +++ b/Engine/Classes/DmgType_Telefragged.uc @@ -0,0 +1,9 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DmgType_Telefragged extends DamageType; + +defaultproperties +{ + bArmorStops=false +} diff --git a/Engine/Classes/DominantDirectionalLight.uc b/Engine/Classes/DominantDirectionalLight.uc new file mode 100644 index 0000000..66612f1 --- /dev/null +++ b/Engine/Classes/DominantDirectionalLight.uc @@ -0,0 +1,54 @@ +/** + * Dominant version of DirectionalLight that generates static shadow maps. + * There can only be one! + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DominantDirectionalLight extends DirectionalLight + native(Light) + ClassGroup(Lights,DirectionalLights) + placeable; + +cpptext +{ + // UObject interface +#if WITH_EDITOR + virtual void CheckForErrors(); +#endif + + /** + * Returns true if the light supports being toggled off and on on-the-fly + **/ + virtual UBOOL IsToggleable() const + { + return TRUE; + } +} + +defaultproperties +{ + // Light component. + Begin Object Class=DominantDirectionalLightComponent Name=DominantDirectionalLightComponent0 + LightAffectsClassification=LAC_DYNAMIC_AND_STATIC_AFFECTING + + CastShadows=TRUE + CastStaticShadows=TRUE + CastDynamicShadows=TRUE + bForceDynamicLight=FALSE + UseDirectLightMap=FALSE + bAllowPreShadow=TRUE +`if(`__TW_LIGHTING_MODIFICATIONS_) // Custom lighting channel implementation + LightingChannels=(Outdoor=TRUE,bInitialized=TRUE) +`else + LightingChannels=(BSP=TRUE,Static=TRUE,Dynamic=TRUE,bInitialized=TRUE) +`endif + LightmassSettings=(LightSourceAngle=.2) + End Object + Components.Remove(DirectionalLightComponent0) + LightComponent=DominantDirectionalLightComponent0 + Components.Add(DominantDirectionalLightComponent0) + + bMovable=FALSE + bStatic=FALSE + bHardAttach=TRUE +} diff --git a/Engine/Classes/DominantDirectionalLightComponent.uc b/Engine/Classes/DominantDirectionalLightComponent.uc new file mode 100644 index 0000000..6830436 --- /dev/null +++ b/Engine/Classes/DominantDirectionalLightComponent.uc @@ -0,0 +1,43 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DominantDirectionalLightComponent extends DirectionalLightComponent + native(Light) + hidecategories(Object) + dependson(EngineTypes) + editinlinenew; + +var private {private} const DominantShadowInfo DominantLightShadowInfo; +/** Array of depths to the furthest shadow casting geometry in each shadowmap cell, quantized to a WORD and stored relative to LightSpaceImportanceBounds.Min.Z. */ +var private {private} const native Array_Mirror DominantLightShadowMap{TArrayNoInit}; + +cpptext +{ + virtual void Serialize(FArchive& Ar); + virtual ELightComponentType GetLightType() const; + virtual void InvalidateLightingCache(); + /** + * Called after property has changed via e.g. property window or set command. + * + * @param PropertyThatChanged UProperty that has been changed, NULL if unknown + */ + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual void FinishDestroy(); + /** Returns information about the data used to calculate dominant shadow transition distance. */ + void GetInfo(INT& SizeX, INT& SizeY, SIZE_T& ShadowMapBytes) const; + /** Populates DominantLightShadowMap and DominantLightShadowInfo with the results from a lighting build. */ + void Initialize(const FDominantShadowInfo& InInfo, const TArray& InShadowMap, UBOOL bOnlyVisible); + /** Returns the distance to the nearest dominant shadow transition, in world space units, starting from the edge of the bounds. */ + FLOAT GetDominantShadowTransitionDistance(const FBoxSphereBounds& Bounds, FLOAT MaxSearchDistance, UBOOL bDebugSearch, TArray& DebugRays, UBOOL& bLightingIsBuilt) const; + + /** Returns true if the dominant light has valid shadow map data */ + UBOOL IsDominantLightShadowMapValid() const + { + return DominantLightShadowMap.Num() > 0; + } +} + +defaultproperties +{ + LightShadowMode=LightShadow_Normal +} diff --git a/Engine/Classes/DominantDirectionalLightMovable.uc b/Engine/Classes/DominantDirectionalLightMovable.uc new file mode 100644 index 0000000..fee7252 --- /dev/null +++ b/Engine/Classes/DominantDirectionalLightMovable.uc @@ -0,0 +1,24 @@ +/** + * Version of DominantDirectionalLight that can be rotated in game and doesn't generate precomputed lighting or shadowing. + * There can only be one dominant directional light in a given level. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DominantDirectionalLightMovable extends DominantDirectionalLight + native(Light) + ClassGroup(Lights,DirectionalLights) + placeable; + +cpptext +{ +} + +defaultproperties +{ + Begin Object Name=DominantDirectionalLightComponent0 + WholeSceneDynamicShadowRadius=2000 + End Object + + bMovable=TRUE + Physics=PHYS_Interpolating +} diff --git a/Engine/Classes/DominantPointLight.uc b/Engine/Classes/DominantPointLight.uc new file mode 100644 index 0000000..573c278 --- /dev/null +++ b/Engine/Classes/DominantPointLight.uc @@ -0,0 +1,52 @@ +/** + * Dominant version of PointLight that generates static shadowmaps. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DominantPointLight extends PointLight + native(Light) + ClassGroup(Lights, PointLights) + placeable; + +cpptext +{ + /** + * Returns true if the light supports being toggled off and on on-the-fly + **/ + virtual UBOOL IsToggleable() const + { + return TRUE; + } +} + +defaultproperties +{ + Begin Object Name=Sprite + Sprite=Texture2D'EditorResources.LightIcons.Light_Point_Toggleable_Statics' + End Object + + // Light component. + Begin Object Class=DominantPointLightComponent Name=DominantPointLightComponent0 + LightAffectsClassification=LAC_DYNAMIC_AND_STATIC_AFFECTING + CastShadows=TRUE + CastStaticShadows=TRUE + CastDynamicShadows=TRUE + bForceDynamicLight=FALSE + UseDirectLightMap=FALSE + bAllowPreShadow=TRUE +`if(`__TW_LIGHTING_MODIFICATIONS_) // Custom lighting channel implementation + LightingChannels=(Indoor=TRUE,Outdoor=TRUE,bInitialized=TRUE) +`else + LightingChannels=(BSP=TRUE,Static=TRUE,Dynamic=TRUE,bInitialized=TRUE) +`endif + PreviewLightRadius=DrawLightRadius0 + PreviewLightSourceRadius=DrawLightSourceRadius0 + End Object + Components.Remove(PointLightComponent0) + LightComponent=DominantPointLightComponent0 + Components.Add(DominantPointLightComponent0) + + bMovable=FALSE + bStatic=FALSE + bHardAttach=TRUE +} diff --git a/Engine/Classes/DominantPointLightComponent.uc b/Engine/Classes/DominantPointLightComponent.uc new file mode 100644 index 0000000..68cb614 --- /dev/null +++ b/Engine/Classes/DominantPointLightComponent.uc @@ -0,0 +1,25 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DominantPointLightComponent extends PointLightComponent + native(Light) + hidecategories(Object) + editinlinenew; + +cpptext +{ + /** + * Called after property has changed via e.g. property window or set command. + * + * @param PropertyThatChanged UProperty that has been changed, NULL if unknown + */ + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual ELightComponentType GetLightType() const; + /** Returns the distance to the nearest dominant shadow transition, in world space units, starting from the edge of the bounds. */ + FLOAT GetDominantShadowTransitionDistance(const FBoxSphereBounds& Bounds, FLOAT MaxSearchDistance, UBOOL bDebugSearch, TArray& DebugRays, UBOOL& bLightingIsBuilt) const; +} + +defaultproperties +{ + LightShadowMode=LightShadow_Normal +} diff --git a/Engine/Classes/DominantSpotLight.uc b/Engine/Classes/DominantSpotLight.uc new file mode 100644 index 0000000..6b346b9 --- /dev/null +++ b/Engine/Classes/DominantSpotLight.uc @@ -0,0 +1,54 @@ +/** + * Dominant version of SpotLight that generates static shadowmaps. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DominantSpotLight extends SpotLight + native(Light) + ClassGroup(Lights,SpotLights) + placeable; + +cpptext +{ + /** + * Returns true if the light supports being toggled off and on on-the-fly + **/ + virtual UBOOL IsToggleable() const + { + return TRUE; + } +} + +defaultproperties +{ + Begin Object Name=Sprite + Sprite=Texture2D'EditorResources.LightIcons.Light_Spot_Toggleable_Statics' + End Object + + // Light component. + Begin Object Class=DominantSpotLightComponent Name=DominantSpotLightComponent0 + LightAffectsClassification=LAC_DYNAMIC_AND_STATIC_AFFECTING + CastShadows=TRUE + CastStaticShadows=TRUE + CastDynamicShadows=TRUE + bForceDynamicLight=FALSE + UseDirectLightMap=FALSE + bAllowPreShadow=TRUE +`if(`__TW_LIGHTING_MODIFICATIONS_) // Custom lighting channel implementation + LightingChannels=(Indoor=TRUE,Outdoor=TRUE,bInitialized=TRUE) +`else + LightingChannels=(BSP=TRUE,Static=TRUE,Dynamic=TRUE,bInitialized=TRUE) +`endif + PreviewLightRadius=DrawLightRadius0 + PreviewInnerCone=DrawInnerCone0 + PreviewOuterCone=DrawOuterCone0 + PreviewLightSourceRadius=DrawLightSourceRadius0 + End Object + Components.Remove(SpotLightComponent0) + LightComponent=DominantSpotLightComponent0 + Components.Add(DominantSpotLightComponent0) + + bMovable=FALSE + bStatic=FALSE + bHardAttach=TRUE +} diff --git a/Engine/Classes/DominantSpotLightComponent.uc b/Engine/Classes/DominantSpotLightComponent.uc new file mode 100644 index 0000000..15cd415 --- /dev/null +++ b/Engine/Classes/DominantSpotLightComponent.uc @@ -0,0 +1,37 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DominantSpotLightComponent extends SpotLightComponent + native(Light) + hidecategories(Object) + dependson(EngineTypes) + editinlinenew; + +var private {private} const DominantShadowInfo DominantLightShadowInfo; +/** Array of depths to the furthest shadow casting geometry in each shadowmap cell, quantized to a WORD and stored relative to LightSpaceImportanceBounds.Min.Z. */ +var private {private} const native Array_Mirror DominantLightShadowMap{TArrayNoInit}; + +cpptext +{ + virtual void Serialize(FArchive& Ar); + virtual ELightComponentType GetLightType() const; + virtual void InvalidateLightingCache(); + /** + * Called after property has changed via e.g. property window or set command. + * + * @param PropertyThatChanged UProperty that has been changed, NULL if unknown + */ + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual void FinishDestroy(); + /** Returns information about the data used to calculate dominant shadow transition distance. */ + void GetInfo(INT& SizeX, INT& SizeY, SIZE_T& ShadowMapBytes) const; + /** Populates DominantLightShadowMap and DominantLightShadowInfo with the results from a lighting build. */ + void Initialize(const FDominantShadowInfo& InInfo, const TArray& InShadowMap, UBOOL bOnlyVisible); + /** Returns the distance to the nearest dominant shadow transition, in world space units, starting from the edge of the bounds. */ + FLOAT GetDominantShadowTransitionDistance(const FBoxSphereBounds& Bounds, FLOAT MaxSearchDistance, UBOOL bDebugSearch, TArray& DebugRays, UBOOL& bLightingIsBuilt) const; +} + +defaultproperties +{ + LightShadowMode=LightShadow_Normal +} diff --git a/Engine/Classes/DoorMarker.uc b/Engine/Classes/DoorMarker.uc new file mode 100644 index 0000000..cab1925 --- /dev/null +++ b/Engine/Classes/DoorMarker.uc @@ -0,0 +1,187 @@ +/** + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + + +/** used to mark a door; handles the usability of paths through it and any special actions needed to open it */ +class DoorMarker extends NavigationPoint + placeable + native; + +/** the door mover associated with this marker */ +var() InterpActor MyDoor; +/** how do we open this door? */ +var() enum EDoorType +{ + DOOR_Shoot, + DOOR_Touch, +} DoorType; +/** trigger for the door; if specified, the opening action will be done to the trigger instead of the door */ +var() Actor DoorTrigger; +/** if true, AI should wait until the door has completely finished opening before trying to move through */ +var() bool bWaitUntilCompletelyOpened; +/** if true, means that the initial position of the mover blocks navigation */ +var() bool bInitiallyClosed; +/** if true, don't even try to go through this path if door is closed */ +var() bool bBlockedWhenClosed; + +/** whether or not the door is currently open */ +var bool bDoorOpen; + +/** internal - used in path building */ +var const transient bool bTempDisabledCollision; + +cpptext +{ + virtual AActor* AssociatedLevelGeometry(); + virtual UBOOL HasAssociatedLevelGeometry(AActor* Other); + virtual void PrePath(); + virtual void PostPath(); + virtual void FindBase(); +#if WITH_EDITOR + virtual void CheckForErrors(); +#endif +} + +event PostBeginPlay() +{ + bBlocked = (bInitiallyClosed && bBlockedWhenClosed); + bDoorOpen = !bInitiallyClosed; + + Super.PostBeginPlay(); +} + +function MoverOpened() +{ + bBlocked = (!bInitiallyClosed && bBlockedWhenClosed); + bDoorOpen = bInitiallyClosed; + WorldInfo.Game.NotifyNavigationChanged(self); +} + +function MoverClosed() +{ + bBlocked = (bInitiallyClosed && bBlockedWhenClosed); + bDoorOpen = !bInitiallyClosed; + WorldInfo.Game.NotifyNavigationChanged(self); +} + +event Actor SpecialHandling(Pawn Other) +{ + local Actor TouchActor; + + if (bDoorOpen || MyDoor == None || bInitiallyClosed == (bDoorOpen || VSizeSq(MyDoor.Velocity) > 1.f)) + { + return self; + } + else if (DoorType == DOOR_Touch) + { + if (DoorTrigger == None) + { + return MyDoor; + } + else + { + TouchActor = DoorTrigger.SpecialHandling(Other); + if (TouchActor == None) + { + TouchActor = DoorTrigger; + } + return TouchActor; + } + } + else + { + return self; + } +} + +function bool ProceedWithMove(Pawn Other) +{ + if (DoorType == DOOR_Shoot && Other.Controller.Focus == MyDoor) + { + Other.Controller.StopFiring(); + } + + if (bDoorOpen || DoorType != DOOR_Shoot) + { + return true; + } + + // door still needs to be shot + Other.Controller.Focus = (DoorTrigger != None) ? DoorTrigger : MyDoor; + if (!Other.Controller.FireWeaponAt(Other.Controller.Focus)) + { + // failed to fire at mover, try again later + Other.Controller.MoveTimer = 0.25f; + } + else if (bWaitUntilCompletelyOpened) + { + Other.Controller.WaitForMover(MyDoor); + } + + return false; +} + +/** tell Other what to do to open the door + * @param Other the Controller to tell what to do + * @return true if Other needs to wait for the door, false if it doesn't need to do anything further + */ +event bool SuggestMovePreparation(Pawn Other) +{ + if (bDoorOpen || MyDoor == None) + { + return false; + } + else if (VSizeSq(MyDoor.Velocity) > 1.f) + { + Other.Controller.WaitForMover(MyDoor); + return true; + } + else if (DoorType == DOOR_Shoot) + { + Other.Controller.Focus = (DoorTrigger != None) ? DoorTrigger : MyDoor; + if (!Other.Controller.FireWeaponAt(Other.Controller.Focus)) + { + // failed to fire at mover, try again later + Other.Controller.MoveTimer = 0.25f; + Other.Controller.bPreparingMove = true; + return true; + } + else if (bWaitUntilCompletelyOpened) + { + Other.Controller.WaitForMover(MyDoor); + Other.Controller.bPreparingMove = true; + return true; + } + else + { + return false; + } + } + else if (DoorType == DOOR_Touch && DoorTrigger != None && Other.Controller.ActorReachable(DoorTrigger)) + { + // go to trigger instead + if (Other.Controller.Focus == Other.Controller.MoveTarget) + { + Other.Controller.Focus = DoorTrigger; + } + Other.Controller.MoveTarget = DoorTrigger; + Other.Controller.CurrentPath = None; + Other.Controller.NextRoutePath = None; + return false; + } + else + { + return false; + } +} + +defaultproperties +{ + RemoteRole=ROLE_None + bNoDelete=true + ExtraCost=100 + bInitiallyClosed=true + bSpecialMove=true +} diff --git a/Engine/Classes/DownloadableContentEnumerator.uc b/Engine/Classes/DownloadableContentEnumerator.uc new file mode 100644 index 0000000..f0d2338 --- /dev/null +++ b/Engine/Classes/DownloadableContentEnumerator.uc @@ -0,0 +1,96 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * This object is responsible for the enumeration of downloadable content bundles + */ +class DownloadableContentEnumerator extends Object + dependson(OnlineSubsystem) + native(GameEngine); + +/** The set of DLC this enumerator is aware of */ +var protectedwrite array DLCBundles; + +/** The root directory to look for DLC in */ +var string DLCRootDir; + +/** List of listeners for the find DLC event */ +var protected array > FindDLCDelegates; + +/** + * Looks for DLC and populates the DLC bundles with the information + */ +native function FindDLC(); + +/** + * Called once the DLC enumeration is complete + */ +delegate OnFindDLCComplete(); + +/** + * Adds a delegate to the list of listeners + * + * @param InDelegate the delegate to use for notifications + */ +function AddFindDLCDelegate(delegate InDelegate) +{ + // Add this delegate to the array if not already present + if (FindDLCDelegates.Find(InDelegate) == INDEX_NONE) + { + FindDLCDelegates.AddItem(InDelegate); + } +} + +/** + * Removes a delegate from the list of listeners + * + * @param InDelegate the delegate to use for notifications + */ +function ClearFindDLCDelegate(delegate InDelegate) +{ + local int RemoveIndex; + + // Remove this delegate from the array if found + RemoveIndex = FindDLCDelegates.Find(InDelegate); + if (RemoveIndex != INDEX_NONE) + { + FindDLCDelegates.Remove(RemoveIndex,1); + } +} + +/** + * Removes a DLC bundle from the local machine. This is not an uninstall, so choose wisely + * + * @param DLCName the name of the DLC bundle to delete + */ +native function DeleteDLC(string DLCName); + +/** + * Adds the list of DLC bundles to the DLC manager + */ +function InstallAllDLC() +{ + local DownloadableContentManager DLCManager; + + DLCManager = class'GameEngine'.static.GetDLCManager(); + if (DLCManager != None) + { + DLCManager.InstallDLCs(DLCBundles); + } +} + +/** + * Installs the named DLC via the DLC manager + * + * @param DLCName the name of the DLC bundle to install + */ +native function InstallDLC(string DLCName); + +/** + * Triggers the FindDLC delegates + */ +native function TriggerFindDLCDelegates(); + +defaultproperties +{ + DLCRootDir="../../DLC/" +} diff --git a/Engine/Classes/DownloadableContentManager.uc b/Engine/Classes/DownloadableContentManager.uc new file mode 100644 index 0000000..e395ae8 --- /dev/null +++ b/Engine/Classes/DownloadableContentManager.uc @@ -0,0 +1,243 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * This object is responsible for the installation and removal of + * downloadable content + */ +class DownloadableContentManager extends Object + native(GameEngine); + +/** The list of DLC config cache changes made by the installed DLC */ +var native const transient array DLCConfigCacheChanges{struct FDLCConfigCacheChanges}; + +/** The list of installed DLC bundles */ +var const transient array InstalledDLC; + +/** Maps the file name to the full path to its location */ +var const native transient Map_Mirror NonPackageFilePathMap{TMap}; + +/** The list of classes that need reloading due to a config change */ +var const native transient array ClassesToReload; + +/** The list of per object config objects that need updating due to a config change */ +var const native transient array ObjectsToReload; + +/** The list of ini files we need to check for always loaded packages after initialization */ +var const transient array QueuedFullyLoadPackageInis; + +/** The owning game engine */ +var const transient GameEngine GameEngine; + +/** + * Installs a DLC bundle + * + * @param DLCBundle the bundle that is to be installed + * + * @return true if the bundle could be installed correctly, false if it failed + */ +native function bool InstallDLC(const out OnlineContent DLCBundle); + +/** + * Installs a set of DLC bundles + * + * @param DLCBundles the set of bundles that are to be installed + */ +native function InstallDLCs(const out array DLCBundles); + +/** + * Clears the DLC cache and restores the config cache to its pre-DLC state + */ +native function ClearDLC(); + +/** + * Determines the full path of the file in DLC + * + * @param NonPackageFileName the bundle that is to be installed + * @param Path receives the full path to the file + * + * @return true if the file was found, false if it wasn't + */ +native function bool GetDLCNonPackageFilePath(name NonPackageFileName,out string Path); + +/** + * Adds the specified section to the classes to update list or to the per object config + * objects to update depending on whether they are found + * + * @param Section the section name being reloaded + */ +native function AddSectionToObjectList(string Section); + +/** + * Looks to see if the section is a per object config section that was removed so the + * object also needs to be destroyed + * + * @param Section the section name being unloaded + */ +native function MarkPerObjectConfigPendingKill(string Section); + +/** + * Reloads config and localization on both of the object lists and empties them + */ +native function UpdateObjectLists(); + +/** + * Installs the list of packages for the DLC + * + * @param DLCBundle the bundle that is being installed + */ +native protected function InstallPackages(const out OnlineContent DLCBundle); + +/** + * Installs the list of non-packages (ini, loc, sha, etc.) for the DLC + * + * @param DLCBundle the bundle that is being installed + */ +native protected function InstallNonPackageFiles(const out OnlineContent DLCBundle); + +/** + * Registers the callback events with the online subsystem that it cares about + */ +event Init() +{ + local OnlineSubsystem OnlineSub; + + OnlineSub = class'GameEngine'.static.GetOnlineSubsystem(); + if (OnlineSub != None) + { + if (OnlineSub.PlayerInterface != None) + { + OnlineSub.PlayerInterface.AddLoginChangeDelegate(OnLoginChange); + } + if (OnlineSub.SystemInterface != None) + { + OnlineSub.SystemInterface.AddStorageDeviceChangeDelegate(OnStorageDeviceChange); + } + if (OnlineSub.ContentInterface != None) + { + OnlineSub.ContentInterface.AddContentChangeDelegate(OnContentChange); + } + } +} + +/** + * Delegate called when a player logs in/out, so we can clear/refresh DLC + * + * @param LocalUserNum the player that logged in/out + */ +function OnLoginChange(byte LocalUserNum) +{ + RefreshDLC(); +} + +/** + * Called when a storage device is inserted/removed. Here so game specific implementations can easily overload + */ +function OnStorageDeviceChange() +{ + RefreshDLC(); +} + +/** + * Called when new DLC is installed. Here so game specific implementations can easily overload + */ +function OnContentChange() +{ + RefreshDLC(); +} + +/** + * Delegate used when content is changed (add or deletion) for any user or + * when any storage devices are changed + */ +function RefreshDLC() +{ + local DownloadableContentEnumerator DLCEnum; + + ClearDLC(); + DLCEnum = class'GameEngine'.static.GetDLCEnumerator(); + if (DLCEnum != None) + { + DLCEnum.AddFindDLCDelegate(RefreshDLCEnumComplete); + DLCEnum.FindDLC(); + } +} + +/** + * Installs the DLC when the enumeration is complete + */ +function RefreshDLCEnumComplete() +{ + local DownloadableContentEnumerator DLCEnum; + + DLCEnum = class'GameEngine'.static.GetDLCEnumerator(); + if (DLCEnum != None) + { + DLCEnum.ClearFindDLCDelegate(RefreshDLCEnumComplete); + DLCEnum.InstallAllDLC(); + } + OnRefreshComplete(); +} + +/** + * Parses the specified section for the key/value set to use for fully loading packages + * + * @param FileName the file name to parse the information from + */ +native function AddPackagesToFullyLoad(string FileName); + +/** Called once the refresh is complete */ +delegate OnRefreshComplete(); + +cpptext +{ + /** + * Creates a map of all the non package files contained in the DLC + * + * @param DLCBundle the DLC bundle being processed + */ + void InstallNonPackages(const FOnlineContent& DLCBundle); + +#if PS3 // PS3 DLC has to be signed + /** + * Adds any SHA hashes to the file hashes for this bundle + * + * @param DLCBundle the DLC bundle being processed + */ + void InstallSHAFiles(const FOnlineContent& DLCBundle); +#endif + + /** + * Process all INI files and our current loc language + * + * @param DLCBundle the DLC bundle being processed + */ + void InstallIniLocFiles(const FOnlineContent& DLCBundle); + + /** + * Parses the specified section for the key/value set to use for fully loading + * + * @param LoadType the type of package loading to use + * @param Section the INI section to parse + * @param KeyOne the key to parse + * @param KeyN the sub keys to parse + * @param FileName the file name to parse the information from + */ + void AddPackagesToFullyLoad(EFullyLoadPackageType LoadType,const TCHAR* Section,const TCHAR* KeyOne,const TCHAR* KeyN,const TCHAR* FileName); + + /** + * For a given DLC ini/loc file, it determines the list of sections in the INI/loc file that are touched + * so that it can determine which ones to replace during unloading and which to remove altogether + * + * @param FileName the name of the DLC ini/loc file to parse for section changes + * @param OutSectionsIncluded gets the list of modified/added sections + */ + void GetListOfSectionNames(const TCHAR* FileName,TArray& OutSectionsIncluded); + + /** + * Builds the set of changes needed to undo this DLC's config changes/additions + * + * @param ConfigFileName the name of the DLC ini/loc file to build the undo set for + * @param SectionsIncluded the list of modified/added sections + */ + void BuildDLCConfigCacheUndo(const TCHAR* ConfigFileName,const TArray& SectionsIncluded); +} \ No newline at end of file diff --git a/Engine/Classes/DrawBoxComponent.uc b/Engine/Classes/DrawBoxComponent.uc new file mode 100644 index 0000000..5e22d15 --- /dev/null +++ b/Engine/Classes/DrawBoxComponent.uc @@ -0,0 +1,25 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DrawBoxComponent extends PrimitiveComponent + native + noexport + collapsecategories + hidecategories(Object) + editinlinenew; + +var() color BoxColor; +var() material BoxMaterial; +var() vector BoxExtent; +var() bool bDrawWireBox; +var() bool bDrawLitBox; +var() bool bDrawOnlyIfSelected; + +defaultproperties +{ + BoxColor=(R=255,G=0,B=0,A=255) + BoxExtent=(X=200.0, Y=200.0, Z=200.0) + bDrawWireBox=true + + HiddenGame=True +} diff --git a/Engine/Classes/DrawCapsuleComponent.uc b/Engine/Classes/DrawCapsuleComponent.uc new file mode 100644 index 0000000..1627733 --- /dev/null +++ b/Engine/Classes/DrawCapsuleComponent.uc @@ -0,0 +1,27 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DrawCapsuleComponent extends PrimitiveComponent + native + noexport + collapsecategories + hidecategories(Object) + editinlinenew; + +var() color CapsuleColor; +var() material CapsuleMaterial; +var() float CapsuleHeight; +var() float CapsuleRadius; +var() bool bDrawWireCapsule; +var() bool bDrawLitCapsule; +var() bool bDrawOnlyIfSelected; + +defaultproperties +{ + CapsuleColor=(R=255,G=0,B=0,A=255) + CapsuleHeight=200.0 + CapsuleRadius=200.0 + bDrawWireCapsule=true + + HiddenGame=True +} diff --git a/Engine/Classes/DrawConeComponent.uc b/Engine/Classes/DrawConeComponent.uc new file mode 100644 index 0000000..aaebfbe --- /dev/null +++ b/Engine/Classes/DrawConeComponent.uc @@ -0,0 +1,34 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DrawConeComponent extends PrimitiveComponent + native + collapsecategories + hidecategories(Object) + editinlinenew; + +var() color ConeColor; +var() float ConeRadius; +var() float ConeAngle; +var() int ConeSides; + +cpptext +{ + // UPrimitiveComponent interface. + /** + * Creates a proxy to represent the primitive to the scene manager in the rendering thread. + * @return The proxy object. + */ + virtual FPrimitiveSceneProxy* CreateSceneProxy(); + virtual void UpdateBounds(); +} + +defaultproperties +{ + ConeColor=(R=150,G=200,B=255,A=255) + ConeRadius=100.0 + ConeAngle=44.0 + ConeSides=16 + + HiddenGame=True +} diff --git a/Engine/Classes/DrawCylinderComponent.uc b/Engine/Classes/DrawCylinderComponent.uc new file mode 100644 index 0000000..da0c2ac --- /dev/null +++ b/Engine/Classes/DrawCylinderComponent.uc @@ -0,0 +1,34 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class DrawCylinderComponent extends PrimitiveComponent + native + noexport + collapsecategories + hidecategories(Object) + editinlinenew; + +var() color CylinderColor; +var() material CylinderMaterial; +var() float CylinderRadius; +var() float CylinderTopRadius; +var() float CylinderHeight; +var() float CylinderHeightOffset; +var() int CylinderSides; +var() bool bDrawWireCylinder; +var() bool bDrawLitCylinder; +var() bool bDrawOnlyIfSelected; + +defaultproperties +{ + CylinderColor=(R=255,G=0,B=0,A=255) + CylinderRadius=100.0 + CylinderTopRadius=100.0 + CylinderHeight=100.0 + CylinderHeightOffset=0.0 + CylinderSides=16 + bDrawWireCylinder=true + + HiddenGame=True +} diff --git a/Engine/Classes/DrawFrustumComponent.uc b/Engine/Classes/DrawFrustumComponent.uc new file mode 100644 index 0000000..79ab016 --- /dev/null +++ b/Engine/Classes/DrawFrustumComponent.uc @@ -0,0 +1,44 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DrawFrustumComponent extends PrimitiveComponent + native + noexport + collapsecategories + hidecategories(Object) + editinlinenew; + +/** + * Utility component for drawing a view frustum. Origin is at the component location, frustum points down position X axis. + */ + +/** Color to draw the wireframe frustum. */ +var() color FrustumColor; + +/** Angle of longest dimension of view shape. + * If the angle is 0 then an orthographic projection is used */ +var() float FrustumAngle; + +/** Ratio of horizontal size over vertical size. */ +var() float FrustumAspectRatio; + +/** Distance from origin to start drawing the frustum. */ +var() float FrustumStartDist; + +/** Distance from origin to stop drawing the frustum. */ +var() float FrustumEndDist; + +/** optional texture to show on the near plane */ +var() Texture Texture; + +defaultproperties +{ + FrustumColor=(R=255,G=0,B=255,A=255) + FrustumAngle=90.0 + FrustumAspectRatio=AspectRatio4x3 + FrustumStartDist=100 + FrustumEndDist=1000 + + HiddenGame=true + CollideActors=false +} diff --git a/Engine/Classes/DrawLightConeComponent.uc b/Engine/Classes/DrawLightConeComponent.uc new file mode 100644 index 0000000..c4e7ee5 --- /dev/null +++ b/Engine/Classes/DrawLightConeComponent.uc @@ -0,0 +1,22 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DrawLightConeComponent extends DrawConeComponent + native(Light) + hidecategories(Physics,Collision,PrimitiveComponent,Rendering); + +cpptext +{ + /** + * Creates a proxy to represent the primitive to the scene manager in the rendering thread. + * @return The proxy object. + */ + virtual FPrimitiveSceneProxy* CreateSceneProxy(); +} + +defaultproperties +{ + AlwaysLoadOnClient=False + AlwaysLoadOnServer=False + AbsoluteScale=TRUE +} diff --git a/Engine/Classes/DrawLightRadiusComponent.uc b/Engine/Classes/DrawLightRadiusComponent.uc new file mode 100644 index 0000000..03848e7 --- /dev/null +++ b/Engine/Classes/DrawLightRadiusComponent.uc @@ -0,0 +1,18 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DrawLightRadiusComponent extends DrawSphereComponent + native(Light) + noexport + hidecategories(Physics,Collision,PrimitiveComponent,Rendering); + +defaultproperties +{ + SphereColor=(R=173,G=239,B=231,A=255) + SphereSides=32 + + AlwaysLoadOnClient=False + AlwaysLoadOnServer=False + + AbsoluteScale=TRUE +} diff --git a/Engine/Classes/DrawPylonRadiusComponent.uc b/Engine/Classes/DrawPylonRadiusComponent.uc new file mode 100644 index 0000000..3a9609a --- /dev/null +++ b/Engine/Classes/DrawPylonRadiusComponent.uc @@ -0,0 +1,24 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DrawPylonRadiusComponent extends DrawSphereComponent + native + hidecategories(Physics,Collision,PrimitiveComponent,Rendering); + +cpptext +{ + FPrimitiveSceneProxy* CreateSceneProxy(); + void UpdateBounds(); + void Attach(); +}; + +defaultproperties +{ + SphereColor=(R=173,G=239,B=231,A=255) + SphereSides=32 + + AlwaysLoadOnClient=False + AlwaysLoadOnServer=False + + AbsoluteScale=TRUE +} diff --git a/Engine/Classes/DrawQuadComponent.uc b/Engine/Classes/DrawQuadComponent.uc new file mode 100644 index 0000000..28cf802 --- /dev/null +++ b/Engine/Classes/DrawQuadComponent.uc @@ -0,0 +1,30 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DrawQuadComponent extends PrimitiveComponent + native + noexport + collapsecategories + hidecategories(Object) + editinlinenew; + +/** + * Utility component for drawing a textured quad face. + * Origin is at the component location, frustum points down position X axis. + */ + +/** Texture source to draw on quad face */ +var() Texture Texture; +/** Width of quad face */ +var() float Width; +/** Height of quad face */ +var() float Height; + +defaultproperties +{ + Width=100 + Height=100 + + HiddenGame=true + CollideActors=false +} diff --git a/Engine/Classes/DrawSoundRadiusComponent.uc b/Engine/Classes/DrawSoundRadiusComponent.uc new file mode 100644 index 0000000..bc3e825 --- /dev/null +++ b/Engine/Classes/DrawSoundRadiusComponent.uc @@ -0,0 +1,18 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DrawSoundRadiusComponent extends DrawSphereComponent + native + noexport + hidecategories(Physics,Collision,PrimitiveComponent,Rendering); + +defaultproperties +{ + SphereColor=(R=173,G=239,B=231,A=255) + SphereSides=32 + + AlwaysLoadOnClient=False + AlwaysLoadOnServer=False + + AbsoluteScale=TRUE +} diff --git a/Engine/Classes/DrawSphereComponent.uc b/Engine/Classes/DrawSphereComponent.uc new file mode 100644 index 0000000..76faf66 --- /dev/null +++ b/Engine/Classes/DrawSphereComponent.uc @@ -0,0 +1,27 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DrawSphereComponent extends PrimitiveComponent + native + noexport + collapsecategories + hidecategories(Object) + editinlinenew; + +var() color SphereColor; +var() material SphereMaterial; +var() float SphereRadius; +var() int SphereSides; +var() bool bDrawWireSphere; +var() bool bDrawLitSphere; +var() bool bDrawOnlyIfSelected; + +defaultproperties +{ + SphereColor=(R=255,G=0,B=0,A=255) + SphereRadius=100.0 + SphereSides=16 + bDrawWireSphere=true + + HiddenGame=True +} diff --git a/Engine/Classes/DrawTaperedCapsuleComponent.uc b/Engine/Classes/DrawTaperedCapsuleComponent.uc new file mode 100644 index 0000000..b3344de --- /dev/null +++ b/Engine/Classes/DrawTaperedCapsuleComponent.uc @@ -0,0 +1,29 @@ +/** + * Copyright 1998-2012 Epic Games, Inc. All Rights Reserved. + */ +class DrawTaperedCapsuleComponent extends PrimitiveComponent + native + noexport + collapsecategories + hidecategories(Object) + editinlinenew; + +var() color CapsuleColor; +var() material CapsuleMaterial; +var() float CapsuleHeight; +var() float CapsuleRadius; +var() float CapsuleTopRadius; +var() bool bDrawWireCapsule; +var() bool bDrawLitCapsule; +var() bool bDrawOnlyIfSelected; + +defaultproperties +{ + CapsuleColor=(R=255,G=0,B=0,A=255) + CapsuleHeight=200.0 + CapsuleRadius=200.0 + CapsuleTopRadius=100.0 + bDrawWireCapsule=true + + HiddenGame=True +} diff --git a/Engine/Classes/DroppedPickup.uc b/Engine/Classes/DroppedPickup.uc new file mode 100644 index 0000000..c7365fc --- /dev/null +++ b/Engine/Classes/DroppedPickup.uc @@ -0,0 +1,270 @@ +//============================================================================= +// Pickup items. +// +// PickupFactory should be used to place items in the level. This class is for dropped inventory, which should attach +// itself to this pickup, and set the appropriate mesh +// +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class DroppedPickup extends Actor + notplaceable + native; + +//----------------------------------------------------------------------------- +// AI related info. +var Inventory Inventory; // the dropped inventory item which spawned this pickup +var repnotify class InventoryClass; // Class of the inventory object to pickup +var NavigationPoint PickupCache; // navigationpoint this pickup is attached to +var repnotify bool bFadeOut; + +native final function AddToNavigation(); // cache dropped inventory in navigation network +native final function RemoveFromNavigation(); + +replication +{ + if( Role==ROLE_Authority ) + InventoryClass, bFadeOut; +} + +event Destroyed() +{ + if (Inventory != None ) + Inventory.Destroy(); +} + +simulated event ReplicatedEvent(name VarName) +{ + if( VarName == 'InventoryClass' ) + { + SetPickupMesh( InventoryClass.default.DroppedPickupMesh ); + SetPickupParticles( InventoryClass.default.DroppedPickupParticles ); + } + else if ( VarName == 'bFadeOut' ) + { + GotoState('Fadeout'); + } + else + { + super.ReplicatedEvent(VarName); + } +} +/* Reset() +reset actor to initial state - used when restarting level without reloading. +*/ +function Reset() +{ + Destroy(); +} + +/** + * Set Pickup mesh to use. + * Replicated through InventoryClass to remote clients using Inventory.DroppedPickup component as default mesh. + */ +simulated event SetPickupMesh(PrimitiveComponent PickupMesh) +{ + local ActorComponent Comp; + + if (PickupMesh != None && WorldInfo.NetMode != NM_DedicatedServer ) + { + Comp = new(self) PickupMesh.Class(PickupMesh); + AttachComponent(Comp); + } +} + +/** + * Set Pickup particles to use. + * Replicated through InventoryClass to remote clients using Inventory.DroppedPickup component as default mesh. + */ +simulated event SetPickupParticles(ParticleSystemComponent PickupParticles) +{ + local ParticleSystemComponent Comp; + + if (PickupParticles != None && WorldInfo.NetMode != NM_DedicatedServer ) + { + Comp = new(self) PickupParticles.Class(PickupParticles); + AttachComponent(Comp); + Comp.SetActive(true); + } +} + +event EncroachedBy(Actor Other) +{ + Destroy(); +} + +/* DetourWeight() +value of this path to take a quick detour (usually 0, used when on route to distant objective, but want to grab inventory for example) +*/ +function float DetourWeight(Pawn Other,float PathWeight) +{ + return Inventory.DetourWeight(Other, PathWeight); +} + +event Landed(Vector HitNormal, Actor FloorActor) +{ + // force full net update + bForceNetUpdate = TRUE; + bNetDirty = true; + // reduce frequency since the pickup isn't moving anymore + NetUpdateFrequency = 3; + + AddToNavigation(); +} + +/** give pickup to player */ +function GiveTo( Pawn P ) +{ + if( Inventory != None ) + { + Inventory.AnnouncePickup(P); + Inventory.GiveTo(P); + Inventory = None; + } + PickedUpBy(P); +} + +function PickedUpBy(Pawn P) +{ + Destroy(); +} + +function RecheckValidTouch(); + +//============================================================================= +// Pickup state: this inventory item is sitting on the ground. + +auto state Pickup +{ + /* + Validate touch (if valid return true to let other pick me up and trigger event). + */ + function bool ValidTouch(Pawn Other) + { + // make sure its a live player + if (Other == None || !Other.bCanPickupInventory || (Other.DrivenVehicle == None && Other.Controller == None)) + { + return false; + } + + // make sure thrower doesn't run over own weapon + if ( (Physics == PHYS_Falling) && (Other == Instigator) && (Velocity.Z > 0) ) + { + return false; + } + + // make sure not touching through wall + if ( !FastTrace(Other.Location, Location) ) + { + SetTimer( 0.5, false, nameof(RecheckValidTouch) ); + return false; + } + + // make sure game will let player pick me up + if (WorldInfo.Game.PickupQuery(Other, Inventory.class, self)) + { + return true; + } + return false; + } + + /** + Pickup was touched through a wall. Check to see if touching pawn is no longer obstructed + */ + function RecheckValidTouch() + { + CheckTouching(); + } + + // When touched by an actor. + event Touch( Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal ) + { + local Pawn P; + + // If touched by a player pawn, let him pick this up. + P = Pawn(Other); + if( P != None && ValidTouch(P) ) + { + GiveTo(P); + } + } + + event Timer() + { + GotoState('FadeOut'); + } + + function CheckTouching() + { + local Pawn P; + + foreach TouchingActors(class'Pawn', P) + { + Touch( P, None, Location, vect(0,0,1) ); + } + } + + event BeginState(Name PreviousStateName) + { + AddToNavigation(); + if( LifeSpan > 0.f ) + { + SetTimer(LifeSpan - 1, false); + } + } + + event EndState(Name NextStateName) + { + RemoveFromNavigation(); + } + +Begin: + CheckTouching(); +} + +State FadeOut extends Pickup +{ + simulated event BeginState(Name PreviousStateName) + { + bFadeOut = true; + RotationRate.Yaw=60000; + SetPhysics(PHYS_Rotating); + LifeSpan = 1.0; + } +} + +defaultproperties +{ + Begin Object Class=SpriteComponent Name=Sprite + Sprite=Texture2D'EditorResources.S_Inventory' + HiddenGame=True + AlwaysLoadOnClient=False + AlwaysLoadOnServer=False + SpriteCategoryName="Inventory" + End Object + Components.Add(Sprite) + + Begin Object Class=CylinderComponent NAME=CollisionCylinder + CollisionRadius=+00030.000000 + CollisionHeight=+00020.000000 + CollideActors=true + End Object + CollisionComponent=CollisionCylinder + Components.Add(CollisionCylinder) + + + bOnlyDirtyReplication=true + NetUpdateFrequency=8 + RemoteRole=ROLE_SimulatedProxy + bHidden=false + NetPriority=+1.4 + bCollideActors=true + bCollideWorld=true + RotationRate=(Yaw=5000) + + bOrientOnSlope=true + bShouldBaseAtStartup=true + bIgnoreEncroachers=false + bIgnoreRigidBodyPawns=true + bUpdateSimulatedPosition=true + LifeSpan=+16.0 +} diff --git a/Engine/Classes/DynamicAnchor.uc b/Engine/Classes/DynamicAnchor.uc new file mode 100644 index 0000000..0c67124 --- /dev/null +++ b/Engine/Classes/DynamicAnchor.uc @@ -0,0 +1,43 @@ +/** + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + + +/** a dynamic anchor is a NavigationPoint temporarily added to the navigation network during gameplay, when the AI is trying + * to get on the network but there is no directly reachable NavigationPoint available. It tries to find something else that is + * reachable (for example, part of a ReachSpec) and places one of these there and connects it to the network. Doing it this way + * allows us to handle these situations without any special high-level code; as far as script is concerned, the AI is moving + * along a perfectly normal NavigationPoint connected to the network just like any other. + * DynamicAnchors handle destroying themselves and cleaning up any connections when they are no longer in use. + */ +class DynamicAnchor extends NavigationPoint + native; + +/** current controller that's using us to navigate */ +var Controller CurrentUser; + +cpptext +{ + /** initializes us with the given user and creates ReachSpecs to connect ourselves to the given endpoints, + * using the given ReachSpec as a template + * @param InUser the Controller that will be using us for navigation + * @param Point1 the first NavigationPoint to connect to + * @param Point2 the second NavigationPoint to connect to + * @param SpecTemplate the ReachSpec to use as a template for the ReachSpecs we create + */ + void Initialize(AController* InUser, ANavigationPoint* Point1, ANavigationPoint* Point2, UReachSpec* SpecTemplate); + void InitHelper( ANavigationPoint* Start, ANavigationPoint* End, INT NewHeight, INT NewRadius, UReachSpec* SpecTemplate ); + + virtual void PostScriptDestroyed(); + + virtual void TickSpecial(FLOAT DeltaSeconds); +} + +defaultproperties +{ + RemoteRole=ROLE_None + bStatic=false + bNoDelete=false + bCollideWhenPlacing=false +} diff --git a/Engine/Classes/DynamicBlockingVolume.uc b/Engine/Classes/DynamicBlockingVolume.uc new file mode 100644 index 0000000..d35ac21 --- /dev/null +++ b/Engine/Classes/DynamicBlockingVolume.uc @@ -0,0 +1,100 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +/** + * This is a movable blocking volume. It can be moved by matinee, being based on + * dynamic objects, etc. + */ +class DynamicBlockingVolume extends BlockingVolume + native + showcategories(Movement) + placeable; + +/** Is the volume enabled by default? */ +var() bool bEnabled; + +cpptext +{ +#if WITH_EDITOR + virtual void CheckForErrors(); +#endif + + /** + * Force TRACE_LevelGeometry to still work with us even though bWorldGeometry is cleared + * bWorldGeometry is cleared so that actors can base properly on moving volumes + * + * @param Primitive - the primitive to trace against + * + * @param SourceActor - the actor doing the trace + * + * @param TraceFlags - misc flags describing the trace + */ + virtual UBOOL ShouldTrace(UPrimitiveComponent* Primitive, AActor *SourceActor, DWORD TraceFlags); +} + +struct CheckpointRecord +{ + var vector Location; + var rotator Rotation; + var bool bCollideActors; + var bool bBlockActors; + var bool bNeedsReplication; +}; + +/** + * Overriden to set the default collision state. + */ +simulated event PostBeginPlay() +{ + Super.PostBeginPlay(); + + SetCollision(bEnabled, bBlockActors); +} + +function CreateCheckpointRecord(out CheckpointRecord Record) +{ + Record.Location = Location; + Record.Rotation = Rotation; + Record.bCollideActors = bCollideActors; + Record.bBlockActors = bBlockActors; + Record.bNeedsReplication = (RemoteRole != ROLE_None); +} + +function ApplyCheckpointRecord(const out CheckpointRecord Record) +{ + if (!bHardAttach) + { + SetLocation(Record.Location); + SetRotation(Record.Rotation); + } + // always leave component colliding and just use the Actor flags + CollisionComponent.SetActorCollision(true, true); + CollisionComponent.SetTraceBlocking(false, true); + CollisionComponent.SetBlockRigidBody(Record.bCollideActors); + SetCollision(Record.bCollideActors, Record.bBlockActors); + + if (Record.bNeedsReplication) + { + ForceNetRelevant(); + } +} + +defaultproperties +{ + //@todo - Change back to PHYS_None + Physics=PHYS_Interpolating + + bStatic=false + + bMovable=true + bAlwaysRelevant=true + bReplicateMovement=true + bOnlyDirtyReplication=true + RemoteRole=ROLE_None + bWorldGeometry=false + + BrushColor=(R=255,G=255,B=100,A=255) + + bEnabled=true +} diff --git a/Engine/Classes/DynamicCameraActor.uc b/Engine/Classes/DynamicCameraActor.uc new file mode 100644 index 0000000..98a9c48 --- /dev/null +++ b/Engine/Classes/DynamicCameraActor.uc @@ -0,0 +1,15 @@ +/* + * DynamicCameraActor + * A CameraActor that can be spawned/deleted dynamically in-game. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class DynamicCameraActor extends CameraActor + native(Camera) + notplaceable; + +defaultproperties +{ + bNoDelete=FALSE +} diff --git a/Engine/Classes/DynamicLightEnvironmentComponent.uc b/Engine/Classes/DynamicLightEnvironmentComponent.uc new file mode 100644 index 0000000..d18433a --- /dev/null +++ b/Engine/Classes/DynamicLightEnvironmentComponent.uc @@ -0,0 +1,241 @@ +/** + * This is used to light components / actors during the game. Doing something like: + * LightEnvironment=FooLightEnvironment + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DynamicLightEnvironmentComponent extends LightEnvironmentComponent + native(Light); + +/** The current state of the light environment. */ +var private native transient const pointer State{class FDynamicLightEnvironmentState}; + +/** The number of seconds between light environment updates for actors which aren't visible. */ +var() float InvisibleUpdateTime; + +/** Minimum amount of time that needs to pass between full environment updates. */ +var() float MinTimeBetweenFullUpdates; + +/** Scales the velocity based update factor. Values near 0 mean velocity will not be a factor in update rate. */ +var float VelocityUpdateTimeScale; + +/** + * Speed to interpolate the current shadow to the newly captured shadow. + * A value of .01 means the interpolation will be complete after the DLE moves 100 Unreal Units. + */ +var float ShadowInterpolationSpeed; + +/** The number of visibility samples to use within the primitive's bounding volume. */ +var() int NumVolumeVisibilitySamples; + +/** Scales the bounds used for light environment calculations. */ +var() float LightingBoundsScale; + +/** The color of the ambient shadow. */ +var LinearColor AmbientShadowColor; + +/** The direction of the ambient shadow source. */ +var vector AmbientShadowSourceDirection; + +/** Ambient color added in addition to the level's lighting. */ +var LinearColor AmbientGlow; + +/** The distance to create the light from the owner's origin, in radius units. */ +var float LightDistance; + +/** The distance for the shadow to project beyond the owner's origin, in radius units. */ +var float ShadowDistance; + +/** Whether the light environment should cast shadows */ +var() bool bCastShadows; + +/** Whether the light environment's shadow includes the effect of dynamic lights. */ +var bool bCompositeShadowsFromDynamicLights; + +/** Whether to represent all lights with the light environment, including dominant lights which are usually rendered separately. */ +var bool bForceCompositeAllLights; + +/** + * Whether to be affected by small dynamic lights (like muzzle flashes) which may expose artifacts since the whole DLE will be lit up by them. + * If FALSE, dynamic lights smaller than the DLE will not affect the DLE. + */ +var bool bAffectedBySmallDynamicLights; + +/** + * Whether to use cheap on/off shadowing from the environment or allow a dynamic preshadow. + */ +var() bool bUseBooleanEnvironmentShadowing; + +/** Whether the light environment should be shadowed by the static environment. */ +var bool bShadowFromEnvironment; + +/** Time since the caster was last visible at which the mod shadow will fade out completely. */ +var float ModShadowFadeoutTime; + +/** Exponent that controls mod shadow fadeout curve. */ +var float ModShadowFadeoutExponent; + +/** Brightest ModulatedShadowColor allowed for the shadow. This can be used to limit the DLE's shadow to a specified darkness. */ +var LinearColor MaxModulatedShadowColor; + +/** + * The distance from the dominant light shadow transition at which to start fading out the DLE's modulated shadow and primary light. + * This must be larger than DominantShadowTransitionEndDistance. + */ +var float DominantShadowTransitionStartDistance; + +/** + * The distance from the dominant light shadow transition at which to end fading out the DLE's modulated shadow and primary light. + * This must be smaller than DominantShadowTransitionStartDistance. + */ +var float DominantShadowTransitionEndDistance; + +/** Whether the light environment should be dynamically updated. */ +var() bool bDynamic; + +/** Whether a directional light should be used to synthesize the dominant lighting in the environment. */ +var bool bSynthesizeDirectionalLight; + +/** + * Whether a SH light should be used to synthesize all light not accounted for by the synthesized directional light. + * If not, a sky light is used instead. Using an SH light gives higher quality secondary lighting, but at a steeper performance cost. + */ +var() bool bSynthesizeSHLight; + +/** + * The minimum angle to allow between the shadow direction and horizontal. An angle > 0 constrains the shadow to never be cast from a light + * below horizontal. + */ +var float MinShadowAngle; + +/** Whether this is an actor that can't tolerate latency in lighting updates; a full lighting update is done every frame. */ +var() bool bRequiresNonLatentUpdates; + +/* + * Whether to do visibility traces from the closest point on the bounds to the light, or just from the center of the bounds. + * This is useful when using a DLE on an object that is likely embedded in shadow casting objects (ie fractured meshes). + */ +var bool bTraceFromClosestBoundsPoint; + +/** + * Whether this light environment is being applied to a character + * And should be affected by character specific lighting like WorldInfo's CharacterLightingContrastFactor. + */ +var() bool bIsCharacterLightEnvironment; + +/** + * Methods used to calculate the bounds that this light environment will use as a representation of what it is lighting. + * The default settings will trace one ray from the center of the calculated bounds to each relevant light. + */ +enum EDynamicLightEnvironmentBoundsMethod +{ + /** The default DLE bounds method, starts with a small sphere at the Owner's origin and adds each component of Owner using this DLE. */ + DLEB_OwnerComponents, + /** Uses OverriddenBounds, doesn't depend on Owner at all. */ + DLEB_ManualOverride, + /** + * Accumulates the bounds of attached components on any actor using this DLE. + * This is useful when the DLE is lighting something whose Owner is placed in the world, like a pool actor. + * This method only works when the components using this DLE are attached before the DLE is updated. + */ + DLEB_ActiveComponents +}; + +var EDynamicLightEnvironmentBoundsMethod BoundsMethod; + +/* The bounds to use for visibility calculations if BoundsMethod==DLEB_ManualOverride. */ +var BoxSphereBounds OverriddenBounds; + +/* Whether to override the lighting channels of the owner with OverriddenLightingChannels. */ +var bool bOverrideOwnerLightingChannels; + +/* The lighting channels to use if bOverrideOwnerLightingChannels is enabled. */ +var LightingChannelContainer OverriddenLightingChannels; + +/** Light components which override lights in GWorld, useful for rendering light environments in preview scenes. */ +var const array OverriddenLightComponents; + +/** When enabled for light environments influenced by a dominant directional light, this indicates that the object should always be treated as influenced by the directional light and the engine should never search for a dominant shadow transition. Enabling this can greatly improve performance for actors with huge bounds that are dynamically lit by dominant directional lights. */ +var bool bAlwaysInfluencedByDominantDirectionalLight; + +cpptext +{ + // UObject interface. + virtual void FinishDestroy(); + virtual void AddReferencedObjects( TArray& ObjectArray ); + virtual void Serialize(FArchive& Ar); + virtual void PostLoad(); + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + // UActorComponent interface. + virtual void Tick(FLOAT DeltaTime); + virtual void Attach(); + virtual void UpdateTransform(); + virtual void Detach( UBOOL bWillReattach = FALSE ); + virtual void BeginPlay(); +#if WITH_EDITOR + virtual void CheckForErrors(); +#endif + /** Adds lights that affect this DLE to RelevantLightList. */ + virtual void AddRelevantLights(TArray& RelevantLightList, UBOOL bDominantOnly) const; + + // ULightEnvironmentComponent interface. + virtual void UpdateLight(const ULightComponent* Light); + virtual void SetNeedsStaticUpdate(); + + friend class FDynamicLightEnvironmentState; + +protected: + + virtual UBOOL NeedsUpdateBasedOnComponent(UPrimitiveComponent* Component) const; + +#if USE_GAMEPLAY_PROFILER + /** + * This function actually does the work for the GetProfilerAssetObject and is virtual. + * It should only be called from GetProfilerAssetObject as GetProfilerAssetObject is safe to call on NULL object pointers + */ + virtual UObject* GetProfilerAssetObjectInternal() const; +#endif + + /** + * This function actually does the work for the GetDetailInfo and is virtual. + * It should only be called from GetDetailedInfo as GetDetailedInfo is safe to call on NULL object pointers + */ + virtual FString GetDetailedInfoInternal() const; +} + +/* Forces a full update the of the dynamic and static environments on the next Tick. */ +native final function ResetEnvironment(); + +defaultproperties +{ + InvisibleUpdateTime=5.0 + MinTimeBetweenFullUpdates=1.0 + NumVolumeVisibilitySamples=1 + // By default, don't update fast moving objects more often + VelocityUpdateTimeScale=0.000001 + LightingBoundsScale=1 + // Using a relatively slow speed so that the shadow is mostly interpolating which hides the low update frequency + ShadowInterpolationSpeed=.004 + AmbientShadowColor=(R=0.001,G=0.001,B=0.001) + AmbientShadowSourceDirection=(X=0.01,Y=0,Z=0.99) + LightDistance=10.0 + ShadowDistance=5.0 + // bRequiresNonLatentUpdates sets it to TG_PostUpdateWork in BeginPlay() + TickGroup=TG_DuringAsyncWork + bCastShadows=TRUE + bCompositeShadowsFromDynamicLights=TRUE + bAffectedBySmallDynamicLights=TRUE + // Cheap default + bUseBooleanEnvironmentShadowing=TRUE + bShadowFromEnvironment=TRUE + ModShadowFadeoutExponent=3.0 + MaxModulatedShadowColor=(R=0.5,G=0.5,B=0.5) + DominantShadowTransitionStartDistance=100 + DominantShadowTransitionEndDistance=10 + bDynamic=TRUE + bSynthesizeDirectionalLight=TRUE + bSynthesizeSHLight=FALSE + MinShadowAngle=25.0 + BoundsMethod=DLEB_OwnerComponents +} diff --git a/Engine/Classes/DynamicPhysicsVolume.uc b/Engine/Classes/DynamicPhysicsVolume.uc new file mode 100644 index 0000000..eaf1e12 --- /dev/null +++ b/Engine/Classes/DynamicPhysicsVolume.uc @@ -0,0 +1,40 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +/** + * This is a movable physics volume. It can be moved by matinee, being based on + * dynamic objects, etc. + */ +class DynamicPhysicsVolume extends PhysicsVolume + showcategories(Movement) + placeable; + +/** Is the volume enabled by default? */ +var() bool bEnabled; + +/** + * Overriden to set the default collision state. + */ +simulated event PostBeginPlay() +{ + Super.PostBeginPlay(); + + SetCollision(bEnabled, bBlockActors); +} + +defaultproperties +{ + Physics=PHYS_Interpolating + bStatic=false + + bAlwaysRelevant=true + bReplicateMovement=true + bOnlyDirtyReplication=true + RemoteRole=ROLE_None + + bColored=true + BrushColor=(R=100,G=255,B=255,A=255) + + bEnabled=true +} diff --git a/Engine/Classes/DynamicPylon.uc b/Engine/Classes/DynamicPylon.uc new file mode 100644 index 0000000..9be2398 --- /dev/null +++ b/Engine/Classes/DynamicPylon.uc @@ -0,0 +1,81 @@ +//============================================================================= +// DynamicPylon +// +// Represents a navigation mesh which is based on a moveable actor +// +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class DynamicPylon extends Pylon + placeable + native(inherit); + +// indicates this Pylon is moving (and thus not connected to the rest of the mesh) +var bool bMoving; + +function PostBeginPlay() +{ + super.PostBeginPlay(); + RebuildDynamicEdges(); +} +cpptext +{ + /** + * indicates whether static cross-pylon edges should be built for this pylon (pylons that move should return false) + */ + virtual UBOOL NeedsStaticCrossPylonEdgesBuilt(){ return FALSE; } + + + /** + * Called from UpdateComponentsInternal when a transform update is needed (when this pylon has moved) + */ + virtual void PylonMoved(); + + virtual void PreBeginPlay(); + + virtual void FindBase(); + + /** + * is this pylon compatible with dynamic obstacles? (e.g. moving meshes aren't) + */ + virtual UBOOL CompatibleWithDynamicObstacles(){return FALSE;} + + void ApplyDynamicSnap(); + +#if WITH_EDITOR + virtual void CheckForErrors(); +#endif +}; + +/** + * will wipe all dynamic edges for this pylon, and rebuild them from the currently position (use this sparingly, it's not cheap) + * good time to call this is after the pylon is finished moving, or comes to rest + */ +native function RebuildDynamicEdges(); + +/** + * will remove all dynamic edges associated with this pylon + */ +native function FlushDynamicEdges(); + +event StartedMoving() +{ + `log(self@GetFuncName()@"-----------"); + bMoving=true; + FlushDynamicEdges(); +} + +event StoppedMoving() +{ + `log(self@GetFuncName()@"-----------"); + bMoving=false; + RebuildDynamicEdges(); +} + +defaultproperties +{ + Begin Object Name=Sprite + Sprite=Texture2D'EditorResources.DynamicPylon' + End Object + + bStatic=FALSE +} diff --git a/Engine/Classes/DynamicSMActor.uc b/Engine/Classes/DynamicSMActor.uc new file mode 100644 index 0000000..3248649 --- /dev/null +++ b/Engine/Classes/DynamicSMActor.uc @@ -0,0 +1,297 @@ +//============================================================================= +// DynamicSMActor. +// A non-static version of StaticMeshActor. This class is abstract, but used as a +// base class for things like KActor and InterpActor. +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= + +class DynamicSMActor extends Actor + native + abstract; + +var() const editconst StaticMeshComponent StaticMeshComponent; +var() const editconst DynamicLightEnvironmentComponent LightEnvironment; +/** Used to replicate mesh to clients */ +var repnotify transient StaticMesh ReplicatedMesh; +/** used to replicate the materials in indices 0 and 1 */ +var repnotify MaterialInterface ReplicatedMaterial0, ReplicatedMaterial1; +/** used to replicate StaticMeshComponent.bForceStaticDecals */ +var repnotify bool bForceStaticDecals; + +/** Extra component properties to replicate */ +var repnotify vector ReplicatedMeshTranslation; +var repnotify rotator ReplicatedMeshRotation; +var repnotify vector ReplicatedMeshScale3D; + +/** If a Pawn can be 'based' on this KActor. If not, they will 'bounce' off when they try to. */ +var() bool bPawnCanBaseOn; +/** Pawn can base on this KActor if it is asleep -- Pawn will disable KActor physics while based */ +var() bool bSafeBaseIfAsleep; + +cpptext +{ + /** + * Function that gets called from within Map_Check to allow this actor to check itself + * for any potential errors and register them with map check dialog. + */ +#if WITH_EDITOR + virtual void CheckForErrors(); +#endif + +protected: +#if USE_GAMEPLAY_PROFILER + /** + * This function actually does the work for the GetProfilerAssetObject and is virtual. + * It should only be called from GetProfilerAssetObject as GetProfilerAssetObject is safe to call on NULL object pointers + */ + virtual UObject* GetProfilerAssetObjectInternal() const; +#endif + /** + * This function actually does the work for the GetDetailInfo and is virtual. + * It should only be called from GetDetailedInfo as GetDetailedInfo is safe to call on NULL object pointers + */ + virtual FString GetDetailedInfoInternal() const; +} + +replication +{ + if (bNetDirty) + ReplicatedMesh, ReplicatedMaterial0, ReplicatedMaterial1, ReplicatedMeshTranslation, ReplicatedMeshRotation, ReplicatedMeshScale3D, bForceStaticDecals; +} + +event PostBeginPlay() +{ + Super.PostBeginPlay(); + + if( StaticMeshComponent != none ) + { + ReplicatedMesh = StaticMeshComponent.StaticMesh; + bForceStaticDecals = StaticMeshComponent.bForceStaticDecals; + } +} + +simulated event ReplicatedEvent(name VarName) +{ + if (VarName == 'ReplicatedMesh') + { + if (ReplicatedMesh != StaticMeshComponent.StaticMesh) + { + // Enable the light environment if it is not already + LightEnvironment.bCastShadows = false; + LightEnvironment.SetEnabled(TRUE); + + StaticMeshComponent.SetStaticMesh(ReplicatedMesh); + } + } + else if (VarName == nameof(ReplicatedMaterial0)) + { + StaticMeshComponent.SetMaterial(0, ReplicatedMaterial0); + } + else if (VarName == nameof(ReplicatedMaterial1)) + { + StaticMeshComponent.SetMaterial(1, ReplicatedMaterial1); + } + else if (VarName == 'ReplicatedMeshTranslation') + { + StaticMeshComponent.SetTranslation(ReplicatedMeshTranslation); + } + else if (VarName == 'ReplicatedMeshRotation') + { + StaticMeshComponent.SetRotation(ReplicatedMeshRotation); + } + else if (VarName == 'ReplicatedMeshScale3D') + { + StaticmeshComponent.SetScale3D(ReplicatedMeshScale3D / 100.0); // remove compensation for replication rounding + } + else if (VarName == nameof(bForceStaticDecals)) + { + StaticMeshComponent.SetForceStaticDecals(bForceStaticDecals); + } + else + { + Super.ReplicatedEvent(VarName); + } +} + +function OnSetMesh(SeqAct_SetMesh Action) +{ + local bool bForce; + if( Action.MeshType == MeshType_StaticMesh ) + { + bForce = Action.bIsAllowedToMove == StaticMeshComponent.bForceStaticDecals || Action.bAllowDecalsToReattach; + + if( (Action.NewStaticMesh != None) && + (Action.NewStaticMesh != StaticMeshComponent.StaticMesh || bForce) ) + { + // Enable the light environment if it is not already + LightEnvironment.bCastShadows = false; + LightEnvironment.SetEnabled(TRUE); + // force decals on this mesh to be treated as movable or not (if False then decals will use fastpath) + bForceStaticDecals = !Action.bIsAllowedToMove; + StaticMeshComponent.SetForceStaticDecals(bForceStaticDecals); + // Don't allow decals to reattach since we are changing the static mesh + StaticMeshComponent.bAllowDecalAutomaticReAttach = Action.bAllowDecalsToReattach; + StaticMeshComponent.SetStaticMesh( Action.NewStaticMesh, Action.bAllowDecalsToReattach ); + StaticMeshComponent.bAllowDecalAutomaticReAttach = true; + ReplicatedMesh = Action.NewStaticMesh; + ForceNetRelevant(); + } + } +} + +function OnSetMaterial(SeqAct_SetMaterial Action) +{ + StaticMeshComponent.SetMaterial( Action.MaterialIndex, Action.NewMaterial ); + if (Action.MaterialIndex == 0) + { + ReplicatedMaterial0 = Action.NewMaterial; + ForceNetRelevant(); + } + else if (Action.MaterialIndex == 1) + { + ReplicatedMaterial1 = Action.NewMaterial; + ForceNetRelevant(); + } +} + +function SetStaticMesh(StaticMesh NewMesh, optional vector NewTranslation, optional rotator NewRotation, optional vector NewScale3D) +{ + StaticMeshComponent.SetStaticMesh(NewMesh); + StaticMeshComponent.SetTranslation(NewTranslation); + StaticMeshComponent.SetRotation(NewRotation); + if (!IsZero(NewScale3D)) + { + StaticMeshComponent.SetScale3D(NewScale3D); + ReplicatedMeshScale3D = NewScale3D * 100.0; // avoid rounding in replication code + } + ReplicatedMesh = NewMesh; + ReplicatedMeshTranslation = NewTranslation; + ReplicatedMeshRotation = NewRotation; + ForceNetRelevant(); +} + +/** + * Query to see if this DynamicSMActor can base the given Pawn + */ +simulated function bool CanBasePawn( Pawn P ) +{ + // Can base pawn if... + // Pawns can be based always OR + // Pawns can be based if physics is not awake + if( bPawnCanBaseOn || + (bSafeBaseIfAsleep && + StaticMeshComponent != None && + !StaticMeshComponent.RigidBodyIsAwake()) ) + { + return TRUE; + } + + return FALSE; +} + +/** + * If pawn is attached while asleep, turn off physics while pawn is on it + */ +event Attach( Actor Other ) +{ + local Pawn P; + + super.Attach( Other ); + + if( bSafeBaseIfAsleep ) + { + P = Pawn(Other); + if( P != None ) + { + SetPhysics( PHYS_None ); + } + } +} + +/** + * If pawn is detached, turn back on physics (make sure no other pawns are based on it) + */ +event Detach( Actor Other ) +{ + local int Idx; + local Pawn P, Test; + local bool bResetPhysics; + + super.Detach( Other ); + + P = Pawn(Other); + if( P != None ) + { + bResetPhysics = TRUE; + for( Idx = 0; Idx < Attached.Length; Idx++ ) + { + Test = Pawn(Attached[Idx]); + if( Test != None && Test != P ) + { + bResetPhysics = FALSE; + break; + } + } + + if( bResetPhysics ) + { + SetPhysics( PHYS_RigidBody ); + } + } +} + + +/** + * This will turn "off" the light environment so it will no longer update. + * This is useful for having a Timer call this once something has come to a stop and doesn't need 100% correct lighting. + **/ +simulated final function SetLightEnvironmentToNotBeDynamic() +{ + if( LightEnvironment != none ) + { + LightEnvironment.bDynamic = FALSE; + } +} + + +defaultproperties +{ + Begin Object Class=DynamicLightEnvironmentComponent Name=MyLightEnvironment + `if(`__TW_LIGHTING_MODIFICATIONS_) + bEnabled=False + `else + bEnabled=True + `endif + End Object + LightEnvironment=MyLightEnvironment + Components.Add(MyLightEnvironment) + + Begin Object Class=StaticMeshComponent Name=StaticMeshComponent0 + BlockRigidBody=false + LightEnvironment=MyLightEnvironment + bUsePrecomputedShadows=FALSE + End Object + CollisionComponent=StaticMeshComponent0 + StaticMeshComponent=StaticMeshComponent0 + Components.Add(StaticMeshComponent0) + + bEdShouldSnap=true + bWorldGeometry=false + bGameRelevant=true + RemoteRole=ROLE_SimulatedProxy + bPathColliding=true + + // DynamicSMActor do not have collision as a default. Having collision on them + // can be very slow (e.g. matinees where the matinee is controlling where + // the actors move and then they are trying to collide also!) + // The overall idea is that it is really easy to see when something doesn't + // collide correct and rectify it. On the other hand, it is hard to see + // something testing collision when it should not be while you wonder where + // your framerate went. + + bCollideActors=false + bPawnCanBaseOn=true + + // Automatically shadow parent to whatever this actor is attached to by default + bShadowParented=true +} diff --git a/Engine/Classes/DynamicSMActor_Spawnable.uc b/Engine/Classes/DynamicSMActor_Spawnable.uc new file mode 100644 index 0000000..525cb98 --- /dev/null +++ b/Engine/Classes/DynamicSMActor_Spawnable.uc @@ -0,0 +1,11 @@ +/** + * Concrete version of DynamicSMActor for spawning mid-game. + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class DynamicSMActor_Spawnable extends DynamicSMActor; + +defaultproperties +{ + bCollideActors=TRUE + bBlockActors=TRUE +} diff --git a/Engine/Classes/DynamicTriggerVolume.uc b/Engine/Classes/DynamicTriggerVolume.uc new file mode 100644 index 0000000..35acb60 --- /dev/null +++ b/Engine/Classes/DynamicTriggerVolume.uc @@ -0,0 +1,39 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +/** + * This is a movable trigger volume. It can be moved by matinee, being based on + * dynamic objects, etc. + */ +class DynamicTriggerVolume extends TriggerVolume + showcategories(Movement) + placeable; + +/** Is the volume enabled by default? */ +var() bool bEnabled; + +/** + * Overriden to set the default collision state. + */ +simulated event PostBeginPlay() +{ + Super.PostBeginPlay(); + + SetCollision(bEnabled, bBlockActors); +} + +defaultproperties +{ + bStatic=false + + bAlwaysRelevant=true + bReplicateMovement=true + bOnlyDirtyReplication=true + RemoteRole=ROLE_None + + bColored=true + BrushColor=(R=100,G=255,B=255,A=255) + + bEnabled=true +} diff --git a/Engine/Classes/EdCoordSystem.uc b/Engine/Classes/EdCoordSystem.uc new file mode 100644 index 0000000..2656be8 --- /dev/null +++ b/Engine/Classes/EdCoordSystem.uc @@ -0,0 +1,23 @@ +/* epic =============================================== +* class EdCoordSystem +* +* A custom coordinate system used by the editor. +* + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class EdCoordSystem extends Object + hidecategories(Object) + editinlinenew + native; + +/** The matrix that defines this coordinate system. */ +var() matrix M; + +/* A human readable description for use in the editor UI. */ +var() string Desc; + +defaultproperties +{ + Desc="Coord System" + M=(XPlane=(X=1,Y=0,Z=0,W=0),YPlane=(X=0,Y=1,Z=0,W=0),ZPlane=(X=0,Y=0,Z=1,W=0),WPlane=(X=0,Y=0,Z=0,W=1)) +} diff --git a/Engine/Classes/EditorLinkSelectionInterface.uc b/Engine/Classes/EditorLinkSelectionInterface.uc new file mode 100644 index 0000000..10e0670 --- /dev/null +++ b/Engine/Classes/EditorLinkSelectionInterface.uc @@ -0,0 +1,17 @@ +//============================================================================= +// EditorLinkSelectionInterface +// +// Implement this interface to allow this object to perform special handling when 'linkselected' or 'unlinkselected' +// is called from the editor (for example, if the user has two objects selected and calls linkselected and you want the objects +// to bind themselves together in some fashion) +// +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +interface EditorLinkSelectionInterface + native; + +cpptext +{ + virtual void LinkSelection(USelection* SelectedObjects){} + virtual void UnLinkSelection(USelection* SelectedObjects){} +} \ No newline at end of file diff --git a/Engine/Classes/Emitter.uc b/Engine/Classes/Emitter.uc new file mode 100644 index 0000000..3cef6b0 --- /dev/null +++ b/Engine/Classes/Emitter.uc @@ -0,0 +1,351 @@ +//============================================================================= +// Emitter actor class. +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class Emitter extends Actor + native + placeable; + +var() editconst const ParticleSystemComponent ParticleSystemComponent; +var() editconst const DynamicLightEnvironmentComponent LightEnvironment; +var bool bDestroyOnSystemFinish; + +var() bool bPostUpdateTickGroup; + +/** used to update status of toggleable level placed emitters on clients */ +var repnotify bool bCurrentlyActive; + +`if(`__TW_) +/** Allows particle emitters to omit depth testing (by setting to false) */ +var transient bool bDepthTestEnabled; +/** Allow this emitter to be rendered in the depth pass and be used as an occluder */ +var(Rendering) const bool bUseAsOccluder; +`endif + +struct CheckpointRecord +{ + var bool bIsActive; +}; + +replication +{ + if (bNoDelete) + bCurrentlyActive; +} + +cpptext +{ + void SetTemplate(UParticleSystem* NewTemplate, UBOOL bDestroyOnFinish=false); + void AutoPopulateInstanceProperties(); + + // AActor interface. + virtual void Spawned(); + virtual void PostBeginPlay(); + /** + * ticks the actor + * @param DeltaTime The time slice of this tick + * @param TickType The type of tick that is happening + * + * @return TRUE if the actor was ticked, FALSE if it was aborted (e.g. because it's in stasis) + */ + virtual UBOOL Tick( FLOAT DeltaTime, enum ELevelTick TickType ); + + /** + * Function that gets called from within Map_Check to allow this actor to check itself + * for any potential errors and register them with map check dialog. + */ +#if WITH_EDITOR + virtual void CheckForErrors(); +#endif + +#if USE_GAMEPLAY_PROFILER + /** + * This function actually does the work for the GetProfilerAssetObject and is virtual. + * It should only be called from GetProfilerAssetObject as GetProfilerAssetObject is safe to call on NULL object pointers + */ + virtual UObject* GetProfilerAssetObjectInternal() const; +#endif + + /** + * This will return detail info about this specific object. (e.g. AudioComponent will return the name of the cue, + * ParticleSystemComponent will return the name of the ParticleSystem) The idea here is that in many places + * you have a component of interest but what you really want is some characteristic that you can use to track + * down where it came from. + * + */ + virtual FString GetDetailedInfoInternal() const; + + /** + * Called to reset the emitter actor in the level. + * Intended for use in editor only + */ + void ResetInLevel(); + +#if __TW_ + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); +#endif +} + +native noexport event SetTemplate(ParticleSystem NewTemplate, optional bool bDestroyOnFinish); + +simulated event PostBeginPlay() +{ + Super.PostBeginPlay(); + + // Let them die quickly on a dedicated server + if (WorldInfo.NetMode == NM_DedicatedServer && (RemoteRole == ROLE_None || bNetTemporary)) + { + LifeSpan = 0.2; +`if(`__TW_PERFORMANCE_) + // Lifespan won't do us much good for NoDelete actors! + if ( bNoDelete ) + { + SetTickIsDisabled(true); + } +`endif + } + + // Set Notification Delegate + if (ParticleSystemComponent != None) + { + ParticleSystemComponent.OnSystemFinished = OnParticleSystemFinished; + bCurrentlyActive = ParticleSystemComponent.bAutoActivate; + +`if(`__TW_) + // Allow certain emitters to be rendered in the depth pass and be used as occluders + ParticleSystemComponent.bUseAsOccluder = bUseAsOccluder; + ReattachComponent(ParticleSystemComponent); +`endif + } +} + +simulated event ReplicatedEvent(name VarName) +{ + if (VarName == 'bCurrentlyActive') + { + ParticleSystemComponent.SetActive(bCurrentlyActive); + } + else + { + Super.ReplicatedEvent(VarName); + } +} + +simulated function OnParticleSystemFinished(ParticleSystemComponent FinishedComponent) +{ + if (bDestroyOnSystemFinish) + { + Lifespan = 0.0001f; + } + bCurrentlyActive = false; +} + +/** + * Handling Toggle event from Kismet. + */ +function OnToggle(SeqAct_Toggle action) +{ + // Turn ON + if (action.InputLinks[0].bHasImpulse) + { + ParticleSystemComponent.ActivateSystem(); + bCurrentlyActive = TRUE; + } + // Turn OFF + else if (action.InputLinks[1].bHasImpulse) + { + ParticleSystemComponent.DeactivateSystem(); + bCurrentlyActive = FALSE; + } + // Toggle + else if (action.InputLinks[2].bHasImpulse) + { + // If spawning is suppressed or we aren't turned on at all, activate. + if (ParticleSystemComponent.bSuppressSpawning || !bCurrentlyActive) + { + ParticleSystemComponent.ActivateSystem(); + bCurrentlyActive = TRUE; + } + else + { + ParticleSystemComponent.DeactivateSystem(); + bCurrentlyActive = FALSE; + } + } + ParticleSystemComponent.LastRenderTime = WorldInfo.TimeSeconds; + ForceNetRelevant(); + + if (RemoteRole != ROLE_None) + { + // force replicate flag if necessary + SetForcedInitialReplicatedProperty(Property'Engine.Emitter.bCurrentlyActive', (bCurrentlyActive == default.bCurrentlyActive)); + } +} + +/** + * Handling ParticleEventGenerator event from Kismet. + * - Does nothing... just here to stop Kismet from complaining + */ +function OnParticleEventGenerator(SeqAct_ParticleEventGenerator action) +{ +} + +simulated function ShutDown() +{ + Super.ShutDown(); + + bCurrentlyActive = false; +} + +simulated function SetFloatParameter(name ParameterName, float Param) +{ + if (ParticleSystemComponent != none) + ParticleSystemComponent.SetFloatParameter(ParameterName, Param); + else + `log("Warning: Attempting to set a parameter on "$self$" when the PSC does not exist"); +} + +simulated function SetVectorParameter(name ParameterName, vector Param) +{ + if (ParticleSystemComponent != none) + ParticleSystemComponent.SetVectorParameter(ParameterName, Param); + else + `log("Warning: Attempting to set a parameter on "$self$" when the PSC does not exist"); +} + +simulated function SetColorParameter(name ParameterName, color Param) +{ + if (ParticleSystemComponent != none) + ParticleSystemComponent.SetColorParameter(ParameterName, Param); + else + `log("Warning: Attempting to set a parameter on "$self$" when the PSC does not exist"); +} + +simulated function SetExtColorParameter(name ParameterName, byte Red, byte Green, byte Blue, byte Alpha) +{ + local color c; + + if (ParticleSystemComponent != none) + { + c.r = Red; + c.g = Green; + c.b = Blue; + c.a = Alpha; + ParticleSystemComponent.SetColorParameter(ParameterName, C); + } + else + `log("Warning: Attempting to set a parameter on "$self$" when the PSC does not exist"); +} + + +simulated function SetActorParameter(name ParameterName, actor Param) +{ + if (ParticleSystemComponent != none) + ParticleSystemComponent.SetActorParameter(ParameterName, Param); + else + `log("Warning: Attempting to set a parameter on "$self$" when the PSC does not exist"); +} + +/** + * Kismet handler for setting particle instance parameters. + */ +simulated function OnSetParticleSysParam(SeqAct_SetParticleSysParam Action) +{ + local int Idx, ParamIdx; + if (ParticleSystemComponent != None && + Action.InstanceParameters.Length > 0) + { + for (Idx = 0; Idx < Action.InstanceParameters.Length; Idx++) + { + if (Action.InstanceParameters[Idx].ParamType != PSPT_None) + { + // look for an existing entry + ParamIdx = ParticleSystemComponent.InstanceParameters.Find('Name',Action.InstanceParameters[Idx].Name); + // create one if necessary + if (ParamIdx == -1) + { + ParamIdx = ParticleSystemComponent.InstanceParameters.Length; + ParticleSystemComponent.InstanceParameters.Length = ParamIdx + 1; + } + // update the instance parm + ParticleSystemComponent.InstanceParameters[ParamIdx] = Action.InstanceParameters[Idx]; + if (Action.bOverrideScalar) + { + ParticleSystemComponent.InstanceParameters[ParamIdx].Scalar = Action.ScalarValue; + } + } + } + } +} + +function bool ShouldSaveForCheckpoint() +{ + return (bNoDelete && RemoteRole != ROLE_None); +} + +function CreateCheckpointRecord(out CheckpointRecord Record) +{ + Record.bIsActive = bCurrentlyActive; +} + +function ApplyCheckpointRecord(const out CheckpointRecord Record) +{ + bCurrentlyActive = Record.bIsActive; + if (bCurrentlyActive) + { + ParticleSystemComponent.ActivateSystem(); + } + else + { + ParticleSystemComponent.DeactivateSystem(); + } + ForceNetRelevant(); +} + +/** Function used to have the emitter hide itself and put itself into stasis **/ +simulated function HideSelf(); + + +defaultproperties +{ + // Visual things should be ticked in parallel with physics + TickGroup=TG_DuringAsyncWork + + Begin Object Class=SpriteComponent Name=Sprite + Sprite=Texture2D'EditorResources.S_Emitter' + HiddenGame=True + AlwaysLoadOnClient=False + AlwaysLoadOnServer=False + bIsScreenSizeScaled=True + ScreenSize=0.0025 + SpriteCategoryName="Effects" + End Object + Components.Add(Sprite) + + Begin Object Class=ParticleSystemComponent Name=ParticleSystemComponent0 + SecondsBeforeInactive=1 + End Object + ParticleSystemComponent=ParticleSystemComponent0 + Components.Add(ParticleSystemComponent0) + + Begin Object Class=ArrowComponent Name=ArrowComponent0 + ArrowColor=(R=0,G=255,B=128) + ArrowSize=1.5 + AlwaysLoadOnClient=False + AlwaysLoadOnServer=False + bTreatAsASprite=True + SpriteCategoryName="Effects" + End Object + Components.Add(ArrowComponent0) + + bEdShouldSnap=true + bHardAttach=true + bGameRelevant=true + bNoDelete=true + +`if(`__TW_) + bDepthTestEnabled=true +`endif + + SupportedEvents.Add(class'SeqEvent_ParticleEvent') +} diff --git a/Engine/Classes/EmitterCameraLensEffectBase.uc b/Engine/Classes/EmitterCameraLensEffectBase.uc new file mode 100644 index 0000000..8e4964e --- /dev/null +++ b/Engine/Classes/EmitterCameraLensEffectBase.uc @@ -0,0 +1,120 @@ +/** + * Base class for Camera Lens Effects. Needed so we can have AnimNotifies be able to show camera effects + * in a nice drop down + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class EmitterCameraLensEffectBase extends Emitter + abstract + dependson(Emitter) + native(Particle); + +/** Particle System to use */ +var protected ParticleSystem PS_CameraEffect; + +/** The effect to use for non extreme content */ +var protected ParticleSystem PS_CameraEffectNonExtremeContent; + +/** In order to get the particle effect looking correct we need to have a base FOV which we just to move the particle closer/further from the camera **/ +var float BaseFOV; + + +/** + * How far in front of the camera this emitter should live, assuming an FOV of 80 degrees. + * Note that the actual distance will be automatically adjusted to account for the actual FOV. + */ +var() protected const float DistFromCamera; + +/** TRUE if multiple instances of this emitter can exist simultaneously, FALSE otherwise. */ +var() protectedwrite const bool bAllowMultipleInstances; + +/** + * If an emitter class in this array is currently playing, do not play this effect. + * Useful for preventing multiple similar or expensive camera effects from playing simultaneously. + */ +var array > EmittersToTreatAsSame; + +/** Camera this emitter is attached to, will be notified when emitter is destroyed */ +var protected transient Camera BaseCamera; + +function Destroyed() +{ + if (BaseCamera != None) + { + BaseCamera.RemoveCameraLensEffect(self); + } + super.Destroyed(); +} + +/** Tell the emitter what camera it is attached to. */ +function RegisterCamera(Camera C) +{ + BaseCamera = C; +} + +/** Called when this emitter is re-triggered, for bAllowMultipleInstances=FALSE emitters. */ +function NotifyRetriggered(); + + + + + + simulated function PostBeginPlay() +{ + ParticleSystemComponent.SetDepthPriorityGroup(SDPG_Foreground); + + Super.PostBeginPlay(); + + ActivateLensEffect(); +} + + +/** This will actually activate the lens Effect. We want this separated from PostBeginPlay so we can cache these emitters **/ +simulated function ActivateLensEffect() +{ + local ParticleSystem PSToActuallySpawn; + + // only play the camera effect on clients + if( WorldInfo.NetMode != NM_DedicatedServer ) + { + if( WorldInfo.GRI.ShouldShowGore() ) + { + PSToActuallySpawn = PS_CameraEffect; + } + else + { + PSToActuallySpawn = PS_CameraEffectNonExtremeContent; + } + + if( PSToActuallySpawn != None ) + { + SetTemplate( PS_CameraEffect, bDestroyOnSystemFinish ); + } + } +} + +/** Given updated camera information, adjust this effect to display appropriately. */ +simulated native function UpdateLocation(const out vector CamLoc, const out rotator CamRot, float CamFOVDeg); + + +DefaultProperties +{ + DistFromCamera=90 + LifeSpan=10.0f + BaseFOV=80.0f + + // makes sure I tick after the camera + TickGroup=TG_PostAsyncWork + + bDestroyOnSystemFinish=TRUE + bNetInitialRotation=TRUE + bNoDelete=FALSE + + Begin Object Name=ParticleSystemComponent0 + bOnlyOwnerSee=TRUE + SecondsBeforeInactive=0.0 + End Object + + Components.Remove(ArrowComponent0) + Components.Remove(Sprite) +} diff --git a/Engine/Classes/EmitterPool.uc b/Engine/Classes/EmitterPool.uc new file mode 100644 index 0000000..f03c069 --- /dev/null +++ b/Engine/Classes/EmitterPool.uc @@ -0,0 +1,213 @@ +/** + * this class manages a pool of ParticleSystemComponents + * it is meant to be used for single shot effects spawned during gameplay + * to reduce object overhead that would otherwise be caused by spawning dozens of Emitters + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class EmitterPool extends Actor + native + transient + config(Game); + +/** template to base pool components off of - should not be used for effects or attached to anything */ +var protected ParticleSystemComponent PSCTemplate; + +/** components currently in the pool */ +var transient const array PoolComponents; +/** components currently active */ +var transient array ActiveComponents; +// NVCHANGE_BEGIN: JCAO - Add surrogate emitter for flex +/** surrogate flex emitters */ +var transient ParticleSystemComponent FlexSurrogateComponent; +// NVCHANGE_END: JCAO - Add surrogate emitter for flex +/** maximum allowed active components - if this is greater than 0 and is exceeded, the oldest active effect is taken */ +var int MaxActiveEffects; + +/** option to log out the names of all active effects when the pool overflows */ +var globalconfig bool bLogPoolOverflow; +var globalconfig bool bLogPoolOverflowList; + +/** list of components that should be relative to an Actor */ +struct native EmitterBaseInfo +{ + var ParticleSystemComponent PSC; + var Actor Base; + var vector RelativeLocation; + var rotator RelativeRotation; + var bool bInheritBaseScale; +}; +var transient array RelativePSCs; + +/** + * The amount of time to allow the SMC and MIC arrays to be beyond their ideals. + */ +var float SMC_MIC_ReductionTime; +var transient float SMC_MIC_CurrentReductionTime; + +/** + * The ideal number of StaticMeshComponents and MaterialInstanceConstants. + * If their counts are greater than this for more than ReductionTime, then + * they will be chopped down to their respective settings. + */ +var int IdealStaticMeshComponents; +var int IdealMaterialInstanceConstants; + +/** The free StaticMeshComponents used by emitters in this pool */ +var private transient const array FreeSMComponents; + +/** The free MaterialInstanceConstants used by emitters in this pool */ +var private transient const array FreeMatInstConsts; + +cpptext +{ + virtual void TickSpecial(FLOAT DeltaTime); +} + +/** set to each pool component's finished delegate to return it to the pool + * for custom lifetime PSCs, must be called manually when done with the component + */ +native function OnParticleSystemFinished(ParticleSystemComponent PSC); + +/** Cleans up the pool components, removing any unused + * + * @param bClearActive If TRUE, clear active as well as inactive pool components + */ +native final function ClearPoolComponents(bool bClearActive = false); + +/** internal - detaches the given PSC and returns it to the pool */ +protected native final function ReturnToPool(ParticleSystemComponent PSC); + +/** internal - moves the SMComponents from given PSC to the pool free list */ +protected native final function FreeStaticMeshComponents(ParticleSystemComponent PSC); + +/** + * internal - retrieves a SMComponent from the pool free list + * + * @param bCreateNewObject If TRUE, create an SMC w/ the pool as its outer + * + * @return StaticMeshComponent The SMC, NULL if none was available/created + */ +protected native final function StaticMeshComponent GetFreeStaticMeshComponent(bool bCreateNewObject = true); + +/** internal - moves the MIConstants from given SMComponent to the pool free list */ +protected native final function FreeMaterialInstanceConstants(StaticMeshComponent SMC); + +/** +* internal - retrieves a MaterialInstanceConstant from the pool free list +* +* @param bCreateNewObject If TRUE, create an MIC w/ the pool as its outer +* +* @return MaterialInstanceConstant The MIC, NULL if none was available/created +*/ +protected native final function MaterialInstanceConstant GetFreeMatInstConsts(bool bCreateNewObject = true); + +/** internal - helper for spawning functions + * gets a component from the appropriate pool array (checks PerEmitterPools) + * includes creating a new one if necessary as well as taking one from the active list if the max number active has been exceeded + * @return the ParticleSystemComponent to use + */ +protected native final function ParticleSystemComponent GetPooledComponent(ParticleSystem EmitterTemplate, bool bAutoActivate); + +/** plays the specified effect at the given location and rotation, taking a component from the pool or creating as necessary + * @note: the component is returned so the caller can perform any additional modifications (parameters, etc), + * but it shouldn't keep the reference around as the component will be returned to the pool as soon as the effect is complete + * @param EmitterTemplate - particle system to create + * @param SpawnLocation - location to place the effect in world space + * @param SpawnRotation (opt) - rotation to place the effect in world space + * @param AttachToActor (opt) - if specified, component will move along with this Actor + * @param InInstigator (opt) - if specified and the particle system is lit, the new component will only share particle light environments with other components with matching instigators + * @param MaxDLEPooledReuses (opt) - if specified, limits how many components can use the same particle light environment. This is effectively a tradeoff between performance and particle lighting update rate. + * @param bInheritScaleFromBase (opt) - if TRUE scale from the base actor will be applied + * @return the ParticleSystemComponent the effect will use + */ +native function ParticleSystemComponent SpawnEmitter(ParticleSystem EmitterTemplate, vector SpawnLocation, optional rotator SpawnRotation, optional Actor AttachToActor, optional Actor InInstigator, optional int MaxDLEPooledReuses, optional bool bInheritScaleFromBase); + +/** spawns a particle system attached to a SkeletalMeshComponent instead of to another Actor or to nothing + * as with SpawnEmitter(), the caller should avoid persistent references to the returned component as it will + * get automatically reclaimed when the effect is complete + * @note: if the owning Actor is destroyed before the effect completes, the ParticleSystemComponent will end up + * being marked pending kill and therefore eventually destroyed as well. The pool handles this gracefully, + * although it's obviously suboptimal. + * @param EmitterTemplate - particle system to create + * @param Mesh - mesh component to attach to + * @param AttachPointName - bone or socket to attach to + * @param bAttachToSocket (opt) - whether AttachPointName is a socket or bone name + * @param RelativeLoc (opt) - offset from bone location to place the effect (not used when attaching to socket) + * @param RelativeRot (opt) - offset from bone rotation to place the effect (not used when attaching to socket) + * @return the ParticleSystemComponent the effect will use + */ +native function ParticleSystemComponent SpawnEmitterMeshAttachment( ParticleSystem EmitterTemplate, + SkeletalMeshComponent Mesh, name AttachPointName, optional bool bAttachToSocket, + optional vector RelativeLoc, optional rotator RelativeRot ); + +/** spawns a pooled component that has a custom lifetime (controlled by the caller) + * the caller is responsible for attaching/detaching the component + * as well as calling our OnParticleSystemFinished() function when it is done with the component + * the pool may take the component back early - if it does, it will trigger the component's OnSystemFinished delegate + * so the caller can guarantee that it will be triggered + * @param EmitterTemplate - particle system to create + * @param bSkipAutoActivate - if TRUE, do not autoactivate the component when retrieving it from the pool + * @return the ParticleSystemComponent to use + */ +native function ParticleSystemComponent SpawnEmitterCustomLifetime(ParticleSystem EmitterTemplate, optional bool bSkipAutoActivate); + +// NVCHANGE_BEGIN: JCAO - Add surrogate emitter for flex +simulated function PostBeginPlay() +{ + // not using defaultproperties solves two problems: Template having stale data in it from the last level/PIE session, + // and LODSettings array being cleared in PostLoad when running the editor. + local ParticleSystem FlexParticleTemplate; + local DynamicLightEnvironmentComponent FlexLightEnvironment; + local ParticleSystemComponent SurrogateComponentTemplate; + local LightingChannelContainer LightingChannels; + + SurrogateComponentTemplate = new() class'ParticleSystemComponent'; + SurrogateComponentTemplate.SecondsBeforeInactive=9999999999999; + SurrogateComponentTemplate.CastShadow=false; + SurrogateComponentTemplate.bUseAsOccluder=true; + // SPH fluid was rendered at first + SurrogateComponentTemplate.TranslucencySortPriority=0; + + FlexParticleTemplate = new(SurrogateComponentTemplate) class'ParticleSystem'; + FlexParticleTemplate.LODSettings.Add(1); + FlexParticleTemplate.LODSettings[0].bLit=true; + FlexParticleTemplate.LODDistances.Add(1); + FlexParticleTemplate.LODDistances[0] = 0; + + FlexLightEnvironment = new(SurrogateComponentTemplate) SurrogateComponentTemplate.LightEnvironmentClass; + FlexLightEnvironment.SetEnabled(false); + SurrogateComponentTemplate.SetLightEnvironment(FlexLightEnvironment); + + LightingChannels.Indoor = true; + LightingChannels.Outdoor = true; + LightingChannels.bInitialized = true; + SurrogateComponentTemplate.SetLightingChannels(LightingChannels); + + FlexSurrogateComponent = new(self) class'ParticleSystemComponent'(SurrogateComponentTemplate); + FlexSurrogateComponent.SetTemplate(new(FlexSurrogateComponent) class'ParticleSystem'(FlexParticleTemplate)); + AttachComponent(FlexSurrogateComponent); + + Super.PostBeginPlay(); +} +// NVCHANGE_END: JCAO - Add surrogate emitter for flex + +defaultproperties +{ + Begin Object Class=ParticleSystemComponent Name=ParticleSystemComponent0 + AbsoluteTranslation=true + AbsoluteRotation=true + SecondsBeforeInactive=0.0 + End Object + PSCTemplate=ParticleSystemComponent0 + + TickGroup=TG_DuringAsyncWork + + SMC_MIC_ReductionTime=2.5 + IdealStaticMeshComponents=250 + IdealMaterialInstanceConstants=250 + +`if(`__TW_) + //MaxActiveEffects=200 +`endif +} diff --git a/Engine/Classes/EmitterSpawnable.uc b/Engine/Classes/EmitterSpawnable.uc new file mode 100644 index 0000000..de7f741 --- /dev/null +++ b/Engine/Classes/EmitterSpawnable.uc @@ -0,0 +1,52 @@ +/** + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + + +class EmitterSpawnable extends Emitter + notplaceable; + +var repnotify ParticleSystem ParticleTemplate; + +replication +{ + if (bNetInitial) + ParticleTemplate; +} + +simulated event SetTemplate(ParticleSystem NewTemplate, optional bool bDestroyOnFinish) +{ + Super.SetTemplate(NewTemplate, bDestroyOnFinish); + + ParticleTemplate = NewTemplate; +} + +simulated event ReplicatedEvent(name VarName) +{ + if (VarName == 'ParticleTemplate') + { + SetTemplate(ParticleTemplate, bDestroyOnSystemFinish); + ParticleSystemComponent.ActivateSystem(); + if (ParticleTemplate == None && bDestroyOnSystemFinish) + { + // prevent emitter from hanging around forever with no template + Destroy(); + } + } + else + { + Super.ReplicatedEvent(VarName); + } +} + +defaultproperties +{ + Begin Object Name=ParticleSystemComponent0 + SecondsBeforeInactive=0 + End Object + + bNoDelete=false + bDestroyOnSystemFinish=true + bNetTemporary=true +} diff --git a/Engine/Classes/Engine.uc b/Engine/Classes/Engine.uc new file mode 100644 index 0000000..c098c66 --- /dev/null +++ b/Engine/Classes/Engine.uc @@ -0,0 +1,1205 @@ +//============================================================================= +// Engine: The base class of the global application object classes. +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class Engine extends Subsystem + native(GameEngine) + abstract + config(Engine) + transient; + +// Fonts. +var private Font TinyFont; +var globalconfig string TinyFontName; + +var private Font SmallFont; +var globalconfig string SmallFontName; + +var private Font MediumFont; +var globalconfig string MediumFontName; + +var private Font LargeFont; +var globalconfig string LargeFontName; + +var private Font SubtitleFont; +var globalconfig string SubtitleFontName; + +/** Any additional fonts that script may use without hard-referencing the font. */ +var private array AdditionalFonts; +var globalconfig array AdditionalFontNames; + +/** The class to use for the game console. */ +var class ConsoleClass; +var globalconfig string ConsoleClassName; + +/** The class to use for the game viewport client. */ +var class GameViewportClientClass; +var globalconfig string GameViewportClientClassName; + +/** The class to use for managing the global data stores */ +var class DataStoreClientClass; +var globalconfig string DataStoreClientClassName; + +/** The class to use for local players. */ +var class LocalPlayerClass; +var config string LocalPlayerClassName; + +/** The material used when no material is explicitly applied. */ +var Material DefaultMaterial; +var globalconfig string DefaultMaterialName; + +/** The decal material used for fallback case of decals */ +var Material DefaultDecalMaterial; +var globalconfig string DefaultDecalMaterialName; + +/** A global default texture. */ +var Texture DefaultTexture; +var globalconfig string DefaultTextureName; + +/** The material used to render wireframe meshes. */ +var Material WireframeMaterial; +var globalconfig string WireframeMaterialName; + +/** A textured material with an instance parameter for the texture. */ +var Material EmissiveTexturedMaterial; +var globalconfig string EmissiveTexturedMaterialName; + +/** A translucent material used to render things in geometry mode. */ +var Material GeomMaterial; +var globalconfig string GeomMaterialName; + +/** The default fog volume material */ +var Material DefaultFogVolumeMaterial; +var globalconfig string DefaultFogVolumeMaterialName; + +/** Material used for drawing a tick mark. */ +var Material TickMaterial; +var globalconfig string TickMaterialName; + +/** Material used for drawing a cross mark. */ +var Material CrossMaterial; +var globalconfig string CrossMaterialName; + +/** Material used for visualizing level membership in lit viewport modes. */ +var Material LevelColorationLitMaterial; +var globalconfig string LevelColorationLitMaterialName; + +/** Material used for visualizing level membership in unlit viewport modes. */ +var Material LevelColorationUnlitMaterial; +var globalconfig string LevelColorationUnlitMaterialName; + +/** Material used for visualizing lighting only w/ lightmap texel density. */ +var Material LightingTexelDensityMaterial; +var globalconfig string LightingTexelDensityName; + +/** Material used for visualizing level membership in lit viewport modes. Uses shading to show axis directions. */ +var Material ShadedLevelColorationLitMaterial; +var globalconfig string ShadedLevelColorationLitMaterialName; + +/** Material used for visualizing level membership in unlit viewport modes. Uses shading to show axis directions. */ +var Material ShadedLevelColorationUnlitMaterial; +var globalconfig string ShadedLevelColorationUnlitMaterialName; + +/** Material used to indicate that the associated BSP surface should be removed. */ +var Material RemoveSurfaceMaterial; +var globalconfig string RemoveSurfaceMaterialName; + +/** Material that renders vertex colour as emissive. */ +var Material VertexColorMaterial; +var globalconfig string VertexColorMaterialName; + +/** Material for visualizing vertex colors on meshes in the scene (color only, no alpha) */ +var Material VertexColorViewModeMaterial_ColorOnly; +var globalconfig string VertexColorViewModeMaterialName_ColorOnly; + +/** Material for visualizing vertex colors on meshes in the scene (alpha channel as color) */ +var Material VertexColorViewModeMaterial_AlphaAsColor; +var globalconfig string VertexColorViewModeMaterialName_AlphaAsColor; + +/** Material for visualizing vertex colors on meshes in the scene (red only) */ +var Material VertexColorViewModeMaterial_RedOnly; +var globalconfig string VertexColorViewModeMaterialName_RedOnly; + +/** Material for visualizing vertex colors on meshes in the scene (green only) */ +var Material VertexColorViewModeMaterial_GreenOnly; +var globalconfig string VertexColorViewModeMaterialName_GreenOnly; + +/** Material for visualizing vertex colors on meshes in the scene (blue only) */ +var Material VertexColorViewModeMaterial_BlueOnly; +var globalconfig string VertexColorViewModeMaterialName_BlueOnly; + +/** Material used to render game stat heatmaps. */ +var Material HeatmapMaterial; +var globalconfig string HeatmapMaterialName; + +/** Material used to render bone weights on skel meshes */ +var Material BoneWeightMaterial; +var globalconfig string BoneWeightMaterialName; + +/** Material used to render tangents on skel meshes */ +var Material TangentColorMaterial; +var globalconfig string TangentColorMaterialName; + +/** The mobile emulation material for Additive. */ +var Material MobileEmulationMasterMaterial; +var globalconfig string MobileEmulationMasterMaterialName; + +/** Material used to render the low detail version of procedural buildings */ +var Material ProcBuildingSimpleMaterial; +var globalconfig string ProcBuildingSimpleMaterialName; + +/** Mesh used when we need a quad */ +var StaticMesh BuildingQuadStaticMesh; +var globalconfig string BuildingQuadStaticMeshName; + +/** Roughly how many texels per world unit when generating a building LOD color texture */ +var globalconfig float ProcBuildingLODColorTexelsPerWorldUnit; + +/** Roughly how many texels per world unit when generating a building LOD lighting texture */ +var globalconfig float ProcBuildingLODLightingTexelsPerWorldUnit; + +/** Maximum size of a building LOD color texture */ +var globalconfig int MaxProcBuildingLODColorTextureSize; + +/** Maximum size of a building LOD lighting texture */ +var globalconfig int MaxProcBuildingLODLightingTextureSize; + +/** Whether to crop building LOD textures to rectangular textures to reduce wasted memory */ +var globalconfig bool UseProcBuildingLODTextureCropping; + +/** Whether to force use of power-of-two LOD textures (uses more memory, but may have better performance) */ +var globalconfig bool ForcePowerOfTwoProcBuildingLODTextures; + + +/** True if we should combine light/shadow maps together if they're very similar to one another */ +var globalconfig bool bCombineSimilarMappings; + +/** Maximum root mean square deviation of the image difference allowed for mappings to be combined. Requires bCombineSimilarLightAndShadowMappings to be enabled. */ +var globalconfig float MaxRMSDForCombiningMappings; + +/** Size of the texture generated by ImageReflectionSceneCapture actors. */ +var globalconfig int ImageReflectionTextureSize; + +var globalconfig LinearColor LightingOnlyBrightness; + +/** The colors used to render light complexity. */ +var globalconfig array LightComplexityColors; + +/** The colors used to render shader complexity. */ +var globalconfig array ShaderComplexityColors; + +/** +* Complexity limits for the various complexity viewmode combinations. +* These limits are used to map instruction counts to ShaderComplexityColors. +*/ +var globalconfig float MaxPixelShaderAdditiveComplexityCount; + +/** Range for the texture density viewmode. */ +var globalconfig float MinTextureDensity; +var globalconfig float IdealTextureDensity; +var globalconfig float MaxTextureDensity; + +/** Range for the lightmap density viewmode. */ +/** Minimum lightmap density value for coloring. */ +var globalconfig float MinLightMapDensity; +/** Ideal lightmap density value for coloring. */ +var globalconfig float IdealLightMapDensity; +/** Maximum lightmap density value for coloring. */ +var globalconfig float MaxLightMapDensity; +/** If TRUE, then render grayscale density. */ +var globalconfig bool bRenderLightMapDensityGrayscale; +/** The scale factor when rendering grayscale density. */ +var globalconfig float RenderLightMapDensityGrayscaleScale; +/** The scale factor when rendering color density. */ +var globalconfig float RenderLightMapDensityColorScale; +/** The color to render vertex mapped objects in for LightMap Density view mode. */ +var globalconfig linearcolor LightMapDensityVertexMappedColor; +/** The color to render selected objects in for LightMap Density view mode. */ +var globalconfig linearcolor LightMapDensitySelectedColor; + +struct native StatColorMapEntry +{ + var globalconfig float In; + var globalconfig color Out; +}; + +struct native StatColorMapping +{ + var globalconfig string StatName; + var globalconfig array ColorMap; + var globalconfig bool DisableBlend; +}; + +var globalconfig array StatColorMappings; + +/** A material used to render the sides of the builder brush/volumes/etc. */ +var Material EditorBrushMaterial; +var globalconfig string EditorBrushMaterialName; + +/** PhysicalMaterial to use if none is defined for a particular object. */ +var PhysicalMaterial DefaultPhysMaterial; +var globalconfig string DefaultPhysMaterialName; + +/** PhysicalMaterial used for landscape and terrain holes */ +var PhysicalMaterial LandscapeHolePhysMaterial; +var globalconfig string LandscapeHolePhysMaterialName; + +/** Optional damage mapping for Apex destructbile actors */ +var ApexDestructibleDamageParameters ApexDamageParams; +var globalconfig string ApexDamageParamsName; + + +/** The material used when terrain compilation is too complex. */ +var Material TerrainErrorMaterial; +var globalconfig string TerrainErrorMaterialName; +var globalconfig int TerrainMaterialMaxTextureCount; + +/** This is the number of frames that are used between terrain tessellation re-calculations */ +var globalconfig int TerrainTessellationCheckCount; +/** + * The radius from the view origin that terrain tessellation checks should be performed. + * If 0.0, every component will be checked for tessellation changes each frame. + */ +var globalconfig float TerrainTessellationCheckDistance; + +/** + * Bool switch for SetRequestScreenshot function + */ +var bool bScreenshotRequested; + +/** OnlineSubsystem class to use for netplay */ +var class OnlineSubsystemClass; +var globalconfig string DefaultOnlineSubsystemName; + +/** Default engine post process chain used for the game and main editor view if none is specified in the WorldInfo */ +var private{private} PostProcessChain DefaultPostProcess; +var private{private} config string DefaultPostProcessName; + +/** post process chain used for skeletal mesh thumbnails */ +var PostProcessChain ThumbnailSkeletalMeshPostProcess; +var config string ThumbnailSkeletalMeshPostProcessName; + +/** post process chain used for particle system thumbnails */ +var PostProcessChain ThumbnailParticleSystemPostProcess; +var config string ThumbnailParticleSystemPostProcessName; + +/** post process chain used for material thumbnails */ +var PostProcessChain ThumbnailMaterialPostProcess; +var config string ThumbnailMaterialPostProcessName; + +/** post process chain used for rendering the UI */ +var PostProcessChain DefaultUIScenePostProcess; +var config string DefaultUIScenePostProcessName; + +/** Material used for drawing meshes when their collision is missing. */ +var Material DefaultUICaretMaterial; +var globalconfig string DefaultUICaretMaterialName; + +/** Material used for visualizing the reflection scene captures on a surface */ +var Material SceneCaptureReflectActorMaterial; +var globalconfig string SceneCaptureReflectActorMaterialName; + +/** Material used for visualizing the cube map scene captures on a mesh */ +var Material SceneCaptureCubeActorMaterial; +var globalconfig string SceneCaptureCubeActorMaterialName; + +/** Texture used to get random opacity values per-pixel for screen-door fading */ +var Texture2D ScreenDoorNoiseTexture; +var globalconfig string ScreenDoorNoiseTextureName; + +/** Texture used to get random image grain values for post processing */ +var Texture2D ImageGrainNoiseTexture; +var globalconfig string ImageGrainNoiseTextureName; + +/** Texture used to get random angles per-pixel by the Branching PCF implementation */ +var Texture2D RandomAngleTexture; +var globalconfig string RandomAngleTextureName; + +/** Texture used to get random normals per-pixel */ +var Texture2D RandomNormalTexture; +var globalconfig string RandomNormalTextureName; + +/** Texture used to get random rotation per-pixel */ +var Texture2D RandomMirrorDiscTexture; +var globalconfig string RandomMirrorDiscTextureName; + +/** Texture used as a placeholder for terrain weight-maps to give the material the correct texture format. */ +var Texture WeightMapPlaceholderTexture; +var globalconfig string WeightMapPlaceholderTextureName; + +/** Texture used to display LightMapDensity */ +var Texture2D LightMapDensityTexture; +var globalconfig string LightMapDensityTextureName; + +/** Texture used to display LightMapDensity */ +var Texture2D LightMapDensityNormal; +var globalconfig string LightMapDensityNormalName; + +`if(`__TW_CUSTOM_VIEWMODES_) +/** Texture used to display SplatterMapDensity */ +var Texture2D SplatterMapDensityTexture; +var globalconfig string SplatterMapDensityTextureName; +`endif + +`if(`__TW_PERSISTENT_SPLATTER_SYSTEM_) +/** + * Texture used by the persistent blood splatter system + * R Channel = Tiling Mask + * G Channel = Reflection (Faked Cubemap) + */ +var Texture2D PersistentBloodMasterTexture; +var globalconfig string PersistentBloodMasterTextureName; +`endif + +`if(`__TW_SCREEN_SPACE_REFLECTIONS_) +var Texture2D DitherTexture; +var globalconfig string DitherTextureName; +`endif + +/** White noise sound */ +var SoundNodeWave DefaultSound; +var globalconfig string DefaultSoundName; + +/** Time in seconds (game time) we should wait between purging object references to objects that are pending kill */ +var(Settings) config float TimeBetweenPurgingPendingKillObjects; + +// Variables. + +/** Abstract interface to platform-specific subsystems */ +var const client Client; + +/** Viewports for all players in all game instances (all PIE windows, for example) */ +var init array GamePlayers; + +/** the viewport representing the current game instance */ +var const GameViewportClient GameViewport; + +/** Array of deferred command strings/ execs that get executed at the end of the frame */ +var init array DeferredCommands; + +var int TickCycles, GameCycles, ClientCycles; +var transient bool bUseSound; + +/** Whether to allow background level streaming. */ +var(Settings) config bool bUseBackgroundLevelStreaming; + +/** Flag for completely disabling subtitles for localized sounds. */ +var(Settings) config bool bSubtitlesEnabled; + +/** Flag for forcibly disabling subtitles even if you try to turn them back on they will be off */ +var(Settings) config bool bSubtitlesForcedOff; + +/** Whether to enable framerate smoothing. */ +var config bool bSmoothFrameRate; +/** Maximum framerate to smooth. Code will try to not go over via waiting. */ +var config float MaxSmoothedFrameRate; +/** Minimum framerate smoothing will kick in. */ +var config float MinSmoothedFrameRate; + +/** + * Whether we should check for more than N pawns spawning in a single frame. + * Basically, spawning pawns and all of their attachments can be slow. And on consoles it + * can be really slow. If this bool is true we will display a + **/ +var config bool bCheckForMultiplePawnsSpawnedInAFrame; + +/** If bCheckForMultiplePawnsSpawnedInAFrame==TRUE, then we will check to see that no more than this number of pawns are spawned in a frame. **/ +var config int NumPawnsAllowedToBeSpawnedInAFrame; + +/** + * Whether or not the simple lightmaps should be generated during lighting rebuilds. + */ +var globalconfig bool bShouldGenerateSimpleLightmaps; + +/** + * Flag for forcing terrain to be 'static' (MinTessellationLevel = MaxTesselationLevel) + * Game time only... + */ +var(Settings) config bool bForceStaticTerrain; + +/** Entry point for RemoteControl, the in-game UI for the exec system. */ +var native pointer RemoteControlExec{class FRemoteControlExec}; + +/** Pointer to a support class to handle mobile material emulation (created on demand) */ +var native pointer MobileMaterialEmulator{class FMobileMaterialEmulator}; + +// Color preferences. +var(Colors) color + C_WorldBox, + C_BrushWire, + C_AddWire, + C_SubtractWire, + C_SemiSolidWire, + C_NonSolidWire, + C_WireBackground, + C_ScaleBoxHi, + C_VolumeCollision, + C_BSPCollision, + C_OrthoBackground, + C_Volume, + C_BrushShape; + +/** Fudge factor for tweaking the distance based miplevel determination */ +var(Settings) float StreamingDistanceFactor; + +/** Class name of the scout to use for path building */ +var const config string ScoutClassName; + +/** + * A transition type. + */ +enum ETransitionType +{ + TT_None, + TT_Paused, + TT_Loading, + TT_Saving, + TT_Connecting, + TT_Precaching +}; + +/** The current transition type. */ +var ETransitionType TransitionType; + +/** The current transition description text. */ +var string TransitionDescription; + +/** The gametype for the destination map */ +var string TransitionGameType; + +/** Level of detail range control for meshes */ +var config float MeshLODRange; +/** Force to CPU skinning only for skeletal mesh rendering */ +var config bool bForceCPUSkinning; +/** Whether to use post processing effects or not */ +var config bool bUsePostProcessEffects; +/** whether to send Kismet warning messages to the screen (via PlayerController::ClientMessage()) */ +var config bool bOnScreenKismetWarnings; +/** whether kismet logging is enabled. */ +var config bool bEnableKismetLogging; +/** whether mature language is allowed **/ +var config bool bAllowMatureLanguage; +/** camera rotation (deg) beyond which occlusion queries are ignored from previous frame (because they are likely not valid) */ +var config float CameraRotationThreshold; +/** camera movement beyond which occlusion queries are ignored from previous frame (because they are likely not valid) */ +var config float CameraTranslationThreshold; +/** The amount of time a primitive is considered to be probably visible after it was last actually visible. */ +var config float PrimitiveProbablyVisibleTime; +`if(`__TW_LIGHT_CULLING_) +/** The amount of time a light is considered to be probably visible after it was last actually visible. */ +var config float LightProbablyVisibleTime; +`endif +/** The percent of previously unoccluded primitives which are requeried every frame. */ +var config float PercentUnoccludedRequeries; +/** Max screen pixel fraction where retesting when unoccluded is worth the GPU time. */ +var config float MaxOcclusionPixelsFraction; + +// NVCHANGE_BEGIN_TURB: Multiple PhysX levels +/** Level of PhysX content. 0 means no hardware acceleration. */ +var globalconfig int PhysXLevel; +// NVCHANGE_END_TURB: Multiple PhysX levels + +/** Do not use Ageia PhysX hardware */ +var globalconfig bool bDisablePhysXHardwareSupport; + +/** Whether to pause the game if focus is lost. */ +var config bool bPauseOnLossOfFocus; + +/** The most vertices a fluid surface can have. The number of verts is clamped to avoid running out of memory and exposing driver bugs. */ +var config int MaxFluidNumVerts; + +/** + * Time limit (in milliseconds) for a fluid simulation update, to avoid spiraling into a bad + * feedback-loop with slower and slower framerate. This value is doubled in debug builds. + */ +var config float FluidSimulationTimeLimit; + +/** + * The maximum allowed size to a ParticleEmitterInstance::Resize call. + * If larger, the function will return without resizing. + */ +var config int MaxParticleResize; +/** +* If the resize request is larger than this, spew out a warning to the log +*/ +var config int MaxParticleResizeWarn; +/** + * If TRUE, then perform particle size checks in non FINAL_RELEASE builds. + */ +var globalconfig bool bCheckParticleRenderSize; +/** The maximum amount of memory any single emitter is allowed to take for its vertices */ +var config int MaxParticleVertexMemory; +var transient int MaxParticleSpriteCount; +var transient int MaxParticleSubUVCount; + +/** The number of times to attempt the Begin*UP call before assuming the GPU is hosed */ +var config int BeginUPTryCount; + +/** Info about one note dropped in the map during PIE. */ +struct native DropNoteInfo +{ + /** Location to create Note actor in edited level. */ + var vector Location; + /** Rotation to create Note actor in edited level. */ + var rotator Rotation; + /** Text to assign to Note actor in edited level. */ + var string Comment; +}; + +/** */ +var transient array PendingDroppedNotes; + +/** Overridable class for cover mesh rendering in-game, used to get around the editoronly restrictions needed by the base CoverMeshComponent */ +var globalconfig string DynamicCoverMeshComponentName; + +/** + * By default, each frame's initial scene color clear is disabled. + * This flag can be toggled at runtime to enable clearing for development. + */ +var globalconfig const bool bEnableColorClear; + +/** Number of times to tick each client per second */ +var globalconfig float NetClientTicksPerSecond; + +/** + * The largest step-size allowed for lens flare occlusion results + * before using the incremental step method. + */ +var globalconfig float MaxTrackedOcclusionIncrement; +/** + * The incremental step size for the above. + */ +var globalconfig float TrackedOcclusionStepSize; + +/** Keeps track whether actors moved via PostEditMove and therefore constraint syncup should be performed. */ +var transient bool bAreConstraintsDirty; + +/** TRUE if the engine needs to perform a delayed global component reattach (really just for editor) */ +var transient bool bHasPendingGlobalReattach; + +/** Default color of selected objects in the level viewport (additive) */ +var globalconfig LinearColor DefaultSelectedMaterialColor; + +/** Default color of hovered objects in the level viewport (additive) */ +var globalconfig LinearColor DefaultHoveredMaterialColor; + +/** Color of selected objects in the level viewport (additive) */ +var transient LinearColor SelectedMaterialColor; + +/** Color of unselected objects in the level viewport (additive) */ +var transient LinearColor UnselectedMaterialColor; + +/** If TRUE, then disable OnScreenDebug messages. Can be toggled in real-time. */ +var globalconfig bool bEnableOnScreenDebugMessages; +/** If TRUE, then disable the display of OnScreenDebug messages (used when running) */ +var transient bool bEnableOnScreenDebugMessagesDisplay; + +/** If TRUE, then skip drawing map warnings on screen even in non FINAL_RELEASE builds */ +var globalconfig bool bSuppressMapWarnings; + +/** If DevAbsorbFuncs logging is unsuppressed and _DEBUG is defined in native, functions listed in this array will not throw a warning when they are absorbed for not being simulated on clients. Useful for functions like Tick, where this behaviour is intentional */ +var globalconfig array IgnoreSimulatedFuncWarnings; + +/** if set, cook game classes into standalone packages (as defined in [Cooker.MPGameContentCookStandalone]) and load the appropriate + * one at game time depending on the gametype specified on the URL + * (the game class should then not be referenced in the maps themselves) + */ +var globalconfig bool bCookSeparateSharedMPGameContent; + +/** + * If TRUE and build w/ WITH_RECAST enabled, use Recast for navmesh + */ +var globalconfig bool bUseRecastNavMesh; + +/** determines whether AI logging should be processed or not */ +var bool bDisableAILogging; + +`if(`__TW_BASEAI_LEAN_) +/** + * AI interface instance + */ +var globalconfig string AISubsystemClassName; +var AISubsystem AISys; +`endif + +/** Semaphore to control screen saver inhibitor thread access. */ +var private{private} transient int ScreenSaverInhibitorSemaphore; + +/** Thread preventing screen saver from kicking. Suspend most of the time. */ +var private{private} transient pointer ScreenSaverInhibitor{FRunnableThread}; + +/** A global translation context handles simple translation scenarios. e.g. */ +var TranslationContext GlobalTranslationContext; + +/** Enables normal map sampling when Lightmass is generating 'simple' light maps. This increases lighting build time, but may improve quality when normal maps are used to represent curvature over a large surface area. When this setting is disabled, 'simple' light maps will not take normal maps into account. */ +var globalconfig bool bUseNormalMapsForSimpleLightMaps; + +/** Timestamp for when a loading movie was started, based on appSeconds(). Cleared to 0.0 when no movies are playing anymore. */ +var const transient double LoadingMovieStartTime; + +/** determines if we should start the matinee capture as soon as the game loads */ +var transient bool bStartWithMatineeCapture; + +/** should we compress the capture */ +var transient bool bCompressMatineeCapture; + +/** the name of the matine that we want to record */ +var transient string MatineeCaptureName; + +/** The package name where the matinee belongs to */ +var transient string MatineePackageCaptureName; + +/** The visible levels that should be loaded when the matinee starts */ +var transient string VisibleLevelsForMatineeCapture; + +/** the fps of the matine that we want to record */ +var transient int MatineeCaptureFPS; + +/** The capture type 0 - AVI, 1 - Screen Shots */ +var transient int MatineeCaptureType; + +/** TRUE if the the user cannot modify levels that are read only. */ +var transient bool bLockReadOnlyLevels; + +//@HSL_BEGIN - BWJ - 8-19-16 - Server query support +/** Net driver for server query support */ +var NetDriver QueryNetDriver; +//@HSL_END + +//@HSL_BEGIN - BWJ - 2-27-17 - Support for safe frame scale +/** The safe frame scale. Currently only used for XB1 */ +var float SafeFrameScale; +//@HSL_END + + +cpptext +{ + // Constructors. + UEngine(); + void StaticConstructor(); + + // UObject interface. + virtual void FinishDestroy(); + + // UEngine interface. + virtual void Init(); + + /** + * Called at shutdown, just before the exit purge. + */ +#if __TW_BASEAI_LEAN_ + virtual void PreExit(); +#else + virtual void PreExit() {} +#endif + + virtual UBOOL Exec( const TCHAR* Cmd, FOutputDevice& Out=*GLog ); + virtual void Tick( FLOAT DeltaSeconds ) PURE_VIRTUAL(UEngine::Tick,); + virtual void SetClientTravel( const TCHAR* NextURL, ETravelType TravelType ) PURE_VIRTUAL(UEngine::SetClientTravel,); + virtual FLOAT GetMaxTickRate( FLOAT /*DeltaTime*/, UBOOL bAllowFrameRateSmoothing = TRUE ); + virtual void SetProgress( EProgressMessageType MessageType, const FString& Title, const FString& Message ); + + /** + * Called by Exec. Memory related execs. + */ + UBOOL ExecMemFunctions( const TCHAR* Cmd, FOutputDevice& Out=*GLog ); + + /** + * Called by Exec. Threading related execs. + */ + UBOOL ExecThreadFunctions( const TCHAR* Cmd, FOutputDevice& Out=*GLog ); + + /** + * Pauses / unpauses the game-play when focus of the game's window gets lost / gained. + * @param EnablePause TRUE to pause; FALSE to unpause the game + */ + virtual void OnLostFocusPause( UBOOL EnablePause ); + +#if DO_CHARTING + /** + * Ticks the FPS chart. + * + * @param DeltaSeconds Time in seconds passed since last tick. + */ + virtual void TickFPSChart( FLOAT DeltaSeconds ); + + /** + * Ticks the Memory chart. + * + * @param DeltaSeconds Time in seconds passed since last tick. + */ + virtual void TickMemoryChart( FLOAT DeltaSeconds ); + + /** + * Resets the FPS chart data. + */ + virtual void ResetFPSChart(); + + /** + * Dumps the FPS chart information to the passed in archive. + * + * @param bForceDump Whether to dump even if FPS chart info is not enabled. + */ + virtual void DumpFPSChart( UBOOL bForceDump = FALSE ); + + /** Dumps info on DistanceFactor used for rendering SkeletalMeshComponents during the game. */ + virtual void DumpDistanceFactorChart(); + + /** + * Resets the Memory chart data. + */ + virtual void ResetMemoryChart(); + + /** + * Dumps the Memory chart information to various places. + * + * @param bForceDump Whether to dump even if no info has been captured yet (will force an update in that case). + */ + virtual void DumpMemoryChart( UBOOL bForceDump = FALSE ); + + +private: + /** + * Dumps the FPS chart information to HTML. + */ + virtual void DumpFPSChartToHTML( FLOAT TotalTime, FLOAT DeltaTime, INT NumFrames, UBOOL bOutputToGlobalLog ); + + /** + * Dumps the FPS chart information to the log. + */ + virtual void DumpFPSChartToLog( FLOAT TotalTime, FLOAT DeltaTime, INT NumFrames ); + + /** + * Dumps the FPS chart information to the special stats log file. + */ + virtual void DumpFPSChartToStatsLog( FLOAT TotalTime, FLOAT DeltaTime, INT NumFrames ); + + /** + * Dumps the frame times information to the special stats log file. + */ + virtual void DumpFrameTimesToStatsLog( FLOAT TotalTime, FLOAT DeltaTime, INT NumFrames ); + + /** + * Dumps the Memory chart information to HTML. + */ + virtual void DumpMemoryChartToHTML( FLOAT TotalTime, FLOAT DeltaTime, INT NumFrames, UBOOL bOutputToGlobalLog ); + + /** + * Dumps the Memory chart information to the log. + */ + virtual void DumpMemoryChartToLog( FLOAT TotalTime, FLOAT DeltaTime, INT NumFrames ); + + /** + * Dumps the Memory chart information to the special stats log file. + */ + virtual void DumpMemoryChartToStatsLog( FLOAT TotalTime, FLOAT DeltaTime, INT NumFrames ); + +#endif // DO_CHARTING + +public: + + /** + * Spawns any registered server actors + */ + virtual void SpawnServerActors(void) + { + } + + /** + * Loads all Engine object references from their corresponding config entries. + */ + void InitializeObjectReferences(); + + /** + * Construct a UNetDriver object based on an .ini setting + * + * @return The created NetDriver object, or NULL if it fails + */ + virtual class UNetDriver* ConstructNetDriver() + { + return NULL; + } + + /** + * Clean up the GameViewport + */ + void CleanupGameViewport(); + + /** Get some viewport. Will be GameViewport in game, and one of the editor viewport windows in editor. */ + virtual FViewport* GetAViewport(); + + /** + * Allows the editor to accept or reject the drawing of wireframe brush shapes based on mode and tool. + */ + virtual UBOOL ShouldDrawBrushWireframe( class AActor* InActor ) { return TRUE; } + + /** + * Issued by code requesting that decals be reattached. + */ + virtual void IssueDecalUpdateRequest() {} + + /** + * Returns whether or not the map build in progressed was cancelled by the user. + */ + virtual UBOOL GetMapBuildCancelled() const + { + return FALSE; + } + + /** + * Sets the flag that states whether or not the map build was cancelled. + * + * @param InCancelled New state for the cancelled flag. + */ + virtual void SetMapBuildCancelled( UBOOL InCancelled ) + { + // Intentionally empty. + } + + /** + * Computes a color to use for property coloration for the given object. + * + * @param Object The object for which to compute a property color. + * @param OutColor [out] The returned color. + * @return TRUE if a color was successfully set on OutColor, FALSE otherwise. + */ + virtual UBOOL GetPropertyColorationColor(class UObject* Object, FColor& OutColor); + + /** Uses StatColorMappings to find a color for this stat's value. */ + UBOOL GetStatValueColoration(const FString& StatName, FLOAT Value, FColor& OutColor); + + /** + * @return TRUE if selection of translucent objects in perspective viewports is allowed + */ + virtual UBOOL AllowSelectTranslucent() const + { + // The editor may override this to disallow translucent selection based on user preferences + return TRUE; + } + + /** + * @return TRUE if only editor-visible levels should be loaded in Play-In-Editor sessions + */ + virtual UBOOL OnlyLoadEditorVisibleLevelsInPIE() const + { + // The editor may override this to apply the user's preference state + return TRUE; + } + + /** + * Enables or disables the ScreenSaver (PC only) + * + * @param bEnable If TRUE the enable the screen saver, if FALSE disable it. + */ + void EnableScreenSaver( UBOOL bEnable ); + + /** + * Get the index of the provided sprite category + * + * @param InSpriteCategory Sprite category to get the index of + * + * @return Index of the provided sprite category, if possible; INDEX_NONE otherwise + */ + virtual INT GetSpriteCategoryIndex( const FName& InSpriteCategory ) + { + // The editor may override this to handle sprite categories as necessary + return INDEX_NONE; + } + + + /** + * Trips a bool in engine side code to signal a screenshot request on next frame + */ + void SetRequestScreenshot(); + + /** + * Starts playing a loading movie from memory. + * Keeps track of the total time fullscreen movies are playing to cover loading. + * + * @param MovieName Name of the movie to play in its entirety + */ + void PlayLoadingMovie( const TCHAR* MovieName ); + +protected: + /** + * Handles freezing/unfreezing of rendering + */ + virtual void ProcessToggleFreezeCommand() + { + // Intentionally empty. + } + + /** + * Handles frezing/unfreezing of streaming + */ + virtual void ProcessToggleFreezeStreamingCommand() + { + // Intentionally empty. + } + + /** + * Updates all physics constraint actor joint locations. + */ + virtual void UpdateConstraintActors(); + +#if __TW_BASEAI_LEAN_ + virtual void InitializeSubsystems(); +#endif +} + +/** @return the GIsEditor flag setting */ +native static final function bool IsEditor(); + +/** @return the GIsGame flag is setting */ +native static final function bool IsGame(); + +/** + * Returns a pointer to the current world. + */ +native static final function WorldInfo GetCurrentWorldInfo(); + +/** + * Returns version info from the engine + */ +native static final function string GetBuildDate(); + +/** + * Returns the UUID of the device (or empty if cannot be determined) + */ +native static final function string GetDeviceUUID(); + +/** + * Return OS version number + */ +native static final function float GetOSVersion(); + +/** + * Return TitleSafe Area Scale. + */ +native static final function float GetTitleSafeArea(); + +/** + * Returns the push notification token for the device + application + */ +native static final function string GetDevicePushNotificationToken(); + +/* + * Returns the proper formatting for a bug data export string +*/ +native static final function string BuildBugSubmissionString(string BugField, string BugFieldData); + +/** + * Return true if there is a network connection + */ +native static final function bool HasNetworkConnection(); + + +/** + * Returns the engine's default tiny font + */ +native static final function Font GetTinyFont(); + +/** + * Returns the engine's default small font + */ +native static final function Font GetSmallFont(); + +/** + * Returns the engine's default medium font + */ +native static final function Font GetMediumFont(); + +/** + * Returns the engine's default large font + */ +native static final function Font GetLargeFont(); + +/** + * Returns the engine's default subtitle font + */ +native static final function Font GetSubtitleFont(); + +/** + * Returns the specified additional font. + * + * @param AdditionalFontIndex Index into the AddtionalFonts array. + */ +native static final function Font GetAdditionalFont(int AdditionalFontIndex); + +/** @return whether we're currently running in splitscreen (more than one local player) */ +native static final function bool IsSplitScreen(); + +/** @return whether we're currently running with stereoscopic 3D enabled */ +native static final function bool IsStereoscopic3D(); + +/** @return whether we're currently running with the OpenGL ES2 renderer */ +native static final function bool IsUsingES2Renderer(); + +/** @return the audio device (will be None if sound is disabled) */ +native static final function AudioDevice GetAudioDevice(); + +`if(`__TW_BASEAI_LEAN_) +/** @return the AISubsystem instantiated in packages loaded later (None if not instantiated) */ +native static final function AISubsystem GetAISubsystem(); +`endif + +/** @return Returns the name of the last movie that was played. */ +native static final function string GetLastMovieName(); + + +/** + * Play one of the LoadMap loading movies as configured by ini file + * + * @return TRUE if a movie was played + */ +native static final function bool PlayLoadMapMovie(); + +/** + * Stops the current movie + * + * @param bDelayStopUntilGameHasRendered If TRUE, the engine will delay stopping the movie until after the game has rendered at least one frame + */ +native static final function StopMovie(bool bDelayStopUntilGameHasRendered); + +/** + * Removes all overlays from displaying + */ +native static final function RemoveAllOverlays(); + +/** + * Adds a text overlay to the movie + * + * @param Font Font to use to display (must be in the root set so this will work during loads) + * @param Text Text to display + * @param X X location in resolution-independent coordinates (ignored if centered) + * @param Y Y location in resolution-independent coordinates + * @param ScaleX Text horizontal scale + * @param ScaleY Text vertical scale + * @param bIsCentered TRUE if the text should be centered + */ +native static final function AddOverlay( Font Font, string Text, float X, float Y, float ScaleX, float ScaleY, bool bIsCentered ); + +/** + * Adds a wrapped text overlay to the movie + * + * @param Font Font to use to display (must be in the root set so this will work during loads) + * @param Text Text to display + * @param X X location in resolution-independent coordinates (ignored if centered) + * @param Y Y location in resolution-independent coordinates + * @param ScaleX Text horizontal scale + * @param ScaleY Text vertical scale + * @param WrapWidth Number of pixels before text should wrap + */ +native static final function AddOverlayWrapped( Font Font, string Text, float X, float Y, float ScaleX, float ScaleY, float WrapWidth ); + +// WITH_REALD BEGIN +/** + * Returns whether RealD stereo rendering is enabled or not + */ +native static final function bool IsRealDStereoEnabled(); +// WITH_REALD END + +/** + * returns GEngine + */ +native static final function Engine GetEngine(); + +/** + * Returns the defualt post process chain (loading it if it has not yet been loaded) + */ +native static final function PostProcessChain GetDefaultPostProcessChain(); + +/** + * Returns the post process chain to be used with the world. + */ +native static final function PostProcessChain GetWorldPostProcessChain(); + +/** + * Adds a world location as a secondary view location for purposes of texture streaming. + * Lasts one frame, or a specified number of seconds (for overriding locations only). + * + * @param InLoc Location to add to texture streaming for this frame + * @param BoostFactor A factor that affects all streaming distances for this location. 1.0f is default. Higher means higher-resolution textures and vice versa. + * @param bOverrideLocation Whether this is an override location, which forces the streaming system to ignore all other locations + * @param OverrideDuration How long the streaming system should keep checking this location if bOverrideLocation is TRUE, in seconds. 0 means just for the next Tick. + */ +native final function AddTextureStreamingSlaveLoc(vector InLoc, float BoostFactor, bool bOverrideLocation, float OverrideDuration); + +/** + * Serializes an object to a file (object pointers to non-always loaded objects are not supported) + * + * @param Obj The object to serialize + * @param Pathname The path to the file to save + * @param bIsSaveGame If TRUE, FILEWRITE_SaveGame will be used to create the file writer + * @param Version A version number to save with the archive, so that we can safely fail when loading old versioned files + * @param bEncrypt - should file be encrypted? Loading it back will be automatic if encrypted. + * + * @return TRUE if successful + */ +native static final function bool BasicSaveObject(Object Obj, string Pathname, bool bIsSaveGame, int Version, optional bool bEncrypt=false); + +/** + * Loads an object from a file (saved with the BasicSaveObject function). It should already be + * allocated just like the original object was allocated + * + * @param Obj The object to serialize + * @param Pathname The path to the file to read and create the object from + * @param bIsSaveGame If TRUE, FILEREAD_SaveGame will be used to create the file reader + * @param Version A version number to match with the version saved in the archive, so that we can safely fail when loading old versioned files + * + * @return TRUE if successful + */ +native static final function bool BasicLoadObject(Object Obj, string Pathname, bool bIsSaveGame, int Version); + +/** Launches the specified platform via appLaunchURL (platform dependent support) */ +native static final function LaunchURL(string URL); + +// NVCHANGE_BEGIN_TURB: Multiple PhysX levels +/** Return level of PhysX content (0, 1, or 2). 0 means no hardware acceleration. */ +native static final function int GetPhysXLevel(); +// NVCHANGE_END_TURB: Multiple PhysX levels + +/** + * Gets the value of the specified boolean System Setting + * + * @param SettingName - Name of the boolean System Setting to retrieve + * + * @return The value of the boolean System Setting + */ +native final function bool GetSystemSettingBool(string SettingName); + +/** + * Gets the value of the specified integer System Setting + * + * @param SettingName - Name of the integer System Setting to retrieve + * + * @return The value of the integer System Setting + */ +native final function int GetSystemSettingInt(string SettingName); + +/** + * Gets the value of the specified float System Setting + * + * @param SettingName - Name of the float System Setting to retrieve + * + * @return The value of the float System Setting + */ +native final function float GetSystemSettingFloat(string SettingName); + +defaultproperties +{ + C_WorldBox=(R=0,G=0,B=40,A=255) + C_BrushWire=(R=192,G=0,B=0,A=255) + C_AddWire=(R=127,G=127,B=255,A=255) + C_SubtractWire=(R=255,G=192,B=63,A=255) + C_SemiSolidWire=(R=127,G=255,B=0,A=255) + C_NonSolidWire=(R=63,G=192,B=32,A=255) + C_WireBackground=(R=0,G=0,B=0,A=255) + C_ScaleBoxHi=(R=223,G=149,B=157,A=255) + C_VolumeCollision=(R=149,G=223,B=157,A=255) + C_BSPCollision=(R=149,G=157,B=223,A=255) + C_OrthoBackground=(R=163,G=163,B=163,A=255) + C_Volume=(R=255,G=196,B=255,A=255) + C_BrushShape=(R=128,G=255,B=128,A=255) + bUseSound=true +} diff --git a/Engine/Classes/EngineBaseTypes.uc b/Engine/Classes/EngineBaseTypes.uc new file mode 100644 index 0000000..e2bdbcc --- /dev/null +++ b/Engine/Classes/EngineBaseTypes.uc @@ -0,0 +1,46 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * This file is for shared structs and enums that need to be declared before the rest of Engine. + * The typical use case is for structs used in the renderer and also in script code. + */ +class EngineBaseTypes extends Object + native(Base) + abstract + config(Engine); + +/** + * Overrides for rendering settings that can be used to increase performance. + */ +struct native RenderingPerformanceOverrides +{ + var() bool bAllowAmbientOcclusion; + var() bool bAllowDominantWholeSceneDynamicShadows; + var() bool bAllowMotionBlurSkinning; + var() bool bAllowTemporalAA; + var() bool bAllowLightShafts; + + structcpptext + { + /* default constructor, for script, values are overwritten by serialization afterwards */ + FRenderingPerformanceOverrides() + {} + + FRenderingPerformanceOverrides(EForceInit) + { + bAllowAmbientOcclusion = TRUE; + bAllowDominantWholeSceneDynamicShadows = TRUE; + bAllowMotionBlurSkinning = TRUE; + bAllowTemporalAA = TRUE; + bAllowLightShafts = TRUE; + } + } + + structdefaultproperties + { + bAllowAmbientOcclusion=True + bAllowDominantWholeSceneDynamicShadows=True + bAllowMotionBlurSkinning=True + bAllowTemporalAA=True + bAllowLightShafts=True + } +}; diff --git a/Engine/Classes/EngineTypes.uc b/Engine/Classes/EngineTypes.uc new file mode 100644 index 0000000..03a2363 --- /dev/null +++ b/Engine/Classes/EngineTypes.uc @@ -0,0 +1,602 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * This will hold all of our enums and types and such that we need to + * use in multiple files where the enum can'y be mapped to a specific file. + */ +class EngineTypes extends Object + native + abstract + config(Engine); + +enum EPathFindingError +{ + PATHERROR_STARTPOLYNOTFOUND, // could not determine starting poly + PATHERROR_GOALPOLYNOTFOUND, // could not determine poly containing our goal + PATHERROR_ANCHORPYLONNOTFOUND, // could not determine which pylon we are in + PATHERROR_NOPATHFOUND, // found start and end polys, but could not construct a path between that suits our parameters + PATHERROR_COMPUTEVALIDFINALDEST_FAIL, // ComputeValidFinalDestination was unable to build a good offset from goal to move to + PATHERROR_GETNEXTMOVELOCATION_FAIL, // GetNextMoveLocation was unable to determine the next move point + PATHERROR_MOVETIMEOUT, // we timed out while moving (e.g. trying to move against a wall and never succeeded) +}; + +/** + * A line of subtitle text and the time at which it should be displayed. + */ +struct native SubtitleCue +{ + /** The text too appear in the subtitle. */ + var() localized string Text; + + /** The time at which the subtitle is to be displayed, in seconds relative to the beginning of the line. */ + var() localized float Time; +}; + +/** + * A subtitle localized to a specific language. + */ +struct native LocalizedSubtitle +{ + /** The 3-letter language for this subtitle */ + var string LanguageExt; + + /** + * Subtitle cues. If empty, use SoundNodeWave's SpokenText as the subtitle. Will often be empty, + * as the contents of the subtitle is commonly identical to what is spoken. + */ + var array Subtitles; + + /** TRUE if this sound is considered to contain mature content. */ + var bool bMature; + + /** TRUE if the subtitles have been split manually. */ + var bool bManualWordWrap; + + /** TRUE if the subtitles should be displayed one line at a time. */ + var bool bSingleLine; +}; + +/** Note: This is mirrored in Lightmass, be sure to update the blend mode structure and logic there if this changes. */ +enum EBlendMode +{ + BLEND_Opaque, + BLEND_Masked, + BLEND_Translucent, + BLEND_Additive, + BLEND_Modulate, + BLEND_ModulateAndAdd, + BLEND_SoftMasked, + BLEND_AlphaComposite, + BLEND_DitheredTranslucent +}; + +enum EMaterialLightingModel +{ + MLM_Phong, + MLM_NonDirectional, + MLM_Unlit, + MLM_SHPRT, + MLM_Custom, + MLM_Anisotropic +}; + +// This is used by the drawing passes to determine tessellation policy, so changes here need to be supported in native code. +enum EMaterialTessellationMode +{ + /** Tessellation disabled */ + MTM_NoTessellation, + + /** Simple tessellation */ + MTM_FlatTessellation, + + /** Simple Spline based tessellation */ + MTM_PNTriangles +}; + + +/** Possible sources for mask values and such */ +enum EMobileValueSource +{ + MVS_Constant, + MVS_VertexColorRed, + MVS_VertexColorGreen, + MVS_VertexColorBlue, + MVS_VertexColorAlpha, + MVS_BaseTextureRed, + MVS_BaseTextureGreen, + MVS_BaseTextureBlue, + MVS_BaseTextureAlpha, + MVS_MaskTextureRed, + MVS_MaskTextureGreen, + MVS_MaskTextureBlue, + MVS_MaskTextureAlpha, + MVS_NormalTextureAlpha, + MVS_EmissiveTextureRed, + MVS_EmissiveTextureGreen, + MVS_EmissiveTextureBlue, + MVS_EmissiveTextureAlpha +}; + +/** Possible options for blend factor source for blending between textures */ +// @todo: Should fold this into EMobileValueSource +enum EMobileTextureBlendFactorSource +{ + /** From the vertex color's red channel */ + MTBFS_VertexColor, + + /** From the mask texture's alpha */ + MTBFS_MaskTexture, +}; + +/** Possible vertex texture coordinate sets that may used to sample textures on mobile platforms */ +enum EMobileTexCoordsSource +{ + /** First texture coordinate from mesh vertex */ + MTCS_TexCoords0, + + /** Second texture coordinate from mesh vertex */ + MTCS_TexCoords1, + + /** Third texture coordinate from mesh vertex */ + MTCS_TexCoords2, + + /** Forth texture coordinate from mesh vertex */ + MTCS_TexCoords3, +}; + +/** Possible vertex texture coordinate sets that may used to sample textures on mobile platforms */ +enum EMobileAlphaValueSource +{ + /** Default in the diffuse channel alpha */ + MAVS_DiffuseTextureAlpha, + + /** Mask Texture Red Channel (platforms with no alpha texture compression) */ + MAVS_MaskTextureRed, + + /** Mask Texture Green Channel (platforms with no alpha texture compression) */ + MAVS_MaskTextureGreen, + + /** Mask Texture Blue Channel (platforms with no alpha texture compression) */ + MAVS_MaskTextureBlue, +}; + +/** Possible vertex texture coordinate sets that may used to sample textures on mobile platforms */ +enum EMobileColorMultiplySource +{ + MCMS_None, + MCMS_BaseTextureRed, + MCMS_BaseTextureGreen, + MCMS_BaseTextureBlue, + MCMS_BaseTextureAlpha, + MCMS_MaskTextureRed, + MCMS_MaskTextureGreen, + MCMS_MaskTextureBlue, + MCMS_MaskTextureAlpha, +}; + +/** Possible sources for mobile emissive color */ +enum EMobileEmissiveColorSource +{ + /** Emissive texture color */ + MECS_EmissiveTexture, + + /** Base texture color */ + MECS_BaseTexture, + + /** Constant color specified in the material properties */ + MECS_Constant, +}; + +/** Possible environment map blend modes */ +enum EMobileEnvironmentBlendMode +{ + /** Add environment map to base color */ + MEBM_Add, + + /** Lerp between base color and environment color */ + MEBM_Lerp +}; + +// @todo: Should fold this into EMobileValueSource +enum EMobileSpecularMask +{ + MSM_Constant, + MSM_Luminance, + MSM_DiffuseRed, + MSM_DiffuseGreen, + MSM_DiffuseBlue, + MSM_DiffuseAlpha, + MSM_MaskTextureRGB, + MSM_MaskTextureRed, + MSM_MaskTextureGreen, + MSM_MaskTextureBlue, + MSM_MaskTextureAlpha +}; + +// @todo: Should fold this into EMobileValueSource +enum EMobileAmbientOcclusionSource +{ + MAOS_Disabled, + MAOS_VertexColorRed, + MAOS_VertexColorGreen, + MAOS_VertexColorBlue, + MAOS_VertexColorAlpha, +}; + +struct LightMapRef +{ + var native private const pointer Reference; +}; + +/** + * Lighting build quality enumeration + */ +enum ELightingBuildQuality +{ + Quality_Preview, + Quality_Medium, + Quality_High, + Quality_Production, + Quality_NoGlobalIllumination // this MUST be placed just before Quality_MAX... +}; + +`if(`__TW_) +/** + * Precomputed visibility build type enumeration + */ +enum EPrecomputedVisibilityBuildType +{ + BuildType_IncrementalBuild, + BuildType_FullRebuild, + BuildType_DoNotBuild +}; +`endif + +struct native DominantShadowInfo +{ + /** Transform from world space to the coordinate space that the DominantLightShadowMap entries are stored in. */ + var Matrix WorldToLight; + /** Inverse of WorldToLight */ + var Matrix LightToWorld; + /** Bounding box of the area that the DominantLightShadowMap entries are stored for, in the coordinate space defined by WorldToLight. */ + var box LightSpaceImportanceBounds; + /** Dimensions of DominantLightShadowMap */ + var int ShadowMapSizeX; + var int ShadowMapSizeY; +}; + +/** + * Per-light settings for Lightmass + */ +struct native LightmassLightSettings +{ + /** Scale factor for the indirect lighting */ + var(General) float IndirectLightingScale ; + /** 0 will be completely desaturated, 1 will be unchanged */ + var(General) float IndirectLightingSaturation ; + /** Controls the falloff of shadow penumbras */ + var(General) float ShadowExponent ; + + structdefaultproperties + { + IndirectLightingScale=1.0 + IndirectLightingSaturation=1.0 + ShadowExponent=2.0 + } +}; + +/** + * Point/spot settings for Lightmass + */ +struct native LightmassPointLightSettings extends LightmassLightSettings +{ + /** The radius of the light's emissive surface, not the light's influence. */ + var(Point) float LightSourceRadius ; + + /** + * IMPORTANT NOTE: This is no longer the default property. It is 32.0. + * However, to avoid breaking existing content, the value is set in + * the APointLight::Spawned function... So if you want to change the + * default again - do it there. + * Yes - it will increase the size on disc to change the default + * property using this method - but it will only be 4 bytes per point + * light serialized to disk (assuming they are using the default + * value). With the move to GI, levels will likely end up with far + * fewer lights. And with compression on shipping content, this + * should not be that big a deal. + * (The alternative is to 'rename' the variable and deprecate the old + * one fixing things up in post load. But we rarely go back and + * remove deprecate members, so this would be a net result of + * increasing each light by 4 bytes IN MEMORY) + */ + structdefaultproperties + { + LightSourceRadius=100.0 + } +}; + +/** + * Direcitonal light settings for Lightmass + */ +struct native LightmassDirectionalLightSettings extends LightmassLightSettings +{ + /** Angle that the directional light's emissive surface extends relative to a receiver, affects penumbra sizes. */ + var(Directional) float LightSourceAngle; + + structdefaultproperties + { + LightSourceAngle=3.0; + } +}; + +/** + * Per-object settings for Lightmass + */ +//@warning: this structure is manually mirrored in UnObj.h +struct LightmassPrimitiveSettings +{ + /** If TRUE, this object will be lit as if it receives light from both sides of its polygons. */ + var() bool bUseTwoSidedLighting; + /** If TRUE, this object will only shadow indirect lighting. */ + var() bool bShadowIndirectOnly; + /** If TRUE, allow using the emissive for static lighting. */ + var() bool bUseEmissiveForStaticLighting; + /** Direct lighting falloff exponent for mesh area lights created from emissive areas on this primitive. */ + var() float EmissiveLightFalloffExponent; + /** + * Direct lighting influence radius. + * The default is 0, which means the influence radius should be automatically generated based on the emissive light brightness. + * Values greater than 0 override the automatic method. + */ + var() float EmissiveLightExplicitInfluenceRadius; + /** Scales the emissive contribution of all materials applied to this object. */ + var() float EmissiveBoost; + /** Scales the diffuse contribution of all materials applied to this object. */ + var() float DiffuseBoost; + /** Scales the specular contribution of all materials applied to this object. */ + var float SpecularBoost; + /** Fraction of samples taken that must be occluded in order to reach full occlusion. */ + var() float FullyOccludedSamplesFraction; + + structdefaultproperties + { + bUseTwoSidedLighting=false + bShadowIndirectOnly=false + bUseEmissiveForstaticLighting=false + EmissiveLightFalloffExponent=2.0 + EmissiveLightExplicitInfluenceRadius=0.0 + EmissiveBoost=1.0 + DiffuseBoost=1.0 + SpecularBoost=1.0 + FullyOccludedSamplesFraction=1.0 + } +}; + +/** + * Debug options for Lightmass + */ +struct native LightmassDebugOptions +{ + /** + * If FALSE, UnrealLightmass.exe is launched automatically (default) + * If TRUE, it must be launched manually (e.g. through a debugger) with the -debug command line parameter. + */ + var() bool bDebugMode; + + /** + * If TRUE, all participating Lightmass agents will report back detailed stats to the log. + */ + var() bool bStatsEnabled; + + /** + * If TRUE, BSP surfaces split across model components are joined into 1 mapping + */ + var() bool bGatherBSPSurfacesAcrossComponents; + + /** + * The tolerance level used when gathering BSP surfaces. + */ + var() float CoplanarTolerance; + + /** + * If TRUE, deterministic lighting mode will be used. + */ + var() bool bUseDeterministicLighting; + + /** + * If TRUE, Lightmass will import mappings immediately as they complete. + * It will not process them, however. + */ + var() bool bUseImmediateImport; + + /** + * If TRUE, Lightmass will process appropriate mappings as they are imported. + * NOTE: Requires ImmediateMode be enabled to actually work. + */ + var() bool bImmediateProcessMappings; + + /** + * If TRUE, Lightmass will sort mappings by texel cost. + */ + var() bool bSortMappings; + + /** + * If TRUE, the generate coefficients will be dumped to binary files. + */ + var() bool bDumpBinaryFiles; + + /** + * If TRUE, Lightmass will write out BMPs for each generated material property + * sample to \ScreenShots\Materials. + */ + var() bool bDebugMaterials; + + /** + * If TRUE, Lightmass will pad the calculated mappings to reduce/eliminate seams. + */ + var() bool bPadMappings; + + /** + * If TRUE, will fill padding of mappings with a color rather than the sampled edges. + * Means nothing if bPadMappings is not enabled... + */ + var() bool bDebugPaddings; + + /** + * If TRUE, only the mapping containing a debug texel will be calculated, all others + * will be set to white + */ + var() bool bOnlyCalcDebugTexelMappings; + + /** If TRUE, color lightmaps a random color */ + var() bool bUseRandomColors; + + /** If TRUE, a green border will be placed around the edges of mappings */ + var() bool bColorBordersGreen; + + /** + * If TRUE, Lightmass will overwrite lightmap data with a shade of red relating to + * how long it took to calculate the mapping (Red = Time / ExecutionTimeDivisor) + */ + var() bool bColorByExecutionTime; + + /** + * The amount of time that will be count as full red when bColorByExecutionTime is enabled + */ + var() float ExecutionTimeDivisor; + + var bool bInitialized; + + structcpptext + { + //@lmtodo. For some reason, the global instance is not initializing to the default settings... + // Be sure to update this function to properly set the desired initial values!!!! + void Touch(); + } + + structdefaultproperties + { + bDebugMode=false + bStatsEnabled=false + bGatherBSPSurfacesAcrossComponents=true + CoplanarTolerance=0.001f + bUseDeterministicLighting=true + bUseImmediateImport=true + bImmediateProcessMappings=true + bSortMappings=true + bDumpBinaryFiles=false + bDebugMaterials=false + bPadMappings=true + bDebugPaddings=false + bOnlyCalcDebugTexelMappings=false + bColorByExecutionTime=false + ExecutionTimeDivisor=15.0f + } +}; + +/** + * Debug options for Swarm + */ +struct native SwarmDebugOptions +{ + /** + * If TRUE, Swarm will distribute jobs. + * If FALSE, only the local machine will execute the jobs. + */ + var() bool bDistributionEnabled; + + /** + * If TRUE, Swarm will force content to re-export rather than using the cached version. + * If FALSE, Swarm will attempt to use the cached version. + */ + var() bool bForceContentExport; + + var bool bInitialized; + + structcpptext + { + //@lmtodo. For some reason, the global instance is not initializing to the default settings... + // Be sure to update this function to properly set the desired initial values!!!! + void Touch(); + } + + structdefaultproperties + { + bDistributionEnabled=true + bForceContentExport=false + } +}; + +/** + * Contains precomputed curve of root motion for a particular animation + */ +struct native RootMotionCurve +{ + /** + * Name of the animation this curve is associated with + */ + var() Name AnimName; + + /** + * List of vectors offset from the start of the curve + */ + var() InterpCurveVector Curve; + /** + * The max input value of the curve + */ + var() float MaxCurveTime; +}; + +/** reference to a specific material in a PrimitiveComponent */ +struct native PrimitiveMaterialRef +{ + var PrimitiveComponent Primitive; + var int MaterialIndex; + + structcpptext + { + FPrimitiveMaterialRef() + {} + FPrimitiveMaterialRef(EEventParm) + { + appMemzero(this, sizeof(FPrimitiveMaterialRef)); + } + FPrimitiveMaterialRef(UPrimitiveComponent* InPrimitive, INT InMaterialIndex) + : Primitive(InPrimitive), MaterialIndex(InMaterialIndex) + {} + } +}; + +/** reference to a specific material in a MaterialEffect */ +struct native PostProcessMaterialRef +{ + var MaterialEffect Effect; + + structcpptext + { + FPostProcessMaterialRef() + {} + FPostProcessMaterialRef(EEventParm) + { + appMemzero(this, sizeof(FPostProcessMaterialRef)); + } + FPostProcessMaterialRef(UMaterialEffect* InEffect) + : Effect(InEffect) + {} + } +}; + +/** used by matinee material parameter tracks to hold material references to modify */ +struct native MaterialReferenceList +{ + var() MaterialInterface TargetMaterial; + var edithide array AffectedMaterialRefs; + var edithide array AffectedPPChainMaterialRefs; +}; + +struct native VelocityObstacleStat +{ + var Vector Position; + var Vector Velocity; + var float Radius; + var int Priority; +}; \ No newline at end of file diff --git a/Engine/Classes/EnvironmentVolume.uc b/Engine/Classes/EnvironmentVolume.uc new file mode 100644 index 0000000..7d40dd0 --- /dev/null +++ b/Engine/Classes/EnvironmentVolume.uc @@ -0,0 +1,128 @@ + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * Used to define certain gameplay areas, and has optional support for interacting with the NavMesh + * (To block some types of enemies from pathing through it). + */ + +class EnvironmentVolume extends Volume + native(AI) + implements(Interface_NavMeshPathObstacle) + implements(Interface_NavMeshPathObject) + placeable; + +/** Keep track is NavMesh is split by this volume to affect AI pathing. + * Change this through SetSplitNavMesh() */ +var const transient bool bSplitNavMesh; + +cpptext +{ + virtual UBOOL ShouldAIAvoidMe(AAIController* AIC); + + virtual void BeginDestroy() + { + Super::BeginDestroy(); + + // Unsplit if it was split. + if( bSplitNavMesh ) + { + SetSplitNavMesh(FALSE); + } + } + + ////////////////////////////////////////////////////////////////////////// + // Interface_NavMeshPathObject + /** + * Called from edges linked to this PO + * @param Interface - the navhandle interface of the entity pathing + * @param PreviousPoint - the previous point in the path search (e.g. the point along the predecessor edge) + * @param out_PathEdgePoint - the point we used along this edge to determine the cost + * @param Edge - the edge linked to this PO which needs to compute cost + * @return - the cost for traversing this edge + */ + virtual INT CostFor( const FNavMeshPathParams& PathParams, const FVector& PreviousPoint, FVector& out_PathEdgePoint, FNavMeshPathObjectEdge* Edge, FNavMeshPolyBase* SourcePoly ); + + /** + * called to allow this PO to draw custom stuff for edges linked to it + * @param DRSP - the sceneproxy we're drawing for + * @param DrawOffset - offset from the actual location we should be drawing + * @param Edge - the edge we're drawing + * @return - whether this PO is doing custom drawing for the passed edge (FALSE indicates the default edge drawing functionality should be used) + */ + virtual UBOOL DrawEdge( FDebugRenderSceneProxy* DRSP, FColor C, FVector DrawOffset, FNavMeshPathObjectEdge* Edge ); + // END path object interface + ////////////////////////////////////////////////////////////////////////// + + + ////////////////////////////////////////////////////////////////////////// + // Interface_NavMeshPathObstacle + /** + * this function should populate out_polyshape with a list of verts which describe this object's + * convex bounding shape + * @param out_PolyShape - output array which holds the vertex buffer for this obstacle's bounding polyshape + * @return TRUE if this object should block things right now (FALSE means this obstacle shouldn't affect the mesh) + */ + virtual UBOOL GetBoundingShape(TArray& out_PolyShape,INT ShapeIdx); + + /** + * when TRUE polys internal to this obstacle will be preserved, but still split. (useful for things like cost volumes that + * need to adjust cost but not completely destroy parts of the mesh + * @return TRUE if polys should be preserved internal to this obstacle + */ + virtual UBOOL PreserveInternalPolys() { return TRUE; } + + /** + * This function is called when an edge is going to be added connecting a polygon internal to this obstacle to another polygon which is not + * Default behavior just a normal edge, override to add special costs or behavior (e.g. link a pathobject to the obstacle) + * @param Status - current status of edges (e.g. what still needs adding) + * @param inV1 - vertex location of first vert in the edge + * @param inV2 - vertex location of second vert in the edge + * @param ConnectedPolys - the polys this edge links + * @param bEdgesNeedToBeDynamic - whether or not added edges need to be dynamic (e.g. we're adding edges between meshes) + * @param PolyAssocatedWithThisPO - the index into the connected polys array parmaeter which tells us which poly from that array is associated with this path object + * @(optional) param SupportedEdgeWidth - width of unit that this edge supports, defaults to -1.0f meaning the length of the edge itself will be used + * @(optional) param EdgeGroupID - ID of the edgegroup this edge is a part of (defaults to no group) + * @return returns an enum describing what just happened (what actions did we take) - used to determien what accompanying actions need to be taken + * by other obstacles and calling code + */ + virtual EEdgeHandlingStatus AddObstacleEdge( EEdgeHandlingStatus Status, const FVector& inV1, const FVector& inV2, TArray& ConnectedPolys, UBOOL bEdgesNeedToBeDynamic, INT PolyAssocatedWithThisPO, FLOAT SupportedEdgeWidth=-1.0f, BYTE EdgeGroupID=MAXBYTE); + + + /** + * For debugging. Verifies that this pathobject is still alive and well and not orphaned or deleted + * @return - TRUE If this path object is in good working order + */ + virtual UBOOL Verify() + { + return !IsPendingKill(); + } + + virtual UBOOL VerifyObstacle() + { + return Verify(); + } + + // END Interface_NavMeshPathObstacle + ////////////////////////////////////////////////////////////////////////// + + /** + * Removes the volume from world info's list of environment volumes. + */ + virtual void ClearComponents( void ); + +protected: + /** + * Adds the volume to world info's list of environment volumes. + */ + virtual void UpdateComponentsInternal( UBOOL bCollisionUpdate = FALSE ); +public: +} + +/** Should this volume register and split the NavMesh to affect AI pathing? */ +final native function SetSplitNavMesh(bool bNewValue); + +defaultproperties +{ + bSplitNavMesh=FALSE // That should not be changed, only through SetSplitNavMesh(). +} diff --git a/Engine/Classes/ExponentialHeightFog.uc b/Engine/Classes/ExponentialHeightFog.uc new file mode 100644 index 0000000..6063e65 --- /dev/null +++ b/Engine/Classes/ExponentialHeightFog.uc @@ -0,0 +1,89 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ExponentialHeightFog extends Info + showcategories(Movement) + ClassGroup(Fog) + placeable; + +var() const editconst ExponentialHeightFogComponent Component; + +/** replicated copy of ExponentialHeightFogComponent's bEnabled property */ +var repnotify bool bEnabled; + +replication +{ + if (Role == ROLE_Authority) + bEnabled; +} + +event PostBeginPlay() +{ + Super.PostBeginPlay(); + + bEnabled = Component.bEnabled; +} + +simulated event ReplicatedEvent(name VarName) +{ + if (VarName == 'bEnabled') + { + Component.SetEnabled(bEnabled); + } + else + { + Super.ReplicatedEvent(VarName); + } +} + +/* epic =============================================== +* ::OnToggle +* +* Scripted support for toggling height fog, checks which +* operation to perform by looking at the action input. +* +* Input 1: turn on +* Input 2: turn off +* Input 3: toggle +* +* ===================================================== +*/ +simulated function OnToggle(SeqAct_Toggle action) +{ + if (action.InputLinks[0].bHasImpulse) + { + // turn on + Component.SetEnabled(TRUE); + } + else if (action.InputLinks[1].bHasImpulse) + { + // turn off + Component.SetEnabled(FALSE); + } + else if (action.InputLinks[2].bHasImpulse) + { + // toggle + Component.SetEnabled(!Component.bEnabled); + } + bEnabled = Component.bEnabled; + ForceNetRelevant(); + SetForcedInitialReplicatedProperty(Property'Engine.ExponentialHeightFog.bEnabled', (bEnabled == default.bEnabled)); +} + +defaultproperties +{ + TickGroup=TG_DuringAsyncWork + + Begin Object Class=ExponentialHeightFogComponent Name=HeightFogComponent0 + End Object + Component=HeightFogComponent0 + Components.Add(HeightFogComponent0) + + Begin Object Name=Sprite + SpriteCategoryName="Fog" + End Object + + bStatic=FALSE + bNoDelete=true + DrawScale=5 +} diff --git a/Engine/Classes/ExponentialHeightFogComponent.uc b/Engine/Classes/ExponentialHeightFogComponent.uc new file mode 100644 index 0000000..343034f --- /dev/null +++ b/Engine/Classes/ExponentialHeightFogComponent.uc @@ -0,0 +1,87 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ExponentialHeightFogComponent extends ActorComponent + native(FogVolume) + collapsecategories + hidecategories(Object) + editinlinenew; + +/** True if the fog is enabled. */ +var() const bool bEnabled; + +/** z-height for the fog plane - updated by the owning actor */ +var const float FogHeight; + +/** Global density factor. */ +var() const interp float FogDensity; + +/** + * Height density factor, controls how the density increases as height decreases. + * Smaller values make the visible transition larger. + */ +var() const interp float FogHeightFalloff; + +/** + * Maximum opacity of the fog. + * A value of 1 means the fog can become fully opaque at a distance and replace scene color completely, + * A value of 0 means the fog color will not be factored in at all. + */ +var() const interp float FogMaxOpacity; + +/** Distance from the camera that the fog will start, in world units. */ +var() const interp float StartDistance; + +/** + * LightInscatteringColor is used in the direction of the dominant directional light, and OppositeLightColor is used in the opposite direction. + * LightTerminatorAngle is the angle in degrees from the dominant directional light that an even amount of OppositeLightColor and LightInscatteringColor are used for the final fog color. + * If there is no dominant directional light enabled, LightInscatteringColor will correspond to up in world space. + */ +var() const interp float LightTerminatorAngle; + +/** Scales OppositeLightColor. */ +var() const interp float OppositeLightBrightness; + +/** Fog Color used for the opposite direction from the dominant directional light. */ +var() const interp color OppositeLightColor; + +/** Scales LightInscatteringColor. */ +var() const interp float LightInscatteringBrightness; + +/** Fog Color used for the direction of the dominant directional light. */ +var() const interp color LightInscatteringColor; + +cpptext +{ +protected: + // ActorComponent interface. + virtual void SetParentToWorld(const FMatrix& ParentToWorld); + virtual void Attach(); + virtual void UpdateTransform(); + virtual void Detach( UBOOL bWillReattach = FALSE ); +public: + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); +} + +/** + * Changes the enabled state of the height fog component. + * @param bSetEnabled - The new value for bEnabled. + */ +final native function SetEnabled(bool bSetEnabled); + +defaultproperties +{ + TickGroup=TG_DuringAsyncWork + + bEnabled=TRUE + + FogDensity=0.02 + FogHeightFalloff=0.2 + FogMaxOpacity=1 + StartDistance=0 + LightTerminatorAngle=45 + OppositeLightBrightness=.2 + OppositeLightColor=(R=177,G=208,B=255) + LightInscatteringBrightness=1 + LightInscatteringColor=(R=245,G=212,B=41) +} diff --git a/Engine/Classes/FaceFXAnimSet.uc b/Engine/Classes/FaceFXAnimSet.uc new file mode 100644 index 0000000..28e1b2c --- /dev/null +++ b/Engine/Classes/FaceFXAnimSet.uc @@ -0,0 +1,84 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class FaceFXAnimSet extends Object + hidecategories(Object) + native; + +/** + * Default FaceFXAsset to use when editing this FaceFXAnimSet etc. + * Is the one that was used as the basis for creating this AnimSet. + */ +var() editoronly const FaceFXAsset DefaultFaceFXAsset; + +/** Internal use. FaceFX representation of this AnimSet. */ +var const native pointer InternalFaceFXAnimSet; +/** + * Internal use. Raw bytes of the FaceFX AnimSet. + * This only stays loaded in the editor. + */ +var const native array RawFaceFXAnimSetBytes; +/** + * Internal use. Raw bytes of the FaceFX Studio mini session for this AnimSet. + * This only stays loaded in the editor. + */ +var const native array RawFaceFXMiniSessionBytes; + +/** + * Array of SoundCue objects that the FaceFXAnimSet references. + */ +var editoronly notforconsole array ReferencedSoundCues; + +// WWISEMODIF_START +/** + * Array of AkEvent objects that the FaceFXAnimSet references. + */ +var editoronly notforconsole array ReferencedAkEvents; +// WWISEMODIF_END + +/** + * Internal use. The number of errors generated during load. + */ +var int NumLoadErrors; + +cpptext +{ + /** Creates a new FaceFX AnimSet for the given FaceFX Asset. This is only called from within the editor. */ + void CreateFxAnimSet( class UFaceFXAsset* FaceFXAsset ); + + /** Get list of FaceFX animations in this AnimSet. Names are in the form GroupName.AnimName.*/ + void GetSequenceNames(TArray& OutNames); + +#if WITH_FACEFX + /** Returns the internal FaceFX representation of this FaceFX AnimSet. */ + class OC3Ent::Face::FxAnimSet* GetFxAnimSet( void ); +#endif + + /** Fixes up the ReferencedSoundCue stuff. */ + void FixupReferencedSoundCues(); + + // UObject interface. + + /** + * Returns a one line description of an object for viewing in the thumbnail view of the generic browser + */ + virtual FString GetDesc(); + virtual void PostLoad(); + virtual void FinishDestroy(); + virtual void Serialize(FArchive& Ar); + + /** + * Returns the size of the object/ resource for display to artists/ LDs in the Editor. + * + * @return size of resource as to be displayed to artists/ LDs in the Editor. + */ + INT GetResourceSize(); + + /** + * Used by various commandlets to purge editor only and platform-specific data from various objects + * + * @param PlatformsToKeep Platforms for which to keep platform-specific data + * @param bStripLargeEditorData If TRUE, data used in the editor, but large enough to bloat download sizes, will be removed + */ + virtual void StripData(UE3::EPlatformType PlatformsToKeep, UBOOL bStripLargeEditorData); +} \ No newline at end of file diff --git a/Engine/Classes/FaceFXAsset.uc b/Engine/Classes/FaceFXAsset.uc new file mode 100644 index 0000000..fc5013e --- /dev/null +++ b/Engine/Classes/FaceFXAsset.uc @@ -0,0 +1,109 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class FaceFXAsset extends Object + hidecategories(Object) + native; + +/** + * Default skeletal mesh to use when previewing this FaceFXAsset etc. + * Is the one that was used as the basis for creating this Asset. + */ +var const editoronly SkeletalMesh DefaultSkelMesh; + +/** Internal use. FaceFX representation of this asset. */ +var const native pointer FaceFXActor; +/** + * Internal use. Raw bytes of the FaceFX Actor for this asset. + * This only stays loaded in the editor. + */ +var const native array RawFaceFXActorBytes; +/** + * Internal use. Raw bytes of the FaceFX Studio session for this asset. + * This only stays loaded in the editor. + */ +var const native array RawFaceFXSessionBytes; + +/** + * MorphTargetSets used when previewing this FaceFXAsset in FaceFX Studio. + * Note that these are only valid in the editor. + */ +var() editoronly array PreviewMorphSets; + +/** + * Array of currently mounted FaceFXAnimSets. + * We only track this if GIsEditor! + */ +var transient array MountedFaceFXAnimSets; + +/** + * Array of SoundCue objects that the FaceFXAsset references. + */ +var editoronly notforconsole array ReferencedSoundCues; + +// WWISEMODIF_START +/** + * Array of AkEvent objects that the FaceFXAsset references. + */ +var editoronly notforconsole array ReferencedAkEvents; +// WWISEMODIF_END + +/** + * Internal use. The number of errors generated during load. + */ +var int NumLoadErrors; + +/** + * Mounts the specified FaceFXAnimSet into this FaceFXAsset. + */ +native final function MountFaceFXAnimSet( FaceFXAnimSet AnimSet ); + +/** + * Internal use. Unmounts the specified FaceFXAnimSet from this FaceFXAsset. + */ +native final function UnmountFaceFXAnimSet( FaceFXAnimSet AnimSet ); + +cpptext +{ + /** Creates a new FaceFX Actor for this FaceFX Asset. This is only called from within the editor. */ + void CreateFxActor( class USkeletalMesh* SkelMesh ); + + /** + * Get list of FaceFX animations in this Asset. Names are in the form GroupName.AnimName. + * @param bExcludeMountedGroups If true, do not show animations that are in separate FaceFXAnimSets currently mounted to the Asset. + */ + void GetSequenceNames(UBOOL bExcludeMountedGroups, TArray& OutNames); + +#if WITH_FACEFX + /** Returns the internal FaceFX representation of this FaceFX Asset. */ + class OC3Ent::Face::FxActor* GetFxActor( void ); +#endif + + /** Fixes up the ReferencedSoundCue stuff. */ + void FixupReferencedSoundCues(); + + // UObject interface. + + /** + * Returns a one line description of an object for viewing in the thumbnail view of the generic browser + */ + virtual FString GetDesc(); + virtual void PostLoad(); + virtual void FinishDestroy(); + virtual void Serialize(FArchive& Ar); + + /** + * Returns the size of the object/ resource for display to artists/ LDs in the Editor. + * + * @return size of resource as to be displayed to artists/ LDs in the Editor. + */ + INT GetResourceSize(); + + /** + * Used by various commandlets to purge editor only and platform-specific data from various objects + * + * @param PlatformsToKeep Platforms for which to keep platform-specific data + * @param bStripLargeEditorData If TRUE, data used in the editor, but large enough to bloat download sizes, will be removed + */ + virtual void StripData(UE3::EPlatformType PlatformsToKeep, UBOOL bStripLargeEditorData); +} \ No newline at end of file diff --git a/Engine/Classes/FacebookIntegration.uc b/Engine/Classes/FacebookIntegration.uc new file mode 100644 index 0000000..17a795f --- /dev/null +++ b/Engine/Classes/FacebookIntegration.uc @@ -0,0 +1,85 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * This is the base class for Facebook integration (each platform has a subclass + */ +class FacebookIntegration extends PlatformInterfaceBase + native(PlatformInterface) + config(Engine); + + + +enum EFacebookIntegrationDelegate +{ + FID_AuthorizationComplete, + FID_FacebookRequestComplete, + FID_DialogComplete, + FID_FriendsListComplete, +}; + + +/** The application ID to link to */ +var config string AppID; + +/** Permissions that are expected by game - see: http://developers.facebook.com/docs/authentication/permissions/ */ +var config array Permissions; + +/** Username of the current user */ +var string Username; + +/** Id of the current user */ +var string UserId; + +/** Access token as retrieved from FB */ +var string AccessToken; + + +/** Structure to hold a Facebook friend */ +struct native FacebookFriend +{ + /** The user's display name */ + var string Name; + + /** The user's id, can be used to send messages, etc */ + var string Id; +}; + +/** The list of friends that is filled out as soon as the user logs on */ +var array FriendsList; + + +/** + * Perform any needed initialization + */ +native event bool Init(); + +/** + * Starts the process of allowing the app to use Facebook + */ +native event bool Authorize(); + +/** + * @return true if the app has been authorized by the current user + */ +native event bool IsAuthorized(); + +/** + * Kicks off a Facebook GraphAPI request (response will come via delegate) + * + * @param GraphRequest The request to make (like "me/groups") + */ +native event FacebookRequest(string GraphRequest); + +/** + * Shows a facebook dialog (ie, posting to wall) + * + * @param Action The dialog to open (like "feed") + * @param KeysAndValues The extra parameters to pass to the dialog (dialog specific). Separate keys and values: < "key1", "value1", "key2", "value2" > + */ +native event FacebookDialog(string Action, array ParamKeysAndValues); + +/** + * Call this to disconnect from Facebook. Next time authorization happens, the auth webpage + * will be shown again + */ +native event Disconnect(); diff --git a/Engine/Classes/FailedConnect.uc b/Engine/Classes/FailedConnect.uc new file mode 100644 index 0000000..8ffca9f --- /dev/null +++ b/Engine/Classes/FailedConnect.uc @@ -0,0 +1,41 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class FailedConnect extends LocalMessage + abstract; + +var localized string FailMessage[4]; + +static function int GetFailSwitch(string FailString) +{ + if ( FailString ~= "NEEDPW" ) + return 0; + + if ( FailString ~= "WRONGPW" ) + return 1; + + if ( FailString ~="GAMESTARTED" ) + return 2; + + return 3; +} + +static function string GetString( + optional int Switch, + optional bool bPRI1HUD, + optional PlayerReplicationInfo RelatedPRI_1, + optional PlayerReplicationInfo RelatedPRI_2, + optional Object OptionalObject + ) +{ + return Default.FailMessage[Clamp(Switch,0,3)]; +} + +defaultproperties +{ + bBeep=false + bIsUnique=True + + DrawColor=(R=255,G=0,B=128,A=255) + FontSize=1 +} diff --git a/Engine/Classes/FileLog.uc b/Engine/Classes/FileLog.uc new file mode 100644 index 0000000..ecd15f9 --- /dev/null +++ b/Engine/Classes/FileLog.uc @@ -0,0 +1,40 @@ +/** + * Opens a file on disk for logging purposes. Spawn one, then call + * OpenLog() with the desired file name, output using Logf(), and then + * finally call CloseLog(), or destroy the FileLog actor. + * + * This functionality has been moved to the new FileWriter class. Stubs + * have been left here for compatibility + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class FileLog extends FileWriter + native; + +/** + * Opens the actual file using the specified name. + * + * @param LogFilename - name of file to open + * + * @param extension - optional file extension to use, defaults to + * .txt if none is specified + * + * @param bUnique - Makes sure the file is unique + + */ + +function OpenLog(coerce string LogFilename, optional string extension, optional bool bUnique) +{ + OpenFile(LogFilename, FWFT_Log, extension, bUnique); +} + +/** + * Closes the log file. + */ + +function CloseLog() +{ + CloseFile(); +} + + diff --git a/Engine/Classes/FileWriter.uc b/Engine/Classes/FileWriter.uc new file mode 100644 index 0000000..b6ffbe4 --- /dev/null +++ b/Engine/Classes/FileWriter.uc @@ -0,0 +1,80 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * This is a simple class that allows for secure writing of output files from within Script. The directory to which it writes + * files is determined by the file type member variable. +*/ + +class FileWriter extends Info + native; + +/** Internal FArchive pointer */ +var const native pointer ArchivePtr{FArchive}; + +/** File name, created via OpenFile() */ +var const string Filename; + +/** Type of file */ +enum FWFileType +{ + FWFT_Log, // Created in %GameDir%/Logs + FWFT_Stats, // Created in %GameDir%/Stats + FWFT_HTML, // Created in %GameDir%/Web/DynamicHTML + FWFT_User, // Created in %GameDir%/User + FWFT_Debug, // Created in %GameDir%/Debug +}; + +/** Holds the file type for this file. */ +var const FWFileType FileType; + +/** + * Whether we should flush to disk every time something is written. + * if false, only flush when the memory buffer is full or when the file is closed + */ +var bool bFlushEachWrite; + +/** Whether to use async writes (if available) or not. Overrides bFlushEachWrite */ +var bool bWantsAsyncWrites; + +cpptext +{ + virtual void BeginDestroy(); +} + +/** + * Opens the actual file using the specified name. + * + * @param InFilename name of file to open + * @param InFileType the type of file being written + * @param InExtension optional file extension to use, defaults to .txt if none is specified + * @param bUnique whether to make unique or not + * @param bIncludeTimeStamp whether to include timestamps or not + */ +native final function bool OpenFile(coerce string InFilename, optional FWFileType InFileType, + optional string InExtension, optional bool bUnique, optional bool bIncludeTimeStamp); + +/** + * Closes the log file. + */ +native final function CloseFile(); + +/** + * Logs the given string to the log file. + * + * @param logString - string to dump + */ +native final function Logf(coerce string logString); + +/** + * Overridden to automatically close the logfile on destruction. + */ +event Destroyed() +{ + CloseFile(); +} + +defaultproperties +{ + bFlushEachWrite=true + bTickIsDisabled=true +} diff --git a/Engine/Classes/FlexActor.uc b/Engine/Classes/FlexActor.uc new file mode 100644 index 0000000..71e033f --- /dev/null +++ b/Engine/Classes/FlexActor.uc @@ -0,0 +1,18 @@ +//============================================================================= +// Copyright 1998-2012 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class FlexActor extends InterpActor + native + placeable; + +defaultproperties +{ + Begin Object Class=FlexComponent Name=FlexComponent0 + BlockRigidBody=false + LightEnvironment=MyLightEnvironment + bUsePrecomputedShadows=FALSE + End Object + StaticMeshComponent=FlexComponent0 + Components.Remove(StaticMeshComponent0) + Components.Add(FlexComponent0) +} diff --git a/Engine/Classes/FlexAsset.uc b/Engine/Classes/FlexAsset.uc new file mode 100644 index 0000000..bede5b3 --- /dev/null +++ b/Engine/Classes/FlexAsset.uc @@ -0,0 +1,121 @@ +/*============================================================================= + FlexAsset.uc: Flex Asset. + Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +=============================================================================*/ + +/* A Flex asset contains the particle and constraint data for a shape, such as cloth, rigid body or inflatable, an asset + is added to a container by spawning through a particle system or Flex actor */ + +class FlexAsset extends Object + native(Physics) + editinlinenew + hidecategories(Object); + +/** The Flex asset type */ +enum EFlexAssetType +{ + FLEX_Cloth, // a particle/constraint network + FLEX_Solid, // solid sampling of the mesh interior for rigid bodies +}; + +//============================================================================= +// Flex Container Parameters +//============================================================================= + + /** The asset type, can either be a thin shell (cloth), or a solid (rigid body) */ + var(Common) EFlexAssetType Type; + + // NVCHANGE_BEGIN: HLLU - Add flex container to flex asset + /** The flex container this asset will use. This container can be overwritten by the FlexActor's container */ + var (Common) FlexContainer FlexAssetContainerTemplate; + + /** The phase-id to assign to particles spawned for this mesh. This can be overwritten by the FlexActor's FlexComponentPhaseId */ + var (Common) int FlexAssetPhaseId; + + /** If true then the particles will be auto-assigned a positive phase-id. This bool can be overwritten by the FlexActor's bFlexComponentAutoAssignPhase */ + var (Common) bool bFlexAssetAutoAssignPhase; + // NVCHANGE_END: HLLU - Add flex container to flex asset + + /** The per-particle mass to use for the particles, for clothing this value be multiplied by 0-1 dependent on the vertex color */ + var(Common) float Mass; + + /** How much the cloth resists stretching */ + var(Cloth) float StretchStiffness; + + /** How much the cloth resists bending */ + var(Cloth) float BendStiffness; + + /** How strong tethers resist stretching */ + var(Cloth) float TetherStiffness; + + /** How much tethers have to stretch past their rest-length before becoming enabled, 0.1=10% elongation */ + var(Cloth) float TetherGive; + + /** Can be enabled for closed meshes, a volume conserving constraint will be added to the simulation */ + var(Inflatable) bool bEnableInflatable; + + /** The inflatable pressure, a value of 1.0 corresponds to the rest volume, 0.5 corressponds to being deflated by half, and values > 1.0 correspond to over-inflation */ + var(Inflatable) float OverPressure; + + /** The rigid body stiffness */ + var(Rigid) float RigidStiffness; + + /** The spacing to use when sampling solid shapes with particles, this should be close to radius of the container this asset will be spawned in */ + var(Rigid) float RigidSamplingDistance; + + /** Store the rigid body center of mass, not editable */ + var vector RigidCenter; + + var float InflatableStiffness; + var float InflatableVolume; + + // the particles and constraints created from the mesh + var array Particles; + var array Phases; + + var array SpringIndices; + var array SpringCoefficients; + var array SpringRestLengths; + + // faces for cloth + var array Triangles; + var array VertexToParticleMap; + + var transient native const pointer Object {struct FlexExtObject}; + +cpptext +{ +#if WITH_EDITOR + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); +#endif // WITH_EDITOR + + virtual void PostLoad(); + virtual void BeginDestroy(); + + virtual void Serialize(FArchive& Ar); +#if WITH_FLEX + FlexExtObject* GetFlexExtObject(); +#endif //WITH_FLEX + void ReImport(const UStaticMesh* Parent); +} + + + +defaultproperties +{ + Type = FLEX_Cloth + // NVCHANGE_BEGIN: HLLU - Add flex container to flex asset + FlexAssetPhaseId = 0 + bFlexAssetAutoAssignPhase = true + // NVCHANGE_END: HLLU - Add flex container to flex asset + Mass = 1.0f + StretchStiffness = 1.0f + BendStiffness = 1.0f + TetherStiffness = 1.0f + TetherGive = 0.1f + bEnableInflatable = false + OverPressure = 1.0f + InflatableStiffness = 1.0f + RigidStiffness = 0.0f + RigidSamplingDistance = 40.0f +} diff --git a/Engine/Classes/FlexComponent.uc b/Engine/Classes/FlexComponent.uc new file mode 100644 index 0000000..98084fe --- /dev/null +++ b/Engine/Classes/FlexComponent.uc @@ -0,0 +1,61 @@ +/** + * Copyright 1998-2012 Epic Games, Inc. All Rights Reserved. + */ +class FlexComponent extends StaticMeshComponent + native(Mesh); + +struct transient native FlexParticleAttachment +{ + var PrimitiveComponent Primitive; + var int ShapeIndex; + var int ParticleIndex; + var float OldMass; + var Vector LocalPos; +}; + + +/** The simulation container to spawn any flex data contained in the static mesh into. If the static mesh has Flex data then it will be spawned into this simulation container. */ +var (FlexComponent) notforconsole FlexContainer FlexComponentContainerTemplate; + +/** The phase-id to assign to particles spawned for this mesh */ +var (FlexComponent) notforconsole int FlexComponentPhaseId; + +/** If true then the particles will be auto-assigned a positive phase-id */ +var (FlexComponent) notforconsole bool bFlexComponentAutoAssignPhase; + +/** If true then the particles will be attached to any overlapping shapes on spawn*/ +var (FlexComponent) notforconsole bool bFlexComponentAttachToRigids; + +/** Instance of a FlexAsset referencing particles and constraints in a solver */ +var notforconsole transient native const pointer FlexComponentAssetInstance {struct FlexExtInstance}; +/* The simulation container the instance belongs to */ +var notforconsole transient native const pointer FlexComponentContainerInstance {class FFlexContainerInstance}; +/* Pre-simulated particle positions */ +var notforconsole const array FlexComponentPreSimPositions; + +/* Simulated particle positions */ +var notforconsole transient native const array SimPositions; +/* Simulated particle normals */ +var notforconsole transient native const array SimNormals; + +/* Attachments to rigid bodies */ +var notforconsole transient array Attachments; + +cpptext +{ + virtual void InitComponentRBPhys(UBOOL bFixed); + virtual void TermComponentRBPhys(FRBPhysScene *InScene); + virtual void UpdateBounds(); + virtual FPrimitiveSceneProxy* CreateSceneProxy(); + virtual UBOOL ShouldRecreateProxyOnUpdateTransform() const; + virtual void DisableSim(); + virtual void EnableSim(); + virtual void Synchronize(); +} + +defaultproperties +{ + FlexComponentPhaseId = 0 + bFlexComponentAutoAssignPhase = true + bFlexComponentAttachToRigids = false +} diff --git a/Engine/Classes/FlexContainer.uc b/Engine/Classes/FlexContainer.uc new file mode 100644 index 0000000..0d01fb5 --- /dev/null +++ b/Engine/Classes/FlexContainer.uc @@ -0,0 +1,222 @@ +/*============================================================================= + FlexContainer.uc: PhysX Emitter Source. + Copyright 2007-2008 AGEIA Technologies. +=============================================================================*/ + +class FlexContainer extends Object + native(Physics) + hidecategories(Object); + + +//============================================================================= +// Flex Container Parameters +//============================================================================= + +enum RelaxationMode +{ + /** The relaxation factor is a fixed multiplier on each constraint's position delta. */ + RelaxationMode_Global, + /** The relaxation factor is a fixed multiplier on each constraint's delta divided by the particle's constraint count, convergence will be slower but more reliable. */ + RelaxationMode_Local, +}; + +struct native ParticleInfo +{ + /** The maximum number of particles in this solver. */ + var() int MaxParticles; + /** The percent of MaxParticles for flex mesh particles, the left is for flex fluid particles. */ + var() float MeshParticlesBudget ; +}; + + /** The radius of particles in this container. */ + var(Flex) float Radius; + + /** The number of particle settings at the different PhysXLevel */ + var(Flex) array MaxParticlesAtPhysXLevel; + + /** Enable debug drawing for this container */ + var(Flex) bool bDebugDrawPoints; + + /** Percentage of radius spheres to be drawn in this container */ + var(Flex) float DebugDrawSpheres ; + + /** Number of solver iterations to perform per-substep */ + var(Simulation) int NumIterations; + + /** Number of sub-steps to take, each sub-step will perform NumIterations constraint iterations. Increasing sub-steps is generally more expensive than taking more solver iterations, but can be more effective at increasing stability. */ + var(Simulation) int NumSubsteps; + + /** Controls the minimum frame-rate that Flex will attempt to sub-step, any time-steps from the game are clamped to this minimum. + * Setting this lower will result in more sub-steps being taken so it should be set as high as possible, (although the simulation + * will appear to run slower than real-time if the game cannot maintain this frame rate). + */ + var (Simulation) int MinFrameRate; + + /** + * If true then each sub-step uses a fixed timestep = 1/(NumSubsteps*60) seconds and will take multiple sub-steps if necessary. + * If this value is false then each substep will use the variable game's dt/NumSubsteps and will take NumSubsteps steps. + * It is highly recommended to leave FixedTimeStep enabled for improved behaviour and stability. + */ + var(Simulation) bool bFixedTimeStep; + + /** Constant acceleration applied to all particles */ + var(Simulation) vector Gravity; + + /** Particles with a velocity magnitude < this threshold will be considered fixed */ + var(Simulation) float SleepThreshold; + + /** Particle velocity will be clamped to this value at the end of each step */ + var(Simulation) float MaxVelocity; + + /** Clamp the maximum bound for this container to prevent crashes if flex particles move too far away*/ + var(Simulation) float MaxContainerBound; + + /** Control the convergence rate of the parallel solver, default: 1, values greater than 1 may lead to instability */ + var(Simulation) float RelaxationFactor; + + /** How the relaxation is applied inside the solver. */ + var(Simulation) RelaxationMode Mode; + + /** If true then a second pass of collision detection will be run against triangle meshes to prevent tunneling, usually not necessary */ + var(Collision) bool bEnableCCD; + + /** If true then particles will collide with complex collision shapes */ + var(Collision) bool bComplexCollision; + + /** Assigning RBChannel for this Flex container */ + var(Collision) ERBCollisionChannel RBChannel; + + /** Types of objects that this physics objects will collide with. */ + var(Collision) const RBCollisionChannelContainer RBCollideWithChannels; + + /** The size of grid cell used for broad phase collision culling */ + var(Collision) float CellSizeFactor; + + /** Increases the radius used during neighbor finding, this is useful if particles are expected to move significantly during a single step to ensure contacts aren't missed on subsequent iterations */ + var(Collision) float CollisionMargin; + + /** Increases the radius used during contact finding against kinematic shapes, this is useful if particles are expected to move significantly during a single step to ensure contacts aren't missed on subsequent iterations */ + var(Collision) float CollisionMarginShapes; + + /** Distance particles maintain against shapes */ + var(Collision) float CollisionDistance; + + /** Coefficient of dynamic friction when collisind against shapes*/ + var(Collision) float Friction; + + /** Multiplier for friction of particles against other particles */ + var(Collision) float ParticleFriction; + + /** Coefficient of static friction, this is used for both particle and shape collisions */ + var(Collision) float StaticFriction; + + /** Coefficient of restitution used when colliding against shapes */ + var(Collision) float Restitution; + + /** Artificially decrease the mass of particles based on height from a fixed reference point, this makes stacks and piles converge faster */ + var(Collision) float ShockPropagation; + + /** Damp particle velocity based on how many particle contacts it has */ + var(Collision) float Dissipation; + + /** Constant acceleration applied to particles that belong to dynamic triangles */ + var(Cloth) vector Wind; + + /** Drag force applied to particles belonging to dynamic triangles, proportional to velocity^2*area in the negative velocity direction */ + var(Cloth) float Drag; + + /** Lift force applied to particles belonging to dynamic triangles, proportional to velocity^2*area in the direction perpendicular to velocity and (if possible), parallel to the plane normal */ + var(Cloth) float Lift; + + /** If true, particles with phase 0 are considered fluid particles and interact using the position based fluids method */ + var(Fluid) bool bFluid; + + /** Controls the distance fluid particles are spaced at the rest density, the absolute distance is given by this value*radius, must be in the range (0, 1) */ + var(Fluid) float RestDistance ; + + /** Control how strongly particles stick to surfaces they hit, default 0.0, range [0.0, +inf] */ + var(Fluid) float Adhesion; + + /** Control how strongly particles hold each other together, default: 0.025, range [0.0, +inf] */ + var(Fluid) float Cohesion; + + /** Controls how strongly particles attempt to minimize surface area, default: 0.0, range: [0.0, +inf] */ + var(Fluid) float SurfaceTension; + + /** Smoothes particle velocities using XSPH viscosity */ + var(Fluid) float Viscosity; + + /** Increases vorticity by applying rotational forces to particles */ + var(Fluid) float VorticityConfinement; + + /** Add pressure from solid surfaces to particles */ + var(Fluid) float SolidPressure; + + /** Drag force applied to boundary fluid particles */ + var(Fluid) float FreeSurfaceDrag; + + /** Particles belonging to rigid shapes that move with a position delta magnitude > threshold will be permanently deformed in the rest pose */ + var(Rigid) float PlasticThreshold; + + /** Controls the rate at which particles in the rest pose are deformed for particles passing the deformation threshold */ + var(Rigid) float PlasticCreep; + + + + + +//============================================================================= +// Non-exposed state +//============================================================================= + +//var transient bool bDestroy; +//var transient bool bSyncFailed; +//// GBX:aalvarez Removed bIsInGame. It's unnecessary now. 2013-08-22 +// +//var native pointer PSys {class FFlexContainer}; + +defaultproperties +{ + //user properties + Radius = 15.0f + MaxParticlesAtPhysXLevel.Add((MaxParticles=8192, MeshParticlesBudget=0.3f)) + bDebugDrawPoints = false + DebugDrawSpheres = 0.0 + bEnableCCD = false + RBCollideWithChannels=(Default=TRUE,BlockingVolume=FALSE,GameplayPhysics=TRUE,EffectPhysics=TRUE) + Gravity = (X=0.0f,Y=0.0f,Z=-1000.0f) + Wind = (X=0.0f,Y=0.0f,Z=0.0f) + Viscosity = 0.0f + Friction = 0.2f + ParticleFriction = 0.1f + StaticFriction = 0.0f + Drag = 0.0f + Lift = 0.0f + NumSubsteps = 1 + MinFrameRate = 60 + NumIterations = 3 + RestDistance = 0.5f + Dissipation = 0.0f + bComplexCollision = false + CellSizeFactor = 2.0f + CollisionMargin = 0.0f + CollisionMarginShapes = 0.0f + CollisionDistance = 0.0f + PlasticThreshold = 0.0f + PlasticCreep = 0.0f + bFluid = false + SleepThreshold = 0.0f + ShockPropagation = 0.0f + Restitution = 0.01f + MaxVelocity = 5000 + MaxContainerBound = 1e12 + RelaxationFactor = 1.0f + Mode=RelaxationMode_Local + SolidPressure = 1.0f + Adhesion = 0.0f + Cohesion = 0.025f + SurfaceTension = 0.0f + VorticityConfinement = 0.0f + bFixedTimeStep = true + RBChannel=RBCC_FlexAsset +} diff --git a/Engine/Classes/FlexForceFieldActor.uc b/Engine/Classes/FlexForceFieldActor.uc new file mode 100644 index 0000000..2f16547 --- /dev/null +++ b/Engine/Classes/FlexForceFieldActor.uc @@ -0,0 +1,50 @@ +/*============================================================================= + FlexForceFieldActor.uc: Flex force field actor integration. + Copyright 2008-2011 NVIDIA Corporation. +=============================================================================*/ + +class FlexForceFieldActor extends Actor + native(Physics) + placeable + dependson(FlexForceFieldComponent); + +var() FlexForceFieldComponent ForceFieldComponent; + +/** Handling Toggle event from Kismet. */ +simulated function OnToggle(SeqAct_Toggle inAction) +{ + if (inAction.InputLinks[0].bHasImpulse) + { + ForceFieldComponent.setEnabled(TRUE); + } + else if (inAction.InputLinks[1].bHasImpulse) + { + ForceFieldComponent.setEnabled(FALSE); + } + else if (inAction.InputLinks[2].bHasImpulse) + { + ForceFieldComponent.setEnabled(!ForceFieldComponent.bEnabled); + } +} + +defaultproperties +{ + TickGroup=TG_PreAsyncWork + + Begin Object Class=FlexForceFieldComponent Name=NewFlexForceFieldComponent + End Object + ForceFieldComponent = NewFlexForceFieldComponent + Components.Add(NewFlexForceFieldComponent) + + Begin Object Class=SpriteComponent Name=Sprite + Sprite=Texture2D'EditorResources.S_RadForce' + HiddenGame=True + AlwaysLoadOnClient=False + AlwaysLoadOnServer=False + End Object + Components.Add(Sprite) + + bEdShouldSnap=True + bStatic=false + bNoDelete=false +} diff --git a/Engine/Classes/FlexForceFieldComponent.uc b/Engine/Classes/FlexForceFieldComponent.uc new file mode 100644 index 0000000..c85d8b8 --- /dev/null +++ b/Engine/Classes/FlexForceFieldComponent.uc @@ -0,0 +1,97 @@ +/*============================================================================= + FlexForceFieldComponent.uc: Flex force field component integration. + Copyright 2008-2011 NVIDIA Corporation. +=============================================================================*/ + +class FlexForceFieldComponent extends PrimitiveComponent + hidecategories(Collision,Lighting,Physics,Rendering,Object,PersistentSplats) + native(Physics) + editinlinenew; + +/** Rotational field strength */ +var(ForceField) float RotationalFieldStrength; +/** Radial field strength */ +var(ForceField) float RadialFieldStrength; +/** Lift field strength */ +var(ForceField) float LiftFieldStrength; + +/** Height of capsule field */ +var(ForceField) float CapsuleFieldHeight ; +/** Bottom radius of capsule field */ +var(ForceField) float CapsuleFieldBottomRadius ; +/** Top radius of capsule field */ +var(ForceField) float CapsuleFieldTopRadius ; +/** Percentage of distance from boundary to center where fade out starts */ +var(ForceField) float BoundaryFadePercentage ; + +/** Enable/Disable Field Sampler */ +var(ForceField) bool bEnabled; + +/** Which types of object to apply this field sampler to */ +var(ForceField) const RBCollisionChannelContainer CollideWithChannels; + +/** enum indicating what collision filtering channel this field sampler should be in */ +var(ForceField) const ERBCollisionChannel CollisionChannel; + +/** Duration in seconds the field sampler should be exist. 0 = Infinite*/ +var(ForceField) float Duration; + +/** Percentage of noise applied to force field. 0 = None 1 = Infinite */ +var(ForceField) float NoiseStrength ; + + +/** Internal variable for storing the elapsed time of the field sampler */ +var float ElapsedTime; + +native function DoInitRBPhys(); +native final function SetEnabled(bool enabled); + +cpptext +{ + virtual FPrimitiveSceneProxy* CreateSceneProxy(); + +#if WITH_FLEX + virtual void GetFlexForceFieldProperties(struct FlexForceField& FlexFF); +#endif + +protected: + + virtual void InitComponentRBPhys(UBOOL bFixed); + virtual void TermComponentRBPhys(FRBPhysScene *InScene); + + virtual void Detach( UBOOL bWillReattach ); + + virtual void Tick(FLOAT DeltaTime); + + virtual void GetTransform(FMatrix& OutTransform) + { + FVector OutScale; + GetTransformAndScale(OutTransform, OutScale); + } +} + +defaultproperties +{ + RotationalFieldStrength = 750 + RadialFieldStrength = -400 + LiftFieldStrength = 0.0 + + CapsuleFieldHeight = 200.0; + CapsuleFieldBottomRadius = 100.0; + CapsuleFieldTopRadius = 50.0; + + BoundaryFadePercentage = 0.1 + + NoiseStrength = 0.01 + + TickGroup=TG_PreAsyncWork + + CollideWithChannels={( + FlexAsset=True + )} + + CollisionChannel=RBCC_FlexAsset + Duration = 0.0 + ElapsedTime = 0.0 + bEnabled = TRUE +} diff --git a/Engine/Classes/FloorToCeilingReachSpec.uc b/Engine/Classes/FloorToCeilingReachSpec.uc new file mode 100644 index 0000000..7064b5e --- /dev/null +++ b/Engine/Classes/FloorToCeilingReachSpec.uc @@ -0,0 +1,25 @@ +/** + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + + +class FloorToCeilingReachSpec extends ForcedReachSpec + native; + +cpptext +{ + virtual INT CostFor(APawn* P); + virtual INT AdjustedCostFor( APawn* P, const FVector& StartToGoalDir, ANavigationPoint* Goal, INT Cost ); +#if __TW_PATHFINDING_ + virtual FPlane PathColor() + { + return FPlane(0.83f,0.58f,0.27f,0.f); // Crawler + } +#endif +} + +defaultproperties +{ + bSkipPrune=TRUE +} diff --git a/Engine/Classes/FluidInfluenceActor.uc b/Engine/Classes/FluidInfluenceActor.uc new file mode 100644 index 0000000..e2ae996 --- /dev/null +++ b/Engine/Classes/FluidInfluenceActor.uc @@ -0,0 +1,106 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class FluidInfluenceActor extends Actor + dependson(FluidInfluenceComponent) + native(Fluid) + ClassGroup(Fluid) + placeable; + + +/** Direction of a flow influence. */ +var private ArrowComponent FlowDirection; + +var private SpriteComponent Sprite; + +var() editconst const FluidInfluenceComponent InfluenceComponent; + +/** replicated flags to pass to component */ +var repnotify bool bActive, bToggled; + +replication +{ + if (bNetDirty) + bActive, bToggled; +} + +/** + * Handling Toggle event from Kismet. + */ +simulated function OnToggle( SeqAct_Toggle inAction ) +{ + // Turn ON + if( inAction.InputLinks[0].bHasImpulse ) + { + InfluenceComponent.bActive = true; + } + // Turn OFF + else if( inAction.InputLinks[1].bHasImpulse ) + { + InfluenceComponent.bActive = false; + } + // Toggle + else if( inAction.InputLinks[2].bHasImpulse ) + { + InfluenceComponent.bActive = !InfluenceComponent.bActive; + InfluenceComponent.bIsToggleTriggered = true; + } + + bActive = InfluenceComponent.bActive; + bToggled = InfluenceComponent.bIsToggleTriggered; + bForceNetUpdate = true; +} + +simulated event ReplicatedEvent(name VarName) +{ + if (VarName == nameof(bActive)) + { + InfluenceComponent.bActive = bActive; + } + else if (VarName == nameof(bToggled)) + { + InfluenceComponent.bIsToggleTriggered = bToggled; + } + else + { + Super.ReplicatedEvent(VarName); + } +} + +defaultproperties +{ + bStatic=false + bMovable=true + bProjTarget=false + bCollideActors=false + bBlockActors=false + RemoteRole=ROLE_SimulatedProxy + bNoDelete=true + bAlwaysRelevant=true + NetUpdateFrequency=0.1 + bOnlyDirtyReplication=true + + Begin Object Class=SpriteComponent Name=NewSprite + Sprite=Texture2D'EditorResources.S_FluidSurfOsc' + HiddenGame=True + AlwaysLoadOnClient=False + AlwaysLoadOnServer=False + SpriteCategoryName="Fluids" + End Object + Sprite=NewSprite + Components.Add(NewSprite) + + Begin Object Class=ArrowComponent Name=NewArrowComponent + bTreatAsASprite=True + HiddenGame=True + SpriteCategoryName="Fluids" + End Object + FlowDirection=NewArrowComponent + Components.Add(NewArrowComponent) + + Begin Object Class=FluidInfluenceComponent Name=NewInfluenceComponent + End Object + InfluenceComponent=NewInfluenceComponent + Components.Add(NewInfluenceComponent) +} diff --git a/Engine/Classes/FluidInfluenceComponent.uc b/Engine/Classes/FluidInfluenceComponent.uc new file mode 100644 index 0000000..0764a09 --- /dev/null +++ b/Engine/Classes/FluidInfluenceComponent.uc @@ -0,0 +1,158 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class FluidInfluenceComponent extends PrimitiveComponent + dependson(FluidSurfaceActor) + native(Fluid) + AutoExpandCategories(FluidInfluenceComponent) + hidecategories(Object,Collision,Lighting,Physics,PrimitiveComponent,Rendering) + editinlinenew; + + +enum EInfluenceType +{ + Fluid_Flow, + Fluid_Raindrops, + Fluid_Wave, + Fluid_Sphere, +}; + + + +/** Whether the effect is active and applying forces to the fluid. */ +var() bool bActive; + +/** If a specific FluidSurfaceActor is set, this influence won't automatically affect any other fluid and MaxDistance is ignored. */ +var() FluidSurfaceActor FluidActor; + +/** Type of fluid influence (a flow of waves, raindrops, or a single wave). */ +var() EInfluenceType InfluenceType; + +/** Maximum distance (from the fluid plane) from where this influence will affect a fluid. */ +var() float MaxDistance; + + +/** Strength of the influencing force. */ +var(FluidWave) interp float WaveStrength; + +/** Wave frequency (can be 0 for a standing wave). */ +var(FluidWave) interp float WaveFrequency; + +/** Angular phase, in 0-360 degrees. */ +var(FluidWave) interp float WavePhase; + +/** Radius of the wave, in world space units. */ +var(FluidWave) interp float WaveRadius; + + + +/** Whether raindrops should fill the entire fluid (TRUE), or just in a circular area around the influenceactor (FALSE). */ +var(FluidRaindrops) interp bool RaindropFillEntireFluid; + +/** Radius of the area where raindrops fall. */ +var(FluidRaindrops) interp float RaindropAreaRadius; + +/** Radius of each raindrop, in world space units. */ +var(FluidRaindrops) interp float RaindropRadius; + +/** Strength of each raindrop. */ +var(FluidRaindrops) interp float RaindropStrength; + +/** Number of raindrops per second. */ +var(FluidRaindrops) interp float RaindropRate; + + + +/** How fast the flow moves thru the fluid, in world space units per second. */ +var(FluidFlow) interp float FlowSpeed; + +/** Number of flow ripples generated on the fluid surface. */ +var(FluidFlow) interp int FlowNumRipples; + +/** How much each flow ripple should oscillate sideways while moving down that flow direction. */ +var(FluidFlow) interp float FlowSideMotionRadius; + +/** Radius of each flow wave, in world space units. */ +var(FluidFlow) interp float FlowWaveRadius; + +/** Strength of each wave ripple. */ +var(FluidFlow) interp float FlowStrength; + +/** Frequency of up/down and sideways motion of each ripple. */ +var(FluidFlow) interp float FlowFrequency; + + +/** Outer radius of the 3D sphere. While inside this radius, the force will increase as it moves closer to the fluid plane. */ +var(FluidSphere) interp float SphereOuterRadius; + +/** Inner radius of the 3D sphere. While inside this radius, the force will decrease as it moves closer to the fluid plane. */ +var(FluidSphere) interp float SphereInnerRadius; + +/** Strength of the force applied by the sphere. */ +var(FluidSphere) interp float SphereStrength; + +/** The "toggle" Kismet event will set this to true, which will enable/disable the influence for 1 tick, then automatically go back to its previous state. */ +var transient bool bIsToggleTriggered; + +var private native transient float CurrentAngle; +var private native transient float CurrentTimer; + +/** The currently affected FluidSurfaceActor. */ +var private native transient FluidSurfaceActor CurrentFluidActor; + + +cpptext +{ +public: + // Base class interfaces + virtual void PostLoad( ); + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual void UpdateBounds( ); + virtual void Tick( FLOAT DeltaTime ); + + // Influence functions + void UpdateFlow( FLOAT DeltaSeconds ); + void UpdateRaindrops( FLOAT DeltaSeconds ); + void UpdateWave( FLOAT DeltaSeconds ); + void UpdateSphere( FLOAT DeltaSeconds ); + void CheckSettings( UBOOL bUpdateIcon ); + UBOOL IsTouching( AFluidSurfaceActor* Fluid ); +} + + + +defaultproperties +{ + bActive=true + InfluenceType=Fluid_Wave + MaxDistance=1000.0 + + WaveStrength=40.0 + WaveFrequency=1.0 + WavePhase=0.0 + WaveRadius=50.0 + + RaindropFillEntireFluid=True + RaindropAreaRadius=300.0 + RaindropRadius=10.0 + RaindropStrength=5.0 + RaindropRate=20.0 + + FlowSpeed=100.0 + FlowNumRipples=10 + FlowSideMotionRadius=30.0 + FlowWaveRadius=50.0 + FlowStrength=20.0 + FlowFrequency=4.0 + + SphereOuterRadius=100.0 + SphereInnerRadius=50.0 + SphereStrength=-40.0 + + bTickInEditor=True + CollideActors=False + BlockZeroExtent=False + BlockNonZeroExtent=False + BlockRigidBody=False +} diff --git a/Engine/Classes/FluidSurfaceActor.uc b/Engine/Classes/FluidSurfaceActor.uc new file mode 100644 index 0000000..f11bc05 --- /dev/null +++ b/Engine/Classes/FluidSurfaceActor.uc @@ -0,0 +1,65 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class FluidSurfaceActor extends Actor + dependson(FluidSurfaceComponent) + native(Fluid) + AutoExpandCategories(FluidSurfaceActor,FluidSurfaceComponent) + ClassGroup(Fluid) + placeable; + +var() editconst const FluidSurfaceComponent FluidComponent; + +/** Particle effect to play when projectile hits water */ +var() ParticleSystem ProjectileEntryEffect; + +cpptext +{ + // UObject interface. + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + // AActor interface. + virtual void PostEditImport(); + virtual void PostEditMove(UBOOL bFinished); + virtual void TickSpecial( FLOAT DeltaSeconds ); + virtual UBOOL IsAFluidSurface() const { return TRUE; } + virtual class AFluidSurfaceActor* GetAFluidSurface() { return this; } + +#if WITH_EDITOR + virtual void EditorApplyScale(const FVector& DeltaScale, const FMatrix& ScaleMatrix, const FVector* PivotLocation, UBOOL bAltDown, UBOOL bShiftDown, UBOOL bCtrlDown); +#endif +} + + + +simulated event TakeDamage(int Damage, Controller EventInstigator, vector HitLocation, vector Momentum, class DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser) +{ + // call Actor's version to handle any SeqEvent_TakeDamage for scripting + Super.TakeDamage(Damage, EventInstigator, HitLocation, Momentum, DamageType, HitInfo, DamageCauser); + + FluidComponent.ApplyForce( HitLocation, FluidComponent.ForceImpact, FluidComponent.TestRippleRadius, True ); +} + +simulated event Touch( Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal ) +{ + Super.Touch( Other, OtherComp, HitLocation, HitNormal ); + + Other.ApplyFluidSurfaceImpact(self, HitLocation); +} + + +defaultproperties +{ + bStatic=false + bMovable=false + bNoDelete=true + bProjTarget=true + bCollideActors=true + bBlockActors=false + + Begin Object Class=FluidSurfaceComponent Name=NewFluidComponent + End Object + FluidComponent=NewFluidComponent + Components.Add(NewFluidComponent) +} diff --git a/Engine/Classes/FluidSurfaceActorMovable.uc b/Engine/Classes/FluidSurfaceActorMovable.uc new file mode 100644 index 0000000..e72036f --- /dev/null +++ b/Engine/Classes/FluidSurfaceActorMovable.uc @@ -0,0 +1,18 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class FluidSurfaceActorMovable extends FluidSurfaceActor + native(Fluid) + placeable; + + +cpptext +{ +} + +defaultproperties +{ + bMovable=true + Physics=PHYS_Interpolating +} diff --git a/Engine/Classes/FluidSurfaceComponent.uc b/Engine/Classes/FluidSurfaceComponent.uc new file mode 100644 index 0000000..3ad9a42 --- /dev/null +++ b/Engine/Classes/FluidSurfaceComponent.uc @@ -0,0 +1,299 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +/** + * Utility component for drawing an interactive body of fluid. + * Origin is at the component location. + */ +class FluidSurfaceComponent extends PrimitiveComponent + native(Fluid) + AutoExpandCategories(FluidSurfaceComponent,Fluid,FluidDetail) + hidecategories(Object) + dependson(LightmassPrimitiveSettingsObject) + editinlinenew; + +/** Surface material */ +var() materialinterface FluidMaterial; + +/** Resolution of the fluid's texture lightmap. */ +var(Lighting) int LightmapResolution; + +/** The Lightmass settings for this object. */ +var(Lightmass) LightmassPrimitiveSettings LightmassSettings ; + +/** Whether the vertex positions in the simulation grid should be animated or not */ +var(Fluid) bool EnableSimulation; + +/** Number of quads in the simulated grid (along the X-axis) */ +var(Fluid) int SimulationQuadsX; + +/** Number of quads in the simulated grid (along the Y-axis) */ +var(Fluid) int SimulationQuadsY; + +/** The size of a grid cell in the vertex simulation (in world space units) */ +var(Fluid) float GridSpacing; + +/** Fluids automatically draw a low-resolution grid when they are deactivated. A reasonable value is needed for vertex fogging to work when the fluid is translucent. A maximum of 65000 vertices are allowed before GridSpacingLowRes is clamped. */ +var(Fluid) float GridSpacingLowRes; + +/** Target actor which the simulation grid will center around. If none is provided, the simulation grid will center around the active camera. */ +var(Fluid) actor TargetSimulation; + +/** How much the GPU should tessellate the fluid grid. (Only used on platforms that completely supports GPU tessellation.) */ +var(Fluid) float GPUTessellationFactor; + +/** How much to dampen the amplitude of waves in the fluid (0.0-30.0) */ +var(Fluid) float FluidDamping; + +/** Wave travel speed factor for the simulation grid (0.0-1.0) */ +var(Fluid) float FluidTravelSpeed; + +/** Wave height scale - higher value produces higher waves */ +var(Fluid) float FluidHeightScale; + +/** Fluid update rate in number of updates per second */ +var(Fluid) float FluidUpdateRate; + +/** How much ripple to make when fluid is hit by a weapon or touched by a object for the first time. */ +var(Fluid) float ForceImpact; + +/** How much ripple to make when an Actor moves through the fluid. */ +var(Fluid) float ForceContinuous; + +/** Increasing this value adds more contrast to the lighting by exaggerating the curvature for the fluid normals. */ +var(Fluid) float LightingContrast; + +/** Target actor which the detail texture will center around. If none is provided, the detail texture will center around the active camera. */ +var(Fluid) actor TargetDetail; + +/** Whether the detail simulation grid should be used or not */ +var(Fluid) bool EnableDetail; + +/** Distance between the camera and the closest fluid edge where the fluid will deactivate and start rendering as a simple flat quad. */ +var(Fluid) float DeactivationDistance; + +/** Number of simulation cells along each axis in the detail texture */ +var(FluidDetail) int DetailResolution; + +/** World space size of one edge of the detail texture */ +var(FluidDetail) float DetailSize; + +/** How much to dampen the amplitude of waves in the detail texture (0.0-30.0) */ +var(FluidDetail) float DetailDamping; + +/** Wave travel speed factor for the detail texture (0.0-1.0) */ +var(FluidDetail) float DetailTravelSpeed; + +/** How much of an applied force should be transferred to the detail texture (0.0-1.0) */ +var(FluidDetail) float DetailTransfer; + +/** Wave height scale for the detail texture - higher value produces higher waves */ +var(FluidDetail) float DetailHeightScale; + +/** Fluid update rate in number of updates per second */ +var(FluidDetail) float DetailUpdateRate; + +/** Whether to make the detail simulation tiled. */ +var(FluidDetail) bool bTiling; + +/** Whether to update the fluid or pause it */ +var(FluidDebug) transient bool bPause; + +/** Whether to render lines for normals */ +var(FluidDebug) transient bool bShowSimulationNormals; + +/** Whether to visualize the placement of the simulated grid */ +var(FluidDebug) bool bShowSimulationPosition; + +/** The length of the visualized normals, when bShowSimulationNormals is turned on */ +var(FluidDebug) float NormalLength; + +/** Whether to render an overlay of the detail normal for debugging */ +var(FluidDebug) bool bShowDetailNormals; + +/** Whether to visualize the placement of the detail texture */ +var(FluidDebug) bool bShowDetailPosition; + +/** Whether to visualize the height of the main fluid grid */ +var(FluidDebug) transient bool bShowFluidSimulation; + +/** Whether to show the detail normalmap on the fluid */ +var(FluidDebug) transient bool bShowFluidDetail; + +/** Whether to enable a force for debugging */ +var(FluidDebug) bool bTestRipple; + +/** Whether the test ripple should center on the detail texture or the main grid. */ +var(FluidDebug) bool bTestRippleCenterOnDetail; + +/** Angular speed of the test ripple */ +var(FluidDebug) float TestRippleSpeed; + +/** Number of seconds between each pling on the test ripple. 0 makes it continuous. */ +var(FluidDebug) float TestRippleFrequency; + +/** Radius of the test ripple, in world space */ +var(FluidDebug) float TestRippleRadius; + +var private float FluidWidth; +var private float FluidHeight; +var private native transient float TestRippleTime; +var private native transient float TestRippleAngle; +var private native transient float DeactivationTimer; +var private native transient float ViewDistance; +var private native transient vector SimulationPosition; +var private native transient vector DetailPosition; + +/** Stores a 1 for each clamped vertex that should not be simulated, and a 0 for each vertex that should be simulated. */ +var const array ClampMap; + +var private const array ShadowMaps; + +/** Reference to the texture lightmap resource. */ +var native private const LightMapRef LightMap; + +/** All transient member variables are contained inside the FFluidSurfaceInfo object. */ +var private native transient const pointer FluidSimulation{class FFluidSimulation}; + +/** Apply a force to the fluid. */ +native final function ApplyForce( vector WorldPos, float Strength, float Radius, optional bool bImpulse ); + +/** Set the position of the origin of the detail texture, within the fluid. */ +native final function SetDetailPosition( vector WorldPos ); + +/** Set the position of the origin of the simulation grid, within the fluid. */ +native final function SetSimulationPosition( vector WorldPos ); + +cpptext +{ +public: + UFluidSurfaceComponent(); + + UMaterialInterface* GetMaterial() const; + FMaterialViewRelevance GetMaterialViewRelevance() const; + const class FFluidGPUResource* GetFluidGPUResource() const; + void InitResources( UBOOL bActive ); + void ReleaseResources( UBOOL bBlockOnRelease ); + void RebuildClampMap(); + void OnScaleChange(); + + // Base class interfaces. + virtual FPrimitiveSceneProxy* CreateSceneProxy(); + virtual void Serialize(FArchive& Ar); + virtual void AddReferencedObjects(TArray& ObjectArray); + virtual void UpdateBounds(); + virtual void Attach(); + virtual void Detach( UBOOL bWillReattach ); + virtual void PreEditChange(UProperty* PropertyAboutToChange); + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual void BeginDestroy(); + virtual UBOOL IsReadyForFinishDestroy(); + virtual void FinishDestroy(); + virtual void Tick(FLOAT DeltaTime); + virtual UBOOL LineCheck(FCheckResult& Result, const FVector& End, const FVector& Start, const FVector& Extent, DWORD TraceFlags); + virtual UBOOL PointCheck(FCheckResult& Result,const FVector& Location,const FVector& Extent,DWORD TraceFlags); + virtual void InvalidateLightingCache(); + + /** + * Retrieves the materials used in this component + * + * @param OutMaterials The list of used materials. + */ + virtual void GetUsedMaterials( TArray& OutMaterials ) const; + + /** + * Returns the lightmap resolution used for this primivite instnace in the case of it supporting texture light/ shadow maps. + * 0 if not supported or no static shadowing. + * + * @param Width [out] Width of light/shadow map + * @param Height [out] Height of light/shadow map + * + * @return UBOOL TRUE if LightMap values are padded, FALSE if not + */ + virtual UBOOL GetLightMapResolution( INT& Width, INT& Height ) const; + virtual INT GetStaticLightMapResolution() const; + virtual void GetLightAndShadowMapMemoryUsage( INT& LightMapMemoryUsage, INT& ShadowMapMemoryUsage ) const; + virtual void GetStaticLightingInfo(FStaticLightingPrimitiveInfo& OutPrimitiveInfo,const TArray& InRelevantLights,const FLightingBuildOptions& Options); + virtual ELightMapInteractionType GetStaticLightingType() const { return LMIT_Texture; } + /** Gets the emissive boost for the primitive component. */ + virtual FLOAT GetEmissiveBoost(INT ElementIndex) const; + /** Gets the diffuse boost for the primitive component. */ + virtual FLOAT GetDiffuseBoost(INT ElementIndex) const; + /** Gets the specular boost for the primitive component. */ + virtual FLOAT GetSpecularBoost(INT ElementIndex) const; + virtual void GetStreamingTextureInfo(TArray& OutStreamingTextures) const; + +private: + UBOOL PropertyNeedsResourceRecreation(UProperty* Property); + void UpdateMemory(FLOAT DeltaTime); + + /** + * Calculates the distance from the fluid's edge to the specified position. + * @param WorldPosition A world-space position to measure the distance to. + * @return Distance from the fluid's edge to the specified position, or 0 if it's inside the fluid. + */ + FLOAT CalcDistance( const FVector& WorldPosition ); +} + +defaultproperties +{ + LightmapResolution=128 + EnableSimulation=true + EnableDetail=true + DeactivationDistance=3000.0 + FluidUpdateRate=30.0 + DetailUpdateRate=30.0 + bTiling=false + FluidHeightScale=1.0 + DetailHeightScale=1.0 + bPause=false + SimulationQuadsX=200 + SimulationQuadsY=200 + GridSpacing=10.0 + GridSpacingLowRes=800.0 + DetailResolution=256 + DetailSize=500 + FluidDamping=1.0 + FluidTravelSpeed=1.0 + DetailDamping=1.0 + DetailTravelSpeed=1.0 + DetailTransfer=0.5 + bTestRipple=false + TestRippleSpeed=1 + TestRippleRadius=30 + TestRippleFrequency=1.0 + bShowFluidDetail=true + bShowFluidSimulation=true + bShowDetailNormals=false + bShowDetailPosition=false + bShowSimulationNormals=false + bShowSimulationPosition=false + NormalLength=10.0 + LightingContrast=1.0 + GPUTessellationFactor=1.0 + + ForceImpact=-3.0 + ForceContinuous=-200.0 + + FluidWidth=2000.0 + FluidHeight=2000.0 + TestRippleTime=0.0 + TestRippleAngle=0.0 + DeactivationTimer=10.0 + ViewDistance=0.0 + + bTickInEditor=true + CollideActors=true + BlockZeroExtent=true + BlockNonZeroExtent=true + BlockRigidBody=false + + CastShadow=false + bForceDirectLightMap=true + bAcceptsLights=true + bUsePrecomputedShadows=true + + // Fluid surfaces often have expensive vertex shaders so we want to make sure they get occlusion queried + bIgnoreNearPlaneIntersection=true +} diff --git a/Engine/Classes/FogVolumeConeDensityComponent.uc b/Engine/Classes/FogVolumeConeDensityComponent.uc new file mode 100644 index 0000000..1241bac --- /dev/null +++ b/Engine/Classes/FogVolumeConeDensityComponent.uc @@ -0,0 +1,47 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class FogVolumeConeDensityComponent extends FogVolumeDensityComponent + native(FogVolume) + collapsecategories + hidecategories(Object) + editinlinenew; + +/** This is the density at the center of the cone, which will be the maximum. */ +var() interp float MaxDensity; + +/** The cone's vertex in world space. */ +var() interp vector ConeVertex; + +/** The cone's radius. */ +var() interp float ConeRadius; + +/** Direction of the cone */ +var() interp vector ConeAxis; + +/** Angle from the axis that limits the cone's volume */ +var() interp float ConeMaxAngle; + +/** A preview component for visualizing the cone in the editor. */ +var const DrawLightConeComponent PreviewCone; + +cpptext +{ +protected: + // ActorComponent interface. + virtual void SetParentToWorld(const FMatrix& ParentToWorld); + virtual void Attach(); + +public: + // FogVolumeDensityComponent interface. + virtual class FFogVolumeDensitySceneInfo* CreateFogVolumeDensityInfo(const UPrimitiveComponent* MeshComponent) const; +} + +defaultproperties +{ + MaxDensity=0.002 + ConeVertex=(X=0.0,Y=0.0,Z=0.0) + ConeRadius=600.0 + ConeAxis=(X=0.0,Y=0.0,Z=-1.0) + ConeMaxAngle=30.0 +} diff --git a/Engine/Classes/FogVolumeConeDensityInfo.uc b/Engine/Classes/FogVolumeConeDensityInfo.uc new file mode 100644 index 0000000..1e244c2 --- /dev/null +++ b/Engine/Classes/FogVolumeConeDensityInfo.uc @@ -0,0 +1,29 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class FogVolumeConeDensityInfo extends FogVolumeDensityInfo + showcategories(Movement) + native(FogVolume) + abstract; + +cpptext +{ +#if WITH_EDITOR + // AActor interface. + virtual void EditorApplyScale(const FVector& DeltaScale, const FMatrix& ScaleMatrix, const FVector* PivotLocation, UBOOL bAltDown, UBOOL bShiftDown, UBOOL bCtrlDown); +#endif +} + +defaultproperties +{ + Begin Object Class=DrawLightConeComponent Name=DrawCone0 + ConeColor=(R=200,G=255,B=255) + End Object + Components.Add(DrawCone0) + + Begin Object Class=FogVolumeConeDensityComponent Name=FogVolumeComponent0 + PreviewCone=DrawCone0 + End Object + DensityComponent=FogVolumeComponent0 + Components.Add(FogVolumeComponent0) +} diff --git a/Engine/Classes/FogVolumeConstantDensityComponent.uc b/Engine/Classes/FogVolumeConstantDensityComponent.uc new file mode 100644 index 0000000..928ad83 --- /dev/null +++ b/Engine/Classes/FogVolumeConstantDensityComponent.uc @@ -0,0 +1,23 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class FogVolumeConstantDensityComponent extends FogVolumeDensityComponent + native(FogVolume) + collapsecategories + hidecategories(Object) + editinlinenew; + +/** The constant density coefficient */ +var() interp float Density; + +cpptext +{ +public: + // FogVolumeDensityComponent interface. + virtual class FFogVolumeDensitySceneInfo* CreateFogVolumeDensityInfo(const UPrimitiveComponent* MeshComponent) const; +} + +defaultproperties +{ + Density=0.0005 +} diff --git a/Engine/Classes/FogVolumeConstantDensityInfo.uc b/Engine/Classes/FogVolumeConstantDensityInfo.uc new file mode 100644 index 0000000..fb8f4ed --- /dev/null +++ b/Engine/Classes/FogVolumeConstantDensityInfo.uc @@ -0,0 +1,15 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class FogVolumeConstantDensityInfo extends FogVolumeDensityInfo + showcategories(Movement) + native(FogVolume) + placeable; + +defaultproperties +{ + Begin Object Class=FogVolumeConstantDensityComponent Name=FogVolumeComponent0 + End Object + DensityComponent=FogVolumeComponent0 + Components.Add(FogVolumeComponent0) +} diff --git a/Engine/Classes/FogVolumeDensityComponent.uc b/Engine/Classes/FogVolumeDensityComponent.uc new file mode 100644 index 0000000..8513c7c --- /dev/null +++ b/Engine/Classes/FogVolumeDensityComponent.uc @@ -0,0 +1,110 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class FogVolumeDensityComponent extends ActorComponent + native(FogVolume) + hidecategories(Object) + abstract + editinlinenew; + +/** Fog Material to use on the AutomaticComponent. This will not be used on FogVolumeActors, they will use their existing materials. */ +var() MaterialInterface FogMaterial; + +var MaterialInterface DefaultFogVolumeMaterial; + +/** True if the fog is enabled. */ +var() const bool bEnabled; + +/** + * Controls whether the fog volume affects intersecting translucency. + * If FALSE, the fog volume will sort normally with translucency and not fog intersecting translucent objects. + */ +var() bool bAffectsTranslucency; + +/** + * Controls whether the fog volume affects opaque pixels, or just intersecting translucency. + */ +var() bool bOnlyAffectsTranslucency; + +/** + * Sets the 'EmissiveColor' Vector Parameter of FogMaterial. + * This will have no effect if FogMaterial has been overridden with a material that does not have a 'EmissiveColor' parameter. + */ +var() interp LinearColor SimpleLightColor; + +/** + * Color used to approximate fog material color on transparency. + * Important: Set this color to match the overall color of the fog material, otherwise transparency will not be fogged correctly. + */ +var() interp LinearColor ApproxFogLightColor; + +/** Distance from the camera that the fog should start, in world units. */ +var() interp float StartDistance; + +/** + * MaxDistance can be tweaked to be as low as it can go without making the fog noticeably less opaque, + * And that will greatly improve the anti aliasing effect on opaque geometry in the foreground. + */ +var() float MaxDistance; + +/** + * Optional array of actors that will define the shape of the fog volume. + * These actors will not be moved along with the fog volume, and they can be selected directly. + */ +var() array FogVolumeActors; + +cpptext +{ +private: + /** Adds the fog volume components to the scene */ + void AddFogVolumeComponents(); + + /** Removes the fog volume components from the scene */ + void RemoveFogVolumeComponents(); + + /** + * Sets up FogVolumeActors's mesh components to defaults that are common usage with fog volumes. + * Collision is disabled for the actor, each component gets assigned the default fog volume material, + * lighting, shadowing, decal accepting, and occluding are disabled. + */ + void SetFogActorDefaults(const INT FogActorIndex); + +protected: + // ActorComponent interface. + virtual void Attach(); + virtual void UpdateTransform(); + virtual void Detach( UBOOL bWillReattach = FALSE ); + + // UObject interface + virtual void PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent); + +public: + // FogVolumeDensityComponent interface. + virtual class FFogVolumeDensitySceneInfo* CreateFogVolumeDensityInfo(const UPrimitiveComponent* MeshComponent) const PURE_VIRTUAL(UFogVolumeDensityComponent::CreateFogVolumeDensityInfo,return NULL;); + + /** Checks for partial fog volume setup that will not render anything. */ +#if WITH_EDITOR + virtual void CheckForErrors(); +#endif + + /** Returns FogMaterial if it is valid, otherwise DefaultFogVolumeMaterial */ + UMaterialInterface* GetMaterial() const; +} + +/** + * Changes the enabled state of the height fog component. + * @param bSetEnabled - The new value for bEnabled. + */ +final native function SetEnabled(bool bSetEnabled); + +defaultproperties +{ + DefaultFogVolumeMaterial=Material'EngineMaterials.FogVolumeMaterial' + bEnabled=TRUE + bAffectsTranslucency=TRUE + bOnlyAffectsTranslucency=FALSE + SimpleLightColor=(R=0.5,G=0.5,B=0.7,A=1.0) + ApproxFogLightColor=(R=0.5,G=0.5,B=0.7,A=1.0) + StartDistance=0.0 + MaxDistance=65535.0 +} diff --git a/Engine/Classes/FogVolumeDensityInfo.uc b/Engine/Classes/FogVolumeDensityInfo.uc new file mode 100644 index 0000000..e2b4867 --- /dev/null +++ b/Engine/Classes/FogVolumeDensityInfo.uc @@ -0,0 +1,145 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class FogVolumeDensityInfo extends Info + showcategories(Movement) + AutoExpandCategories(FogVolumeDensityInfo) + ClassGroup(Fog) + native(FogVolume) + abstract; + +/** The fog component which stores data specific to each density function. */ +var() FogVolumeDensityComponent DensityComponent; + +/** + * The automatic mesh component, which sizes with this fog volume actor. This mesh component gets rendered with FogMaterial. + * It is optional, and individual actors can be specified using the FogVolumeActors array instead. + */ +var() StaticMeshComponent AutomaticMeshComponent; + +/** replicated copy of HeightFogComponent's bEnabled property */ +var repnotify bool bEnabled; + +struct CheckpointRecord +{ + var bool bEnabled; +}; + +replication +{ + if (Role == ROLE_Authority) + bEnabled; +} + +cpptext +{ +public: + virtual void Serialize(FArchive& Ar); + virtual void PostLoad(); + virtual void PostEditImport(); + virtual void SetupDefaultFogVolume(); +} + +event PostBeginPlay() +{ + Super.PostBeginPlay(); + + if( DensityComponent != none ) + { + bEnabled = DensityComponent.bEnabled; + } +} + +simulated event ReplicatedEvent(name VarName) +{ + if (VarName == 'bEnabled') + { + DensityComponent.SetEnabled(bEnabled); + } + else + { + Super.ReplicatedEvent(VarName); + } +} + +/* epic =============================================== +* ::OnToggle +* +* Scripted support for toggling height fog, checks which +* operation to perform by looking at the action input. +* +* Input 1: turn on +* Input 2: turn off +* Input 3: toggle +* +* ===================================================== +*/ +simulated function OnToggle(SeqAct_Toggle action) +{ + if (action.InputLinks[0].bHasImpulse) + { + // turn on + DensityComponent.SetEnabled(TRUE); + } + else if (action.InputLinks[1].bHasImpulse) + { + // turn off + DensityComponent.SetEnabled(FALSE); + } + else if (action.InputLinks[2].bHasImpulse) + { + // toggle + DensityComponent.SetEnabled(!DensityComponent.bEnabled); + } + bEnabled = DensityComponent.bEnabled; + ForceNetRelevant(); + SetForcedInitialReplicatedProperty(Property'Engine.FogVolumeDensityInfo.bEnabled', (bEnabled == default.bEnabled)); +} + +function bool ShouldSaveForCheckpoint() +{ + return (RemoteRole != ROLE_None); +} + +function CreateCheckpointRecord(out CheckpointRecord Record) +{ + Record.bEnabled = bEnabled; +} + +function ApplyCheckpointRecord(const out CheckpointRecord Record) +{ + bEnabled = Record.bEnabled; + DensityComponent.SetEnabled(bEnabled); + ForceNetRelevant(); + SetForcedInitialReplicatedProperty(Property'Engine.FogVolumeDensityInfo.bEnabled', (bEnabled == default.bEnabled)); +} + +defaultproperties +{ + bStatic=FALSE + bNoDelete=true + + Begin Object Class=StaticMeshComponent Name=AutomaticMeshComponent0 + StaticMesh=StaticMesh'EngineMeshes.Cube' + bCastDynamicShadow=FALSE + BlockRigidBody=FALSE + bForceDirectLightMap=FALSE + bAcceptsDynamicLights=FALSE + bAcceptsLights=FALSE + CastShadow=FALSE + bUsePrecomputedShadows=FALSE + bAcceptsStaticDecals=FALSE + bAcceptsDynamicDecals=FALSE + bUseAsOccluder=FALSE + bSelectable=FALSE + bIgnoreOwnerHidden=TRUE + WireframeColor=(R=100,G=100,B=200,A=255) + End Object + + AutomaticMeshComponent=AutomaticMeshComponent0 + Components.Add(AutomaticMeshComponent0) + + Begin Object Name=Sprite + SpriteCategoryName="Fog" + End Object +} diff --git a/Engine/Classes/FogVolumeLinearHalfspaceDensityComponent.uc b/Engine/Classes/FogVolumeLinearHalfspaceDensityComponent.uc new file mode 100644 index 0000000..1902900 --- /dev/null +++ b/Engine/Classes/FogVolumeLinearHalfspaceDensityComponent.uc @@ -0,0 +1,31 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class FogVolumeLinearHalfspaceDensityComponent extends FogVolumeDensityComponent + native(FogVolume) + collapsecategories + hidecategories(Object) + editinlinenew; + +/** The linear distance based density coefficient */ +var() interp float PlaneDistanceFactor; + +/** The plane that defines the fogged halfspace. The normal of this plane faces away from the fogged halfspace. */ +var interp plane HalfspacePlane; + +cpptext +{ +protected: + // ActorComponent interface. + virtual void SetParentToWorld(const FMatrix& ParentToWorld); + +public: + // FogVolumeDensityComponent interface. + virtual class FFogVolumeDensitySceneInfo* CreateFogVolumeDensityInfo(const UPrimitiveComponent* MeshComponent) const; +} + +defaultproperties +{ + PlaneDistanceFactor=0.1 + HalfspacePlane=(X=0.0,Y=0.0,Z=1.0,W=-300.0) +} diff --git a/Engine/Classes/FogVolumeLinearHalfspaceDensityInfo.uc b/Engine/Classes/FogVolumeLinearHalfspaceDensityInfo.uc new file mode 100644 index 0000000..419d712 --- /dev/null +++ b/Engine/Classes/FogVolumeLinearHalfspaceDensityInfo.uc @@ -0,0 +1,15 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class FogVolumeLinearHalfspaceDensityInfo extends FogVolumeDensityInfo + showcategories(Movement) + native(FogVolume) + placeable; + +defaultproperties +{ + Begin Object Class=FogVolumeLinearHalfspaceDensityComponent Name=FogVolumeComponent0 + End Object + DensityComponent=FogVolumeComponent0 + Components.Add(FogVolumeComponent0) +} diff --git a/Engine/Classes/FogVolumeSphericalDensityComponent.uc b/Engine/Classes/FogVolumeSphericalDensityComponent.uc new file mode 100644 index 0000000..116a080 --- /dev/null +++ b/Engine/Classes/FogVolumeSphericalDensityComponent.uc @@ -0,0 +1,39 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class FogVolumeSphericalDensityComponent extends FogVolumeDensityComponent + native(FogVolume) + collapsecategories + hidecategories(Object) + editinlinenew; + +/** This is the density at the center of the sphere, which will be the maximum. */ +var() interp float MaxDensity; + +/** The sphere's center in world space. */ +var vector SphereCenter; + +/** The sphere's radius. */ +var float SphereRadius; + +/** A preview component for visualizing the sphere in the editor. */ +var const DrawLightRadiusComponent PreviewSphereRadius; + +cpptext +{ +protected: + // ActorComponent interface. + virtual void SetParentToWorld(const FMatrix& ParentToWorld); + virtual void Attach(); + +public: + // FogVolumeDensityComponent interface. + virtual class FFogVolumeDensitySceneInfo* CreateFogVolumeDensityInfo(const UPrimitiveComponent* MeshComponent) const; +} + +defaultproperties +{ + MaxDensity=0.002 + SphereCenter=(X=0.0,Y=0.0,Z=0.0) + SphereRadius=600.0 +} diff --git a/Engine/Classes/FogVolumeSphericalDensityInfo.uc b/Engine/Classes/FogVolumeSphericalDensityInfo.uc new file mode 100644 index 0000000..6cf486e --- /dev/null +++ b/Engine/Classes/FogVolumeSphericalDensityInfo.uc @@ -0,0 +1,37 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class FogVolumeSphericalDensityInfo extends FogVolumeDensityInfo + showcategories(Movement) + native(FogVolume) + placeable; + +defaultproperties +{ + Begin Object Name=AutomaticMeshComponent0 + StaticMesh=StaticMesh'EngineMeshes.Sphere' + bCastDynamicShadow=FALSE + BlockRigidBody=false + bForceDirectLightMap=FALSE + bAcceptsDynamicLights=FALSE + bAcceptsLights=FALSE + CastShadow=FALSE + bUsePrecomputedShadows=FALSE + bAcceptsStaticDecals=FALSE + bAcceptsDynamicDecals=FALSE + bUseAsOccluder=FALSE + bSelectable=FALSE + bIgnoreOwnerHidden=TRUE + CollideActors=FALSE + End Object + + Begin Object Class=DrawLightRadiusComponent Name=DrawSphereRadius0 + End Object + Components.Add(DrawSphereRadius0) + + Begin Object Class=FogVolumeSphericalDensityComponent Name=FogVolumeComponent0 + PreviewSphereRadius=DrawSphereRadius0 + End Object + DensityComponent=FogVolumeComponent0 + Components.Add(FogVolumeComponent0) +} diff --git a/Engine/Classes/Font.uc b/Engine/Classes/Font.uc new file mode 100644 index 0000000..569c9c9 --- /dev/null +++ b/Engine/Classes/Font.uc @@ -0,0 +1,282 @@ +/** + * + * A font object, containing information about a set of glyphs. + * The glyph bitmaps are stored in the contained textures, while + * the font database only contains the coordinates of the individual + * glyph. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class Font extends Object + hidecategories(object) + dependsOn(FontImportOptions) + native; + + +// This is the character that RemapChar will return if the specified character doesn't exist in the font +const NULLCHARACTER = 127; + +/** this struct is serialized using binary serialization so any changes to it require a package version bump */ +struct immutable native FontCharacter +{ + var() int StartU; + var() int StartV; + var() int USize; + var() int VSize; + var() BYTE TextureIndex; + var() int VerticalOffset; + + structcpptext + { + // Serializer. + friend FArchive& operator<<( FArchive& Ar, FFontCharacter& Ch ) + { + Ar << Ch.StartU << Ch.StartV << Ch.USize << Ch.VSize << Ch.TextureIndex; + + if( Ar.Ver() < VER_FONT_FORMAT_AND_UV_TILING_CHANGES ) + { + Ch.VerticalOffset = 0; + } + else + { + Ar << Ch.VerticalOffset; + } + + return Ar; + } + } +}; + + +/** List of characters in the font. For a MultiFont, this will include all characters in all sub-fonts! Thus, + the number of characters in this array isn't necessary the number of characters available in the font */ +var() editinline array Characters; + +/** Textures that store this font's glyph image data */ +//NOTE: Do not expose this to the editor as it has nasty crash potential +var array Textures; + +/** When IsRemapped is true, this array maps unicode values to entries in the Characters array */ +var private const native Map{WORD,WORD} CharRemap; + +/** True if font is 'remapped'. That is, the character array is not a direct mapping to unicode values. Instead, + all characters are indexed indirectly through the CharRemap array */ +var int IsRemapped; + +/** Font metrics. */ +var() float EmScale; +var() float Ascent; +var() float Descent; +var() float Leading; + +/** Default horizontal spacing between characters when rendering text with this font */ +var() int Kerning; + +/** Options used when importing this font */ +var() FontImportOptionsData ImportOptions; + +/** Number of characters in the font, not including multiple instances of the same character (for multi-fonts). + This is cached at load-time or creation time, and is never serialized. */ +var transient int NumCharacters; + +/** The maximum height of a character in this font. For multi-fonts, this array will contain a maximum + character height for each multi-font, otherwise the array will contain only a single element. This is + cached at load-time or creation time, and is never serialized. */ +var transient array MaxCharHeight; + +/** Scale to apply to the font. */ +var() const float ScalingFactor; + +cpptext +{ + /** + * Returns the size of the object/ resource for display to artists/ LDs in the Editor. + * + * @return Size of resource as to be displayed to artists/ LDs in the Editor. + */ + virtual INT GetResourceSize(); + + // UFont interface + FORCEINLINE TCHAR RemapChar(TCHAR CharCode) const + { + const WORD UCode = ToUnicode(CharCode); + if ( IsRemapped ) + { + // currently, fonts are only remapped if they contain Unicode characters. + // For remapped fonts, all characters in the CharRemap map are valid, so + // if the characters exists in the map, it's safe to use - otherwise, return + // the null character (an empty square on windows) + const WORD* FontChar = CharRemap.Find(UCode); + if ( FontChar == NULL ) + return UCONST_NULLCHARACTER; + + return (TCHAR)*FontChar; + } + + // Otherwise, our Characters array will contains 256 members, and is + // a one-to-one mapping of character codes to array indexes, though + // not every character is a valid character. + if ( UCode >= NumCharacters ) + { + return UCONST_NULLCHARACTER; + } + + // If the character's size is 0, it's non-printable or otherwise unsupported by + // the font. Return the default null character (an empty square on windows). + if ( Characters(UCode).VSize == 0 && UCode >= TEXT(' ') ) + { + return UCONST_NULLCHARACTER; + } + + return CharCode; + } + + FORCEINLINE void GetCharSize(TCHAR InCh, FLOAT& Width, FLOAT& Height, INT ResolutionPageIndex=0) const + { + Width = Height = 0.f; + + const INT Ch = (INT)RemapChar(InCh) + ResolutionPageIndex; + if( Ch < Characters.Num() ) + { + const FFontCharacter& Char = Characters(Ch); + if( Char.TextureIndex < Textures.Num() && Textures(Char.TextureIndex) != NULL ) + { + Width = Char.USize; + + // The height of the character will always be the maximum height of any character in this + // font. This ensures consistent vertical alignment of text. For example, we don't want + // vertically centered text to visually shift up and down as characters are added to a string. + // NOTE: This also gives us consistent alignment with fonts generated by the legacy importer. + const INT MultiFontIndex = Ch / NumCharacters; + Height = MaxCharHeight( MultiFontIndex ); + } + } + } + + /** + * Calculate the width of the string using this font's default size and scale. + * + * @param Text the string to size + * @param ResolutionPageIndex the index for the multi-font page to use; get by calling GetResolutionPageIndex() + * + * @return the width (in pixels) of the specified text, or 0 if Text was NULL. + */ + FORCEINLINE INT GetStringSize( const TCHAR *Text, INT ResolutionPageIndex=0 ) const + { + FLOAT Width, Height, Total; + + Total = 0.0f; + while( *Text ) + { + GetCharSize( *Text++, Width, Height, ResolutionPageIndex ); + Total += Width; + } + + return( appCeil( Total ) ); + } + + /** + * Calculate the width of the string using this font's default size and scale. + * + * @param Text the string to size + * @param ResolutionPageIndex the index for the multi-font page to use; get by calling GetResolutionPageIndex() + * + * @return the width (in pixels) of the specified text, or 0 if Text was NULL. + */ + FORCEINLINE INT GetStringHeightSize( const TCHAR *Text, INT ResolutionPageIndex=0 ) const + { + FLOAT Width, Height, Total; + + Total = 0.0f; + while( *Text ) + { + GetCharSize( *Text++, Width, Height, ResolutionPageIndex ); + Total = Max( Total, Height ); + } + + return( appCeil( Total ) ); + } + + // UObject interface + + /** + * Serialize the object struct with the given archive + * + * @param Ar - archive to serialize with + */ + virtual void Serialize( FArchive& Ar ); + + /** + * Called after object and all its dependencies have been serialized. + */ + virtual void PostLoad(); + + /** + * Caches the character count and maximum character height for this font (as well as sub-fonts, in the multi-font case) + */ + virtual void CacheCharacterCountAndMaxCharHeight(); + + virtual UBOOL IsLocalizedResource(); + + /** + * Set the scaling factor + * + * @param InScalingFactor The scaling factor to set + */ + virtual void SetFontScalingFactor(FLOAT InScalingFactor) + { + ScalingFactor = InScalingFactor; + } + + /** + * Get the scaling factor + * + * @return FLOAT The scaling factor currently set + */ + virtual FLOAT GetFontScalingFactor() + { + return ScalingFactor; + } +} + +/** + * Calulate the index for the texture page containing the multi-font character set to use, based on the specified screen resolution. + * + * @param HeightTest the height (in pixels) of the viewport being rendered to. + * + * @return the index of the multi-font "subfont" that most closely matches the specified resolution. this value is used + * as the value for "ResolutionPageIndex" when calling other font-related methods. + */ +native function int GetResolutionPageIndex(float HeightTest) const; + +/** + * Calculate the amount of scaling necessary to match the multi-font subfont which most closely matches the specified resolution. + * + * @param HeightTest the height (in pixels) of the viewport being rendered to. + * + * @return the percentage scale required to match the size of the multi-font's closest matching subfont. + */ +native function float GetScalingFactor(float HeightTest) const; + +/** + * Determine the height of the mutli-font resolution page which will be used for the specified resolution. + * + * @param ViewportHeight the height (in pixels) of the viewport being rendered to. + */ +native final function virtual float GetAuthoredViewportHeight( float ViewportHeight ) const; + +/** + * Returns the maximum height for any character in this font + */ +native function float GetMaxCharHeight() const; + + +/** + * Determines the height and width for the passed in string. + */ +native function GetStringHeightAndWidth( const out string InString, out int Height, out int Width ) const; + +defaultproperties +{ + ScalingFactor=1.0 +} \ No newline at end of file diff --git a/Engine/Classes/FontImportOptions.uc b/Engine/Classes/FontImportOptions.uc new file mode 100644 index 0000000..4d2ac92 --- /dev/null +++ b/Engine/Classes/FontImportOptions.uc @@ -0,0 +1,88 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class FontImportOptions extends Object + hidecategories( Object ) + transient + native; + + +/** Font character set type for importing TrueType fonts */ +enum EFontImportCharacterSet +{ + FontICS_Default, + FontICS_Ansi, + FontICS_Symbol +}; + + +/** Font import options */ +struct native FontImportOptionsData +{ + var() string FontName; // Name of the typeface for the font to import + var() float Height; // Height of font (point size) + var() bool bEnableAntialiasing; // Whether the font should be antialiased or not. Usually you should leave this enabled. + var() bool bEnableBold; // Whether the font should be generated in bold or not + var() bool bEnableItalic; // Whether the font should be generated in italics or not + var() bool bEnableUnderline; // Whether the font should be generated with an underline or not + var() bool bAlphaOnly; // if TRUE then forces PF_G8 and only maintains Alpha value and discards color + var() EFontImportCharacterSet CharacterSet; // Character set for this font + + var() string Chars; // Explicit list of characters to include in the font + var() string UnicodeRange; // Range of Unicode character values to include in the font. You can specify ranges using hyphens and/or commas (e.g. '400-900') + var() string CharsFilePath; // Path on disk to a folder where files that contain a list of characters to include in the font + var() string CharsFileWildcard; // File mask wildcard that specifies which files within the CharsFilePath to scan for characters in include in the font + var() bool bCreatePrintableOnly; // Skips generation of glyphs for any characters that are not considered 'printable' + var() bool bIncludeASCIIRange; // When specifying a range of characters and this is enabled, forces ASCII characters (0 thru 255) to be included as well + + var() LinearColor ForegroundColor; // Color of the foreground font pixels. Usually you should leave this white and instead use the UI Styles editor to change the color of the font on the fly + var() bool bEnableDropShadow; // Enables a very simple, 1-pixel, black colored drop shadow for the generated font + + var() int TexturePageWidth; // Horizontal size of each texture page for this font in pixels + var() int TexturePageMaxHeight; // The maximum vertical size of a texture page for this font in pixels. The actual height of a texture page may be less than this if the font can fit within a smaller sized texture page. + var() int XPadding; // Horizontal padding between each font character on the texture page in pixels + var() int YPadding; // Vertical padding between each font character on the texture page in pixels + + var() int ExtendBoxTop; // How much to extend the top of the UV coordinate rectangle for each character in pixels + var() int ExtendBoxBottom; // How much to extend the bottom of the UV coordinate rectangle for each character in pixels + var() int ExtendBoxRight; // How much to extend the right of the UV coordinate rectangle for each character in pixels + var() int ExtendBoxLeft; // How much to extend the left of the UV coordinate rectangle for each character in pixels + + var() bool bEnableLegacyMode; // Enables legacy font import mode. This results in lower quality antialiasing and larger glyph bounds, but may be useful when debugging problems + + var() int Kerning; // The initial horizontal spacing adjustment between rendered characters. This setting will be copied directly into the generated Font object's properties. + + /** If TRUE then the alpha channel of the font textures will store a distance field instead of a color mask */ + var() bool bUseDistanceFieldAlpha; + /** + * Scale factor determines how big to scale the font bitmap during import when generating distance field values + * Note that higher values give better quality but importing will take much longer. + */ + var() int DistanceFieldScaleFactor; + /** Shrinks or expands the scan radius used to determine the silhouette of the font edges. */ + var() float DistanceFieldScanRadiusScale; + + structdefaultproperties + { + FontName = "Arial"; + Height = 16.0; + bEnableAntialiasing = true; + CharacterSet = FontICS_Default; + + bIncludeASCIIRange = true; + + ForegroundColor = ( R=1.0, G=1.0, B=1.0, A=1.0 ); + + TexturePageWidth = 256; + TexturePageMaxHeight = 256; + XPadding = 1; + YPadding = 1; + + DistanceFieldScaleFactor = 16; + DistanceFieldScanRadiusScale = 1.0; + } +}; + + +/** The actual data for this object. We wrap it in a struct so that we can copy it around between objects. */ +var() FontImportOptionsData Data ; diff --git a/Engine/Classes/ForceFeedbackManager.uc b/Engine/Classes/ForceFeedbackManager.uc new file mode 100644 index 0000000..db956b6 --- /dev/null +++ b/Engine/Classes/ForceFeedbackManager.uc @@ -0,0 +1,134 @@ +/** +* This class handles various waveform activities. It manages the waveform data +* that is being played on any given gamepad at any given time. It is called by +* the player controller to start/stop/pause a waveform for a given gamepad. It +* is queried by the Viewport to get the current rumble state information +* to apply that to the gamepad. It does this by evaluating the function +* defined in the waveform sample data. +* +* Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +*/ + +class ForceFeedbackManager extends Object within PlayerController + native + abstract + transient; + +/** Whether the player has disabled gamepad rumble or not (TCR C5-3) */ +var bool bAllowsForceFeedback; + +/** The currently playing waveform */ +var ForceFeedbackWaveform FFWaveform; + +/** Whether it was paused by the player controller or not */ +var bool bIsPaused; + +/** The current waveform sample being played */ +var int CurrentSample; + +/** The amount of time elapsed since the start of this waveform */ +var float ElapsedTime; + +//@HSL_BEGIN_XBOX +/** The next waveform sample being played */ +var int NextSample; + +/** The amount of time elapsed since the start of this waveform, for the next frame */ +var float NextElapsedTime; +//@HSL_END_XBOX + +/** The amount to scale all waveforms by (user settable) (TCR C5-3) */ +var float ScaleAllWaveformsBy; + +/** Used with max waveform distance on the waveform to determine waveform attenuation */ +var Actor WaveformInstigator; + +/** + * Sets the waveform to play for the gamepad + * + * @param ForceFeedbackWaveform The waveform data to play + * @param Instigator the actor causing the rumble + */ +simulated function PlayForceFeedbackWaveform(ForceFeedbackWaveform Waveform,Actor WaveInstigator) +{ +`if(`__TW_) + if (Waveform == None || Waveform.Samples.Length == 0 || !bAllowsForceFeedback) + { + return; + } +`endif // __TW_ + + // Zero out the current sample and duration and unpause if paused + CurrentSample = 0; + ElapsedTime = 0.0; +//@HSL_BEGIN_XBOX + NextSample = 0; + NextElapsedTime = 0.0; +//@HSL_END_XBOX + bIsPaused = false; + FFWaveform = None; + WaveformInstigator = None; + // Make sure the waveform is valid + if (Waveform != None && + Waveform.Samples.Length > 0 && + bAllowsForceFeedback == true) + { + // Set the wave form to play + FFWaveform = Waveform; + WaveformInstigator = WaveInstigator; + } +} + +/** + * Stops the waveform by nulling out the waveform + */ +simulated function StopForceFeedbackWaveform(optional ForceFeedbackWaveform Waveform) +{ + if (Waveform == None || Waveform == FFWaveform) + { + // Remove the current waveform + FFWaveform = None; + WaveformInstigator = None; + } +} + +/** + * Pauses/unpauses the playback of the waveform for the gamepad + * + * @param bPause True to pause, False to resume + */ +simulated function PauseWaveform(optional bool bPause) +{ + // Set the paused state for the gamepad + bIsPaused = bPause; +} + +cpptext +{ +protected: + /** + * Update the currently playing waveform sample + * + * @param DeltaTime The amount of elapsed time since the last update + */ + virtual void UpdateWaveformData(FLOAT DeltaTime); + +public: + /** + * Applies the current waveform data to the gamepad/mouse/etc + * This function is platform specific + * + * @param DeviceID The device that needs updating + * @param DeltaTime The amount of elapsed time since the last update + */ + virtual void ApplyForceFeedback(INT DeviceID,FLOAT DeltaTime) {} + + /** Clear any vibration going on this device right away. */ + virtual void ForceClearWaveformData(INT DeviceID) {} +} + +defaultproperties +{ + bAllowsForceFeedback=true + ScaleAllWaveformsBy=1.0 +} diff --git a/Engine/Classes/ForceFeedbackWaveform.uc b/Engine/Classes/ForceFeedbackWaveform.uc new file mode 100644 index 0000000..e0c3a16 --- /dev/null +++ b/Engine/Classes/ForceFeedbackWaveform.uc @@ -0,0 +1,97 @@ +/** + * This class manages the waveform data for a forcefeedback device, + * specifically for the xbox gamepads. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class ForceFeedbackWaveform extends Object + native + editinlinenew; + + +/** The type of function that generates the waveform sample */ +enum EWaveformFunction +{ + WF_Constant, + WF_LinearIncreasing, + WF_LinearDecreasing, + WF_Sin0to90, + WF_Sin90to180, + WF_Sin0to180, + WF_Noise +}; + +/** Holds a single sample's information */ +struct native WaveformSample +{ + /** + * Use a byte with a range of 0 to 100 to represent the percentage of + * "on". This cuts the data needed to store the waveforms in half. + */ + var() byte LeftAmplitude; + var() byte RightAmplitude; +//@HSL_BEGIN_XBOX + var() byte LeftTriggerAmplitude; + var() byte RightTriggerAmplitude; + /** For function generated samples, the type of function */ + var() EWaveformFunction LeftFunction; + var() EWaveformFunction RightFunction; + var() EWaveformFunction LeftTriggerFunction; + var() EWaveformFunction RightTriggerFunction; +//@HSL_END_XBOX + /** The amount of time this sample plays */ + var() float Duration; + + structcpptext + { + friend FArchive& operator<<(FArchive& Ar,FWaveformSample& A) + { +//@HSL_BEGIN_XBOX + Ar << A.LeftAmplitude << A.RightAmplitude << A.LeftFunction + << A.RightFunction << A.Duration; + if (Ar.IsLoading() && Ar.Ver() < VER_XBOX_ONE_INTEGRATION) + { + A.LeftTriggerAmplitude = 0; + A.RightTriggerAmplitude = 0; + A.LeftTriggerFunction = WF_Constant; + A.RightTriggerFunction = WF_Constant; + } + else + { + Ar << A.LeftTriggerAmplitude << A.RightTriggerAmplitude + << A.LeftTriggerFunction << A.RightTriggerFunction; + } + + return Ar; +//@HSL_END_XBOX + } + } +}; + +/** Whether this waveform should be looping or not */ +var() bool bIsLooping; + +/** The list of samples that make up this waveform */ +var() array Samples; + +/** The distance at which the waveform starts to falloff in strength */ +var() float WaveformFalloffStartDistance; + +/** The distance at which the waveform is no longer felt */ +var() float MaxWaveformDistance; + +cpptext +{ + void Serialize( FArchive& Ar ) + { + Super::Serialize(Ar); + if (Ar.IsLoading() && Ar.Ver() < VER_FORCEFEEDBACKWAVERFORM_NOEXPORT_CHANGE) + { + INT TempIsLooping = 0; + Ar << TempIsLooping; + bIsLooping = (TempIsLooping == 0) ? FALSE : TRUE; + Ar << Samples; + } + } +} diff --git a/Engine/Classes/ForceFieldShape.uc b/Engine/Classes/ForceFieldShape.uc new file mode 100644 index 0000000..684ae78 --- /dev/null +++ b/Engine/Classes/ForceFieldShape.uc @@ -0,0 +1,26 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class ForceFieldShape extends Object + native(ForceField) + editinlinenew + abstract; + +event FillBySphere(float Radius); +event FillByBox(vector Dimension); +event FillByCapsule(float Height, float Radius); +event FillByCylinder(float BottomRadius, float TopRadius, float Height, float HeightOffset); + +event PrimitiveComponent GetDrawComponent(); + +cpptext +{ +#if WITH_NOVODEX + virtual class NxForceFieldShapeDesc * CreateNxDesc(){ return NULL; } +#endif +} + +defaultproperties +{ +} diff --git a/Engine/Classes/ForceFieldShapeBox.uc b/Engine/Classes/ForceFieldShapeBox.uc new file mode 100644 index 0000000..c5d7f63 --- /dev/null +++ b/Engine/Classes/ForceFieldShapeBox.uc @@ -0,0 +1,61 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class ForceFieldShapeBox extends ForceFieldShape + native(ForceField) + ; + +var DrawBoxComponent Shape; + +event vector GetRadii() +{ + return Shape.BoxExtent; +} + +event FillBySphere(float Radius) +{ + Shape.BoxExtent.X = Radius; + Shape.BoxExtent.Y = Radius; + Shape.BoxExtent.Z = Radius; +} + +event FillByBox(vector Extent) +{ + Shape.BoxExtent = Extent; +} + +event FillByCapsule(float Height, float Radius) +{ + Shape.BoxExtent.X = Radius; + Shape.BoxExtent.Y = Radius; + Shape.BoxExtent.Z = Radius + Height/2; +} + +event FillByCylinder(float BottomRadius, float TopRadius, float Height, float HeightOffset) +{ + Shape.BoxExtent.X = FMax(BottomRadius, TopRadius); + Shape.BoxExtent.Y = Shape.BoxExtent.X; + Shape.BoxExtent.Z = Height/2 + Abs(HeightOffset); +} + +event PrimitiveComponent GetDrawComponent() +{ + return Shape; +} + +cpptext +{ +#if WITH_NOVODEX + virtual class NxForceFieldShapeDesc * CreateNxDesc(); +#endif +} + +defaultproperties +{ + Begin Object Class=DrawBoxComponent Name=DrawBox0 + BoxExtent=(X=200.0, Y=200.0, Z=200.0) + End Object + + Shape = DrawBox0 +} diff --git a/Engine/Classes/ForceFieldShapeCapsule.uc b/Engine/Classes/ForceFieldShapeCapsule.uc new file mode 100644 index 0000000..695b47b --- /dev/null +++ b/Engine/Classes/ForceFieldShapeCapsule.uc @@ -0,0 +1,67 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class ForceFieldShapeCapsule extends ForceFieldShape + native(ForceField) + ; + +var DrawCapsuleComponent Shape; + +// UE3 capsule is x up by default. The fill... functions are not right because of the direction. Todo. +event float GetHeight() +{ + return Shape.CapsuleHeight; +} + +event float GetRadius() +{ + return Shape.CapsuleRadius; +} + +event FillBySphere(float Radius) +{ + Shape.CapsuleRadius = Radius; + Shape.CapsuleHeight = 0; +} + +event FillByBox(vector Extent) +{ + Shape.CapsuleRadius = Sqrt(Extent.X*Extent.X + Extent.Y*Extent.Y); + Shape.CapsuleHeight = Extent.Z*2; +} + +event FillByCapsule(float Height, float Radius) +{ + Shape.CapsuleHeight = Height; + Shape.CapsuleRadius = Radius; +} + +event FillByCylinder(float BottomRadius, float TopRadius, float Height, float HeightOffset) +{ + Shape.CapsuleRadius = FMax(BottomRadius, TopRadius); + Shape.CapsuleHeight = Height; +} + +event PrimitiveComponent GetDrawComponent() +{ + return Shape; +} + +cpptext +{ +#if WITH_NOVODEX + virtual class NxForceFieldShapeDesc * CreateNxDesc(); +#endif +} + +defaultproperties +{ + Begin Object Class=DrawCapsuleComponent Name=DrawCapsule0 + CapsuleRadius=200.0 + CapsuleHeight=200.0 + Rotation=(Pitch=0, Yaw=0, Roll=16384)//make it z upwards like cylinder + End Object + + Shape = DrawCapsule0 +} diff --git a/Engine/Classes/ForceFieldShapeSphere.uc b/Engine/Classes/ForceFieldShapeSphere.uc new file mode 100644 index 0000000..525b319 --- /dev/null +++ b/Engine/Classes/ForceFieldShapeSphere.uc @@ -0,0 +1,59 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class ForceFieldShapeSphere extends ForceFieldShape + native(ForceField); + +var DrawSphereComponent Shape; + +event float GetRadius() +{ + return Shape.SphereRadius; +} + +event FillBySphere(float Radius) +{ + Shape.SphereRadius = Radius; +} + +event FillByBox(vector Extent) +{ + Shape.SphereRadius = vsize(Extent); +} + +event FillByCapsule(float Height, float Radius) +{ + Shape.SphereRadius = Height/2 + Radius; +} + +event FillByCylinder(float BottomRadius, float TopRadius, float Height, float HeightOffset) +{ + local float topDistance, bottomDistance, centerBelowTop, centerAboveBottom; + centerBelowTop = Height/2 + HeightOffset; + centerAboveBottom = Height/2 - HeightOffset; + topDistance = Sqrt(TopRadius*TopRadius + centerBelowTop*centerBelowTop); + bottomDistance = Sqrt(BottomRadius*BottomRadius + centerAboveBottom*centerAboveBottom); + Shape.SphereRadius = FMax(topDistance, bottomDistance); +} + +event PrimitiveComponent GetDrawComponent() +{ + return Shape; +} + +cpptext +{ +#if WITH_NOVODEX + virtual class NxForceFieldShapeDesc * CreateNxDesc(); +#endif +} + +defaultproperties +{ + Begin Object Class=DrawSphereComponent Name=DrawSphere0 + SphereRadius=200.0 + End Object + + Shape = DrawSphere0 +} diff --git a/Engine/Classes/ForcedLoopSoundNode.uc b/Engine/Classes/ForcedLoopSoundNode.uc new file mode 100644 index 0000000..383a41f --- /dev/null +++ b/Engine/Classes/ForcedLoopSoundNode.uc @@ -0,0 +1,21 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +/** + * Fake SoundNode used by SimpleSplineAudioComponent only to force endless loop. + * Should not be used anywhere else. + */ +class ForcedLoopSoundNode extends SoundNode + native( Sound ); + +cpptext +{ + virtual UBOOL NotifyWaveInstanceFinished( struct FWaveInstance* WaveInstance ); + virtual FLOAT GetDuration( ); + /** + * Returns the maximum distance this sound can be heard from. Very large for looping sounds as the + * player can move into the hearable range during a loop. + */ + virtual FLOAT MaxAudibleDistance( FLOAT CurrentMaxDistance ); +} diff --git a/Engine/Classes/ForcedReachSpec.uc b/Engine/Classes/ForcedReachSpec.uc new file mode 100644 index 0000000..b5b9fde --- /dev/null +++ b/Engine/Classes/ForcedReachSpec.uc @@ -0,0 +1,27 @@ +//============================================================================= +// ForcedReachSpec. +// +// A ForcedReachspec is forced by the level designer +// +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class ForcedReachSpec extends ReachSpec + native; + +cpptext +{ + virtual FPlane PathColor() + { + // yellow for forced paths + return FPlane(1.f, 1.f, 0.f, 0.f); + } + + virtual UBOOL IsForced() { return true; } + virtual UBOOL PrepareForMove( AController * C ); + virtual INT CostFor(APawn* P); +} + +defaultproperties +{ +} + diff --git a/Engine/Classes/FractureManager.uc b/Engine/Classes/FractureManager.uc new file mode 100644 index 0000000..b318d3c --- /dev/null +++ b/Engine/Classes/FractureManager.uc @@ -0,0 +1,172 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class FractureManager extends Actor + native(Mesh) + config(Game); + +/* Number of FSM parts in the pool */ +var int FSMPartPoolSize; + +/** If TRUE, look for vibrating FSM parts and kill them */ +var() bool bEnableAntiVibration; +/** How much vibration (defined as changes in angular velocity direction) must occur before part is killed. */ +var() float DestroyVibrationLevel; +/** Min angular velocity of part to be killed by vibration detection code. */ +var() float DestroyMinAngVel; + +/** If TRUE, spawn effect for chunks falling off when doing radial damage (ie removing many chunks at once)*/ +var() bool bEnableSpawnChunkEffectForRadialDamage; + +/** */ +var() float ExplosionVelScale; + +/* + * Time after spawning a part during which the part is guaranteed to not be recycled again. + * Used to avoid redundant work when spawning a lot of parts relative to the pool size. + */ +const FSM_DEFAULTRECYCLETIME = 0.2; + +var array PartPool; +var array FreeParts; + +/** List of actors that have fracture parts that have been deferred to spawn on upcoming frames */ +var transient array< FracturedStaticMeshActor > ActorsWithDeferredPartsToSpawn; + +/** Function use to spawn particle effect when a chunk is destroyed. */ +`if(`__TW_LIGHTING_MODIFICATIONS_) +simulated event SpawnChunkDestroyEffect(ParticleSystem Effect, box ChunkBox, vector ChunkDir, float Scale, const FracturedStaticMeshComponent MeshComp) +`else +simulated event SpawnChunkDestroyEffect(ParticleSystem Effect, box ChunkBox, vector ChunkDir, float Scale) +`endif +{ + local vector ChunkMiddle; + local ParticleSystemComponent EffectComp; + +`if(`__TW_PERFORMANCE_) + if( WorldInfo.bDropDetail ) + { + return; + } +`endif + + ChunkMiddle = 0.5 * (ChunkBox.Min + ChunkBox.Max); + EffectComp = WorldInfo.MyEmitterPool.SpawnEmitter(Effect, ChunkMiddle, rotator(ChunkDir)); + EffectComp.SetScale(Scale); + +`if(`__TW_LIGHTING_MODIFICATIONS_) + if ( MeshComp != None ) + { + EffectComp.SetLightingChannels(MeshComp.LightingChannels); + } +`endif +} + +native function float GetNumFSMPartsScale(); + +/** Returns a scalar to the percentage chance of a fractured static mesh spawning a rigid body after + taking direct damage */ +native function float GetFSMDirectSpawnChanceScale(); + +/** Returns a scalar to the percentage chance of a fractured static mesh spawning a rigid body after + taking radial damage, such as from an explosion */ +native function float GetFSMRadialSpawnChanceScale(); + +/** Returns a distance scale for whether a fractured static mesh should actually fracture when damaged */ +native function float GetFSMFractureCullDistanceScale(); + +cpptext +{ + virtual void TickSpecial( FLOAT DeltaSeconds ); +}; + +simulated event PreBeginPlay() +{ + Super.PreBeginPlay(); + + CreateFSMParts(); +} + +simulated event Destroyed() +{ + Super.Destroyed(); + + CleanUpFSMParts(); +} + + + +simulated final function CleanUpFSMParts() +{ + local int Idx; + + for( Idx=0; Idx 0 ) + { + for( CurActorIndex = 0; CurActorIndex < ActorsWithDeferredPartsToSpawn.length; ++CurActorIndex ) + { + if( ActorsWithDeferredPartsToSpawn[ CurActorIndex ].SpawnDeferredParts() ) + { + // No chunks left to spawn, so we can remove it from our list + ActorsWithDeferredPartsToSpawn.remove( CurActorIndex, 1 ); + --CurActorIndex; + } + } + } +} + +defaultproperties +{ + FSMPartPoolSize=50 + + bEnableAntiVibration=FALSE + DestroyVibrationLevel=3.0 + DestroyMinAngVel=2.5 + ExplosionVelScale=1.0 +} diff --git a/Engine/Classes/FractureMaterial.uc b/Engine/Classes/FractureMaterial.uc new file mode 100644 index 0000000..65dcee0 --- /dev/null +++ b/Engine/Classes/FractureMaterial.uc @@ -0,0 +1,16 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class FractureMaterial extends Object + native(Physics) + collapsecategories + hidecategories(Object); + +/** Particle system effect to play at fracture location. */ +var() ParticleSystem FractureEffect; +/** Sound cue to play at fracture location. */ +var() SoundCue FractureSound; + +defaultproperties +{ +} diff --git a/Engine/Classes/FracturedBaseComponent.uc b/Engine/Classes/FracturedBaseComponent.uc new file mode 100644 index 0000000..dc795ae --- /dev/null +++ b/Engine/Classes/FracturedBaseComponent.uc @@ -0,0 +1,144 @@ +/** + * FracturedBaseComponent.uc - Declaration of the base fractured component which handles rendering with a dynamic index buffer. + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class FracturedBaseComponent extends StaticMeshComponent + native(Mesh) + abstract; + +/** This component's index buffer, used for rendering when bUseDynamicIndexBuffer is true. */ +var protected{protected} const native transient pointer ComponentBaseResources{class FFracturedBaseResources}; + +/** A fence used to track when the rendering thread has released the component's resources. */ +var protected{protected} native const transient RenderCommandFence_Mirror ReleaseResourcesFence{FRenderCommandFence}; + +/** Stores non-zero for each fragment that is visible, and 0 otherwise. */ +var protected{protected} transient const array VisibleFragments; + +/** If true, VisibleFragments has changed since the last attach and the dynamic index buffer needs to be updated. */ +var protected{protected} transient bool bVisibilityHasChanged; + +/** True if VisibleFragments was reset to bInitialVisibilityValue since the last component attach. */ +var protected{protected} transient const bool bVisibilityReset; + +/** Initial visibility value for this component. */ +var protected{protected} const bool bInitialVisibilityValue; + +/** + * If true, each element will be rendered with one draw call by using a dynamic index buffer that is repacked when visibility changes. + * If false, each element will be rendered with n draw calls, where n is the number of consecutive index ranges, and there will be no memory overhead. + */ +var protected{protected} const bool bUseDynamicIndexBuffer; + +/** + * If true, bUseDynamicIndexBuffer will be enabled when at least one fragment is hidden, otherwise it will be disabled. + * If false, bUseDynamicIndexBuffer will not be overridden. + */ +var protected{protected} const bool bUseDynamicIBWithHiddenFragments; + +/** + * Number of indices in the resource's index buffer the last time the component index buffer was built. + * Used to detect when the resource's index buffer has changed and the component's index buffer should be rebuilt. + */ +var private{private} const int NumResourceIndices; + +/** TRUE whenever the static mesh is being reset during Reattach */ +var protected{protected} transient const int bResetStaticMesh; + +cpptext +{ +public: + //UObject + + /** Blocks until the component's render resources have been released so that they can safely be modified */ + virtual void PreEditChange(UProperty* PropertyAboutToChange); + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + /** + * Signals to the object to begin asynchronously releasing resources + */ + virtual void BeginDestroy(); + + /** + * Check for asynchronous resource cleanup completion + * @return TRUE if the rendering resources have been released + */ + virtual UBOOL IsReadyForFinishDestroy(); + + //Accessors + INT GetNumVisibleTriangles() const; + UBOOL GetInitialVisibilityValue() const; + +protected: + + /** + * Called after all objects referenced by this object have been serialized. Order of PostLoad routed to + * multiple objects loaded in one set is not deterministic though ConditionalPostLoad can be forced to + * ensure an object has been "PostLoad"ed. + */ + virtual void PostLoad(); + + virtual void InitResources(); + virtual void ReleaseResources(); + void ReleaseBaseResources(); + + /** Attaches the component to the scene, and initializes the component's resources if they have not been yet. */ + virtual void Attach(); + + /** Checks if the given fragment is visible. */ + virtual UBOOL IsElementFragmentVisible(INT ElementIndex, INT FragmentIndex, INT InteriorElementIndex, INT CoreFragmentIndex, UBOOL bAnyFragmentsHidden) const; + + /** + * Updates the fragments of this component that are visible. + * @param NewVisibleFragments - visibility factors for this component, corresponding to FracturedStaticMesh's Fragments array + * @param bForceUpdate - whether to update this component's resources even if no fragments have changed visibility + */ + virtual void UpdateVisibleFragments(const TArray& NewVisibleFragments, UBOOL bForceUpdate); + + /** + * Resets VisibleFragments to bInitialVisibilityValue. + * Does not cause a reattach, so the results won't be propagated to the render thread until the next reattach. + */ + void ResetVisibility(); + + /** + * Determine if the mesh currently has any hidden fragments + * @return TRUE if >0 hidden fragments + */ + UBOOL HasHiddenFragments() const; + +private: + + /** Enqueues a rendering command to update the component's dynamic index buffer. */ + void UpdateComponentIndexBuffer(); + + friend class FFracturedBaseSceneProxy; +} + +/** + * Change the StaticMesh used by this instance, and resets VisibleFragments to all be visible if NewMesh is valid. + * @param NewMesh - StaticMesh to set. If this is not also a UFracturedStaticMesh, assignment will fail. + * @return bool - TRUE if assignment succeeded. + */ +simulated native function bool SetStaticMesh( StaticMesh NewMesh, optional bool bForce ); + +/** Returns array of currently visible fragments. */ +simulated native function array GetVisibleFragments() const; + +/** Returns whether the specified fragment is currently visible or not. */ +simulated native function bool IsFragmentVisible(INT FragmentIndex) const; + +/** Get the number of chunks in the assigned fractured mesh. */ +native function int GetNumFragments() const; + +/** Get the number of chunks that are currently visible. */ +native function int GetNumVisibleFragments() const; + +defaultproperties +{ + bUseDynamicIndexBuffer=true + bInitialVisibilityValue=true + bAcceptsDecalsDuringGameplay=FALSE + bAcceptsStaticDecals=FALSE + bAcceptsDynamicDecals=TRUE +} diff --git a/Engine/Classes/FracturedSMActorSpawnable.uc b/Engine/Classes/FracturedSMActorSpawnable.uc new file mode 100644 index 0000000..64ef1f2 --- /dev/null +++ b/Engine/Classes/FracturedSMActorSpawnable.uc @@ -0,0 +1,20 @@ +//============================================================================= +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= + +class FracturedSMActorSpawnable extends FracturedStaticMeshActor; + + +defaultproperties +{ + Begin Object Name=LightEnvironment0 + bEnabled=TRUE + End Object + + Begin Object Name=FracturedStaticMeshComponent0 + bForceDirectLightMap=FALSE + LightEnvironment=LightEnvironment0 + End Object + + bNoDelete=FALSE +} \ No newline at end of file diff --git a/Engine/Classes/FracturedSkinnedMeshComponent.uc b/Engine/Classes/FracturedSkinnedMeshComponent.uc new file mode 100644 index 0000000..4db8026 --- /dev/null +++ b/Engine/Classes/FracturedSkinnedMeshComponent.uc @@ -0,0 +1,80 @@ +/** + * FracturedSkinnedMeshComponent.uc - Uses skinning to draw detached parts with as few sections as possible. + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class FracturedSkinnedMeshComponent extends FracturedBaseComponent + native(Mesh); + +/* Render resources used by this component, and whose release progress is tracked by the FRenderCommandFence in FracturedBaseComponent. */ +var protected{protected} const native transient pointer ComponentSkinResources{class FFracturedSkinResources}; + +/* A transform for each fragment, used to skin vertices from each fragment into position while minimizing draw calls. */ +var protected{protected} transient const array FragmentTransforms; + +/* An array of components whose visibility information will be used. */ +var protected{protected} transient const array DependentComponents; + +/* TRUE when at least one fragment is unhidden after visibility is reset. */ +var protected{protected} transient const bool bBecameVisible; + +/** TRUE if fragment transforms have changed and the GPU should be refreshed */ +var protected{protected} transient const bool bFragmentTransformsChanged; + + +cpptext +{ +public: + //UPrimitiveComponent + virtual void UpdateBounds(); + virtual FPrimitiveSceneProxy* CreateSceneProxy(); + virtual UBOOL ShouldRecreateProxyOnUpdateTransform() const; + + /* Sets the visiblity of a single fragment, and starts a deferred reattach if visiblity changed. */ + void SetFragmentVisibility(INT FragmentIndex, UBOOL bVisibility); + + /* Updates the transform of a single fragment. */ + void SetFragmentTransform(INT FragmentIndex, const FMatrix& LocalToWorld); + + /* Adds a dependent component whose visibility will affect this component's visibility. */ + void RegisterDependentComponent(UFracturedStaticMeshComponent* InComponent); + + /* Removes a dependent component whose visibility will affect this component's visibility. */ + void RemoveDependentComponent(UFracturedStaticMeshComponent* InComponent); + + /** Static: Updates the GPU with bone matrices for this skinned fractured mesh */ + static void UpdateDynamicBoneData_RenderThread(FFracturedSkinResources* ComponentSkinResources, const TArray& FragmentTransforms); + +protected: + + virtual void InitResources(); + virtual void ReleaseResources(); + void ReleaseSkinResources(); + + /** Attaches the component to the scene, and initializes the component's resources if they have not been yet. */ + virtual void Attach(); + + virtual void UpdateTransform(); + + friend class FFracturedSkinnedMeshSceneProxy; +} + +defaultproperties +{ + bAllowCullDistanceVolume=FALSE + bInitialVisibilityValue=FALSE + CastShadow=FALSE + bCastDynamicShadow=FALSE + bForceDirectLightMap=FALSE + bAllowApproximateOcclusion=TRUE + RBCollideWithChannels=(Default=FALSE,GameplayPhysics=FALSE,EffectPhysics=FALSE,FracturedMeshPart=FALSE) + CollideActors=FALSE + BlockActors=FALSE + BlockZeroExtent=FALSE + BlockNonZeroExtent=FALSE + BlockRigidBody=FALSE + bAcceptsStaticDecals=FALSE + bAcceptsDynamicDecals=FALSE // this is set to FALSE as we will get floating decals after the various fracture pieces break off + bOverrideLightMapResolution=FALSE + bOverrideLightMapRes=FALSE + bUsePrecomputedShadows=FALSE +} diff --git a/Engine/Classes/FracturedStaticMeshActor.uc b/Engine/Classes/FracturedStaticMeshActor.uc new file mode 100644 index 0000000..5538fa4 --- /dev/null +++ b/Engine/Classes/FracturedStaticMeshActor.uc @@ -0,0 +1,753 @@ +//============================================================================= +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= + +class FracturedStaticMeshActor extends Actor + dependson(FracturedStaticMeshComponent) + dependson(WorldInfo) + ClassGroup(StaticMeshes) + native(Mesh) + placeable; + + +/** Maximum number of rigid body parts to spawn off per actor, per frame */ +var() int MaxPartsToSpawnAtOnce; + +/** Info about a fracture part that should be spawned in an upcoming Tick */ +struct native DeferredPartToSpawn +{ + /** Index of the chunk to spawn */ + var int ChunkIndex; + + /** Exit velocity for this chunk */ + var vector InitialVel; + + /** Exit angular velocity for this chunk */ + var vector InitialAngVel; + + /** Relative scale */ + var float RelativeScale; + + /** TRUE if this part was spawned because of an explosion */ + var bool bExplosion; +}; + + +var() const editconst FracturedStaticMeshComponent FracturedStaticMeshComponent; + +/** Skinned component which will handle rendering for FracturedStaticMeshComponent */ +var const FracturedSkinnedMeshComponent SkinnedComponent; + +/** Current health of each chunk */ +var array ChunkHealth; + +/** Used so we only display the 'missing sound' warning once */ +var transient bool bHasShownMissingSoundWarning; + +/** If true, detach parts when an Actor with bCanCauseFractureOnTouch contacts them. Actor must not be blocked by this FSMA. */ +var() bool bBreakChunksOnActorTouch; + +/** Set of damage types that can cause pieces to break off this FSAM. If empty, all damage types can do this. */ +var() array< class > FracturedByDamageType; + +/** Allows controlling how much 'health' chunks have on a per-instance basis */ +var() float ChunkHealthScale; + +/** Allows you to override particle effects to play when chunk is hidden for just this actor. */ +var() array OverrideFragmentDestroyEffects; + +/** Minimum distance from player where actor will ALWAYS fracture, even when outside the view frustum (scaled by global settings.) */ +var() float FractureCullMinDistance; + +/** Maximum distance from player where actor will be allowed to fracture (scaled by global settings.) */ +var() float FractureCullMaxDistance; + +/** Array of parts that are waiting to be spawned in an upcoming tick */ +var transient array< DeferredPartToSpawn > DeferredPartsToSpawn; + +/** Cached info for part impacts */ +var PhysEffectInfo PartImpactEffect; + +/** Cached sound for large fractures. */ +var AkBaseSoundObject ExplosionFractureSound; +/** Cached sound for single chunk fractures. */ +var AkBaseSoundObject SingleChunkFractureSound; + +/** This is the material that was set on this FracuredStaticMeshActor before we overrode it with LoseChunkOutsideMaterial **/ +var transient MaterialInterface MI_LoseChunkPreviousMaterial; + +/** Data relevant to checkpoint save/load, see CreateCheckpointRecord/ApplyCheckpointRecord below */ +struct CheckpointRecord +{ + var bool bIsShutdown; + var array FragmentVis; +}; +/** whether this should be saved in checkpoints */ +var() bool bShouldSaveForCheckpoint; + +`if(`__TW_PHYSICS_) +/** If set, fractures parts are destroyed on any collision */ +var(KFFracturedMeshActor) bool bDestroyFragmentsOnImpact; + +/** Used by reset system to determine if actor needs to be processed */ +var transient bool bHasBeenDirtied; +`endif + +cpptext +{ + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual void TickSpecial(FLOAT DeltaSeconds); + virtual UBOOL InStasis(); +}; + + +/** Spawn one chunk of this mesh as its own Actor, with the supplied velocities and scale relative to this Actor. */ +simulated native final function FracturedStaticMeshPart SpawnPart(int ChunkIndex, vector InitialVel, vector InitialAngVel, float RelativeScale, bool bExplosion); + +/** Does the same as SpawnPart, but takes an array of chunks to make part of the new part. */ +simulated native final function FracturedStaticMeshPart SpawnPartMulti(array ChunkIndices, vector InitialVel, vector InitialAngVel, float RelativeScale, bool bExplosion); + + +simulated event PostBeginPlay() +{ + local PhysicalMaterial PhysMat; + + super.PostBeginPlay(); + ResetHealth(); + if (!bBreakChunksOnActorTouch) + { + SetTickIsDisabled(true); + } + + // Cache effects for impact and sound for large fracture + PhysMat = FracturedStaticMeshComponent.GetFracturedMeshPhysMaterial(); + PartImpactEffect = PhysMat.FindPhysEffectInfo(EPMET_Impact); + + PhysMat.FindFractureSounds(ExplosionFractureSound, SingleChunkFractureSound); + + ResetVisibility(); +} + +/** Used to init/reset health array. */ +simulated native final function ResetHealth(); + +function bool ShouldSaveForCheckpoint() +{ + return bShouldSaveForCheckpoint; +} + +/** Called when this actor is being saved in a checkpoint, records pertinent information for restoration via ApplyCheckpointRecord. */ +function CreateCheckpointRecord(out CheckpointRecord Record) +{ + if (Physics == PHYS_None && bHidden) + { + Record.bIsShutdown = true; + } + else + { + Record.FragmentVis = FracturedStaticMeshComponent.GetVisibleFragments(); + } +} + +/** Restores this actor from its checkpoint record */ +function ApplyCheckpointRecord(const out CheckpointRecord Record) +{ + if (Record.bIsShutdown) + { + ShutDown(); + } + else + { + FracturedStaticMeshComponent.SetVisibleFragments(Record.FragmentVis); + } +} + +/** + * Find all groups of chunks which are not connected to 'root' parts, and spawn them as new physics objects. + * Updates FragmentVis with new chunks that get hidden by the process. + */ +native simulated event BreakOffIsolatedIslands(out array FragmentVis, array IgnoreFrags, vector ChunkDir, array DisableCollWithPart, bool bWantPhysChunks); + +/** + * Gives the actor a chance to spawn chunks that may have been deferred + * + * @return Returns true if there are still any deferred parts left to spawn + */ +native simulated event bool SpawnDeferredParts(); + +/** Util for checking if this damage type will cause fracture. */ +simulated function bool IsFracturedByDamageType(class DmgType) +{ + local int i; + + if(FracturedByDamageType.length == 0) + { + return TRUE; + } + + for(i=0; i 1) ) + { + if ( bForceDedicated ) + { + return true; + } + if ( (EffectInstigator != None) && EffectInstigator.IsHumanControlled() && EffectInstigator.IsLocallyControlled() ) + { + return true; + } + } + else if ( (EffectInstigator != None) && EffectInstigator.IsHumanControlled() ) + { + return true; + } + + // Apply global system settings scale to cull distances + FinalMinDistance = FractureCullMinDistance * WorldInfo.MyFractureManager.GetFSMFractureCullDistanceScale(); + FinalCullDistance = FractureCullMaxDistance * WorldInfo.MyFractureManager.GetFSMFractureCullDistanceScale(); + + // Determine how far to the nearest local viewer + DistSq = 10000000000.0; + foreach LocalPlayerControllers(class'PlayerController', P) + { + P.GetPlayerViewPoint(CameraLoc, CameraRot); + DistSq = FMin(DistSq, VSizeSq(Location - CameraLoc)); + } + + if ( DistSq > FinalCullDistance*FinalCullDistance ) + { + bResult = false; + } + else if ( DistSq < FinalMinDistance*FinalMinDistance ) + { + // If close enough, always spawn even if hidden + return true; + } + + // For fractured meshes, we only want to spawn effects if the mesh actor itself has been seen recently + if( bResult ) + { + if( WorldInfo.TimeSeconds - LastRenderTime < 0.5 ) + { + // We're on screen and close enough to render! + return true; + } + else + { + // We're off screen, but still close enough to allow the effect, but we'll skip + // spawning rigid bodies. + bWantPhysChunksAndParticles = 0; + return true; + } + } + else + { + // Too far away! + bWantPhysChunksAndParticles = 0; + return false; + } + } +} + + +/** + * This function will remove all of the currently attached decals from the object. + * Basically, we want to have decals attach to these objects and then on state change (due to damage usually), we will + * just detach them all with the big particle effect that occurs it should not be noticeable. + **/ +simulated native final protected function RemoveDecals( int IndexToRemoveDecalsFrom ); + + + +/** TakeDamage will hide/spawn chunks when they get shot. */ +simulated event TakeDamage(int Damage, Controller EventInstigator, vector HitLocation, vector Momentum, class DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser) +{ + local array FragmentVis; + local vector ChunkDir, MomentumDir; + local FracturedStaticMesh FracMesh; + local FracturedStaticMeshPart FracPart; + local array NoCollParts; + local int TotalVisible; + local array IgnoreFrags; + local box ChunkBox; + local ParticleSystem EffectPSys; + local float PhysChance, PartScale; + local byte bWantPhysChunksAndParticles; + local Pawn InstigatorPawn; + local WorldFractureSettings FractureSettings; + local vector NewHitLocation, HitNormal; + + // call Actor's version to handle any SeqEvent_TakeDamage for scripting + Super.TakeDamage(Damage, EventInstigator, HitLocation, Momentum, DamageType, HitInfo, DamageCauser); + + // Ignore invalid damage type, hits to the core, to parts that are not destroyable, or parts which are already hidden (somehow) + if( (DamageType != None && !DamageType.default.bCausesFracture) || !IsFracturedByDamageType(DamageType) ) + { + return; + } + + if ( HitInfo.HitComponent == None ) + { + // Perform trace to retrieve hit info + if ( Momentum == vect(0,0,0) ) + { + Momentum = Location - HitLocation; + } + TraceComponent(NewHitLocation, HitNormal, FracturedStaticMeshComponent, HitLocation+100*Normal(Momentum), HitLocation,, HitInfo, true); + } + + if ( HitInfo.Item == FracturedStaticMeshComponent.GetCoreFragmentIndex() || + !FracturedStaticMeshComponent.IsFragmentVisible(HitInfo.Item) || + !FracturedStaticMeshComponent.IsFragmentDestroyable(HitInfo.Item) ) + { + return; + } + + // Make sure the impacted fractured mesh is visually relevant + if (EventInstigator != None) + { + InstigatorPawn = EventInstigator.Pawn; + } + else if (DamageCauser != None) + { + InstigatorPawn = DamageCauser.Instigator; + } + if (!FractureEffectIsRelevant(false, InstigatorPawn, bWantPhysChunksAndParticles)) + { + return; + } + // Take away from chunks health - if scripted, force to zero. + if( RB_LineImpulseActor(DamageCauser) != None ) + { + ChunkHealth[HitInfo.Item] = 0.0; + } + else if ( DamageType != None ) + { + ChunkHealth[HitInfo.Item] -= WorldInfo.FracturedMeshWeaponDamage * DamageType.default.FracturedMeshDamage; + } + else + { + ChunkHealth[HitInfo.Item] -= WorldInfo.FracturedMeshWeaponDamage; + } + //`log("FSM:TAKEDAMAGE"@HitInfo.Item@ChunkHealth[HitInfo.Item]); + +`if(`__TW_PHYSICS_) + // Dirty actor for reset + bHasBeenDirtied = true; +`endif + + // If its hit zero health, hide part and spawn part. + if(ChunkHealth[HitInfo.Item] <= 0) + { + FracMesh = FracturedStaticMesh(FracturedStaticMeshComponent.StaticMesh); + + // Get fracture settings from relevant WorldInfo. + FractureSettings = WorldInfo.GetWorldFractureSettings(); + + FragmentVis = FracturedStaticMeshComponent.GetVisibleFragments(); + TotalVisible = FracturedStaticMeshComponent.GetNumVisibleFragments(); + + // If physics object - ignore hits if you are the last part + if(Physics == PHYS_RigidBody) + { + if(TotalVisible == 1) + { + return; + } + } + + // If we are losing the first chunk, change exterior material (if replacement is defined). + if(TotalVisible == FragmentVis.length) + { + SetLoseChunkReplacementMaterial(); + } + + FragmentVis[HitInfo.Item] = 0; + + // Start with average exterior normal of chunk + ChunkDir = FracturedStaticMeshComponent.GetFragmentAverageExteriorNormal(HitInfo.Item); + + // If bad normal, or its pointing away from us, add in the shot momentum + MomentumDir = Normal(Momentum); + if((VSize(ChunkDir) < 0.01) || (MomentumDir Dot ChunkDir > -0.2)) + { + ChunkDir += MomentumDir; + } + + // Take out any downwards force + ChunkDir.Z = Max(ChunkDir.Z, 0.0); + // Reduce Z vel + ChunkDir.Z /= FracMesh.ChunkLinHorizontalScale; + // Normalize + ChunkDir = Normal(ChunkDir); + + // See if we want to spawn physics chunks, and take into account chance of it happening + if ( WorldInfo.NetMode != NM_DedicatedServer ) + { + PhysChance = FractureSettings.bEnableChanceOfPhysicsChunkOverride ? FractureSettings.ChanceOfPhysicsChunkOverride : FracMesh.ChanceOfPhysicsChunk; + PhysChance *= WorldInfo.MyFractureManager.GetFSMDirectSpawnChanceScale(); + if( bWantPhysChunksAndParticles == 1 && + FracMesh.bSpawnPhysicsChunks && + (FRand() < PhysChance) && + !FracturedStaticMeshComponent.IsNoPhysFragment(HitInfo.Item) ) + { + PartScale = FracMesh.NormalPhysicsChunkScaleMin + FRand() * (FracMesh.NormalPhysicsChunkScaleMax - FracMesh.NormalPhysicsChunkScaleMin); + // Spawn part moving from center of mesh + FracPart = SpawnPart(HitInfo.Item, (ChunkDir * FracMesh.ChunkLinVel) + Velocity, VRand() * FracMesh.ChunkAngVel, PartScale, FALSE); + //RemoveDecals( HitInfo.Item ); + + if (FracPart != None) + { + // Disable collision between spawned part and this mesh. + FracPart.FracturedStaticMeshComponent.DisableRBCollisionWithSMC(FracturedStaticMeshComponent, TRUE); + } + } + + // Assign effect if there is one. + if( bWantPhysChunksAndParticles == 1 ) + { + // Look for override first + if(OverrideFragmentDestroyEffects.length > 0) + { + // Pick randomly + EffectPSys = OverrideFragmentDestroyEffects[Rand(OverrideFragmentDestroyEffects.length)]; + } + // No override array, try the mesh + else if(FracMesh.FragmentDestroyEffects.length > 0) + { + EffectPSys = FracMesh.FragmentDestroyEffects[Rand(FracMesh.FragmentDestroyEffects.length)]; + } + + // If we have an effect and a manager - spawn it + if(EffectPSys != None && WorldInfo.MyFractureManager != None) + { + ChunkBox = FracturedStaticMeshComponent.GetFragmentBox(HitInfo.Item); +`if(`__TW_LIGHTING_MODIFICATIONS_) + WorldInfo.MyFractureManager.SpawnChunkDestroyEffect(EffectPSys, ChunkBox, ChunkDir, FracMesh.FragmentDestroyEffectScale, FracturedStaticMeshComponent); +`else + WorldInfo.MyFractureManager.SpawnChunkDestroyEffect(EffectPSys, ChunkBox, ChunkDir, FracMesh.FragmentDestroyEffectScale); +`endif + } + } + } + + // If no core (or 'always break off isolated parts'), and not overriding - we have to look for un-rooted 'islands' + if((FracMesh.bAlwaysBreakOffIsolatedIslands || FracturedStaticMeshComponent.GetCoreFragmentIndex() == INDEX_NONE) && !FracMesh.bFixIsolatedChunks) + { + IgnoreFrags[0] = HitInfo.Item; + if(FracPart != None) + { + NoCollParts[0] = FracPart; + } + BreakOffIsolatedIslands( + FragmentVis, + IgnoreFrags, + ChunkDir, + NoCollParts, + bWantPhysChunksAndParticles == 1 ? true : false ); + } + + // Right at the end, change fragment visibility + FracturedStaticMeshComponent.SetVisibleFragments(FragmentVis); + + // If this is a physical part - reset physics state, to take notice of new hidden parts. + if (Physics == PHYS_RigidBody) + { + FracturedStaticMeshComponent.RecreatePhysState(); + } + } +} + +/** + * Break off all pieces in one go. + */ +simulated event Explode() +{ + local array FragmentVis; + local int i; + local vector SpawnDir; + local FracturedStaticMesh FracMesh; + local FracturedStaticMeshPart FracPart; + local float PartScale; + +`if(`__TW_PHYSICS_) + // Dirty actor for reset + bHasBeenDirtied = true; +`endif + + FracMesh = FracturedStaticMesh(FracturedStaticMeshComponent.StaticMesh); + + // Iterate over all visible fragments spawning them + FragmentVis = FracturedStaticMeshComponent.GetVisibleFragments(); + for(i=0; i FragmentVis; + local int i; + + // Iterate over all fragments + FragmentVis = FracturedStaticMeshComponent.GetVisibleFragments(); + for(i=0; i FragmentVis; + local int i; + local int Incr; + + // we want to break 25% of the vis to maximize the memory usage + Incr = 4; + + // Iterate over all fragments + FragmentVis = FracturedStaticMeshComponent.GetVisibleFragments(); + for(i=0; i DmgType) +{ + local int idx; + local SeqEvent_TakeDamage DmgEvent; + + // search for any damage events + for (idx = 0; idx < GeneratedEvents.Length; idx++) + { + DmgEvent = SeqEvent_TakeDamage(GeneratedEvents[idx]); + if (DmgEvent != None) + { + // notify the event of the damage received + DmgEvent.HandleDamage(self, InstigatorController, DmgType, DamageAmount); + } + } +} + +`if(`__TW_PHYSICS_) +/** Level was reset without reloading */ +simulated function Reset() +{ + if( !bHasBeenDirtied ) + { + return; + } + + // Reset dirtied flag + bHasBeenDirtied = false; + + // Reset all hidden chunks (destroyed chunks) back to their visible states + ResetVisibility(); + + // Reset chunk health (individual chunks) + ResetHealth(); + + // Reset collision + FracturedStaticMeshComponent.SetBlockRigidBody( true ); + + // Switch back to initial material + if( MI_LoseChunkPreviousMaterial != none ) + { + FracturedStaticMeshComponent.SetMaterial( FracturedStaticMesh(FracturedStaticMeshComponent.StaticMesh).OutsideMaterialIndex, MI_LoseChunkPreviousMaterial ); + MI_LoseChunkPreviousMaterial = none; + } +} +`endif + +defaultproperties +{ + MaxPartsToSpawnAtOnce=6 + + ChunkHealthScale=1.0 + FractureCullMinDistance=512.0 + FractureCullMaxDistance=4096.0 + + bEdShouldSnap=TRUE + bCollideActors=TRUE + bBlockActors=TRUE + bWorldGeometry=TRUE + bProjTarget=TRUE + bGameRelevant=TRUE + bRouteBeginPlayEvenIfStatic=FALSE + bCollideWhenPlacing=FALSE + bStatic=FALSE + bMovable=FALSE + bNoDelete=TRUE + bPathColliding=TRUE + // Without this explosions won't do damage to them because they are world geometry + bCanBeDamaged=true + + Begin Object Class=DynamicLightEnvironmentComponent Name=LightEnvironment0 + bEnabled=FALSE + bDynamic=FALSE + bForceNonCompositeDynamicLights=TRUE // needed since we are using a static light environment + End Object +`if(`__TW_LIGHTING_MODIFICATIONS_) + // Don't add to components list +`else + Components.Add(LightEnvironment0) +`endif + + Begin Object Class=FracturedSkinnedMeshComponent Name=FracturedSkinnedComponent0 + bDisableAllRigidBody=TRUE + LightEnvironment=LightEnvironment0 + End Object + Components.Add(FracturedSkinnedComponent0) + SkinnedComponent=FracturedSkinnedComponent0 + + Begin Object Class=FracturedStaticMeshComponent Name=FracturedStaticMeshComponent0 + WireframeColor=(R=0,G=128,B=255,A=255) + bAllowApproximateOcclusion=TRUE + bForceDirectLightMap=TRUE + BlockRigidBody=TRUE + bAcceptsStaticDecals=FALSE + bAcceptsDynamicDecals=TRUE + bAcceptsDecalsDuringGameplay=FALSE + bUseDynamicIndexBuffer=TRUE + bUseDynamicIBWithHiddenFragments=TRUE + End Object + CollisionComponent=FracturedStaticMeshComponent0 + FracturedStaticMeshComponent=FracturedStaticMeshComponent0 + Components.Add(FracturedStaticMeshComponent0) +} diff --git a/Engine/Classes/FracturedStaticMeshActor_Spawnable.uc b/Engine/Classes/FracturedStaticMeshActor_Spawnable.uc new file mode 100644 index 0000000..84936de --- /dev/null +++ b/Engine/Classes/FracturedStaticMeshActor_Spawnable.uc @@ -0,0 +1,12 @@ +//============================================================================= +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= + +class FracturedStaticMeshActor_Spawnable extends FracturedStaticMeshActor; + + +DefaultProperties +{ + bNoDelete=FALSE +} + diff --git a/Engine/Classes/FracturedStaticMeshComponent.uc b/Engine/Classes/FracturedStaticMeshComponent.uc new file mode 100644 index 0000000..1dbd69e --- /dev/null +++ b/Engine/Classes/FracturedStaticMeshComponent.uc @@ -0,0 +1,168 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class FracturedStaticMeshComponent extends FracturedBaseComponent + native(Mesh); + +/** Stores non-zero for each fragment whose neighbors are all visible, and 0 otherwise. */ +var protected{protected} transient const array FragmentNeighborsVisible; + +/** Local space bounding box of visible fragments, updated on attach. */ +var protected{protected} const Box VisibleBox; + +/** If true, all fragment visibility and transform information will be forwarded to SkinnedComponent, which will handle rendering. */ +var protected{protected} const bool bUseSkinnedRendering; + +/** + * If true, the only thing considered when calculating the bounds of this component are the graphics verts current visible. + * Using this and having simplified collision will cause unpredictable results. + */ +var bool bUseVisibleVertsForBounds; + +/** + * Allows per-instance override of chunk support/destroyable flags. + * Marks chunks at top of mesh as 'root' and 'non destroyable'. + */ +var() bool bTopFragmentsRootNonDestroyable; + +/** + * Allows per-instance override of chunk support/destroyable flags. + * Marks chunks at bottom of mesh as 'root' and 'non destroyable'. + */ +var() bool bBottomFragmentsRootNonDestroyable; + +/** Threshold distance of fragment box from top/bottom of mesh to be considered for bTop/BottomFragmentsRootNonDestroyable */ +var() float TopBottomFragmentDistThreshold; + +/** Allows overriding the LoseChunkOutsideMaterial on a per-instance basis. */ +var() MaterialInterface LoseChunkOutsideMaterialOverride; + +/** Z value of top of fractured piece bounds. */ +var float FragmentBoundsMaxZ; + +/** Z value of bottom of fractured piece bounds. */ +var float FragmentBoundsMinZ; + +/** Component which handles rendering if bUseSkinnedRendering is true. */ +var transient FracturedSkinnedMeshComponent SkinnedComponent; + +/** */ +struct native FragmentGroup +{ + var array FragmentIndices; + var bool bGroupIsRooted; +}; + +cpptext +{ +public: + //UObject + virtual void Serialize(FArchive& Ar); + + //UPrimitiveComponent + virtual void UpdateBounds(); + virtual FPrimitiveSceneProxy* CreateSceneProxy(); + virtual UBOOL LineCheck(FCheckResult& Result, const FVector& End, const FVector& Start, const FVector& Extent, DWORD TraceFlags); + virtual UBOOL PointCheck(FCheckResult& Result,const FVector& Location,const FVector& Extent,DWORD TraceFlags); + virtual void CookPhysConvexDataForScale(ULevel* Level, const FVector& TotalScale3D, INT& TriByteCount, INT& TriMeshCount, INT& HullByteCount, INT& HullCount); +#if WITH_EDITOR + virtual void CheckForErrors(); +#endif + virtual void GenerateDecalRenderData(class FDecalState* Decal, TArray< FDecalRenderData* >& OutDecalRenderDatas) const; + + /** Allocates an implementation of FStaticLightingMesh that will handle static lighting for this component */ + virtual class FStaticMeshStaticLightingMesh* AllocateStaticLightingMesh(INT LODIndex, const TArray& InRelevantLights); + +protected: + + /** Attaches the component to the scene, and initializes the component's resources if they have not been yet. */ + virtual void Attach(); + + /** + * Detach the component from the scene and remove its render proxy + * @param bWillReattach TRUE if the detachment will be followed by an attachment + */ + virtual void Detach( UBOOL bWillReattach = FALSE ); + + /** + * @return FALSE since fractured geometry will handle its own decal detachment + */ + virtual UBOOL AllowDecalRemovalOnDetach() const + { + return FALSE; + } + + /** + * Retrieves the materials used in this component + * + * @param OutMaterials The list of used materials. + */ + virtual void GetUsedMaterials( TArray& OutMaterials ) const; + + virtual void UpdateTransform(); + + /** Update FragmentBoundsMin/MaxZ */ + void UpdateFragmentMinMaxZ(); + + /** See if the bTopFragmentsSupportNonDestroyable/bBottomFragmentsSupportNonDestroyable flags indicate this chunk. */ + UBOOL FragmentInstanceIsSupportNonDestroyable(int FragmentIndex) const; + + /** Checks if the given fragment is visible. */ + virtual UBOOL IsElementFragmentVisible(INT ElementIndex, INT FragmentIndex, INT InteriorElementIndex, INT CoreFragmentIndex, UBOOL bAnyFragmentsHidden) const; + + /** + * Updates the fragments of this component that are visible. + * @param NewVisibleFragments - visibility factors for this component, corresponding to FracturedStaticMesh's Fragments array + * @param bForceUpdate - whether to update this component's resources even if no fragments have changed visibility + */ + virtual void UpdateVisibleFragments(const TArray& NewVisibleFragments, UBOOL bForceUpdate); + + friend class FFracturedStaticMeshSceneProxy; +} + +/** Change the set of visible fragments. */ +native final function SetVisibleFragments(array VisibilityFactors); + +/** Returns if this fragment is destroyable. */ +native final function bool IsFragmentDestroyable(INT FragmentIndex) const; + +/** Returns if this is a supporting 'root' fragment. */ +native final function bool IsRootFragment(INT FragmentIndex) const; + +/** Returns if this fragment should never spawn a physics object. */ +native final function bool IsNoPhysFragment(INT FragmentIndex) const; + +/** Get the bounding box of a specific chunk, in world space. */ +native final function box GetFragmentBox(int FragmentIndex) const; + +/** Returns average exterior normal of a particular chunk. */ +native final function vector GetFragmentAverageExteriorNormal(int FragmentIndex) const; + +/** Gets the index that is the 'core' of this mesh. */ +native final function int GetCoreFragmentIndex() const; + +/** + * Based on the hidden state of chunks, groups which are connected. + * @param IgnoreFragments Additional fragments to ignore when finding islands. These will not end up in any groups. + */ +native final function array GetFragmentGroups(array IgnoreFragments, float MinConnectionArea) const; + +/** + * Return set of fragments that are hidden, but who have at least one visible neighbour. + * @param AdditionalVisibleFragments Additional fragments to consider 'visible' when finding fragments. Will not end up in resulting array. + */ +native final function array GetBoundaryHiddenFragments(array AdditionalVisibleFragments) const; + +/** Re-create physics state - needed if hiding parts would change physics collision of the object. */ +native final function RecreatePhysState(); + +/** Util for getting the PhysicalMaterial applied to this mesh */ +native final function PhysicalMaterial GetFracturedMeshPhysMaterial(); + +defaultproperties +{ + OverriddenLightMapResolution=64 + OverriddenLightMapRes=64 + TopBottomFragmentDistThreshold=0.1 + bUsePrecomputedShadows=TRUE +} diff --git a/Engine/Classes/FracturedStaticMeshPart.uc b/Engine/Classes/FracturedStaticMeshPart.uc new file mode 100644 index 0000000..ba7d970 --- /dev/null +++ b/Engine/Classes/FracturedStaticMeshPart.uc @@ -0,0 +1,167 @@ +//============================================================================= +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= + +class FracturedStaticMeshPart extends FracturedStaticMeshActor + native(Mesh) + notplaceable; + +/** This part will be destroyed if it gets further than BaseFracturedMeshActor's radius * DestroyPartRadiusFactor from BaseFracturedMeshActor. */ +var float DestroyPartRadiusFactor; + +/** Base FracturedStaticMeshActor that this part was spawned off of. */ +var transient FracturedStaticMeshActor BaseFracturedMeshActor; + +/** Indicates whether this part has already been recycled and just needs to be initialized to be used again. */ +var bool bHasBeenRecycled; + +/** Last time that this pieces was spawned. */ +var float LastSpawnTime; + +/** Used to know index within pool in FractureManager, so we replace it in the free pool. */ +var int PartPoolIndex; + +/** Additional gravity scaling for fracture pieces*/ +var float FracPartGravScale; + +/** If TRUE, check when piece goes to sleep, and then change its RBChannel. */ +var bool bChangeRBChannelWhenAsleep; +/** If bChangeRBChannelWhenAsleep is TRUE, RBChannel to switch to when asleep. */ +var ERBCollisionChannel AsleepRBChannel; + +/** Used to store preview frames velocity, to look for sudden velocity changes. */ +var vector OldVelocity; + +/** If oldvel dot newvel < -DestroyVelChangeThresh, destroy piece. */ +var float CurrentVibrationLevel; + +/** Indicates that this part consists of more than 1 chunk - and should explode upon impact. */ +var bool bCompositeThatExplodesOnImpact; + +/** Time since last physics impact sound */ +var float LastImpactSoundTime; + +/** Revive part, set physics to PHYS_RigidBody, enabled collision etc */ +simulated native function Initialize(); +/** Reset state of this part - clear mesh reference, put in PHYS_None, disable collision etc */ +simulated native function RecyclePart(bool bAddToFreePool); + +cpptext +{ + virtual void TickSpecial(FLOAT DeltaSeconds); + virtual FLOAT GetGravityZ(); + virtual void OnRigidBodyCollision(const FRigidBodyCollisionInfo& MyInfo, const FRigidBodyCollisionInfo& OtherInfo, const FCollisionImpactData& RigidCollisionData); +#if WITH_NOVODEX + virtual void ModifyNxActorDesc(NxActorDesc& ActorDesc, UPrimitiveComponent* PrimComp, const class NxGroupsMask& GroupsMask, UINT MatIndex); + virtual void PostInitRigidBody(NxActor* nActor, NxActorDesc& ActorDesc, UPrimitiveComponent* PrimComp); +#endif // WITH_NOVODEX + +#if WITH_PHYSX + virtual void ModifyPxActor(PxActor* nActor, UPrimitiveComponent* PrimComp, UPhysicalMaterial* PhysMat); +#endif //WITH_PHYSX +}; + + +/** Used so weapons etc move parts. */ +simulated event TakeDamage(int Damage, Controller EventInstigator, vector HitLocation, vector Momentum, class DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser) +{ + Super.TakeDamage(Damage, EventInstigator, HitLocation, Momentum, DamageType, HitInfo, DamageCauser); + + FracturedStaticMeshComponent.AddImpulse(Normal(momentum) * damageType.default.KDamageImpulse, HitLocation); +} + +/** Try to clean up this part if its not seen or it's parent has been removed. If it is seen, keep trying until it isn't. */ +simulated function TryToCleanUp() +{ + if(BaseFracturedMeshActor == None || WorldInfo.TimeSeconds - BaseFracturedMeshActor.SkinnedComponent.LastRenderTime > 1.0) + { + RecyclePart(TRUE); + } + else + { + SetTimer( 2.0, FALSE, nameof(TryToCleanUp) ); + } +} + +simulated event FellOutOfWorld(class dmgType) +{ + RecyclePart(TRUE); +} + +simulated event Explode() +{ + // Explode is called from OnRigidBodyCollision, which can be fired off multiple times for the same actor, so we must prevent re-entrance + if (!bHasBeenRecycled) + { + super.Explode(); + RecyclePart(TRUE); + } +} + +/** For broken off pieces, we only want to spawn more parts if its a shatterable composite. */ +simulated event BreakOffPartsInRadius(vector Origin, float Radius, float RBStrength, bool bWantPhysChunksAndParticles) +{ + if(bCompositeThatExplodesOnImpact) + { + super.BreakOffPartsInRadius(Origin, Radius, RBStrength, bWantPhysChunksAndParticles); + } +} + +`if(`__TW_PHYSICS_) +simulated event Reset() +{ + RecyclePart( true ); +} +`endif + +defaultproperties +{ +`if(`__TW_LIGHTING_MODIFICATIONS_) + // Light environment is not in components list to begin with +`else + Components.Remove(LightEnvironment0) +`endif + Components.Remove(FracturedSkinnedComponent0) + SkinnedComponent=none + + Begin Object Name=FracturedStaticMeshComponent0 + bCastDynamicShadow=FALSE + bForceDirectLightMap=FALSE + bAllowApproximateOcclusion=TRUE + BlockRigidBody=TRUE + bAcceptsStaticDecals=FALSE + bAcceptsDynamicDecals=FALSE + bSkipRBGeomCreation=TRUE // ModifyNxActorDesc fills in geometry + BlockNonZeroExtent=FALSE + BlockZeroExtent=FALSE + RBChannel=RBCC_FracturedMeshPart + RBCollideWithChannels=(Default=TRUE,GameplayPhysics=TRUE,EffectPhysics=TRUE,FracturedMeshPart=TRUE) + bUseVisibleVertsForBounds=TRUE + bUseDynamicIndexBuffer=FALSE + bUseDynamicIBWithHiddenFragments=FALSE + bUseSkinnedRendering=TRUE + bInitialVisibilityValue=FALSE + bUsePrecomputedShadows=FALSE +`if(`__TW_PHYSICS_) + bNotifyRigidBodyCollision=true +`endif + End Object + + DestroyPartRadiusFactor=10; + bNoDelete=FALSE + bMovable=TRUE + bWorldGeometry=FALSE + bPathColliding=FALSE + TickGroup=TG_PostAsyncWork + bNetInitialRotation=true + bCollideActors=TRUE + bBlockActors=FALSE + bNoEncroachCheck=TRUE + Physics=PHYS_RigidBody + RemoteRole=ROLE_None + LifeSpan=15.0 + FracPartGravScale=2.0 + + bChangeRBChannelWhenAsleep=FALSE + AsleepRBChannel=RBCC_GameplayPhysics +} diff --git a/Engine/Classes/GameEngine.uc b/Engine/Classes/GameEngine.uc new file mode 100644 index 0000000..c03e859 --- /dev/null +++ b/Engine/Classes/GameEngine.uc @@ -0,0 +1,643 @@ +//============================================================================= +// GameEngine: The game subsystem. +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class GameEngine extends Engine + native(GameEngine) + config(Engine) + transient; + +// URL structure. +struct transient native URL +{ + var string Protocol; // Protocol, i.e. "unreal" or "http". + var string Host; // Optional hostname, i.e. "204.157.115.40" or "unreal.epicgames.com", blank if local. + var int Port; // Optional host port. + var string Map; // Map name, i.e. "SkyCity", default is "Index". + var array Op; // Options. + var string Portal; // Portal to enter through, default is "". +//@HSL_BEGIN_XBOX - BWJ - 11/20/14 - Adding support for secure address (for use in XB1) + var string SecureAddress; +//@HSL_END_XBOX + var int Valid; +structcpptext +{ + + // Statics. + static FString DefaultProtocol; + static FString DefaultName; + static FString DefaultMap; + static FString DefaultLocalMap; + static FString DefaultLocalOptions; + static FString DefaultTransitionMap; // map used as in-between for seamless travel + static FString DefaultHost; + static FString DefaultPortal; + static FString DefaultMapExt; + static FString DefaultSaveExt; + /** Additional map extension to look for when parsing urls for map loading */ + static FString AdditionalMapExt; + static INT DefaultPort; + /** port to listen for new client peer connections */ + static INT DefaultPeerPort; + static UBOOL bDefaultsInitialized; + + // Constructors. + FURL( const TCHAR* Filename=NULL ); + FURL( FURL* Base, const TCHAR* TextURL, ETravelType Type ); + static void StaticInit(); + static void StaticExit(); + + /** + * Static: Removes any special URL characters from the specified string + * + * @param Str String to be filtered + */ + static void FilterURLString( FString& Str ); + +//@HSL_BEGIN_XBOX + /** + * Static: Replaces any special URL characters with encoded versions + * + * @param Str String to be encoded + */ + static void EncodeURLString( FString& Str ); + + /** + * Static: Replaces any encoded versions of special URL characters with their decoded versions + * + * @param Str String to be decoded + */ + static void DecodeURLString( FString& Str ); +//@HSL_END_XBOX + + + // Functions. + UBOOL IsInternal() const; + UBOOL IsLocalInternal() const; + UBOOL HasOption( const TCHAR* Test ) const; + const TCHAR* GetOption( const TCHAR* Match, const TCHAR* Default ) const; + void LoadURLConfig( const TCHAR* Section, const TCHAR* Filename=NULL ); + void SaveURLConfig( const TCHAR* Section, const TCHAR* Item, const TCHAR* Filename=NULL ) const; + void AddOption( const TCHAR* Str ); + void RemoveOption( const TCHAR* Key, const TCHAR* Section = NULL, const TCHAR* Filename = NULL); + FString String( UBOOL FullyQualified=0 ) const; + friend FArchive& operator<<( FArchive& Ar, FURL& U ); +//@HSL_BEGIN_XBOX - BWJ - 11-20-14- Adding support for secure address (for use in XB1) + UBOOL HasSecureAddress() const; +//@HSL_END_XBOX + + // Operators. + UBOOL operator==( const FURL& Other ) const; +} +}; + +var PendingLevel GPendingLevel; + +`if(`__TW_) +var string PendingLevelPlayerControllerClassName; +`else +/** The name of the class to spawn as the temporary pending level player controller */ +var config string PendingLevelPlayerControllerClassName; +`endif + +/** URL the last time we travelled */ +var URL LastURL; + +/** last server we connected to (for "reconnect" command) */ +var URL LastRemoteURL; +var config array ServerActors; + +var string TravelURL; +var byte TravelType; + +`if(`__TW_NETWORKING_) +//@HSL_BEGIN - BWJ - 8-10-16 - Saved client URL for takeover (contains client options) +var string ClientOptionsForTakeoverURL; + +var string TakeoverURL; +var globalconfig bool bUsedForTakeover; +var bool bAvailableForTakeover; +/** TRUE if this is a private server. Used for console */ +var bool bPrivateServer; +`endif + +/** set for one tick after completely loading and initializing a new world + * (regardless of whether it's LoadMap() or seamless travel) + */ +var const transient bool bWorldWasLoadedThisTick; + +/** check to see if we need to start a movie capture + * (used on the first tick when we want to record a matinee) + */ +var const transient bool bCheckForMovieCapture; + +/** + * Triggers a call to PostLoadMap() the next Tick, turns off loading movie if LoadMap() has been called. + */ +var const transient bool bTriggerPostLoadMap; + +/** + * TRUE if the loading movie was started during LoadMap(). + */ +var const transient bool bStartedLoadMapMovie; + +/** The singleton online interface for all game code to use */ +var const transient OnlineSubsystem OnlineSubsystem; + +//@HSL_BEGIN - BWJ - 4-5-16 - Playfab support +var const transient PlayfabInterface PlayfabInterfaceInst; +//@HSL_END + +//@zombie_ps4_begin - Adding a gamepad light system +var const transient GamePadLightbarSubSystem GamePadLightBarSubsystem; +//@zombie_ps4_end +/** The singleton interface that enumerates available DLC */ +var const transient DownloadableContentEnumerator DLCEnumerator; + +`if(`__TW_) +var string DownloadableContentEnumeratorClassName; +`else +/** The name of the class to use for the DLC enumeration */ +var config string DownloadableContentEnumeratorClassName; +`endif + +/** The singleton interface that manages the installation and removal of DLC */ +var const transient DownloadableContentManager DLCManager; + +`if(`__TW_) + var bool bSaveBenchmarkGraphs; + struct native transient BenchmarkSample + { + var float AppTime, RenderThreadTime, GameThreadTime, GPUFrameTime, FrameTime; + }; + + var array BenchmarkSamples; +`endif + +`if(`__TW_) +var string DownloadableContentManagerClassName; +`else +/** The name of the class to use for the DLC manager */ +var config string DownloadableContentManagerClassName; +`endif + +/** + * Array of package/ level names that need to be loaded for the pending map change. First level in that array is + * going to be made a fake persistent one by using ULevelStreamingPersistent. + */ +var const array LevelsToLoadForPendingMapChange; +/** Array of already loaded levels. The ordering is arbitrary and depends on what is already loaded and such. */ +var const array LoadedLevelsForPendingMapChange; +/** Human readable error string for any failure during a map change request. Empty if there were no failures. */ +var const string PendingMapChangeFailureDescription; +/** If TRUE, commit map change the next frame. */ +var const bool bShouldCommitPendingMapChange; +/** Maximium delta time the engine uses to populate GDeltaTime. If 0, unbound. */ +var config float MaxDeltaTime; +/** + * If true - clear all AnimSet LinkupCaches during map load. + * You need to do this is the set of skeletal meshes that you are playing anims on is not bounded. + */ +var config bool bClearAnimSetLinkupCachesOnLoadMap; + +/** If true, and the platform allows it, the game engine will utilize a secondary screen */ +var config bool bEnableSecondaryDisplay; +/** + * If true, the game engine will create a secondary viewport on init + * Dependent on bEnabledSecondaryDisplay being enabled. + * If false, and bEnableSecondaryDisplay is true, the secondary screen will just copy the first. + */ +var config bool bEnableSecondaryViewport; + +`if(`__TW_) +var string SecondaryViewportClientClassName; +`else +/** String name for any secondary viewport clients created for secondary screens */ +var config string SecondaryViewportClientClassName; +`endif + +/** Secondary viewport clients inside of secondary windows (not for split screen) */ +var init array SecondaryViewportClients; + +/** Array parallel to SecondaryViewportClients - these are the frames that render the SecondaryViewport clients */ +var init array SecondaryViewportFrames{FViewportFrame}; + +//@HSL_MOD_BEGIN - amiller 4/11/2016 - Adding support to ignore specific packages for Using Handshake +/** An Array of config package names to ignore GUID mismatch errors during connection handshake*/ +var const config array IgnoredUsesGUIDPackages; +//@HSL_MOD_END + +/** level streaming updates that should be applied immediately after committing the map change */ +struct native LevelStreamingStatus +{ + var name PackageName; + var bool bShouldBeLoaded, bShouldBeVisible; + + structcpptext + { + /** Constructors */ + FLevelStreamingStatus(FName InPackageName, UBOOL bInShouldBeLoaded, UBOOL bInShouldBeVisible) + : PackageName(InPackageName), bShouldBeLoaded(bInShouldBeLoaded), bShouldBeVisible(bInShouldBeVisible) + {} + FLevelStreamingStatus() + {} + FLevelStreamingStatus(EEventParm) + { + appMemzero(this, sizeof(FLevelStreamingStatus)); + } + } +}; +var const array PendingLevelStreamingStatusUpdates; + +/** Handles to object references; used by the engine to e.g. the prevent objects from being garbage collected. */ +var const array ObjectReferencers; + +enum EFullyLoadPackageType +{ + /** Load the packages when the map in Tag is loaded */ + FULLYLOAD_Map, + /** Load the packages before the game class in Tag is loaded. The Game name MUST be specified in the URL (game=Package.GameName). Useful for loading packages needed to load the game type (a DLC game type, for instance) */ + FULLYLOAD_Game_PreLoadClass, + /** Load the packages after the game class in Tag is loaded. Will work no matter how game is specified in UWorld::SetGameInfo. Useful for modifying shipping gametypes by loading more packages (mutators, for instance) */ + FULLYLOAD_Game_PostLoadClass, + /** Fully load the package as long as the DLC is loaded */ + FULLYLOAD_Always, + /** Load the package for a mutator that is active */ + FULLYLOAD_Mutator, +}; + +/** Struct to help hold information about packages needing to be fully-loaded for DLC, etc */ +struct native FullyLoadedPackagesInfo +{ + /** When to load these packages */ + var EFullyLoadPackageType FullyLoadType; + + /** When this map or gametype is loaded, the packages in the following array will be loaded and added to root, then removed from root when map is unloaded */ + var string Tag; + + /** The list of packages that will be fully loaded when the above Map is loaded */ + var array PackagesToLoad; + + /** List of objects that were loaded, for faster cleanup */ + var array LoadedObjects; +}; + +/** A list of tag/array pairs that is used at LoadMap time to fully load packages that may be needed for the map/game with DLC, but we can't use DynamicLoadObject to load from the packages */ +var array PackagesToFullyLoad; + +//keeps track of whether we launched on partial install ie playgo, etc +var bool bPartialInstallLaunch; + +/** Struct to hold a UNetDriver and an assoicated name */ +struct native NamedNetDriver +{ + /** The name associated with the driver */ + var name NetDriverName; + + /** A pointer to a UNetDriver */ + var const native pointer NetDriver{class UNetDriver}; +}; + +/** A list of named UNetDrivers */ +var const transient array NamedNetDrivers; + +/** Temporary Animation Tagging Information: until we integrate Content Tagging + * This is configurable information in Engine + * Tag: Name of Tag + * Contains: Contains text + * Priority is index of array + */ +struct native AnimTag +{ + var string Tag; // This is Tag name + var array Contains; // This is contains strings, i.e. _cvr_ or _cover_ for Tag name Cover +}; + +/** + * Animation tag for stat system: This is temporary until we can add content tag to animation + * Currently it auto tags based on "contains" - Check DefaultEngine.ini for modification + */ +var config array AnimTags; + +//@HSL_BEGIN_XBOX +/** True if trial mode is active */ +var const transient bool bTrialActive; +//@HSL_END_XBOX + +/** + * Creates a UNetDriver and associates a name with it. + * + * @param NetDriverName The name to associate with the driver. + * + * @return True if the driver was created successfully, false if there was an error. + */ +native final function bool CreateNamedNetDriver(name NetDriverName); + +/** + * Destroys a UNetDriver based on its name. + * + * @param NetDriverName The name associated with the driver to destroy. + */ +native final function DestroyNamedNetDriver(name NetDriverName); + +/** Returns the global online subsytem pointer. This will be null for PIE */ +native static final noexport function OnlineSubsystem GetOnlineSubsystem(); + +//@HSL_BEGIN - BWJ - 4-5-16 - Playfab support +native static final function PlayfabInterface GetPlayfabInterface(); +//@HSL_END + +/** Returns the DLC enumerator object pointer. This will be null for PIE */ +native static final noexport function DownloadableContentEnumerator GetDLCEnumerator(); + +/** Returns the DLC manager object pointer. This will be null for PIE */ +native static final noexport function DownloadableContentManager GetDLCManager(); + +/** Returns whether this game engine has any secondary screens attached */ +native static final noexport function bool HasSecondaryScreenActive(); + +`if(`__TW_NETWORKING_) +native function TakeoverServer( string InHostStr, string InUrlStr ); +native static function int GetWebAdminPort(); +native final function DisableServerTakeover(); +`endif + +//@HSL_BEGIN_XBOX +/** Encodes special URL characters in a string */ +native static final noexport function EncodeURLString(out string Str); + +/** Decodes special URL characters in a string */ +native static final noexport function DecodeURLString(out string Str); +//@HSL_END_XBOX + + +//@HSL_BEGIN +/** Retrieves percentage of installation finished for streaming install */ +native static final function float GetPercentageOfStreamingInstallComplete(); +/** Checks to see if streaming install has finished */ +native static final function bool IsGameFullyInstalled(); +/** Checks to see if some particular chunks have finished installing */ +native static final function bool AreChunksInstalled(const out array ChunksToCheck); +/** Gets the install progress of some particular chunks */ +native static final function float GetChunksInstallProgress(const out array ChunksToCheck); +/** Gets the install progress of a particular chunk */ +native static final function float GetChunkInstallProgress(int ChunkToCheck); +//@HSL_END + +//function to determine whether or not the game was launched on partial install, ie playgo, etc +native static final function bool WasLaunchedOnPartialInstall(); + +cpptext +{ + + // Constructors. + UGameEngine(); + + /** + * Redraws all viewports. + * + * @param bShouldPresent Whether we want this frame to be presented + */ + void RedrawViewports( UBOOL bShouldPresent = TRUE ); + + /** + * Called to allow overloading by child engines + */ + virtual void LoadMapRedrawViewports(void) + { + RedrawViewports(); + } + + // UObject interface. + void FinishDestroy(); + + // UEngine interface. + void Init(); + + /** + * Called at shutdown, just before the exit purge. + */ + virtual void PreExit(); + + virtual void Tick( FLOAT DeltaSeconds ); + UBOOL Exec( const TCHAR* Cmd, FOutputDevice& Ar=*GLog ); + void SetClientTravel( const TCHAR* NextURL, ETravelType TravelType ); + virtual FLOAT GetMaxTickRate( FLOAT DeltaTime, UBOOL bAllowFrameRateSmoothing = TRUE ); + virtual void SetProgress( EProgressMessageType MessageType, const FString& Title, const FString& Message ); + + /** + * Handles freezing/unfreezing of rendering + */ + virtual void ProcessToggleFreezeCommand(); + + /** + * Handles frezing/unfreezing of streaming + */ + virtual void ProcessToggleFreezeStreamingCommand(); + + // UGameEngine interface. + virtual UBOOL Browse( FURL URL, FString& Error ); + virtual UBOOL LoadMap( const FURL& URL, class UPendingLevel* Pending, FString& Error ); + virtual void PostLoadMap(); + virtual void CancelPending(); +`if(`__TW_ONLINESUBSYSTEM_) + virtual void PerformBetweenMapTasks(); +`endif + /** + * Spawns all of the registered server actors + */ + virtual void SpawnServerActors(void); + + /** + * Construct a UNetDriver object based on an .ini setting + * + * @return The created NetDriver object, or NULL if it fails + */ + virtual class UNetDriver* ConstructNetDriver(); + + /** + * Returns the online subsystem object. Returns null if GEngine isn't a + * game engine + */ + static UOnlineSubsystem* GetOnlineSubsystem(void); + + /** + * Creates the online subsystem that was specified in UEngine's + * OnlineSubsystemClass. This function is virtual so that licensees + * can provide their own version without modifying Epic code. + */ + virtual void InitOnlineSubsystem(void); + + /** + * Creates the specified objects for dealing with DLC. + */ + void InitGameSingletonObjects(void); + + /** + * @return the DLC enumerator, or null if GEngine isn't a game engine + */ + static UDownloadableContentEnumerator* GetDLCEnumerator(void) + { + UGameEngine* GameEngine = Cast(GEngine); + if (GameEngine) + { + return GameEngine->DLCEnumerator; + } + return NULL; + } + + /** + * @return the DLC manager, or null if GEngine isn't a game engine + */ + static UDownloadableContentManager* GetDLCManager(void) + { + UGameEngine* GameEngine = Cast(GEngine); + if (GameEngine) + { + return GameEngine->DLCManager; + } + return NULL; + } + + /** + * @return TRUE, if the GEngine is a game engine and has any secondary screens active + */ + static UBOOL HasSecondaryScreenActive(void) + { + UGameEngine* GameEngine = Cast(GEngine); + if (GameEngine) + { + check(GameEngine->SecondaryViewportClients.Num() == GameEngine->SecondaryViewportFrames.Num()); + return (GameEngine->SecondaryViewportFrames.Num() > 0 ? TRUE : FALSE); + } + return FALSE; + } + + // Async map change/ persistent level transition code. + + /** + * Prepares the engine for a map change by pre-loading level packages in the background. + * + * @param LevelNames Array of levels to load in the background; the first level in this + * list is assumed to be the new "persistent" one. + * + * @return TRUE if all packages were in the package file cache and the operation succeeded, + * FALSE otherwise. FALSE as a return value also indicates that the code has given + * up. + */ + UBOOL PrepareMapChange(const TArray& LevelNames); + + /** + * Returns the failure description in case of a failed map change request. + * + * @return Human readable failure description in case of failure, empty string otherwise + */ + FString GetMapChangeFailureDescription(); + + /** + * Returns whether we are currently preparing for a map change or not. + * + * @return TRUE if we are preparing for a map change, FALSE otherwise + */ + UBOOL IsPreparingMapChange(); + + /** + * Returns whether the prepared map change is ready for commit having called. + * + * @return TRUE if we're ready to commit the map change, FALSE otherwise + */ + UBOOL IsReadyForMapChange(); + + /** + * Finalizes the pending map change that was being kicked off by PrepareMapChange. + * + * @return TRUE if successful, FALSE if there were errors (use GetMapChangeFailureDescription + * for error description) + */ + UBOOL CommitMapChange(); + + /** + * Commit map change if requested and map change is pending. Called every frame. + */ + void ConditionalCommitMapChange(); + + /** + * Cancels pending map change. + */ + void CancelPendingMapChange(); + + /** + * Adds a map/package array pair for pacakges to load at LoadMap + * + * @param FullyLoadType When to load the packages (based on map, gametype, etc) + * @param Tag Map/game for which the packages need to be loaded + * @param Packages List of package names to fully load when the map is loaded + * @param bLoadPackagesForCurrentMap If TRUE, the packages for the currently loaded map will be loaded now + */ + void AddPackagesToFullyLoad(EFullyLoadPackageType FullyLoadType, const FString& Tag, const TArray& Packages, UBOOL bLoadPackagesForCurrentMap); + + /** + * Empties the PerMapPackages array, and removes any currently loaded packages from the Root + */ + void CleanupAllPackagesToFullyLoad(); + + /** + * Loads the PerMapPackages for the given map, and adds them to the RootSet + * + * @param FullyLoadType When to load the packages (based on map, gametype, etc) + * @param Tag Name of the map/game to load packages for + */ + void LoadPackagesFully(EFullyLoadPackageType FullyLoadType, const FString& Tag); + + /** + * Removes the PerMapPackages from the RootSet + * + * @param FullyLoadType When to load the packages (based on map, gametype, etc) + * @param Tag Name of the map/game to cleanup packages for + */ + void CleanupPackagesToFullyLoad(EFullyLoadPackageType FullyLoadType, const FString& Tag); + + /** + * Finds a UNetDriver based on its name. + * + * @param NetDriverName The name associated with the driver to find. + * + * @return A pointer to the UNetDriver that was found, or NULL if it wasn't found. + */ + UNetDriver* FindNamedNetDriver(FName NetDriverName); + + /** + * Creates a new FViewportFrame with a viewport client of class SecondaryViewportClientClassName + */ + void CreateSecondaryViewport(UINT SizeX, UINT SizeY); + + /** + * Closes all secondary viewports opened with CreateSecondaryViewport + */ + void CloseSecondaryViewports(); + +//@HSL_BEGIN_XBOX + /** Encodes special URL characters in a string */ + static void EncodeURLString(FString& Str) + { + // Simply forward the call to FURL + FURL::EncodeURLString(Str); + } + + /** Decodes special URL characters in a string */ + static void DecodeURLString(FString& Str) + { + // Simply forward the call to FURL + FURL::DecodeURLString(Str); + } +//@HSL_END_XBOX + + /** + * When enabled, this will save the profile stats to file which can be used for + */ + #if __TW_ + void UpdateBenchmarkStats(); + void SaveBenchmarkStats(); + void SecureConnect(const TCHAR* URL); + #endif +} diff --git a/Engine/Classes/GameInfo.uc b/Engine/Classes/GameInfo.uc new file mode 100644 index 0000000..569f40c --- /dev/null +++ b/Engine/Classes/GameInfo.uc @@ -0,0 +1,4099 @@ +//============================================================================= +// GameInfo. +// +// The GameInfo defines the game being played: the game rules, scoring, what actors +// are allowed to exist in this game type, and who may enter the game. While the +// GameInfo class is the public interface, much of this functionality is delegated +// to several classes to allow easy modification of specific game components. These +// classes include GameInfo, AccessControl, Mutator, and BroadcastHandler. +// A GameInfo actor is instantiated when the level is initialized for gameplay (in +// C++ UGameEngine::LoadMap() ). The class of this GameInfo actor is determined by +// (in order) either the URL ?game=xxx, or the +// DefaultGame entry in the game's .ini file (in the Engine.Engine section), unless +// its a network game in which case the DefaultServerGame entry is used. +// The GameType used can be overridden in the GameInfo script event SetGameType(), called +// on the game class picked by the above process. +// +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class GameInfo extends Info + config(Game) + native + dependson(OnlineSubsystem); + +//----------------------------------------------------------------------------- +// Variables. + +var bool bRestartLevel; // Level should be restarted when player dies +var bool bPauseable; // Whether the game is pauseable. +var bool bTeamGame; // This is a team game. +var bool bGameEnded; // set when game ends +var bool bOverTime; +var bool bDelayedStart; +var bool bWaitingToStartMatch; +var globalconfig bool bChangeLevels; +var bool bAlreadyChanged; +var globalconfig bool bAdminCanPause; +var bool bGameRestarted; +var bool bLevelChange; // level transition in progress +var globalconfig bool bKickLiveIdlers; // if true, even playercontrollers with pawns can be kicked for idling + +/** Whether this match is going to use arbitration or not */ +var bool bUsingArbitration; + +/** + * Whether the arbitrated handshaking has occurred or not. + * NOTE: The code will reject new connections once handshaking has started + */ +var bool bHasArbitratedHandshakeBegun; + +/** Whether the arbitrated handshaking has occurred or not. */ +var bool bNeedsEndGameHandshake; + +/** Whether the arbitrated handshaking has completed or not. */ +var bool bIsEndGameHandshakeComplete; + +/** Used to indicate when an arbitrated match has started its end sequence */ +var bool bHasEndGameHandshakeBegun; + +/** Whether the game expects a fixed player start for profiling. */ +var bool bFixedPlayerStart; + +/** The causeevent= string that the game passed in This is separate from automatedPerfTesting which is going to probably spawn bots / effects **/ +var string CauseEventCommand; + +/** This is the BugIt String Data. Other info should be stored here **/ +/** Currently stores the location string form **/ +var string BugLocString; + +/** Currently stores the rotation in string form **/ +var string BugRotString; + +/** + * List of player controllers we're awaiting handshakes with + * + * NOTE: Any PC in this list that does not complete the handshake within + * ArbitrationHandshakeTimeout will be kicked from the match + */ +var array PendingArbitrationPCs; + +/** + * Holds the list of players that passed handshaking and require finalization + * of arbitration data written to the online subsystem + */ +var array ArbitrationPCs; + +/** Amount of time a client can take for arbitration handshaking before being kicked */ +var globalconfig float ArbitrationHandshakeTimeout; + +var globalconfig float GameDifficulty; +`if(`__TW_) +var float GameDifficultyModifier; +`endif +var globalconfig int GoreLevel; // 0=Normal, increasing values=less gore +var float GameSpeed; // Scale applied to game rate. + +var class DefaultPawnClass; + +// user interface +var class HUDType; // HUD class this game uses. +var class SecondaryHUDType; // Secondary HUD class this game uses. + +var globalconfig int MaxSpectators; // Maximum number of spectators allowed by this server. +var int MaxSpectatorsAllowed; // Maximum number of spectators ever allowed (MaxSpectators is clamped to this in initgame() +var int NumSpectators; // Current number of spectators. +`if (`__TW_) +var config int MaxPlayers; // Maximum number of players allowed by this server. +`else +var globalconfig int MaxPlayers; // Maximum number of players allowed by this server. +`endif +var int MaxPlayersAllowed; // Maximum number of players ever allowed (MaxPlayers is clamped to this in initgame() +var int NumPlayers; // number of human players +var int NumBots; // number of non-human players (AI controlled but participating as a player) +//@SABER_EGS_BEGIN Crossplay support +var int NumEosPlayers; // number of players, using epic online system +//@SABER_EGS_END +/** number of players that are still travelling from a previous map */ +var int NumTravellingPlayers; +var int CurrentID; // used to assign unique PlayerIDs to each PlayerReplicationInfo +var localized string DefaultPlayerName; +var localized string GameName; +var float FearCostFallOff; // how fast the FearCost in NavigationPoints falls off +var bool bDoFearCostFallOff; // If true, FearCost will fall off over time in NavigationPoints. Reset to false once all reach FearCosts reach 0. + +var config int GoalScore; // what score is needed to end the match +var config int MaxLives; // max number of lives for match, unless overruled by level's GameDetails +var config int TimeLimit; // time limit in minutes + +// Message classes. +var class DeathMessageClass; +var class GameMessageClass; + +//------------------------------------- +// GameInfo components +var Mutator BaseMutator; // linked list of Mutators (for modifying actors as they enter the game) +var class AccessControlClass; +var AccessControl AccessControl; // AccessControl controls whether players can enter and/or become admins +var class BroadcastHandlerClass; +var BroadcastHandler BroadcastHandler; // handles message (text and localized) broadcasts + +/** Class of automated test manager used by this game class */ +var class AutoTestManagerClass; + +/** Instantiated AutoTestManager - only exists if requested by command-line */ +var AutoTestManager MyAutoTestManager; + +var class PlayerControllerClass; // type of player controller to spawn for players logging in +var class PlayerReplicationInfoClass; + +// ReplicationInfo +var() class GameReplicationInfoClass; +var GameReplicationInfo GameReplicationInfo; + +var CrowdPopulationManagerBase PopulationManager; +var class PopulationManagerClass; + +var globalconfig float MaxIdleTime; // maximum time players are allowed to idle before being kicked + +/** Max interval that client clock is allowed to get ahead of server clock before triggering speed hack detection */ +var globalconfig float MaxTimeMargin; + +/** How fast we allow client clock to drift from server clock over time without ever triggering speed hack detection */ +var globalconfig float TimeMarginSlack; + +/** Clamps how far behind server clock we let time margin get. Used to prevent speedhacks where client slows their clock down for a while then speeds it up. */ +var globalconfig float MinTimeMargin; + +var array InactivePRIArray; /** PRIs of players who have left game (saved in case they reconnect) */ + +/** The list of delegates to check before unpausing a game */ +var array > Pausers; + +/** Cached online subsystem variable */ +var OnlineSubsystem OnlineSub; + +//@HSL_BEGIN - BWJ - 6-16-16 - Playfab support +var PlayfabInterface PlayfabInter; +//@HSL_END + +/** Cached online game interface variable */ +var OnlineGameInterface GameInterface; + +/** Class sent to clients to use to create and hold their stats */ +var class OnlineStatsWriteClass; + +/** The leaderboard to write the stats to for skill/scoring */ +var int LeaderboardId; + +/** The arbitrated leaderboard to write the stats to for skill/scoring */ +var int ArbitratedLeaderboardId; + +/** perform map travels using SeamlessTravel() which loads in the background and doesn't disconnect clients + * @see WorldInfo::SeamlessTravel() + */ +var bool bUseSeamlessTravel; + +/** Base copy of cover changes that need to be replicated to clients on join */ +var protected CoverReplicator CoverReplicatorBase; + +/** Tracks whether the server can travel due to a critical network error or not */ +var bool bHasNetworkError; + +/** Whether this game type requires voice to be push to talk or not */ +var const bool bRequiresPushToTalk; + +/** The class to use when registering dedicated servers with the online service */ +var const class OnlineGameSettingsClass; + +/** The options to apply for dedicated server when it starts to register */ +var string ServerOptions; + +/** Current adjusted net speed - Used for dynamically managing netspeed for listen servers*/ +var int AdjustedNetSpeed; + +/** Last time netspeed was updated for server (by client entering or leaving) */ +var float LastNetSpeedUpdateTime; + +/** Total available bandwidth for listen server, split dynamically across net connections */ +var globalconfig int TotalNetBandwidth; + +/** Minimum bandwidth dynamically set per connection */ +var globalconfig int MinDynamicBandwidth; + +/** Maximum bandwidth dynamically set per connection */ +var globalconfig int MaxDynamicBandwidth; + +/** Standby cheat detection vars */ +/** Used to determine if checking for standby cheats should occur */ +var config bool bIsStandbyCheckingEnabled; +/** Tracks standby checking status */ +var bool bIsStandbyCheckingOn; +/** Used to determine whether we've already caught a cheat or not */ +var bool bHasStandbyCheatTriggered; +/** The amount of time without packets before triggering the cheat code */ +var config float StandbyRxCheatTime; +/** The amount of time without packets before triggering the cheat code */ +var config float StandbyTxCheatTime; +/** The point we determine the server is either delaying packets or has bad upstream */ +var config int BadPingThreshold; +/** The percentage of clients missing RX data before triggering the standby code */ +var config float PercentMissingForRxStandby; +/** The percentage of clients missing TX data before triggering the standby code */ +var config float PercentMissingForTxStandby; +/** The percentage of clients with bad ping before triggering the standby code */ +var config float PercentForBadPing; +/** The amount of time to wait before checking a connection for standby issues */ +var config float JoinInProgressStandbyWaitTime; + +/** Material used for drawing a streaming pause icon. */ +var Material StreamingPauseIcon; + +/** Describes which standby detection event occured so the game can take appropriate action */ +enum EStandbyType +{ + STDBY_Rx, + STDBY_Tx, + STDBY_BadPing +}; +/** End standby cheat vars */ + +struct native GameClassShortName +{ + var string ShortName; + var string GameClassName; +}; +`if(`__TW_) +var() protected const array GameInfoClassAliases; +`else +var() protected config const array GameInfoClassAliases; +`endif + +/** + * GameTypePrefix helper structure. + * Used to find valid gametypes for a map via its prefix. + */ +struct native GameTypePrefix +{ + /** map prefix, e.g. "DM" */ + var string Prefix; + /** if TRUE, generate a common package for the gametype */ + var bool bUsesCommonPackage; + /** gametype used if none specified on the URL */ + var string GameType; + /** additional gametypes supported by this map prefix via the URL (used for cooking) */ + var array AdditionalGameTypes; + /** forced objects (and classes) that should go into the common package to avoid cooking into every map */ + var array ForcedObjects; +}; + +/** The default game type to use on a map */ +var config string DefaultGameType; +/** Used for loading appropriate game type if non-specified in URL */ +var config array DefaultMapPrefixes; +/** Used for loading appropriate game type if non-specified in URL */ +var config array CustomMapPrefixes; + + +/** Size of the AnimTree pool. System will keep this number of extra AnimTrees around per Template */ +var config int AnimTreePoolSize; + +/** + * Retrieve the FGameTypePrefix struct for the given map filename. + * + * @param InFilename The map file name + * @param OutGameType The gametype prefix struct to fill in + * @param bCheckExt Optional parameter to check the extension of the InFilename to ensure it is a map + * + * @return UBOOL TRUE if successful, FALSE if map prefix not found. + * NOTE: FALSE will fill in with the default gametype. + */ +function native bool GetSupportedGameTypes(const out string InFilename, out GameTypePrefix OutGameType, optional bool bCheckExt = false) const; + +/** + * Retrieve the name of the common package (if any) for the given map filename. + * + * @param InFilename The map file name + * @param OutCommonPackageName The nane of the common package for the given map + * + * @return UBOOL TRUE if successful, FALSE if map prefix not found. + */ +function native bool GetMapCommonPackageName(const out string InFilename, out string OutCommonPackageName) const; + +cpptext +{ + /** called on the default object of the class specified by DefaultGame in the [Engine.GameInfo] section of Game.ini + * whenever worlds are saved. + * Gives the game a chance to add supported gametypes to the WorldInfo's GameTypesSupportedOnThisMap array + * (used for console cooking) + * @param Info: the WorldInfo of the world being saved + */ + virtual void AddSupportedGameTypes(AWorldInfo* Info, const TCHAR* WorldFilename, TArray& AdditionalPackagesToCook) const + { + } + + /** Allows for game classname remapping and/or aliasing (e.g. for shorthand names) */ + static FString StaticGetRemappedGameClassName(FString const& GameClassName); + +#if __TW_SDK_ + virtual void PreBeginPlay(); + virtual UBOOL IsWhitelisted(); + virtual UBOOL IsStandardGame(); + virtual void SetGameUnranked( UBOOL bUnranked ) {} + virtual UBOOL IsUnrankedGame() { return true; } +#endif +} + +//------------------------------------------------------------------------------ +// Engine notifications. + +event PreBeginPlay() +{ + AdjustedNetSpeed = MaxDynamicBandwidth; + SetGameSpeed(GameSpeed); + GameReplicationInfo = Spawn(GameReplicationInfoClass); + WorldInfo.GRI = GameReplicationInfo; + + InitGameReplicationInfo(); + InitCrowdPopulationManager(); +} + +function CoverReplicator GetCoverReplicator() +{ + if (CoverReplicatorBase == None && WorldInfo.NetMode != NM_Standalone) + { + CoverReplicatorBase = Spawn(class'CoverReplicator'); + } + return CoverReplicatorBase; +} + +event PostBeginPlay() +{ + local OnlineGameSettings GameSettings; + + if ( MaxIdleTime > 0 ) + { + MaxIdleTime = FMax(MaxIdleTime, 20); + } + +//@HSL_BEGIN - BWJ - 6-16-16 - Playfab support + PlayfabInter = class'GameEngine'.static.GetPlayfabInterface(); + //@SABER_EGS IsEOSDedicatedServer() case added + if( WorldInfo.IsConsoleDedicatedServer() || WorldInfo.IsEOSDedicatedServer() ) + { + if( PlayfabInter != none ) + { + if( PlayfabInter.GetGameSettings() == None ) + { + PlayfabInter.CreateGameSettings( OnlineGameSettingsClass ); + GameSettings = PlayfabInter.GetGameSettings(); + GameSettings.UpdateFromURL(ServerOptions, self); + + // If this server wasn't launched by playfab, register the server now + if( !WasLaunchedByPlayfab() ) + { + // First we update game settings + UpdateGameSettings(); + // Now register the game + PlayfabInter.ServerRegisterGame(); + } + + // Initialize title data, see also TWRefreshOnlineGameData + PlayfabInter.AddTitleDataReadCompleteDelegate( OnServerTitleDataRead ); + PlayfabInter.ReadTitleData(); + } + } + } + else // So that it'll get deleted if Hardsuit ever removes this block +//@HSL_END + if (WorldInfo.NetMode == NM_DedicatedServer) + { + // Update any online advertised settings + UpdateGameSettings(); + } +} + + +//@HSL_BEGIN - BWJ - 1-5-17 - Support for reading title data +function OnServerTitleDataRead() +{ + PlayfabInter.ClearTitleDataReadCompleteDelegate(OnServerTitleDataRead); +} +//@HSL_END + + +/** + * Use 'ShowGameDebug' console command to show this debug info + * Useful to show general debug info not tied to a particular actor physically in the level. + */ +simulated function DisplayDebug(HUD HUD, out float out_YL, out float out_YPos) +{ + local Canvas Canvas; + + Canvas = HUD.Canvas; + Canvas.SetDrawColor(255,255,255); + + Canvas.DrawText("Game:" $GameName ); + out_YPos += out_YL; + Canvas.SetPos(4,out_YPos); + + if ( WorldInfo.PopulationManager != None ) + { + WorldInfo.PopulationManager.DisplayDebug(HUD, out_YL, out_YPos); + } +} + + +/* Reset() - reset actor to initial state - used when restarting level without reloading. + @note: GameInfo::Reset() called after all other actors have been reset */ +function Reset() +{ + super.Reset(); + + bGameEnded = false; + bOverTime = false; + InitGameReplicationInfo(); +} + +/** @return true if ActorToReset should have Reset() called on it while restarting the game, false if the GameInfo will manually reset it + or if the actor does not need to be reset +*/ +function bool ShouldReset(Actor ActorToReset) +{ + return true; +} + +/** Resets level by calling Reset() on all actors */ +function ResetLevel() +{ + local Controller C; + local Actor A; + local Sequence GameSeq; + local array AllSeqEvents; + local array ActivateIndices; + local int i; + + `Log("Reset" @ self); + // Reset ALL controllers first + foreach WorldInfo.AllControllers(class'Controller', C) + { + if ( PlayerController(C) != None ) + { + PlayerController(C).ClientReset(); + } + C.Reset(); + } + + // Reset all actors (except controllers, the GameInfo, and any other actors specified by ShouldReset()) + foreach AllActors(class'Actor', A) + { + if (A != self && !A.IsA('Controller') && ShouldReset(A)) + { + A.Reset(); + } + } + + // reset the GameInfo + Reset(); + + // reset Kismet and activate any Level Reset events + GameSeq = WorldInfo.GetGameSequence(); + if (GameSeq != None) + { + // reset the game sequence + GameSeq.Reset(); + + // find any Level Loaded events that exist + GameSeq.FindSeqObjectsByClass(class'SeqEvent_LevelLoaded', true, AllSeqEvents); + + // activate them + ActivateIndices[0] = 2; + for (i = 0; i < AllSeqEvents.Length; i++) + { + SeqEvent_LevelLoaded(AllSeqEvents[i]).CheckActivate(WorldInfo, None, false, ActivateIndices); + } + } +} + + +event Timer() +{ + BroadcastHandler.UpdateSentText(); + + // Update navigation point fear cost fall off. + if ( bDoFearCostFallOff ) + { + DoNavFearCostFallOff(); + } +} + +/** + * Check to see if we should start in cinematic mode (e.g. matinee movie capture). + * + * @param OutHidePlayer Whether to hide the player + * @param OutHideHud Whether to hide the HUD + * @param OutDisableMovement Whether to disable movement + * @param OutDisableTurning Whether to disable turning + * @param OutDisableInput Whether to disable input + * + * @return UBOOL TRUE if we should turn on cinematic mode, + * FALSE if if we should not. + */ +final native function bool ShouldStartInCinematicMode(out int OutHidePlayer, out int OutHideHud, out int OutDisableMovement, out int OutDisableTurning, out int OutDisableInput); + +/** Update navigation point fear cost fall off. */ +final native function DoNavFearCostFallOff(); + +/** notification when a NavigationPoint becomes blocked or unblocked */ +function NotifyNavigationChanged(NavigationPoint N); + +// Called when game shutsdown. +event GameEnding() +{ + if (AccessControl != none) + { + AccessControl.NotifyGameEnding(); + } + + ClearOnlineDelegates(); + + EndLogging("serverquit"); +} + +/* KickIdler() called if + if ( (Pawn != None) || (PlayerReplicationInfo.bOnlySpectator && (ViewTarget != self)) + || (WorldInfo.Pauser != None) || WorldInfo.Game.bWaitingToStartMatch || WorldInfo.Game.bGameEnded ) + { + LastActiveTime = WorldInfo.TimeSeconds; + } + else if ( (WorldInfo.Game.MaxIdleTime > 0) && (WorldInfo.TimeSeconds - LastActiveTime > WorldInfo.Game.MaxIdleTime) ) + KickIdler(self); +*/ +event KickIdler(PlayerController PC) +{ + `log("Kicking idle player "$PC.PlayerReplicationInfo.PlayerName); + AccessControl.KickPlayer(PC, AccessControl.IdleKickReason); +} + +// This will kick any player, even if they are an admin. +event ForceKickPlayer(PlayerController PC, string KickReason) +{ + `log("Force kicking player "$PC.PlayerReplicationInfo.PlayerName); + AccessControl.ForceKickPlayer(PC, KickReason); +} + +//------------------------------------------------------------------------------ +// Replication + +function InitGameReplicationInfo() +{ + GameReplicationInfo.GameClass = Class; + GameReplicationInfo.ReceivedGameClass(); +} + +native function string GetNetworkNumber(); + +function int GetNumPlayers() +{ + return NumPlayers + NumTravellingPlayers; +} + +//------------------------------------------------------------------------------ +// Misc. + +/** + * Default delegate that provides an implementation for those that don't have + * special needs other than a toggle + */ +delegate bool CanUnpause() +{ + return true; +} + +/** + * Adds the delegate to the list if the player controller has the right to pause + * the game. The delegate is called to see if it is ok to unpause the game, e.g. + * the reason the game was paused has been cleared. + * + * @param PC the player controller to check for admin privs + * @param CanUnpauseDelegate the delegate to query when checking for unpause + */ +function bool SetPause(PlayerController PC, optional delegate CanUnpauseDelegate=CanUnpause) +{ + local int FoundIndex; + + if ( AllowPausing(PC) ) + { + // Don't add the delegate twice (no need) + FoundIndex = Pausers.Find(CanUnpauseDelegate); + if (FoundIndex == INDEX_NONE) + { + // Not in the list so add it for querying + FoundIndex = Pausers.Length; + Pausers.Length = FoundIndex + 1; + Pausers[FoundIndex] = CanUnpauseDelegate; + } + // Let the first one in "own" the pause state + if (WorldInfo.Pauser == None) + { + WorldInfo.Pauser = PC.PlayerReplicationInfo; + } + return true; + } + return false; +} + +/** + * Checks the list of delegates to determine if the pausing can be cleared. If + * the delegate says it's ok to unpause, that delegate is removed from the list + * and the rest are checked. The game is considered unpaused when the list is + * empty. + */ +event ClearPause() +{ + local int Index; + local delegate CanUnpauseCriteriaMet; + + if ( !AllowPausing() && Pausers.Length > 0 ) + { + `log("Clearing list of UnPause delegates for" @ Name @ "because game type is not pauseable"); + Pausers.Length = 0; + } + + for (Index = 0; Index < Pausers.Length; Index++) + { + CanUnpauseCriteriaMet = Pausers[Index]; + if (CanUnpauseCriteriaMet()) + { + Pausers.Remove(Index--,1); + } + } + + // Clear the pause state if the list is empty + if ( Pausers.Length == 0 ) + { + WorldInfo.Pauser = None; + } +} + +/** + * Forcibly removes an object's CanUnpause delegates from the list of pausers. If any of the object's CanUnpause delegate + * handlers were in the list, triggers a call to ClearPause(). + * + * Called when the player controller is being destroyed to prevent the game from being stuck in a paused state when a PC that + * paused the game is destroyed before the game is unpaused. + */ +native final function ForceClearUnpauseDelegates( Actor PauseActor ); + +/** + * Dumps the pause delegate list to track down who has the game paused + */ +function DebugPause() +{ + local int Index; + local delegate CanUnpauseCriteriaMet; + + for (Index = 0; Index < Pausers.Length; Index++) + { + CanUnpauseCriteriaMet = Pausers[Index]; + if (CanUnpauseCriteriaMet()) + { + `Log("Pauser in index "$Index$" thinks it's ok to unpause:" @ CanUnpauseCriteriaMet); + } + else + { + `Log("Pauser in index "$Index$" thinks the game should remain paused:" @ CanUnpauseCriteriaMet); + } + } +} + +//------------------------------------------------------------------------------ +// Game parameters. + +// +// Set gameplay speed. +// +function SetGameSpeed( Float T ) +{ + GameSpeed = FMax(T, 0.00001); + WorldInfo.TimeDilation = GameSpeed; + SetTimer(WorldInfo.TimeDilation, true); +} + +//------------------------------------------------------------------------------ +// Player start functions + +// +// Grab the next option from a string. +// +static function bool GrabOption( out string Options, out string Result ) +{ + if( Left(Options,1)=="?" ) + { + // Get result. + Result = Mid(Options,1); + if( InStr(Result,"?")>=0 ) + Result = Left( Result, InStr(Result,"?") ); + + // Update options. + Options = Mid(Options,1); + if( InStr(Options,"?")>=0 ) + Options = Mid( Options, InStr(Options,"?") ); + else + Options = ""; + + return true; + } + else return false; +} + +// +// Break up a key=value pair into its key and value. +// +static function GetKeyValue( string Pair, out string Key, out string Value ) +{ + if( InStr(Pair,"=")>=0 ) + { + Key = Left(Pair,InStr(Pair,"=")); + Value = Mid(Pair,InStr(Pair,"=")+1); + } + else + { + Key = Pair; + Value = ""; + } +} + +/* ParseOption() + Find an option in the options string and return it. +*/ +static function string ParseOption( string Options, string InKey ) +{ + local string Pair, Key, Value; + while( GrabOption( Options, Pair ) ) + { + GetKeyValue( Pair, Key, Value ); + if( Key ~= InKey ) + return Value; + } + return ""; +} + +// +// HasOption - return true if the option is specified on the command line. +// +static function bool HasOption( string Options, string InKey ) +{ + local string Pair, Key, Value; + while( GrabOption( Options, Pair ) ) + { + GetKeyValue( Pair, Key, Value ); + if( Key ~= InKey ) + return true; + } + return false; +} + +static function int GetIntOption( string Options, string ParseString, int CurrentValue) +{ + local string InOpt; + + InOpt = ParseOption( Options, ParseString ); + if ( InOpt != "" ) + { + return int(InOpt); + } + return CurrentValue; +} + +/** @return the full path to the optimal GameInfo class to use for the specified map and options + * this is used for preloading cooked packages, etc. and therefore doesn't need to include any fallbacks + * as SetGameType() will be called later to actually find/load the desired class + */ +static event string GetDefaultGameClassPath(string MapName, string Options, string Portal) +{ + return PathName(Default.Class); +} + +/** @return the class of GameInfo to spawn for the game on the specified map and the specified options + * this function should include any fallbacks in case the desired class can't be found + */ +static event class SetGameType(string MapName, string Options, string Portal) +{ + return Default.Class; +} + +/* Initialize the game. + The GameInfo's InitGame() function is called before any other scripts (including + PreBeginPlay() ), and is used by the GameInfo to initialize parameters and spawn + its helper classes. + Warning: this is called before actors' PreBeginPlay. +*/ +event InitGame( string Options, out string ErrorMessage ) +{ + local string InOpt, LeftOpt; + local int pos; + local class ACClass; + local AccessControl CurAC; + local OnlineGameSettings GameSettings; + + MaxPlayers = Clamp(GetIntOption( Options, "MaxPlayers", MaxPlayers ),0,MaxPlayersAllowed); + MaxSpectators = Clamp(GetIntOption( Options, "MaxSpectators", MaxSpectators ),0,MaxSpectatorsAllowed); + GameDifficulty = FMax(0,GetIntOption(Options, "Difficulty", GameDifficulty)); + + InOpt = ParseOption( Options, "GameSpeed"); + if( InOpt != "" ) + { + `log("GameSpeed"@InOpt); + SetGameSpeed(float(InOpt)); + } + + TimeLimit = Max(0,GetIntOption( Options, "TimeLimit", TimeLimit )); + + BroadcastHandler = spawn(BroadcastHandlerClass); + + InOpt = ParseOption( Options, "AccessControl"); + if( InOpt != "" ) + { + ACClass = class(DynamicLoadObject(InOpt, class'Class')); + } + if ( ACClass == None ) + { + ACClass = AccessControlClass; + } + + LeftOpt = ParseOption( Options, "AdminName" ); + InOpt = ParseOption( Options, "AdminPassword"); + /* @FIXME: this is a compiler error, "can't set defaults of non-config properties". Fix or remove at some point. + if( LeftOpt!="" && InOpt!="" ) + ACClass.default.bDontAddDefaultAdmin = true; + */ + + // Only spawn access control if we are a server + if (WorldInfo.NetMode == NM_ListenServer || WorldInfo.NetMode == NM_DedicatedServer) + { + // If we are coming out of seamless travel, and there is an access control carried over from the previous level, + // use that instead of creating a new one + if (WorldInfo.IsInSeamlessTravel()) + { + foreach DynamicActors(Class'AccessControl', CurAC) + { + AccessControl = CurAC; + break; + } + } + + if (AccessControl == none) + { + AccessControl = Spawn(ACClass); + } + + if (AccessControl != None && InOpt != "") + { + AccessControl.SetAdminPassword(InOpt); + } + } + + InOpt = ParseOption( Options, "Mutator"); + if ( InOpt != "" ) + { + `log("Mutators"@InOpt); + while ( InOpt != "" ) + { + pos = InStr(InOpt,","); + if ( pos > 0 ) + { + LeftOpt = Left(InOpt, pos); + InOpt = Right(InOpt, Len(InOpt) - pos - 1); + } + else + { + LeftOpt = InOpt; + InOpt = ""; + } + AddMutator(LeftOpt, true); + } + } + + InOpt = ParseOption( Options, "GamePassword"); + if( InOpt != "" && AccessControl != None) + { + AccessControl.SetGamePassWord(InOpt); + `log( "GamePassword" @ InOpt ); + } + + bFixedPlayerStart = ( ParseOption( Options, "FixedPlayerStart" ) ~= "1" ); + CauseEventCommand = ( ParseOption( Options, "causeevent" ) ); + + if ( ParseOption( Options, "AutoTests" ) ~= "1" ) + { + if ( MyAutoTestManager == None ) + { + MyAutoTestManager = spawn(AutoTestManagerClass); + } + MyAutoTestManager.InitializeOptions(Options); + } + + BugLocString = ParseOption(Options, "BugLoc"); + BugRotString = ParseOption(Options, "BugRot"); + + if (BaseMutator != none) + { + BaseMutator.InitMutator(Options, ErrorMessage); + } + + // Cache a pointer to the online subsystem + OnlineSub = class'GameEngine'.static.GetOnlineSubsystem(); + if (OnlineSub != None) + { + // And grab one for the game interface since it will be used often + GameInterface = OnlineSub.GameInterface; + if (GameInterface != None) + { + // Grab the current game settings object out + GameSettings = GameInterface.GetGameSettings(PlayerReplicationInfoClass.default.SessionName); + if (GameSettings != None) + { + // Check for an arbitrated match + bUsingArbitration = GameSettings.bUsesArbitration; + } + } + } + + if ((WorldInfo.IsConsoleBuild(CONSOLE_Any) == false) && + (WorldInfo.NetMode != NM_Standalone) && + // Don't register the session if the UI already has + (GameSettings == None)) + { + // Cache this so it can be used later by async processes + ServerOptions = Options; + // If there isn't a login to process, immediately register the server + // Otherwise the server will be registered when the login completes + if (!ProcessServerLogin()) + { + RegisterServer(); + } + } +} + +/** Called when a connection closes before getting to PostLogin() */ +event NotifyPendingConnectionLost(); + +function AddMutator(string mutname, optional bool bUserAdded) +{ + local class mutClass; + local Mutator mut; + local int i; + + if ( !Static.AllowMutator(MutName) ) + return; + + mutClass = class(DynamicLoadObject(mutname, class'Class')); + if (mutClass == None) + return; + + if (mutClass.Default.GroupNames.length > 0 && BaseMutator != None) + { + // make sure no mutators with same groupname + for (mut = BaseMutator; mut != None; mut = mut.NextMutator) + { + for (i = 0; i < mut.GroupNames.length; i++) + { + if (mutClass.default.GroupNames.Find(mut.GroupNames[i]) != INDEX_NONE) + { + `log("Not adding "$mutClass$" because already have a mutator in the same group - "$mut); + return; + } + } + } + } + + // make sure this mutator is not added already + for ( mut=BaseMutator; mut!=None; mut=mut.NextMutator ) + if ( mut.Class == mutClass ) + { + `log("Not adding "$mutClass$" because this mutator is already added - "$mut); + return; + } + + mut = Spawn(mutClass); + // mc, beware of mut being none + if (mut == None) + return; + + // Meant to verify if this mutator was from Command Line parameters or added from other Actors + mut.bUserAdded = bUserAdded; + + if (BaseMutator == None) + { + BaseMutator = mut; + } + else + { + BaseMutator.AddMutator(mut); + } +} + +/* RemoveMutator() +Remove a mutator from the mutator list +*/ +function RemoveMutator( Mutator MutatorToRemove ) +{ + local Mutator M; + + // remove from mutator list + if ( BaseMutator == MutatorToRemove ) + { + BaseMutator = MutatorToRemove.NextMutator; + } + else if ( BaseMutator != None ) + { + for ( M=BaseMutator; M!=None; M=M.NextMutator ) + { + if ( M.NextMutator == MutatorToRemove ) + { + M.NextMutator = MutatorToRemove.NextMutator; + break; + } + } + } +} + +`if (`__TW_) +function string CheckNextMap(string NextMap) +{ + return NextMap; +} + +static function bool GetShouldShowLength() +{ + return true; +} +`endif + +/* ProcessServerTravel() + Optional handling of ServerTravel for network games. +*/ +function ProcessServerTravel(string URL, optional bool bAbsolute) +{ + local PlayerController LocalPlayer; + local bool bSeamless; +//@HSL_BEGIN_XBOX + local string NextMap, EncodedPlayerName; +//@HSL_END_XBOX + local Guid NextMapGuid; + local int OptionStart; + + bLevelChange = true; + EndLogging("mapchange"); + + // force an old style load screen if the server has been up for a long time so that TimeSeconds doesn't overflow and break everything + bSeamless = (bUseSeamlessTravel && WorldInfo.TimeSeconds < 172800.0f); // 172800 seconds == 48 hours + + if (InStr(Caps(URL), "?RESTART") != INDEX_NONE) + { + NextMap = string(WorldInfo.GetPackageName()); + } + else + { + OptionStart = InStr(URL, "?"); + if (OptionStart == INDEX_NONE) + { + NextMap = URL; + } + else + { + NextMap = Left(URL, OptionStart); + } + } +`if (`__TW_) + NextMap = CheckNextMap(NextMap); + if (OptionStart == INDEX_NONE) + { + URL = NextMap; + } + else + { + URL = NextMap $ Right(URL, Len(URL)-OptionStart); + } +`endif + + NextMapGuid = GetPackageGuid(name(NextMap)); + + // Notify clients we're switching level and give them time to receive. + LocalPlayer = ProcessClientTravel(URL, NextMapGuid, bSeamless, bAbsolute); + + `log("ProcessServerTravel:"@URL); + WorldInfo.NextURL = URL; + if (WorldInfo.NetMode == NM_ListenServer && LocalPlayer != None) + { +//@HSL_BEGIN_XBOX + // is this necessary or can we assume the DefaultURL name is valid? + EncodedPlayerName = LocalPlayer.GetDefaultURL("Name"); + class'GameEngine'.static.EncodeURLString(EncodedPlayerName); + + WorldInfo.NextURL $= "?Team="$LocalPlayer.GetDefaultURL("Team") + $"?Name="$EncodedPlayerName + $"?Class="$LocalPlayer.GetDefaultURL("Class") + $"?Character="$LocalPlayer.GetDefaultURL("Character"); +//@HSL_END_XBOX + } + + + // Notify access control, to cleanup online subsystem references + if (AccessControl != none) + { + AccessControl.NotifyServerTravel(bSeamless); + } + + // Trigger cleanup of online delegates + ClearOnlineDelegates(); + + if (bSeamless) + { + WorldInfo.SeamlessTravel(WorldInfo.NextURL, bAbsolute); + WorldInfo.NextURL = ""; + } + // Switch immediately if not networking. + else if (WorldInfo.NetMode != NM_DedicatedServer && WorldInfo.NetMode != NM_ListenServer) + { + WorldInfo.NextSwitchCountdown = 0.0; + } +} + +/** + * Notifies all clients to travel to the specified URL. + * + * @param URL a string containing the mapname (or IP address) to travel to, along with option key/value pairs + * @param NextMapGuid the GUID of the server's version of the next map + * @param bSeamless indicates whether the travel should use seamless travel or not. + * @param bAbsolute indicates which type of travel the server will perform (i.e. TRAVEL_Relative or TRAVEL_Absolute) + */ +function PlayerController ProcessClientTravel( out string URL, Guid NextMapGuid, bool bSeamless, bool bAbsolute ) +{ + local PlayerController P, LP; + + // We call PreClientTravel directly on any local PlayerPawns (ie listen server) + foreach WorldInfo.AllControllers(class'PlayerController', P) + { + if ( NetConnection(P.Player) != None ) + { + // remote player + P.ClientTravel(URL, TRAVEL_Relative, bSeamless, NextMapGuid); + } + else + { + // local player + LP = P; + P.PreClientTravel(URL, bAbsolute ? TRAVEL_Absolute : TRAVEL_Relative, bSeamless); + } + } + + return LP; +} + +function byte GetModifiedGameDifficulty() +{ + return GameDifficulty; +} + +function bool RequiresPassword() +{ + return ( (AccessControl != None) && AccessControl.RequiresPassword() ); +} + +// +// Accept or reject a player on the server. +// Fails login if you set the Error to a non-empty string. +// NOTE: UniqueId should not be trusted at this stage, it requires authentication +// +event PreLogin(string Options, string Address, const UniqueNetId UniqueId, bool bSupportsAuth, out string ErrorMessage) +{ + local bool bSpectator; + local bool bPerfTesting; + + // Check for an arbitrated match in progress and kick if needed + if (WorldInfo.NetMode != NM_Standalone && bUsingArbitration && bHasArbitratedHandshakeBegun) + { + ErrorMessage = PathName(WorldInfo.Game.GameMessageClass) $ ".ArbitrationMessage"; + return; + } + + // If this player is banned, reject him + if (AccessControl != none && AccessControl.IsIDBanned(UniqueId)) + { + `log(Address@"is banned, rejecting..."); + ErrorMessage = "Engine.AccessControl.SessionBanned"; + return; + } + + + bPerfTesting = ( ParseOption( Options, "AutomatedPerfTesting" ) ~= "1" ); + bSpectator = bPerfTesting || ( ParseOption( Options, "SpectatorOnly" ) ~= "1" ) || ( ParseOption( Options, "CauseEvent" ) ~= "FlyThrough" ); + + if (AccessControl != None) + { + AccessControl.PreLogin(Options, Address, UniqueId, bSupportsAuth, ErrorMessage, bSpectator); + } +} + +/** + * If called from within PreLogin, pauses the login process for the currently connecting client (usually to delay login for authentication) + * + * @return A reference to the Player/NetConnection representing the connecting client; used to resume the login process + */ +native static final function Player PauseLogin(); + +/** + * Resumes the login process for the specified client Player/NetConnection + * + * @param InPlayer The Player/NetConnection to resume logging in + */ +native static final function ResumeLogin(Player InPlayer); + +/** + * Rejects login for the specified client/NetConnection, with the specified error message + * NOTE: Error is the same error format PreLogin would take in OutError + * NOTE: Not restricted to clients at login; can be used on any valid NetConnection to disconnect a client + * + * @param InPlayer The Player/NetConnection to reject from the server + * @param Error The error message to give the player + */ +native static final function RejectLogin(Player InPlayer, string Error); + +/* + * Is the server currently at capacity? + * @param bSpectator - Whether we should check against player or spectator limits + * @return TRUE if the server is full, FALSE otherwise + */ +`if (`__TW_ONLINESUBSYSTEM_) +function bool AtCapacity(bool bSpectator, optional const UniqueNetId PlayerID) +`else +function bool AtCapacity(bool bSpectator) +`endif +{ + if ( WorldInfo.NetMode == NM_Standalone ) + return false; + + if ( bSpectator ) + return ( (NumSpectators >= MaxSpectators) + && ((WorldInfo.NetMode != NM_ListenServer) || (NumPlayers > 0)) ); + else + return ( (MaxPlayers>0) && (GetNumPlayers() >= MaxPlayers) ); +} + +native final function int GetNextPlayerID(); + +/** spawns a PlayerController at the specified location; split out from Login()/HandleSeamlessTravelPlayer() for easier overriding */ +function PlayerController SpawnPlayerController(vector SpawnLocation, rotator SpawnRotation) +{ + return Spawn(PlayerControllerClass,,, SpawnLocation, SpawnRotation); +} + +// +// Log a player in. +// Fails login if you set the Error string. +// PreLogin is called before Login, but significant game time may pass before +// Login is called, especially if content is downloaded. +// NOTE: If the AccessControl utilizes PauseLogin, UniqueID should be fully authenticated here +// +event PlayerController Login(string Portal, string Options, const UniqueNetID UniqueID, out string ErrorMessage) +{ + local NavigationPoint StartSpot; + local PlayerController NewPlayer; + local string InName, InCharacter/*, InAdminName*/, InPassword; + local byte InTeam; + local bool bSpectator, bAdmin, bPerfTesting; + local rotator SpawnRotation; + local UniqueNetId ZeroId; + + bAdmin = false; + + // Kick the player if they joined during the handshake process + if (bUsingArbitration && bHasArbitratedHandshakeBegun) + { +`if(`__TW_) + ErrorMessage = ""; +`else + ErrorMessage = PathName(WorldInfo.Game.GameMessageClass) $ ".ArbitrationMessage"; +`endif + return None; + } + + if ( BaseMutator != None ) + BaseMutator.ModifyLogin(Portal, Options); + + bPerfTesting = ( ParseOption( Options, "AutomatedPerfTesting" ) ~= "1" ); + bSpectator = bPerfTesting || ( ParseOption( Options, "SpectatorOnly" ) ~= "1" ); + + // Get URL options. +`if(`__TW_) +//@HSL_BEGIN_XBOX + InName = ParseOption ( Options, "Name"); + // Steam names can contain up to 32 characters + InName = Left(ParseOption ( Options, "Name"), 32); + class'GameEngine'.static.DecodeURLString(InName); +//@HSL_END_XBOX +`else + InName = Left(ParseOption ( Options, "Name"), 20); +`endif + InTeam = GetIntOption( Options, "Team", 255 ); // default to "no team" + //InAdminName= ParseOption ( Options, "AdminName"); + InPassword = ParseOption ( Options, "Password" ); + //InChecksum = ParseOption ( Options, "Checksum" ); + + if ( AccessControl != None ) + { + bAdmin = AccessControl.ParseAdminOptions(Options); + } + + // Make sure there is capacity except for admins. (This might have changed since the PreLogin call). + if ( !bAdmin && AtCapacity(bSpectator) ) + { +`if(`__TW_) + ErrorMessage = ""; +`else + ErrorMessage = PathName(WorldInfo.Game.GameMessageClass) $ ".MaxedOutMessage"; +`endif + return None; + } + + // if this player is banned, kick him + if( ( WorldInfo.Game.AccessControl != none ) && (WorldInfo.Game.AccessControl.IsIDBanned(UniqueId)) ) + { + `Log(InName @ "is banned, rejecting..."); +`if(`__TW_) + ErrorMessage = ""; +`else + ErrorMessage = "Engine.AccessControl.SessionBanned"; +`endif + return None; + } + + // If admin, force spectate mode if the server already full of reg. players + if ( bAdmin && AtCapacity(false) ) + { + bSpectator = true; + } + + // Pick a team (if need teams) +`if(`__TW_) + InTeam = PickTeam(InTeam,None,UniqueID); +`else + InTeam = PickTeam(InTeam,None); +`endif + // Find a start spot. + StartSpot = FindPlayerStart( None, InTeam, Portal ); + + if( StartSpot == None ) + { +`if(`__TW_) + ErrorMessage = ""; +`else + ErrorMessage = PathName(WorldInfo.Game.GameMessageClass) $ ".FailedPlaceMessage"; +`endif + return None; + } + + SpawnRotation.Yaw = StartSpot.Rotation.Yaw; + NewPlayer = SpawnPlayerController(StartSpot.Location, SpawnRotation); + + // Handle spawn failure. + if( NewPlayer == None ) + { + `log("Couldn't spawn player controller of class "$PlayerControllerClass); +`if(`__TW_) + ErrorMessage = ""; +`else + ErrorMessage = PathName(WorldInfo.Game.GameMessageClass) $ ".FailedSpawnMessage"; +`endif + return None; + } + + NewPlayer.StartSpot = StartSpot; + + // Set the player's ID. + NewPlayer.PlayerReplicationInfo.PlayerID = GetNextPlayerID(); + + // If the access control is currently authenticating the players UID, don't store the UID until it is authenticated + if (AccessControl == none || !AccessControl.IsPendingAuth(UniqueId)) + { + NewPlayer.PlayerReplicationInfo.SetUniqueId(UniqueId); + } + + if (OnlineSub != None && + OnlineSub.GameInterface != None && + UniqueId != ZeroId) + { + // Go ahead and register the player as part of the session + WorldInfo.Game.OnlineSub.GameInterface.RegisterPlayer(PlayerReplicationInfoClass.default.SessionName, UniqueId, HasOption(Options, "bIsFromInvite")); + } + // Now that the unique id is replicated, this player can contribute to skill + RecalculateSkillRating(); + + // Init player's name + if( InName=="" ) + { + InName=DefaultPlayerName$NewPlayer.PlayerReplicationInfo.PlayerID; + } + + ChangeName( NewPlayer, InName, false ); + + InCharacter = ParseOption(Options, "Character"); + NewPlayer.SetCharacter(InCharacter); + + if ( bSpectator || NewPlayer.PlayerReplicationInfo.bOnlySpectator || !ChangeTeam(newPlayer, InTeam, false) ) + { + NewPlayer.GotoState('Spectating'); + NewPlayer.PlayerReplicationInfo.bOnlySpectator = true; + NewPlayer.PlayerReplicationInfo.bIsSpectator = true; + NewPlayer.PlayerReplicationInfo.bOutOfLives = true; + return NewPlayer; + } + + // perform auto-login if admin password/name was passed on the url + if ( AccessControl != None && AccessControl.AdminLogin(NewPlayer, InPassword) ) + { + AccessControl.AdminEntered(NewPlayer); + } + + + // if delayed start, don't give a pawn to the player yet + // Normal for multiplayer games + if ( bDelayedStart ) + { + // @todo ib2merge: Chair had this commented out + NewPlayer.GotoState('PlayerWaiting'); + return NewPlayer; + } + + return newPlayer; +} + +`if(`__TW_) +static function bool AllowAnalyticsLogging(); + +function ScoreDamage( int DamageAmount, int HealthBeforeDamage, Controller InstigatedBy, Pawn DamagedPawn, class DamageType ); +function ScoreHeal( int HealAmount, int HealthBeforeHeal, Controller InstigatedBy, Pawn HealedPawn, class DamageType ); + +// OnlineSubsystem +event bool SeatPlayer(const UniqueNetId SeatedPlayerID); +event MakeReservations(const string URLOptions, const UniqueNetId PlayerId, out string OutError); +event bool ConfirmReservation(const UniqueNetId PlayerID); + +native function SetNeedsRestart(); +native function SetNeedsReload(); +`endif + +/* StartMatch() +Start the game - inform all actors that the match is starting, and spawn player pawns +*/ +function StartMatch() +{ + local Actor A; + + if ( MyAutoTestManager != None ) + { + MyAutoTestManager.StartMatch(); + } + + // tell all actors the game is starting + ForEach AllActors(class'Actor', A) + { + A.MatchStarting(); + } + + // start human players first + StartHumans(); + + // start AI players + StartBots(); + + bWaitingToStartMatch = false; + + StartOnlineGame(); + + // fire off any level startup events + WorldInfo.NotifyMatchStarted(); +} + +/** + * Tells the online system to start the game and waits for the callback. Tells + * each connected client to mark their session as in progress + */ +function StartOnlineGame() +{ + local PlayerController PC; + + if (GameInterface != None) + { + // Tell clients to mark their game as started + foreach WorldInfo.AllControllers(class'PlayerController',PC) + { + // Skip notifying local PCs as they are handled automatically + if (!PC.IsLocalPlayerController()) + { + PC.ClientStartOnlineGame(); + } + } + // Register the start callback so that the stat guid can be read + GameInterface.AddStartOnlineGameCompleteDelegate(OnStartOnlineGameComplete); + // Start the game locally and wait for it to complete + GameInterface.StartOnlineGame(PlayerReplicationInfoClass.default.SessionName); + } + else + { + // Notify all clients that the match has begun + GameReplicationInfo.StartMatch(); + } +} + +/** + * Callback when the start completes + * + * @param SessionName the name of the session this is for + * @param bWasSuccessful true if it worked, false otherwise + */ +function OnStartOnlineGameComplete(name SessionName,bool bWasSuccessful) +{ + local PlayerController PC; + local string StatGuid; + + GameInterface.ClearStartOnlineGameCompleteDelegate(OnStartOnlineGameComplete); + if (bWasSuccessful && OnlineSub.StatsInterface != None) + { + // Get the stat guid for the server + StatGuid = OnlineSub.StatsInterface.GetHostStatGuid(); + if (StatGuid != "") + { + // Send the stat guid to all clients + foreach WorldInfo.AllControllers(class'PlayerController',PC) + { + if (PC.IsLocalPlayerController() == false) + { + PC.ClientRegisterHostStatGuid(StatGuid); + } + } + } + } + + // Notify all clients that the match has begun + GameReplicationInfo.StartMatch(); +} + +function StartHumans() +{ + local PlayerController P; + + foreach WorldInfo.AllControllers(class'PlayerController', P) + { + if (P.Pawn == None) + { + if ( bGameEnded ) + { + return; // telefrag ended the game with ridiculous frag limit + } + else if (P.CanRestartPlayer()) + { + RestartPlayer(P); + } + } + } +} + +function StartBots() +{ + local Controller P; + + foreach WorldInfo.AllControllers(class'Controller', P) + { + if (P.bIsPlayer && !P.IsA('PlayerController')) + { + if (WorldInfo.NetMode == NM_Standalone) + { + RestartPlayer(P); + } + else + { + P.GotoState('Dead','MPStart'); + } + } + } +} +// +// Restart a player. +// +function RestartPlayer(Controller NewPlayer) +{ + local NavigationPoint startSpot; + local int TeamNum, Idx; + local array Events; + local SeqEvent_PlayerSpawned SpawnedEvent; + local LocalPlayer LP; + local PlayerController PC; + + if( bRestartLevel && WorldInfo.NetMode!=NM_DedicatedServer && WorldInfo.NetMode!=NM_ListenServer ) + { + `warn("bRestartLevel && !server, abort from RestartPlayer"@WorldInfo.NetMode); + return; + } + // figure out the team number and find the start spot + TeamNum = ((NewPlayer.PlayerReplicationInfo == None) || (NewPlayer.PlayerReplicationInfo.Team == None)) ? 255 : NewPlayer.PlayerReplicationInfo.Team.TeamIndex; + StartSpot = FindPlayerStart(NewPlayer, TeamNum); + + // if a start spot wasn't found, + if (startSpot == None) + { + // check for a previously assigned spot + if (NewPlayer.StartSpot != None) + { + StartSpot = NewPlayer.StartSpot; + `warn("Player start not found, using last start spot"); + } + else + { + // otherwise abort + `warn("Player start not found, failed to restart player"); + return; + } + } + // try to create a pawn to use of the default class for this player + if (NewPlayer.Pawn == None) + { + NewPlayer.Pawn = SpawnDefaultPawnFor(NewPlayer, StartSpot); + } + if (NewPlayer.Pawn == None) + { + `log("failed to spawn player at "$StartSpot); + NewPlayer.GotoState('Dead'); + if ( PlayerController(NewPlayer) != None ) + { + PlayerController(NewPlayer).ClientGotoState('Dead','Begin'); + } + } + else + { + // initialize and start it up + NewPlayer.Pawn.SetAnchor(startSpot); + if ( PlayerController(NewPlayer) != None ) + { + PlayerController(NewPlayer).TimeMargin = -0.1; + startSpot.AnchoredPawn = None; // SetAnchor() will set this since IsHumanControlled() won't return true for the Pawn yet + } + NewPlayer.Pawn.LastStartSpot = PlayerStart(startSpot); + NewPlayer.Pawn.LastStartTime = WorldInfo.TimeSeconds; + NewPlayer.Possess(NewPlayer.Pawn, false); + NewPlayer.Pawn.PlayTeleportEffect(true, true); + NewPlayer.ClientSetRotation(NewPlayer.Pawn.Rotation, TRUE); + + if (!WorldInfo.bNoDefaultInventoryForPlayer) + { + AddDefaultInventory(NewPlayer.Pawn); + } + SetPlayerDefaults(NewPlayer.Pawn); + + // activate spawned events + if (WorldInfo.GetGameSequence() != None) + { + WorldInfo.GetGameSequence().FindSeqObjectsByClass(class'SeqEvent_PlayerSpawned',TRUE,Events); + for (Idx = 0; Idx < Events.Length; Idx++) + { + SpawnedEvent = SeqEvent_PlayerSpawned(Events[Idx]); + if (SpawnedEvent != None && + SpawnedEvent.CheckActivate(NewPlayer,NewPlayer)) + { + SpawnedEvent.SpawnPoint = startSpot; + SpawnedEvent.PopulateLinkedVariableValues(); + } + } + } + } + + // To fix custom post processing chain when not running in editor or PIE. + PC = PlayerController(NewPlayer); + if (PC != none) + { + LP = LocalPlayer(PC.Player); + if(LP != None) + { + LP.RemoveAllPostProcessingChains(); + LP.InsertPostProcessingChain(LP.Outer.GetWorldPostProcessChain(),INDEX_NONE,true); + if(PC.myHUD != None) + { + PC.myHUD.NotifyBindPostProcessEffects(); + } + } + } +} + +/** + * Returns a pawn of the default pawn class + * + * @param NewPlayer - Controller for whom this pawn is spawned + * @param StartSpot - PlayerStart at which to spawn pawn + * + * @return pawn + */ +function Pawn SpawnDefaultPawnFor(Controller NewPlayer, NavigationPoint StartSpot) +{ + local class DefaultPlayerClass; + local Rotator StartRotation; + local Pawn ResultPawn; + + DefaultPlayerClass = GetDefaultPlayerClass(NewPlayer); + + // don't allow pawn to be spawned with any pitch or roll + StartRotation.Yaw = StartSpot.Rotation.Yaw; + + ResultPawn = Spawn(DefaultPlayerClass,,,StartSpot.Location,StartRotation); + if ( ResultPawn == None ) + { + `log("Couldn't spawn player of type "$DefaultPlayerClass$" at "$StartSpot); + } + return ResultPawn; +} + +/** + * Returns the default pawn class for the specified controller, + * + * @param C - controller to figure out pawn class for + * + * @return default pawn class + */ +function class GetDefaultPlayerClass(Controller C) +{ + // default to the game specified pawn class + return DefaultPawnClass; +} + +/** replicates the current level streaming status to the given PlayerController */ +function ReplicateStreamingStatus(PlayerController PC) +{ + local int LevelIndex; + local LevelStreaming TheLevel; + + // don't do this for local players or players after the first on a splitscreen client + if (LocalPlayer(PC.Player) == None && ChildConnection(PC.Player) == None) + { + // if we've loaded levels via CommitMapChange() that aren't normally in the StreamingLevels array, tell the client about that + if (WorldInfo.CommittedPersistentLevelName != 'None') + { + PC.ClientPrepareMapChange(WorldInfo.CommittedPersistentLevelName, true, true); + // tell the client to commit the level immediately + PC.ClientCommitMapChange(); + } + + if (WorldInfo.StreamingLevels.length > 0) + { + // Tell the player controller the current streaming level status + for (LevelIndex = 0; LevelIndex < WorldInfo.StreamingLevels.Length; LevelIndex++) + { + // streamingServer + TheLevel = WorldInfo.StreamingLevels[LevelIndex]; + + if( TheLevel != none ) + { + `log( "levelStatus: " $ TheLevel.PackageName $ " " + $ TheLevel.bShouldBeVisible $ " " + $ TheLevel.bIsVisible $ " " + $ TheLevel.bShouldBeLoaded $ " " + $ TheLevel.LoadedLevel $ " " + $ TheLevel.bHasLoadRequestPending $ " " + ) ; + + PC.ClientUpdateLevelStreamingStatus( + TheLevel.PackageName, + TheLevel.bShouldBeLoaded, + TheLevel.bShouldBeVisible, + TheLevel.bShouldBlockOnLoad); + } + } + PC.ClientFlushLevelStreaming(); + } + + // if we're preparing to load different levels using PrepareMapChange() inform the client about that now + if (WorldInfo.PreparingLevelNames.length > 0) + { + for (LevelIndex = 0; LevelIndex < WorldInfo.PreparingLevelNames.length; LevelIndex++) + { + PC.ClientPrepareMapChange(WorldInfo.PreparingLevelNames[LevelIndex], LevelIndex == 0, LevelIndex == WorldInfo.PreparingLevelNames.length - 1); + } + // DO NOT commit these changes yet - we'll send that when we're done preparing them + } + } +} + +/** handles all player initialization that is shared between the travel methods + * (i.e. called from both PostLogin() and HandleSeamlessTravelPlayer()) + */ +function GenericPlayerInitialization(Controller C) +{ + local PlayerController PC; + + PC = PlayerController(C); + if (PC != None) + { + // Keep track of the best host to migrate to in case of a disconnect + UpdateBestNextHosts(); + + // Notify the game that we can now be muted and mute others + UpdateGameplayMuteList(PC); + + // tell client what hud class to use + PC.ClientSetHUD(HudType); + + // tell client what secondary hud class to use + PC.ClientSetSecondaryHUD(SecondaryHudType); + + ReplicateStreamingStatus(PC); + + // see if we need to spawn a CoverReplicator for this player + if (CoverReplicatorBase != None) + { + PC.SpawnCoverReplicator(); + } + + // Set the rich presence strings on the client (has to be done there) + PC.ClientSetOnlineStatus(); + } + + if (BaseMutator != None) + { + BaseMutator.NotifyLogin(C); + } +} + +/** + * Sort the list of best hosts. Clients with the most peer connections come first. + * Then sort based on time of join so that newest players are preferred. + * + * @param A first item to compare + * @param B second item to compare + * @return 0 if A==B, < 0 if A < B, > 0 if A > B + */ +function int BestNextHostSort(PlayerController A, PlayerController B) +{ + local int Result; + + if (A.ConnectedPeers.Length == B.ConnectedPeers.Length && + A.PlayerReplicationInfo != None && B.PlayerReplicationInfo != None) + { + // sort by newest start time + Result = FCeil(B.PlayerReplicationInfo.StartTime) - FCeil(A.PlayerReplicationInfo.StartTime); + } + else + { + // sort by largest connected peers + Result = A.ConnectedPeers.Length - B.ConnectedPeers.Length; + } + + return Result; +} + +/** + * Updates the list of best next hosts on the current server and also replicates this list to all clients. + */ +function UpdateBestNextHosts() +{ + local PlayerController PC; + local array SortedPCList; + local UniqueNetId SortedPlayerIdList[10]; + local UniqueNetId ZeroId; + local int Idx,NumEntries; + + // copy list of remote PCs + foreach WorldInfo.AllControllers(class'PlayerController',PC) + { + if (!PC.IsLocalPlayerController() && + PC.PlayerReplicationInfo != None && + PC.PlayerReplicationInfo.UniqueId != ZeroId && + PC.IsPrimaryPlayer()) + { + SortedPCList.AddItem(PC); + } + } + // sort list of PCs from best to worst host + SortedPCList.Sort(BestNextHostSort); + + // copy to list of unique net ids + NumEntries = Min(SortedPCList.Length,10); + for (Idx=0; Idx < NumEntries; Idx++) + { + SortedPlayerIdList[Idx] = SortedPCList[Idx].PlayerReplicationInfo.UniqueId; + } + + // send list of best hosts to clients + foreach WorldInfo.AllControllers(class'PlayerController',PC) + { + if (!PC.IsLocalPlayerController()) + { + PC.ClientUpdateBestNextHosts(SortedPlayerIdList,NumEntries); + } + } +} + +// +// Called after a successful login. This is the first place +// it is safe to call replicated functions on the PlayerController. +// +event PostLogin( PlayerController NewPlayer ) +{ + local string Address, StatGuid; + local int pos, i; + local Sequence GameSeq; + local array AllInterpActions; + + local int HidePlayer, HideHud, DisableMovement, DisableTurning, DisableInput; + + // update player count + if (NewPlayer.PlayerReplicationInfo.bOnlySpectator) + { + NumSpectators++; + } + else if (WorldInfo.IsInSeamlessTravel() || NewPlayer.HasClientLoadedCurrentWorld()) + { + NumPlayers++; + } + else + { + NumTravellingPlayers++; + } + //@SABER_EGS_BEGIN Crossplay support + if (WorldInfo.IsEOSDedicatedServer() && NewPlayer.bIsEosPlayer && !NewPlayer.PlayerReplicationInfo.bOnlySpectator) + { + NumEosPlayers++; + } + //@SABER_EGS_END + // Tell the online subsystem the number of players in the game + UpdateGameSettingsCounts(); + + // save network address for re-associating with reconnecting player, after stripping out port number + Address = NewPlayer.GetPlayerNetworkAddress(); + pos = InStr(Address,":"); + NewPlayer.PlayerReplicationInfo.SavedNetworkAddress = (pos > 0) ? left(Address,pos) : Address; + + // check if this player is reconnecting and already has PRI + FindInactivePRI(NewPlayer); + + if ( !bDelayedStart ) + { + // start match, or let player enter, immediately + bRestartLevel = false; // let player spawn once in levels that must be restarted after every death + if ( bWaitingToStartMatch ) + StartMatch(); + else + RestartPlayer(newPlayer); + bRestartLevel = Default.bRestartLevel; + } + + if (NewPlayer.Pawn != None) + { + NewPlayer.Pawn.ClientSetRotation(NewPlayer.Pawn.Rotation); + } + + NewPlayer.ClientCapBandwidth(NewPlayer.Player.CurrentNetSpeed); + UpdateNetSpeeds(); + + GenericPlayerInitialization(NewPlayer); + + // Tell the new player the stat guid + if (GameReplicationInfo.bMatchHasBegun && OnlineSub != None && OnlineSub.StatsInterface != None) + { + // Get the stat guid for the server + StatGuid = OnlineSub.StatsInterface.GetHostStatGuid(); + if (StatGuid != "") + { + NewPlayer.ClientRegisterHostStatGuid(StatGuid); + } + } + + // HSL - BWJ - 3-18-16 - Push to talk for non console build sonly + // Tell the player to disable voice by default and use the push to talk method + if (bRequiresPushToTalk && !WorldInfo.IsConsoleDedicatedServer()) + { + NewPlayer.ClientStopNetworkedVoice(); + } + else + { + NewPlayer.ClientStartNetworkedVoice(); + } + + if (NewPlayer.PlayerReplicationInfo.bOnlySpectator) + { + NewPlayer.ClientGotoState('Spectating'); + } + + // add the player to any matinees running so that it gets in on any cinematics already running, etc + GameSeq = WorldInfo.GetGameSequence(); + if (GameSeq != None) + { + // find any matinee actions that exist + GameSeq.FindSeqObjectsByClass(class'SeqAct_Interp', true, AllInterpActions); + + // tell them all to add this PC to any running Director tracks + for (i = 0; i < AllInterpActions.Length; i++) + { + SeqAct_Interp(AllInterpActions[i]).AddPlayerToDirectorTracks(NewPlayer); + } + } + + //Check to see if we should start in cinematic mode (matinee movie capture) + if(ShouldStartInCinematicMode(HidePlayer, HideHud, DisableMovement, DisableTurning, DisableInput)) + { + NewPlayer.SetCinematicMode(true, HidePlayer == 1, HideHud == 1, DisableMovement == 1, DisableTurning == 1, DisableInput == 1); + } + + // Pass on to access control + if (AccessControl != none) + { + AccessControl.PostLogin(NewPlayer); + } +} + +function UpdateNetSpeeds() +{ + local int NewNetSpeed; + local PlayerController PC; + local OnlineGameSettings GameSettings; + + if (GameInterface != None) + { + GameSettings = GameInterface.GetGameSettings(PlayerReplicationInfoClass.default.SessionName); + } + + if ( (WorldInfo.NetMode == NM_DedicatedServer) || (WorldInfo.NetMode == NM_Standalone) || (GameSettings != None && GameSettings.bIsLanMatch) ) + { + return; + } + + if ( WorldInfo.TimeSeconds - LastNetSpeedUpdateTime < 1.0 ) + { + SetTimer( 1.0, false, nameof(UpdateNetSpeeds) ); + return; + } + + LastNetSpeedUpdateTime = WorldInfo.TimeSeconds; + + NewNetSpeed = CalculatedNetSpeed(); + `log("New Dynamic NetSpeed "$NewNetSpeed$" vs old "$AdjustedNetSpeed,,'DevNet'); + + if ( AdjustedNetSpeed != NewNetSpeed ) + { + AdjustedNetSpeed = NewNetSpeed; + ForEach WorldInfo.AllControllers(class'PlayerController', PC) + { + PC.SetNetSpeed(AdjustedNetSpeed); + } + } +} + +function int CalculatedNetSpeed() +{ + return Clamp(TotalNetBandwidth/Max(NumPlayers,1), MinDynamicBandwidth, MaxDynamicBandwidth); +} + +/** + * Engine is shutting down. + */ +event PreExit() +{ + if (AccessControl != none) + { + AccessControl.NotifyExit(); + } + + ClearOnlineDelegates(); +} + +// +// Player exits. +// +function Logout( Controller Exiting ) +{ + local PlayerController PC; + local int PCIndex; + + PC = PlayerController(Exiting); + if ( PC != None ) + { + if (AccessControl != None && + AccessControl.AdminLogout( PlayerController(Exiting) )) + { + AccessControl.AdminExited( PlayerController(Exiting) ); + } + + if ( PC.PlayerReplicationInfo.bOnlySpectator ) + { + NumSpectators--; + } + else + { + if (WorldInfo.IsInSeamlessTravel() || PC.HasClientLoadedCurrentWorld()) + { + NumPlayers--; + } + else + { + NumTravellingPlayers--; + } + //@SABER_EGS_BEGIN Crossplay support + if (WorldInfo.IsEOSDedicatedServer() && PC.bIsEosPlayer) + { + NumEosPlayers--; + } + //@SABER_EGS_END + // Tell the online subsystem the number of players in the game + UpdateGameSettingsCounts(); + } + // This person has left during an arbitration period + if (bUsingArbitration && bHasArbitratedHandshakeBegun && !bHasEndGameHandshakeBegun) + { + `Log("Player "$PC.PlayerReplicationInfo.PlayerName$" has dropped"); + } + // Unregister the player from the online layer + UnregisterPlayer(PC); + // Remove from the arbitrated PC list if in an arbitrated match + if (bUsingArbitration) + { + // Find the PC in the list and remove it if found + PCIndex = ArbitrationPCs.Find(PC); + if (PCIndex != INDEX_NONE) + { + ArbitrationPCs.Remove(PCIndex,1); + } + } + } + //notify mutators that a player exited + if (BaseMutator != None) + { + BaseMutator.NotifyLogout(Exiting); + } + if ( PC != None ) + { + UpdateNetSpeeds(); + } +} + +/** + * Removes the player from the named session when they leave + * + * @param PC the player controller that just left + */ +function UnregisterPlayer(PlayerController PC) +{ + local UniqueNetId ZeroId; + + // If there is a session that matches the name, unregister this remote player + if (WorldInfo.NetMode != NM_Standalone && + GameInterface != None && + PC.PlayerReplicationInfo.UniqueId != ZeroId && + GameInterface.GetGameSettings(PC.PlayerReplicationInfo.SessionName) != None) + { + // Unregister the player from the session + GameInterface.UnregisterPlayer(PC.PlayerReplicationInfo.SessionName,PC.PlayerReplicationInfo.UniqueId); + } +} + +// +// Examine the passed player's inventory, and accept or discard each item. +// AcceptInventory needs to gracefully handle the case of some inventory +// being accepted but other inventory not being accepted (such as the default +// weapon). There are several things that can go wrong: A weapon's +// AmmoType not being accepted but the weapon being accepted -- the weapon +// should be killed off. Or the player's selected inventory item, active +// weapon, etc. not being accepted, leaving the player weaponless or leaving +// the HUD inventory rendering messed up (AcceptInventory should pick another +// applicable weapon/item as current). +// +event AcceptInventory(pawn PlayerPawn) +{ + //default accept all inventory except default weapon (spawned explicitly) +} + +// +// Spawn any default inventory for the player. +// +event AddDefaultInventory(Pawn P) +{ + // Allow the pawn itself to modify its inventory + P.AddDefaultInventory(); + + if ( P.InvManager == None ) + { + `warn("GameInfo::AddDefaultInventory - P.InvManager == None"); + } +} + +/* Mutate() +Pass an input string to the mutator list. Used by PlayerController.Mutate(), intended to allow +mutators to have input exec functions (by binding mutate xxx to keys) +*/ +function Mutate(string MutateString, PlayerController Sender) +{ + if ( BaseMutator != None ) + BaseMutator.Mutate(MutateString, Sender); +} + +/* SetPlayerDefaults() + first make sure pawn properties are back to default, then give mutators an opportunity + to modify them +*/ +function SetPlayerDefaults(Pawn PlayerPawn) +{ + PlayerPawn.AirControl = PlayerPawn.Default.AirControl; + PlayerPawn.GroundSpeed = PlayerPawn.Default.GroundSpeed; + PlayerPawn.WaterSpeed = PlayerPawn.Default.WaterSpeed; + PlayerPawn.AirSpeed = PlayerPawn.Default.AirSpeed; + PlayerPawn.Acceleration = PlayerPawn.Default.Acceleration; + PlayerPawn.AccelRate = PlayerPawn.Default.AccelRate; + PlayerPawn.JumpZ = PlayerPawn.Default.JumpZ; + if ( BaseMutator != None ) + BaseMutator.ModifyPlayer(PlayerPawn); + PlayerPawn.PhysicsVolume.ModifyPlayer(PlayerPawn); +} + +function NotifyKilled(Controller Killer, Controller Killed, Pawn KilledPawn, class damageType ) +{ + local Controller C; + + foreach WorldInfo.AllControllers(class'Controller', C) + { + C.NotifyKilled(Killer, Killed, KilledPawn, damageType); + } +} + +function Killed( Controller Killer, Controller KilledPlayer, Pawn KilledPawn, class damageType ) +{ + if( KilledPlayer != None && KilledPlayer.bIsPlayer ) + { + KilledPlayer.PlayerReplicationInfo.IncrementDeaths(); + KilledPlayer.PlayerReplicationInfo.SetNetUpdateTime(FMin(KilledPlayer.PlayerReplicationInfo.NetUpdateTime, WorldInfo.TimeSeconds + 0.3 * FRand())); + BroadcastDeathMessage(Killer, KilledPlayer, damageType); + } + + if( KilledPlayer != None ) + { + ScoreKill(Killer, KilledPlayer); + } + + DiscardInventory(KilledPawn, Killer); + NotifyKilled(Killer, KilledPlayer, KilledPawn, damageType); +} + +function bool PreventDeath(Pawn KilledPawn, Controller Killer, class DamageType, vector HitLocation) +{ + if ( BaseMutator == None ) + return false; + return BaseMutator.PreventDeath(KilledPawn, Killer, DamageType, HitLocation); +} + +function BroadcastDeathMessage(Controller Killer, Controller Other, class damageType) +{ + if ( (Killer == Other) || (Killer == None) ) + { + BroadcastLocalized(self, DeathMessageClass, 1, None, Other.PlayerReplicationInfo, damageType); + } + else + { + BroadcastLocalized(self, DeathMessageClass, 0, Killer.PlayerReplicationInfo, Other.PlayerReplicationInfo, damageType); + } +} + +function Kick( string S ) +{ + if (AccessControl != None) + { + AccessControl.Kick(S); + } + else + { + `log("NO ACCESS CONTROL!!!"); + } +} + +function KickBan( string S ) +{ + if (AccessControl != None) + AccessControl.KickBan(S); +} + +//------------------------------------------------------------------------------------- +// Level gameplay modification. + +// +// Return whether Viewer is allowed to spectate from the +// point of view of ViewTarget. +// +function bool CanSpectate( PlayerController Viewer, PlayerReplicationInfo ViewTarget ) +{ + return true; +} + +/* ReduceDamage: + Use reduce damage for teamplay modifications, etc. */ +`if(`__TW_) +function ReduceDamage(out int Damage, pawn injured, Controller instigatedBy, vector HitLocation, out vector Momentum, class DamageType, Actor DamageCauser, TraceHitInfo HitInfo) +`else +function ReduceDamage(out int Damage, pawn injured, Controller instigatedBy, vector HitLocation, out vector Momentum, class DamageType, Actor DamageCauser) +`endif +{ + local int OriginalDamage; + + OriginalDamage = Damage; + + if ( injured.PhysicsVolume.bNeutralZone || injured.InGodMode() ) + { + Damage = 0; + return; + } + + if (BaseMutator != None) + { + BaseMutator.NetDamage(OriginalDamage, Damage, Injured, InstigatedBy, HitLocation, Momentum, DamageType, DamageCauser); + } +} + +/* CheckRelevance() +returns true if actor is relevant to this game and should not be destroyed. Called in Actor.PreBeginPlay(), intended to allow +mutators to remove or replace actors being spawned +*/ +function bool CheckRelevance(Actor Other) +{ + if ( BaseMutator == None ) + return true; + return BaseMutator.CheckRelevance(Other); +} + +/** + * Return whether an item should respawn. Default implementation allows item respawning in multiplayer games. + */ +function bool ShouldRespawn( PickupFactory Other ) +{ + return ( WorldInfo.NetMode != NM_Standalone ); +} + +/** + * Called when pawn has a chance to pick Item up (i.e. when + * the pawn touches a weapon pickup). Should return true if + * he wants to pick it up, false if he does not want it. + * @param Other the Pawn that wants the item + * @param ItemClass the Inventory class the Pawn can pick up + * @param Pickup the Actor containing that item (this may be a PickupFactory or it may be a DroppedPickup) + * @return whether or not the Pickup actor should give its item to Other + */ +function bool PickupQuery(Pawn Other, class ItemClass, Actor Pickup) +{ + local byte bAllowPickup; + + if (BaseMutator != None && BaseMutator.OverridePickupQuery(Other, ItemClass, Pickup, bAllowPickup)) + { + return bool(bAllowPickup); + } + + if ( Other.InvManager == None ) + { + return false; + } + else + { + return Other.InvManager.HandlePickupQuery(ItemClass, Pickup); + } +} + +/** + * Discard a player's inventory after he dies. + */ +function DiscardInventory( Pawn Other, optional controller Killer ) +{ + if ( Other.InvManager != None ) + Other.InvManager.DiscardInventory(); +} + +/* Try to change a player's name. +*/ +function ChangeName( Controller Other, coerce string S, bool bNameChange ) +{ + if( S == "" ) + { + return; + } + + Other.PlayerReplicationInfo.SetPlayerName(S); +} + +/* Return whether a team change is allowed. +*/ +function bool ChangeTeam(Controller Other, int N, bool bNewTeam) +{ + return true; +} + +/* Return a picked team number if none was specified +*/ +`if(`__TW_) +function byte PickTeam(byte Current, Controller C, const out UniqueNetId PlayerId) +`else +function byte PickTeam(byte Current, Controller C) +`endif +{ + return Current; +} + +/* Send a player to a URL. +*/ +function SendPlayer( PlayerController aPlayer, string URL ) +{ + aPlayer.ClientTravel( URL, TRAVEL_Relative ); +} + +/** @return the map we should travel to for the next game */ +function string GetNextMap(); + +/** + * Returns true if we want to travel_absolute + */ +function bool GetTravelType() +{ + return false; +} + +/* Restart the game. +*/ +function RestartGame() +{ + local string NextMap; + local string TransitionMapCmdLine; + local string URLString; + local int URLMapLen; + local int MapNameLen; + + // If we are using arbitration and haven't done the end game handshaking, + // do that process first and then come back here afterward + if (bUsingArbitration) + { + if (bIsEndGameHandshakeComplete) + { + // All arbitrated matches must exit after one match + NotifyArbitratedMatchEnd(); + } + return; + } + + if (BaseMutator != None && BaseMutator.HandleRestartGame()) + { + return; + } + + if (bGameRestarted) + { + return; + } + bGameRestarted = true; + + // these server travels should all be relative to the current URL + if ( bChangeLevels && !bAlreadyChanged ) + { + // get the next map and start the transition + bAlreadyChanged = true; + + if ( (MyAutoTestManager != None) && MyAutoTestManager.bUsingAutomatedTestingMapList) + { + NextMap = MyAutoTestManager.GetNextAutomatedTestingMap(); + } + else + { + NextMap = GetNextMap(); + } + + if (NextMap != "") + { + if ( (MyAutoTestManager == None) || !MyAutoTestManager.bUsingAutomatedTestingMapList ) + { + WorldInfo.ServerTravel(NextMap,GetTravelType()); + } + else + { + if ( !MyAutoTestManager.bAutomatedTestingWithOpen ) + { + URLString = WorldInfo.GetLocalURL(); + URLMapLen = Len(URLString); + + MapNameLen = InStr(URLString, "?"); + if (MapNameLen != -1) + { + URLString = Right(URLString, URLMapLen - MapNameLen); + } + + // The ENTIRE url needs to be recreated here... + TransitionMapCmdLine = NextMap$URLString$"?AutomatedTestingMapIndex="$MyAutoTestManager.AutomatedTestingMapIndex; + `log(">>> Issuing server travel on " $ TransitionMapCmdLine); + WorldInfo.ServerTravel(TransitionMapCmdLine,GetTravelType()); + } + else + { + TransitionMapCmdLine = "?AutomatedTestingMapIndex="$MyAutoTestManager.AutomatedTestingMapIndex$"?NumberOfMatchesPlayed="$MyAutoTestManager.NumberOfMatchesPlayed$"?NumMapListCyclesDone="$MyAutoTestManager.NumMapListCyclesDone; + `log(">>> Issuing open command on " $ NextMap $ TransitionMapCmdLine); + ConsoleCommand( "open " $ NextMap $ TransitionMapCmdLine); + } + } + return; + } + } + + `log("GameInfo - RestartGame - Call ServerTravel()"); + WorldInfo.ServerTravel("?Restart",GetTravelType()); +} + +//========================================================================== +// Message broadcasting functions (handled by the BroadCastHandler) + +event Broadcast( Actor Sender, coerce string Msg, optional name Type ) +{ + BroadcastHandler.Broadcast(Sender,Msg,Type); +} + +function BroadcastTeam( Controller Sender, coerce string Msg, optional name Type ) +{ + BroadcastHandler.BroadcastTeam(Sender,Msg,Type); +} + +/* + Broadcast a localized message to all players. + Most message deal with 0 to 2 related PRIs. + The LocalMessage class defines how the PRI's and optional actor are used. +*/ +event BroadcastLocalized( actor Sender, class Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ) +{ + BroadcastHandler.AllowBroadcastLocalized(Sender,Message,Switch,RelatedPRI_1,RelatedPRI_2,OptionalObject); +} + +/* + Broadcast a localized message to all players on a team. + Most message deal with 0 to 2 related PRIs. + The LocalMessage class defines how the PRI's and optional actor are used. +*/ +event BroadcastLocalizedTeam( int TeamIndex, actor Sender, class Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ) +{ + BroadcastHandler.AllowBroadcastLocalizedTeam(TeamIndex, Sender,Message,Switch,RelatedPRI_1,RelatedPRI_2,OptionalObject); +} + +//========================================================================== +function bool CheckModifiedEndGame(PlayerReplicationInfo Winner, string Reason) +{ + return (BaseMutator != None && !BaseMutator.CheckEndGame(Winner, Reason)); +} + +function bool CheckEndGame(PlayerReplicationInfo Winner, string Reason) +{ + local Controller P; + + if ( CheckModifiedEndGame(Winner, Reason) ) + return false; + + // all player cameras focus on winner or final scene (picked by mutator) + foreach WorldInfo.AllControllers(class'Controller', P) + { + P.GameHasEnded(); + } + return true; +} + +/** + * Tells all clients to write stats and then handles writing local stats + */ +function WriteOnlineStats() +{ + local PlayerController PC; + local OnlineGameSettings CurrentSettings; + + if (GameInterface != None) + { + // Make sure that we are recording stats + CurrentSettings = GameInterface.GetGameSettings(PlayerReplicationInfoClass.default.SessionName); + if (CurrentSettings != None && CurrentSettings.bUsesStats) + { + // Iterate through the controllers telling them to write stats + foreach WorldInfo.AllControllers(class'PlayerController',PC) + { + if (PC.IsLocalPlayerController() == false) + { + PC.ClientWriteLeaderboardStats(OnlineStatsWriteClass); + } + } + // Iterate through local controllers telling them to write stats + foreach WorldInfo.AllControllers(class'PlayerController',PC) + { + if (PC.IsLocalPlayerController()) + { + PC.ClientWriteLeaderboardStats(OnlineStatsWriteClass); + } + } + } + } +} + +/** + * If the match is arbitrated, tells all clients to write out their copies + * of the player scores. If not arbitrated, it only has the first local player + * write the scores. + */ +function WriteOnlinePlayerScores() +{ + local PlayerController PC; + + if (bUsingArbitration) + { + // Iterate through the controllers telling them to write stats + foreach WorldInfo.AllControllers(class'PlayerController',PC) + { + PC.ClientWriteOnlinePlayerScores(ArbitratedLeaderboardId); + } + } + else + { + // Find the first local player and have them write the data + foreach WorldInfo.AllControllers(class'PlayerController',PC) + { + if (PC.IsLocalPlayerController()) + { + PC.ClientWriteOnlinePlayerScores(LeaderboardId); + break; + } + } + } +} + +/* End of game. +*/ +function EndGame( PlayerReplicationInfo Winner, string Reason ) +{ + // don't end game if not really ready + if ( !CheckEndGame(Winner, Reason) ) + { + bOverTime = true; + return; + } + + // Allow replication to happen before reporting scores, stats, etc. + SetTimer( 1.5,false,nameof(PerformEndGameHandling) ); + + bGameEnded = true; + EndLogging(Reason); +} + +/** Does end of game handling for the online layer */ +function PerformEndGameHandling() +{ + if (GameInterface != None) + { + // Write out any online stats + WriteOnlineStats(); + // Write the player data used in determining skill ratings + WriteOnlinePlayerScores(); + // Force the stats to flush and change the status of the match + // to ended making join in progress an option again + EndOnlineGame(); + // Notify clients that the session has ended for arbitrated + if (bUsingArbitration) + { + PendingArbitrationPCs.Length = 0; + ArbitrationPCs.Length = 0; + // Do end of session handling + NotifyArbitratedMatchEnd(); + } + } +} + +/** + * Tells the online system to end the game and tells all clients to do the same + */ +function EndOnlineGame() +{ + local PlayerController PC; + + GameReplicationInfo.EndGame(); + if (GameInterface != None) + { + // Have clients end their games + foreach WorldInfo.AllControllers(class'PlayerController',PC) + { + // Skip notifying local PCs as they are handled automatically + if (!PC.IsLocalPlayerController()) + { + PC.ClientEndOnlineGame(); + } + } + // Server is handled here + GameInterface.EndOnlineGame(PlayerReplicationInfoClass.default.SessionName); + } +} + +/** Entry point of the stats code for custom game logging at a regular interval */ +function GameEventsPoll(); +function EndLogging(string Reason); // Stub function + +/** returns whether the given Controller StartSpot property should be used as the spawn location for its Pawn */ +function bool ShouldSpawnAtStartSpot(Controller Player) +{ + return ( WorldInfo.NetMode == NM_Standalone && Player != None && Player.StartSpot != None && + (bWaitingToStartMatch || (Player.PlayerReplicationInfo != None && Player.PlayerReplicationInfo.bWaitingPlayer)) ); +} + +/** FindPlayerStart() +* Return the 'best' player start for this player to start from. PlayerStarts are rated by RatePlayerStart(). +* @param Player is the controller for whom we are choosing a playerstart +* @param InTeam specifies the Player's team (if the player hasn't joined a team yet) +* @param IncomingName specifies the tag of a teleporter to use as the Playerstart +* @returns NavigationPoint chosen as player start (usually a PlayerStart) + */ +function NavigationPoint FindPlayerStart( Controller Player, optional byte InTeam, optional string IncomingName ) +{ + local NavigationPoint N, BestStart; + local Teleporter Tel; + + // allow GameRulesModifiers to override playerstart selection + if (BaseMutator != None) + { + N = BaseMutator.FindPlayerStart(Player, InTeam, IncomingName); + if (N != None) + { + return N; + } + } + + // if incoming start is specified, then just use it + if( incomingName!="" ) + { + ForEach WorldInfo.AllNavigationPoints( class 'Teleporter', Tel ) + if( string(Tel.Tag)~=incomingName ) + return Tel; + } + + // always pick StartSpot at start of match +`if(`__TW_) + // Allow ShouldSpawnAtStartSpot() to handle rating - see KFGameInfo + if ( ShouldSpawnAtStartSpot(Player) ) +`else + if ( ShouldSpawnAtStartSpot(Player) && + (PlayerStart(Player.StartSpot) == None || RatePlayerStart(PlayerStart(Player.StartSpot), InTeam, Player) >= 0.0) ) +`endif + { + return Player.StartSpot; + } + + BestStart = ChoosePlayerStart(Player, InTeam); + + if ( (BestStart == None) && (Player == None) ) + { + // no playerstart found, so pick any NavigationPoint to keep player from failing to enter game + `log("Warning - PATHS NOT DEFINED or NO PLAYERSTART with positive rating"); + ForEach AllActors( class 'NavigationPoint', N ) + { + BestStart = N; + break; + } + } + return BestStart; +} + +/** ChoosePlayerStart() +* Return the 'best' player start for this player to start from. PlayerStarts are rated by RatePlayerStart(). +* @param Player is the controller for whom we are choosing a playerstart +* @param InTeam specifies the Player's team (if the player hasn't joined a team yet) +* @returns NavigationPoint chosen as player start (usually a PlayerStart) + */ +function PlayerStart ChoosePlayerStart( Controller Player, optional byte InTeam ) +{ + local PlayerStart P, BestStart; + local float BestRating, NewRating; + local byte Team; + + // use InTeam if player doesn't have a team yet + Team = ( (Player != None) && (Player.PlayerReplicationInfo != None) && (Player.PlayerReplicationInfo.Team != None) ) + ? byte(Player.PlayerReplicationInfo.Team.TeamIndex) + : InTeam; + + // Find best playerstart + foreach WorldInfo.AllNavigationPoints(class'PlayerStart', P) + { + NewRating = RatePlayerStart(P,Team,Player); + if ( NewRating > BestRating ) + { + BestRating = NewRating; + BestStart = P; + } + } + return BestStart; +} + +/** RatePlayerStart() +* Return a score representing how desireable a playerstart is. +* @param P is the playerstart being rated +* @param Team is the team of the player choosing the playerstart +* @param Player is the controller choosing the playerstart +* @returns playerstart score +*/ +function float RatePlayerStart(PlayerStart P, byte Team, Controller Player) +{ + local float Rating; + if ( !P.bEnabled ) + { + return 5.f; + } + else + { + Rating = 10.f; + if (P.bPrimaryStart) + { + Rating += 10.f; + } + if (P.TeamIndex == Team) + { + Rating += 15.f; + } + return Rating; + } +} + +function AddObjectiveScore(PlayerReplicationInfo Scorer, Int Score) +{ + if ( Scorer != None ) + { + Scorer.Score += Score; + } + if (BaseMutator != None) + { + BaseMutator.ScoreObjective(Scorer, Score); + } +} + +function ScoreObjective(PlayerReplicationInfo Scorer, Int Score) +{ + AddObjectiveScore(Scorer, Score); + CheckScore(Scorer); +} + +/* CheckScore() +see if this score means the game ends +*/ +function bool CheckScore(PlayerReplicationInfo Scorer) +{ + return true; +} + +function ScoreKill(Controller Killer, Controller Other) +{ + if( (killer == Other) || (killer == None) ) + { + if ( (Other!=None) && (Other.PlayerReplicationInfo != None) ) + { + Other.PlayerReplicationInfo.Score -= 1; + Other.PlayerReplicationInfo.bForceNetUpdate = TRUE; + } + } + else if ( killer.PlayerReplicationInfo != None ) + { + Killer.PlayerReplicationInfo.Score += 1; + Killer.PlayerReplicationInfo.bForceNetUpdate = TRUE; + Killer.PlayerReplicationInfo.Kills++; + } + + ModifyScoreKill(Killer, Other); + + if (Killer != None || MaxLives > 0) + { + CheckScore(Killer.PlayerReplicationInfo); + } +} + +/** + * For subclasses which don't call GameInfo.ScoreKill() + */ +function ModifyScoreKill(Controller Killer, Controller Other) +{ + if (BaseMutator != None) + { + BaseMutator.ScoreKill(Killer, Other); + } +} + +function DriverEnteredVehicle(Vehicle V, Pawn P) +{ + if ( BaseMutator != None ) + BaseMutator.DriverEnteredVehicle(V, P); +} + +function bool CanLeaveVehicle(Vehicle V, Pawn P) +{ + if ( BaseMutator == None ) + return true; + return BaseMutator.CanLeaveVehicle(V, P); +} + +function DriverLeftVehicle(Vehicle V, Pawn P) +{ + if ( BaseMutator != None ) + BaseMutator.DriverLeftVehicle(V, P); +} + +function bool PlayerCanRestartGame( PlayerController aPlayer ) +{ + return true; +} + +// Player Can be restarted ? +function bool PlayerCanRestart( PlayerController aPlayer ) +{ + return true; +} + +// Returns whether a mutator should be allowed with this gametype +static function bool AllowMutator( string MutatorClassName ) +{ + return !class'WorldInfo'.static.IsDemoBuild(); +} + + +function bool AllowCheats(PlayerController P) +{ + return ( WorldInfo.NetMode == NM_Standalone ); +} + +/** + * @return TRUE if the player is allowed to pause the game. + */ +function bool AllowPausing( optional PlayerController PC ) +{ + return bPauseable + || WorldInfo.NetMode == NM_Standalone + || (bAdminCanPause && AccessControl.IsAdmin(PC)); +} + +/** + * Called from C++'s CommitMapChange before unloading previous level + * @param PreviousMapName Name of the previous persistent level + * @param NextMapName Name of the persistent level being streamed to + */ +event PreCommitMapChange(string PreviousMapName, string NextMapName); + +/** + * Called from C++'s CommitMapChange after unloading previous level and loading new level+sublevels + */ +event PostCommitMapChange(); + +/** AddInactivePRI() +* Add PRI to the inactive list, remove from the active list +*/ +function AddInactivePRI(PlayerReplicationInfo PRI, PlayerController PC) +{ + local int i; + local PlayerReplicationInfo NewPRI, CurrentPRI; + local bool bIsConsole; + + // don't store if it's an old PRI from the previous level or if it's a spectator + if (!PRI.bFromPreviousLevel && !PRI.bOnlySpectator) + { + NewPRI = PRI.Duplicate(); + WorldInfo.GRI.RemovePRI(NewPRI); + + // make PRI inactive + NewPRI.RemoteRole = ROLE_None; + + // delete after 5 minutes + NewPRI.LifeSpan = 300; + + // On console, we have to check the unique net id as network address isn't valid + bIsConsole = WorldInfo.IsConsoleBuild(); + + // make sure no duplicates + for (i=0; i 16 ) + { + InactivePRIArray.Remove(0, InactivePRIArray.Length - 16); + } + } + + PRI.Destroy(); + // Readjust the skill rating now that this player has left + RecalculateSkillRating(); +} + +/** FindInactivePRI() +* returns the PRI associated with this re-entering player +*/ +function bool FindInactivePRI(PlayerController PC) +{ + local string NewNetworkAddress, NewName; + local int i; + local PlayerReplicationInfo OldPRI, CurrentPRI; + local bool bIsConsole; + + // don't bother for spectators + if (PC.PlayerReplicationInfo.bOnlySpectator) + { + return false; + } + + // On console, we have to check the unique net id as network address isn't valid + bIsConsole = WorldInfo.IsConsoleBuild(); + + NewNetworkAddress = PC.PlayerReplicationInfo.SavedNetworkAddress; + NewName = PC.PlayerReplicationInfo.PlayerName; + for (i=0; i entry, false if we are going from entry -> new level + * @param ActorList (out) list of actors to maintain + */ +event GetSeamlessTravelActorList(bool bToEntry, out array ActorList) +{ + local int i; + + // always keep PlayerReplicationInfos and TeamInfos, so that after we restart we can keep players on the same team, etc + for (i = 0; i < WorldInfo.GRI.PRIArray.Length; i++) + { + WorldInfo.GRI.PRIArray[i].bFromPreviousLevel = true; + WorldInfo.GRI.PRIArray[i].bForceNetUpdate = true; + ActorList[ActorList.length] = WorldInfo.GRI.PRIArray[i]; + } + + if (bToEntry) + { + // keep general game state until we transition to the final destination + ActorList[ActorList.length] = WorldInfo.GRI; + if (BroadcastHandler != None) + { + ActorList[ActorList.length] = BroadcastHandler; + } + } + + if (BaseMutator != None) + { + BaseMutator.GetSeamlessTravelActorList(bToEntry, ActorList); + } + + if (MyAutoTestManager != None) + { + ActorList[ActorList.length] = MyAutoTestManager; + } + + // Keep the AccessControl persistent, as it needs to >always< be ready for handling auth callbacks + if (AccessControl != none) + { + ActorList[ActorList.Length] = AccessControl; + } +} + +/** used to swap a viewport/connection's PlayerControllers when seamless travelling and the new gametype's + * controller class is different than the previous + * includes network handling + * @param OldPC - the old PC that should be discarded + * @param NewPC - the new PC that should be used for the player + */ +native final function SwapPlayerControllers(PlayerController OldPC, PlayerController NewPC); + +/** called after a seamless level transition has been completed on the *new* GameInfo + * used to reinitialize players already in the game as they won't have *Login() called on them + */ +event PostSeamlessTravel() +{ + local Controller C; + + // handle players that are already loaded + foreach WorldInfo.AllControllers(class'Controller', C) + { + if (C.bIsPlayer) + { + if (PlayerController(C) == None) + { + HandleSeamlessTravelPlayer(C); + } + else + { + if (!C.PlayerReplicationInfo.bOnlySpectator) + { + NumTravellingPlayers++; + } + if (PlayerController(C).HasClientLoadedCurrentWorld()) + { + HandleSeamlessTravelPlayer(C); + } + } + } + } + + if (bWaitingToStartMatch && !bDelayedStart && NumPlayers + NumBots > 0) + { + StartMatch(); + } + if (WorldInfo.NetMode == NM_DedicatedServer) + { + // Update any online advertised settings + UpdateGameSettings(); + } +} + +/** + * Used to update any changes in game settings that need to be published to + * players that are searching for games + */ +function UpdateGameSettings(); + +/** handles reinitializing players that remained through a seamless level transition + * called from C++ for players that finished loading after the server + * @param C the Controller to handle + */ +event HandleSeamlessTravelPlayer(out Controller C) +{ + local rotator StartRotation; + local NavigationPoint StartSpot; + local PlayerController PC, NewPC; + local PlayerReplicationInfo OldPRI; + + `log(">> GameInfo::HandleSeamlessTravelPlayer:" @ C,,'SeamlessTravel'); + + PC = PlayerController(C); + if (PC != None && PC.Class != PlayerControllerClass) + { + if (PC.Player != None) + { + // we need to spawn a new PlayerController to replace the old one + NewPC = SpawnPlayerController(PC.Location, PC.Rotation); + if (NewPC == None) + { + `Warn("Failed to spawn new PlayerController for" @ PC.GetHumanReadableName() @ "(old class" @ PC.Class $ ")"); + PC.Destroy(); + return; + } + else + { + PC.CleanUpAudioComponents(); + PC.SeamlessTravelTo(NewPC); + NewPC.SeamlessTravelFrom(PC); + SwapPlayerControllers(PC, NewPC); + PC = NewPC; + C = NewPC; + } + } + else + { + PC.Destroy(); + } + } + else + { + // clear out data that was only for the previous game + C.PlayerReplicationInfo.Reset(); + // create a new PRI and copy over info; this is necessary because the old gametype may have used a different PRI class + OldPRI = C.PlayerReplicationInfo; + C.InitPlayerReplicationInfo(); + OldPRI.SeamlessTravelTo(C.PlayerReplicationInfo); + // we don't need the old PRI anymore + //@fixme: need a way to replace PRIs that doesn't cause incorrect "player left the game"/"player entered the game" messages + OldPRI.Destroy(); + } + + // get rid of team if this is not a team game + if (!bTeamGame && C.PlayerReplicationInfo.Team != None) + { + C.PlayerReplicationInfo.Team.Destroy(); + C.PlayerReplicationInfo.Team = None; + } + + // Find a start spot. + StartSpot = FindPlayerStart(C, C.GetTeamNum()); + + if (StartSpot == None) + { + `warn(GameMessageClass.Default.FailedPlaceMessage); + } + else + { + StartRotation.Yaw = StartSpot.Rotation.Yaw; + C.SetLocation(StartSpot.Location); + C.SetRotation(StartRotation); + } + + C.StartSpot = StartSpot; + + if (PC != None) + { + PC.CleanUpAudioComponents(); + + // tell the player controller to register its data stores again + PC.ClientInitializeDataStores(); + + SetSeamlessTravelViewTarget(PC); + if (PC.PlayerReplicationInfo.bOnlySpectator) + { + PC.GotoState('Spectating'); + PC.PlayerReplicationInfo.bIsSpectator = true; + PC.PlayerReplicationInfo.bOutOfLives = true; + NumSpectators++; + } + else + { + NumPlayers++; + NumTravellingPlayers--; + PC.GotoState('PlayerWaiting'); + } + + + } + else + { + NumBots++; + C.GotoState('RoundEnded'); + } + + GenericPlayerInitialization(C); + + `log("<< GameInfo::HandleSeamlessTravelPlayer:" @ C,,'SeamlessTravel'); +} + +function SetSeamlessTravelViewTarget(PlayerController PC) +{ + PC.SetViewTarget(PC); +} + +/** + * Updates the online subsystem's information for player counts so that + * LAN matches can show the correct player counts + */ +function UpdateGameSettingsCounts() +{ + local OnlineGameSettings GameSettings; + + if (GameInterface != None) + { + GameSettings = GameInterface.GetGameSettings(PlayerReplicationInfoClass.default.SessionName); + if (GameSettings != None && GameSettings.bIsLanMatch) + { + // Update the number of open slots available + GameSettings.NumOpenPublicConnections = GameSettings.NumPublicConnections - GetNumPlayers(); + if (GameSettings.NumOpenPublicConnections < 0) + { + GameSettings.NumOpenPublicConnections = 0; + } + } + } +} + +/** + * This is a base (empty) implementation of the completion notification + * + * @param PC the player controller to mark as done + * @param bWasSuccessful whether the PC was able to register for arbitration or not + */ +function ProcessClientRegistrationCompletion(PlayerController PC,bool bWasSuccessful); + +/** + * Empty implementation of the code that kicks off async registration + */ +function StartArbitrationRegistration(); + +/** + * Empty implementation of the code that starts an arbitrated match + */ +function StartArbitratedMatch(); + +/** + * Empty implementation of the code that registers the server for arbitration + */ +function RegisterServerForArbitration(); + +/** + * Empty implementation of the code that handles the callback for completion + * + * @param SessionName the name of the session this is for + * @param bWasSuccessful whether the call worked or not + */ +function ArbitrationRegistrationComplete(name SessionName,bool bWasSuccessful); + +function bool MatchIsInProgress() +{ + return true; +} + +/** + * This state is used to change the flow of start/end match to handle arbitration + * + * Basic flow of events: + * Server prepares to start the match and tells all clients to register arbitration + * Clients register with arbitration and tell the server when they are done + * Server checks for all clients to be registered and kicks any clients if + * they don't register in time. + * Server registers with arbitration and the match begins + * + * Match ends and the server tells connected clients to write arbitrated stats + * Clients write stats and notifies server of completion + * Server writes stats and ends the match + */ +auto State PendingMatch +{ + function bool MatchIsInProgress() + { + return false; + } + + /** + * Tells all of the currently connected clients to register with arbitration. + * The clients will call back to the server once they have done so, which + * will tell this state to see if it is time for the server to register with + * arbitration. + */ + function StartMatch() + { + if (bUsingArbitration) + { + StartArbitrationRegistration(); + } + else + { + Global.StartMatch(); + } + } + + /** + * Kicks off the async tasks of having the clients register with + * arbitration before the server does. Sets a timeout for when + * all slow to respond clients get kicked + */ + function StartArbitrationRegistration() + { + local PlayerController PC; + local UniqueNetId HostId; + local OnlineGameSettings GameSettings; + + if (!bHasArbitratedHandshakeBegun) + { + // Tell PreLogin() to reject new connections + bHasArbitratedHandshakeBegun = true; + + // Get the host id from the game settings in case splitscreen works with arbitration + GameSettings = GameInterface.GetGameSettings(PlayerReplicationInfoClass.default.SessionName); + HostId = GameSettings.OwningPlayerId; + + PendingArbitrationPCs.Length = 0; + // Iterate the controller list and tell them to register with arbitration + foreach WorldInfo.AllControllers(class'PlayerController', PC) + { + // Skip notifying local PCs as they are handled automatically + if (!PC.IsLocalPlayerController()) + { + PC.ClientSetHostUniqueId(HostId); + PC.ClientRegisterForArbitration(); + // Add to the pending list + PendingArbitrationPCs[PendingArbitrationPCs.Length] = PC; + } + else + { + // Add them as having completed arbitration + ArbitrationPCs[ArbitrationPCs.Length] = PC; + } + } + // Start the kick timer + SetTimer( ArbitrationHandshakeTimeout,false,nameof(ArbitrationTimeout) ); + } + } + + /** + * Does the registration for the server. This must be done last as it + * includes all the players info from their registration + */ + function RegisterServerForArbitration() + { + if (GameInterface != None) + { + GameInterface.AddArbitrationRegistrationCompleteDelegate(ArbitrationRegistrationComplete); + GameInterface.RegisterForArbitration(PlayerReplicationInfoClass.default.SessionName); + } + else + { + // Fake as working without subsystem + ArbitrationRegistrationComplete(PlayerReplicationInfoClass.default.SessionName,true); + } + } + + /** + * Callback from the server that starts the match if the registration was + * successful. If not, it goes back to the menu + * + * @param SessionName the name of the session this is for + * @param bWasSuccessful whether the registration worked or not + */ + function ArbitrationRegistrationComplete(name SessionName,bool bWasSuccessful) + { + // Clear the delegate so we don't leak with GC + GameInterface.ClearArbitrationRegistrationCompleteDelegate(ArbitrationRegistrationComplete); + if (bWasSuccessful) + { + // Start the match + StartArbitratedMatch(); + } + else + { + ConsoleCommand("Disconnect"); + } + } + + /** + * Handles kicking any clients that haven't completed handshaking + */ + function ArbitrationTimeout() + { + local int Index; + + // Kick any pending players + for (Index = 0; Index < PendingArbitrationPCs.Length; Index++) + { +`if(`__TW_) + AccessControl.KickPlayer(PendingArbitrationPCs[Index], ""); +`else + AccessControl.KickPlayer(PendingArbitrationPCs[Index],GameMessageClass.Default.MaxedOutMessage); +`endif + } + PendingArbitrationPCs.Length = 0; + // Do the server registration now that any remaining clients are kicked + RegisterServerForArbitration(); + } + + /** + * Called once arbitration has completed and kicks off the real start of the match + */ + function StartArbitratedMatch() + { + bNeedsEndGameHandshake = true; + // Start the match + Global.StartMatch(); + } + + /** + * Removes the player controller from the pending list. Kicks that PC if it + * failed to register for arbitration. Starts the match if all clients have + * completed their registration + * + * @param PC the player controller to mark as done + * @param bWasSuccessful whether the PC was able to register for arbitration or not + */ + function ProcessClientRegistrationCompletion(PlayerController PC,bool bWasSuccessful) + { + local int FoundIndex; + + // Search for the specified PC and remove if found + FoundIndex = PendingArbitrationPCs.Find(PC); + if (FoundIndex != INDEX_NONE) + { + PendingArbitrationPCs.Remove(FoundIndex,1); + if (bWasSuccessful) + { + // Add to the completed list + ArbitrationPCs[ArbitrationPCs.Length] = PC; + } + else + { +`if(`__TW_) + AccessControl.KickPlayer(PC, ""); +`else + AccessControl.KickPlayer(PC,GameMessageClass.Default.MaxedOutMessage); +`endif + } + } + // Start the match if all clients have responded + if (PendingArbitrationPCs.Length == 0) + { + // Clear the kick timer + SetTimer( 0,false,nameof(ArbitrationTimeout) ); + RegisterServerForArbitration(); + } + } + + event EndState(name NextStateName) + { + // Clear the kick timer + SetTimer( 0,false,nameof(ArbitrationTimeout) ); + + if( GameInterface != None ) + { + GameInterface.ClearArbitrationRegistrationCompleteDelegate(ArbitrationRegistrationComplete); + } + } +} + +/** + * Tells all clients to disconnect and then goes to the menu + */ +function NotifyArbitratedMatchEnd() +{ + local PlayerController PC; + + // Iterate through the controllers telling them to disconnect + foreach WorldInfo.AllControllers(class'PlayerController',PC) + { + if (PC.IsLocalPlayerController() == false) + { + PC.ClientArbitratedMatchEnded(); + } + } + // Iterate through local controllers telling them to disconnect + foreach WorldInfo.AllControllers(class'PlayerController',PC) + { + if (PC.IsLocalPlayerController()) + { + PC.ClientArbitratedMatchEnded(); + } + } +} + +/** + * Used to notify the game type that it is ok to update a player's gameplay + * specific muting information now. The playercontroller needs to notify + * the server when it is possible to do so or the unique net id will be + * incorrect and the muting not work. + * + * @param PC the playercontroller that is ready for updates + */ +function UpdateGameplayMuteList(PlayerController PC) +{ + // Let the server start sending voice packets + PC.bHasVoiceHandshakeCompleted = true; + // And tell the client it can start sending voice packets + PC.ClientVoiceHandshakeComplete(); +} + +/** + * Used by the game type to update the advertised skill for this game + */ +function RecalculateSkillRating() +{ + local int Index; + local array Players; + local UniqueNetId ZeroId; + + if (WorldInfo.NetMode != NM_Standalone && + OnlineSub != None && + OnlineSub.GameInterface != None) + { + // Iterate through the players adding their unique id for skill calculation + for (Index = 0; Index < GameReplicationInfo.PRIArray.Length; Index++) + { + if (ZeroId != GameReplicationInfo.PRIArray[Index].UniqueId) + { + Players[Players.Length] = GameReplicationInfo.PRIArray[Index].UniqueId; + } + } + if (Players.Length > 0) + { + // Update the skill rating with the list of players + OnlineSub.GameInterface.RecalculateSkillRating(PlayerReplicationInfoClass.default.SessionName,Players); + } + }; +} + +/** Called when this PC is in cinematic mode, and its matinee is cancelled by the user. */ +event MatineeCancelled(); + + +/** + * Checks for the login parameters being passed on the command line. If + * present, it does an async login before starting the dedicated server + * registration process + * + * @return true if the login is in progress, false otherwise + */ +function bool ProcessServerLogin() +{ + if (OnlineSub != None) + { + if (OnlineSub.PlayerInterface != None) + { + OnlineSub.PlayerInterface.AddLoginChangeDelegate(OnLoginChange); + OnlineSub.PlayerInterface.AddLoginFailedDelegate(0,OnLoginFailed); + // Check the command line for login information and login async + if (OnlineSub.PlayerInterface.AutoLogin() == false) + { + ClearAutoLoginDelegates(); + return false; + } + return true; + } + } + return false; +} + +/** + * Clears the login delegates once the login process has passed or failed + */ +function ClearAutoLoginDelegates() +{ + if (OnlineSub.PlayerInterface != None) + { + OnlineSub.PlayerInterface.ClearLoginChangeDelegate(OnLoginChange); + OnlineSub.PlayerInterface.ClearLoginFailedDelegate(0,OnLoginFailed); + } +} + +/** + * Called if the autologin fails + * + * @param LocalUserNum the controller number of the associated user + * @param ErrorCode the async error code that occurred + */ +function OnLoginFailed(byte LocalUserNum,EOnlineServerConnectionStatus ErrorCode) +{ + ClearAutoLoginDelegates(); +} + +/** + * Used to tell the game when the autologin has completed + * + * @param LocalUserNum ignored + */ +function OnLoginChange(byte LocalUserNum) +{ + ClearAutoLoginDelegates(); + // The login has completed so start the dedicated server + RegisterServer(); +} + +/** + * Registers the dedicated server with the online service + */ +function RegisterServer() +{ + local OnlineGameSettings GameSettings; + + if (OnlineGameSettingsClass != None && OnlineSub != None && OnlineSub.GameInterface != None) + { + // Create the default settings to get the standard settings to advertise + GameSettings = new OnlineGameSettingsClass; + // Serialize any custom settings from the URL + GameSettings.UpdateFromURL(ServerOptions, self); + + // If 'bIsLanMatch' is set, disable all authentication + if (AccessControl != None && + (WorldInfo.NetMode == NM_DedicatedServer || WorldInfo.NetMode == NM_ListenServer) && GameSettings.bIsLanMatch) + { + `log("Disabling all authentication, due to bIsLanMatch being set to true"); + AccessControl.ClearAuthDelegates(false); + } + + // Register the delegate so we can see when it's done + OnlineSub.GameInterface.AddCreateOnlineGameCompleteDelegate(OnServerCreateComplete); + // Now kick off the async publish + if ( !OnlineSub.GameInterface.CreateOnlineGame(0,PlayerReplicationInfoClass.default.SessionName,GameSettings) ) + { + OnlineSub.GameInterface.ClearCreateOnlineGameCompleteDelegate(OnServerCreateComplete); + } + } + else + { + `Warn("No game settings to register with the online service. Game won't be advertised"); + } +} + +/** + * Notifies us of the game being registered successfully or not + * + * @param SessionName the name of the session that was created + * @param bWasSuccessful flag telling us whether it worked or not + */ +function OnServerCreateComplete(name SessionName,bool bWasSuccessful) +{ + local OnlineGameSettings GameSettings; + + GameInterface.ClearCreateOnlineGameCompleteDelegate(OnServerCreateComplete); + if (bWasSuccessful == false) + { + GameSettings = GameInterface.GetGameSettings(PlayerReplicationInfoClass.default.SessionName); + if (GameSettings != None && GameSettings.bIsLanMatch == false) + { + `Warn("Failed to register game with online service. Registering as a LAN match"); + // Force to be a LAN match + GameSettings.bIsLanMatch = true; + // Register the delegate so we can see when it's done + GameInterface.AddCreateOnlineGameCompleteDelegate(OnServerCreateComplete); + // Now kick off the async publish + if (!GameInterface.CreateOnlineGame(0,SessionName,GameSettings)) + { + GameInterface.ClearCreateOnlineGameCompleteDelegate(OnServerCreateComplete); + } + } + else + { + `Warn("Failed to register game with online service. Game won't be advertised"); + } + } + else + { + // If a game server is started without Steam running, auth code needs late initialization + // (as the auth interface is only setup within CreateOnlineGame when Steam was not started) + if (OnlineSub.Class.Name == 'OnlineSubsystemSteamworks' && AccessControl != none && AccessControl.CachedAuthInt == none) + { + AccessControl.InitAuthHooks(); + + // This delegate was not set until after the auth interface became ready, so kick it off here + AccessControl.OnAuthReady(); + } + + UpdateGameSettings(); + } +} + +/** + * Iterates the player controllers and tells them to return to their party + */ +function TellClientsToReturnToPartyHost() +{ + local PlayerController PC; + local OnlineGameSettings GameSettings; + local UniqueNetId RequestingPlayerId; + + OnlineSub = class'GameEngine'.static.GetOnlineSubsystem(); + if (OnlineSub != None) + { + // And grab one for the game interface since it will be used often + GameInterface = OnlineSub.GameInterface; + if (GameInterface != None) + { + // Use the game session owner as the host requesting travel + GameSettings = GameInterface.GetGameSettings(PlayerReplicationInfoClass.default.SessionName); + if (GameSettings != None) + { + RequestingPlayerId = GameSettings.OwningPlayerId; + } + else + { + // If no valid game session then use local player's net id as the host requesting the travel + foreach LocalPlayerControllers(class'PlayerController',PC) + { + if (PC.IsPrimaryPlayer() && + PC.PlayerReplicationInfo != None) + { + RequestingPlayerId = PC.PlayerReplicationInfo.UniqueId; + break; + } + } + } + // Tell all clients to return using the net id of the host + foreach WorldInfo.AllControllers(class'PlayerController',PC) + { + if (!PC.IsLocalPlayerController() && + PC.IsPrimaryPlayer()) + { + PC.ClientReturnToParty(RequestingPlayerId); + } + } + // Host travels last as this can trigger a disconnect on clients + foreach LocalPlayerControllers(class'PlayerController',PC) + { + if (PC.IsPrimaryPlayer()) + { + PC.ClientReturnToParty(RequestingPlayerId); + break; + } + } + } + } +} + +/** + * Send notification to clients that a party host is about to leave the match + * + * @param PartyHostPlayerId net id of the party host that is leaving + */ +function TellClientsPartyHostIsLeaving(UniqueNetId PartyHostPlayerId) +{ + local PlayerController PC; + + // Tell all clients to return using the net id of the host + foreach WorldInfo.AllControllers(class'PlayerController',PC) + { + if ( PC.IsPrimaryPlayer() ) + { + PC.ClientNotifyPartyHostLeaving(PartyHostPlayerId); + } + } +} + + +/** + * Iterates the player controllers and tells remote players to travel to the specified session + * + * @param SessionName the name of the session to register + * @param SearchClass the search that should be populated with the session + * @param PlatformSpecificInfo the binary data to place in the platform specific areas + */ +function TellClientsToTravelToSession(name SessionName,class SearchClass,byte PlatformSpecificInfo[80]) +{ + local PlayerController PC; + + foreach WorldInfo.AllControllers(class'PlayerController',PC) + { + if ( !PC.IsLocalPlayerController() && PC.IsPrimaryPlayer() ) + { + PC.ClientTravelToSession(SessionName,SearchClass,PlatformSpecificInfo); + } + } +} + +//================================================================= +/** + * AutoTestManager INTERFACE + */ + +/** function to start the world traveling **/ +exec function DoTravelTheWorld() +{ + if ( MyAutoTestManager != None ) + { + GotoState('TravelTheWorld'); + MyAutoTestManager.DoTravelTheWorld(); + } +} + +/** Alters the synthetic bandwidth limit for a running game **/ +exec native function SetBandwidthLimit( float AsyncIOBandwidthLimit ); + +/** This our state which allows us to have delayed actions while traveling the world (e.g. waiting for levels to stream in) **/ +state TravelTheWorld +{ +} + +/** + * @returns true if Automated Performance testing is enabled + */ +function bool IsAutomatedPerfTesting() +{ + return (MyAutoTestManager != None) && MyAutoTestManager.bAutomatedPerfTesting; +} + +/** + * @returns true if checking for fragmentation is enabled + */ +function bool IsCheckingForFragmentation() +{ + return (MyAutoTestManager != None) && MyAutoTestManager.bCheckingForFragmentation; +} + +/** + * @returns true if checking for memory leaks is enabled + */ +function bool IsCheckingForMemLeaks() +{ + return (MyAutoTestManager != None) && MyAutoTestManager.bCheckingForMemLeaks; +} + +/** + * @returns true if doing a sentinel run + */ +function bool IsDoingASentinelRun() +{ + return (MyAutoTestManager != None) && MyAutoTestManager.bDoingASentinelRun; +} + +/** + * @returns true if should auto-continue to next round + */ +function bool ShouldAutoContinueToNextRound() +{ + return (MyAutoTestManager != None) && MyAutoTestManager.bAutoContinueToNextRound; +} + +/** + * Asks AutoTestManager to start a sentinel run if needed + * Must be called by gameinfo subclass - not called in base implementation of GameInfo.StartMatch() + * @returns true if should skip normal startmatch process + */ +function bool CheckForSentinelRun() +{ + return (MyAutoTestManager != None) && MyAutoTestManager.CheckForSentinelRun(); +} + +/** This is for the QA team who don't use UFE nor commandline :-( **/ +exec simulated function BeginBVT( optional coerce string TagDesc ) +{ + if ( MyAutoTestManager == None ) + { + MyAutoTestManager = spawn(AutoTestManagerClass); + } + + MyAutoTestManager.BeginSentinelRun( "BVT", "", TagDesc ); + MyAutoTestManager.SetTimer( 3.0f, TRUE, nameof(MyAutoTestManager.DoTimeBasedSentinelStatGathering) ); +} + + + +/** + * Turns standby detection on/off + * + * @param bIsEnabled true to turn it on, false to disable it + */ +native function EnableStandbyCheatDetection(bool bIsEnabled); + +/** + * Notifies the game code that a standby cheat was detected + * + * @param StandbyType the type of cheat detected + */ +event StandbyCheatDetected(EStandbyType StandbyType); + + +/** + * Used to create a new online session after the previous one has been destroyed after travelling + * + * @param SessionName The name of the game session (not used with Steamworks) + * @param bWasSuccesful Whether or not the session was succesfully destroyed + */ +function OnDestroyOnlineGameComplete(name SessionName, bool bWasSuccessful) +{ + if (!ProcessServerLogin()) + RegisterServer(); + + GameInterface.ClearDestroyOnlineGameCompleteDelegate(OnDestroyOnlineGameComplete); +} + +/** + * Notifies the game code that the engine has finished loading. This + * function will only be called one time only. + */ +event OnEngineHasLoaded(); + +function InitCrowdPopulationManager() +{ + if( PopulationManagerClass != None ) + { + PopulationManager = Spawn(PopulationManagerClass); + } +} + +/** + * Cleans up any online subsystem delegates that are set + */ +function ClearOnlineDelegates(); + + +//@HSL_BEGIN - BWJ - 6-8-16 - Playfab hooks for server. Not using delegates for these because they are one-off and don't have to worry about cleanup +event OnRetreivedPFInternalUserData( const string ForPlayerId, array Keys, array Values ); + +/** returns TRUE if this server was launched by playfab */ +native function bool WasLaunchedByPlayfab(); + +event string GetFriendlyNameForCurrentGameMode(); +//@HSL_END + + +//@HSL_BEGIN - BWJ - 2-16-17 - Hooks for controller change notifications +function NotifyControllerDisconnected(); +function NotifyControllerReconnected(); +//@HSL_END + +`if (`__TW_) +event bool GetRequiresPassword() +{ + return RequiresPassword(); +} +`endif + +defaultproperties +{ + // The game spawns bots/players which can't be done during physics ticking + TickGroup=TG_PreAsyncWork + + GameSpeed=1.0 + bDelayedStart=true + HUDType=class'Engine.HUD' + bWaitingToStartMatch=false + bRestartLevel=True + bPauseable=True + AccessControlClass=class'Engine.AccessControl' + BroadcastHandlerClass=class'Engine.BroadcastHandler' + DeathMessageClass=class'LocalMessage' + PlayerControllerClass=class'Engine.PlayerController' + GameMessageClass=class'GameMessage' + GameReplicationInfoClass=class'GameReplicationInfo' + AutoTestManagerClass=class'Engine.AutoTestManager' + FearCostFalloff=+0.95 + CurrentID=1 + PlayerReplicationInfoClass=Class'Engine.PlayerReplicationInfo' + MaxSpectatorsAllowed=32 + MaxPlayersAllowed=32 + + Components.Remove(Sprite) + + // Defaults for if your game has only one skill leaderboard + LeaderboardId=0xFFFE0000 + ArbitratedLeaderboardId=0xFFFF0000 + +// PopulationManagerClass=class'CrowdPopulationManagerBase' + + StreamingPauseIcon=Material'EngineResources.M_StreamingPause' + +`if(`__TW_) + // @note: this could be be done in the config (GameInfoClassAliases is normally config), + // but then we have to mess with ini patching, etc... so just do it here. + GameInfoClassAliases.Add((ShortName="BenchMark", GameClassName="KFGameContent.KFGameInfo_BenchMark")) + GameInfoClassAliases.Add((ShortName="Survival", GameClassName="KFGameContent.KFGameInfo_Survival")) + GameInfoClassAliases.Add((ShortName="Versus", GameClassName="KFGameContent.KFGameInfo_VersusSurvival")) + GameInfoClassAliases.Add((ShortName="Weekly", GameClassName="KFGameContent.KFGameInfo_WeeklySurvival")) + GameInfoClassAliases.Add((ShortName="Tutorial", GameClassName="KFGameContent.KFGameInfo_Tutorial")) + GameInfoClassAliases.Add((ShortName="Endless", GameClassName="KFGameContent.KFGameInfo_Endless")) + GameInfoClassAliases.Add((ShortName="Objective", GameClassName="KFGameContent.KFGameInfo_Objective")) +`endif +//@SABER_EGS_BEGIN Crossplay support + // number of players, using epic online system + NumEosPlayers=0 +//@SABER_EGS_END +} diff --git a/Engine/Classes/GameMessage.uc b/Engine/Classes/GameMessage.uc new file mode 100644 index 0000000..50de3ad --- /dev/null +++ b/Engine/Classes/GameMessage.uc @@ -0,0 +1,119 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class GameMessage extends LocalMessage; + +var localized string SwitchLevelMessage; +var localized string LeftMessage; +var localized string FailedTeamMessage; +var localized string FailedPlaceMessage; +var localized string FailedSpawnMessage; +var localized string EnteredMessage; +var localized string MaxedOutMessage; +var localized string ArbitrationMessage; +var localized string OvertimeMessage; +var localized string GlobalNameChange; +var localized string NewTeamMessage; +var localized string NewTeamMessageTrailer; +var localized string NoNameChange; +var localized string VoteStarted; +var localized string VotePassed; +var localized string MustHaveStats; +var localized string CantBeSpectator; +var localized string CantBePlayer; +var localized string BecameSpectator; + +var localized string NewPlayerMessage; +var localized string KickWarning; +var localized string NewSpecMessage, SpecEnteredMessage; + +// +// Messages common to GameInfo derivatives. +// +static function string GetString( + optional int Switch, + optional bool bPRI1HUD, + optional PlayerReplicationInfo RelatedPRI_1, + optional PlayerReplicationInfo RelatedPRI_2, + optional Object OptionalObject + ) +{ + switch (Switch) + { + case 0: + return Default.OverTimeMessage; + break; + case 1: + // @todo ib2merge: Chair had commented out this entire case and returned "" + if (RelatedPRI_1 == None) + return Default.NewPlayerMessage; + + return RelatedPRI_1.PlayerName$Default.EnteredMessage; + break; + case 2: + if (RelatedPRI_1 == None) + return ""; + + return RelatedPRI_1.OldName@Default.GlobalNameChange@RelatedPRI_1.PlayerName; + break; + case 3: + if (RelatedPRI_1 == None) + return ""; + if (OptionalObject == None) + return ""; + + return RelatedPRI_1.PlayerName@Default.NewTeamMessage@TeamInfo(OptionalObject).GetHumanReadableName()$Default.NewTeamMessageTrailer; + break; + case 4: + if (RelatedPRI_1 == None) + return ""; + + return RelatedPRI_1.PlayerName$Default.LeftMessage; + break; + case 5: + return Default.SwitchLevelMessage; + break; + case 6: + return Default.FailedTeamMessage; + break; + case 7: + return Default.MaxedOutMessage; + break; + case 8: + return Default.NoNameChange; + break; + case 9: + return RelatedPRI_1.PlayerName@Default.VoteStarted; + break; + case 10: + return Default.VotePassed; + break; + case 11: + return Default.MustHaveStats; + break; + case 12: + return Default.CantBeSpectator; + break; + case 13: + return Default.CantBePlayer; + break; + case 14: + return RelatedPRI_1.PlayerName@Default.BecameSpectator; + break; + case 15: + return Default.KickWarning; + break; + case 16: + if (RelatedPRI_1 == None) + return Default.NewSpecMessage; + + return RelatedPRI_1.PlayerName$Default.SpecEnteredMessage; + break; + } + return ""; +} + +defaultproperties +{ + bIsConsoleMessage=true +} diff --git a/Engine/Classes/GamePadLightbarSubsystem.uc b/Engine/Classes/GamePadLightbarSubsystem.uc new file mode 100644 index 0000000..da489fb --- /dev/null +++ b/Engine/Classes/GamePadLightbarSubsystem.uc @@ -0,0 +1,305 @@ +//* =================================================================================== +//* ::Scr GamePadLightbarSubsystem.uc +//* =================================================================================== +/** + * @author Brandon Johnson + * @brief Gamepad light bar used for setting light on gamepad. Currently only supported for orbis +*/ +//* =================================================================================== +//* Created: Jun 07, 2013 01:00PM +//* Modified: Jun 07, 2013 01:00PM +//* Copyright (c) 2013 Zombie, Inc. All Rights Reserved. +//* =================================================================================== +class GamePadLightbarSubsystem extends Object + native + config(LightBar); + +//* =================================================================================== +// VARIABLES +//* =================================================================================== + + +enum LightBarState +{ + ELBS_Standby, + ELBS_Lerping, + ELBS_Pulsing +}; + +/** The current light bar state */ +var LightBarState CurrentLightBarState; + +/** The current color */ +var LinearColor CurrentColor; + +/** The original color used before lerping */ +var LinearColor OriginalColor; + +/** The target color to set */ +var LinearColor TargetColor; + +/** The lerp time remaining */ +var float LerpTimeRemaining; + +/** The total time required for lerp/pulse */ +var float TotalLerpTime; + +/** The default color to display (blue) */ +var() const config Color DefaultColor; + + +struct native ColorDefinition +{ + /** The string ID for the color */ + var init string Id; + /** The R color to use */ + var byte R; + /** The G color to use */ + var byte G; + /** The B color to use */ + var byte B; +}; + +/** The list of color definitions to use */ +var() const config editinline array ColorDefinitions; + + +struct native LerpToInstruction +{ + /** The ID of this lerp instruction */ + var init string Id; + /** The time for this instruction to complete */ + var float Time; + /** The color to lerp to. If empty will be the default color */ + var init string LerpToId; +}; + +/** The list of instructions to lerp to */ +var() const config editinline array LerpToInstructions; + + +struct native SetAndLerpInstruction extends LerpToInstruction +{ + /** The color to set to */ + var init string LerpFromId; +}; + +/** The list of instructions to set to a color and lerp after */ +var() const config editinline array SetAndLerpInstructions; + + +struct native PulseInstruction extends SetAndLerpInstruction +{ +}; + +/** The list of pulse instructions */ +var const config editinline array PulseInstructions; + + +//* =================================================================================== +// FUNCTIONS +//* =================================================================================== + +cpptext +{ + //* =================================================================================== + //* @function Initialize + //* @date Jun 07, 2013 01:24PM + //* @author Brandon Johnson + //* @brief Instantiates and initializes this subsystem + //* =================================================================================== + virtual void Initialize(); + + //* =================================================================================== + //* @function Tick + //* @date Jun 07, 2013 01:04PM + //* @author Brandon Johnson + //* @brief Update function for the light bar + //* @param DeltaTime is the elapsed time + //* =================================================================================== + virtual void Tick( FLOAT DeltaTime ); + + //* =================================================================================== + //* @function UpdateLerp + //* @date Jun 07, 2013 01:57PM + //* @author Brandon Johnson + //* @brief Updates the lerp + //* @param DeltaTime is the elapsed time + //* =================================================================================== + virtual void UpdateLerp( FLOAT DeltaTime ); + + //* =================================================================================== + //* @function UpdatePulse + //* @date Jun 07, 2013 01:57PM + //* @author Brandon Johnson + //* @brief Updates the pulse + //* @param DeltaTime is the elapsed time + //* =================================================================================== + virtual void UpdatePulse( FLOAT DeltaTime ); + + //* =================================================================================== + //* @function SetColor + //* @date Jun 07, 2013 03:31PM + //* @author Brandon Johnson + //* @brief Sets a new linear color + //* @param NewColor is the new linear color to set + //* =================================================================================== + void SetColor( FLinearColor& NewColor ); + + //* =================================================================================== + //* @function SetColor + //* @date Jun 07, 2013 01:18PM + //* @author Brandon Johnson + //* @brief Sets a new color to the pad + //* @param NewColor is the new color to set + //* =================================================================================== + void SetColor( FColor& NewColor ); + + //* =================================================================================== + //* @function GetColorFromId + //* @date Jun 10, 2013 11:08AM + //* @author Brandon Johnson + //* @brief Retrieves a color from a color ID found in config + //* @param TheColorId is the string Id of the color + //* @out Color is the result color. Set to default if not found. + //* @return TRUE on success + //* =================================================================================== + UBOOL GetColorFromId( const FString& TheColorId, FColor& Color ); + + //* =================================================================================== + //* @function GetLerpInstructionFromId + //* @date Jun 10, 2013 11:11AM + //* @author Brandon Johnson + //* @brief Retrieves a lerp instruction from an ID + //* @param InstructionId is the string Id of the instruction + //* @out Instruction is the result instruction + //* @return TRUE on success + //* =================================================================================== + UBOOL GetLerpInstructionFromId( const FString& InstructionId, FLerpToInstruction& Instruction ); + + //* =================================================================================== + //* @function GetSetAndLerpInstructionFromId + //* @date Jun 10, 2013 11:14AM + //* @author Brandon Johnson + //* @brief Retrieves a set and lerp instruction from an ID + //* @param InstructionId is the string Id of the instruction + //* @out Instruction is the result instruction + //* @return TRUE on success + //* =================================================================================== + UBOOL GetSetAndLerpInstructionFromId( const FString& InstructionId, FSetAndLerpInstruction& Instruction ); + + //* =================================================================================== + //* @function GetPulseInstructionFromId + //* @date Jun 10, 2013 11:14AM + //* @author Brandon Johnson + //* @brief Retrieves a set and pulse instruction from an ID + //* @param InstructionId is the string Id of the instruction + //* @out Instruction is the result instruction + //* @return TRUE on success + //* =================================================================================== + UBOOL GetPulseInstructionFromId( const FString& InstructionId, FPulseInstruction& Instruction ); +} + +//* =================================================================================== +//* @function SetPadColor +//* @date Jun 07, 2013 01:21PM +//* @author Brandon Johnson +//* @brief Sets the pad to a new color +//* @param NewPadColor is the new pad color +//* =================================================================================== +static native function SetPadColor( Color NewPadColor ); + + +//* =================================================================================== +//* @function SetPadColorFromDef +//* @date Jun 10, 2013 11:01AM +//* @author Brandon Johnson +//* @brief Sets the pad color from a color definition in config +//* @param TheColorId is the color ID to use +//* =================================================================================== +static native function SetPadColorFromDef( string TheColorId ); + + +//* =================================================================================== +//* @function BeginLerp +//* @date Jun 07, 2013 01:22PM +//* @author Brandon Johnson +//* @brief Begins a lerp +//* @param NewLerpColor is the new color to lerp to +//* @param LerpTime is the time for the lerp +//* =================================================================================== +static native function BeginLerp( Color NewLerpColor, float LerpTime ); + + +//* =================================================================================== +//* @function BeginLerpFromDef +//* @date Jun 10, 2013 11:02AM +//* @author Brandon Johnson +//* @brief Begins a lerp from an instruction in config +//* @param InstructionId is the string Id of the instruction +//* =================================================================================== +static native function BeginLerpFromDef( string InstructionId ); + + +//* =================================================================================== +//* @function SetPadColorAndLerp +//* @date Jun 07, 2013 01:26PM +//* @author Brandon Johnson +//* @brief Sets a pad color and begins lerping +//* @param LerpTime is the total time used to lerp +//* @param NewPadColor is the new pad color to set +//* @param NewTargetColor is the new target color to set +//* =================================================================================== +static native function SetPadColorAndLerp( float LerpTime, Color NewPadColor, Color NewTargetColor = default.DefaultColor ); + + +//* =================================================================================== +//* @function SetPadColorAndLerpFromDef +//* @date Jun 10, 2013 11:03AM +//* @author Brandon Johnson +//* @brief Sets the pad color and lerp from instruction Id in config +//* @param InstructionId is the string Id of the instruction +//* =================================================================================== +static native function SetPadColorAndLerpFromDef( string InstructionId ); + + +//* =================================================================================== +//* @function SetPulsing +//* @date Jun 07, 2013 03:49PM +//* @author Brandon Johnson +//* @brief Sets the lighting to pulse. Is reset by calling ResetState +//* @param LerpTime is the total time used to lerp +//* @param Target1 is the first color to lerp to +//* @param Target2 is the second target to lerp to +//* =================================================================================== +static native function SetPulsing( float LerpTime, Color Target1, Color Target2 = default.DefaultColor ); + + +//* =================================================================================== +//* @function SetPulsingFromDef +//* @date Jun 10, 2013 11:06AM +//* @author Brandon Johnson +//* @brief Sets pulsing between 2 colors from an instruction found in config +//* @param InstructionId is the Id of the instruction +//* =================================================================================== +static native function SetPulsingFromDef( string InstructionId ); + + +//* =================================================================================== +//* @function InterruptState +//* @date Jun 07, 2013 01:28PM +//* @author Brandon Johnson +//* @brief Interrupts the current state, whether it be lerping or pulsing and sets to default color +//* =================================================================================== +static native function ResetState(); + + +//* =================================================================================== +// DEFAULT PROPERTIES +//* =================================================================================== +defaultproperties +{ + +} +//EOF + diff --git a/Engine/Classes/GameReplicationInfo.uc b/Engine/Classes/GameReplicationInfo.uc new file mode 100644 index 0000000..dbe6745 --- /dev/null +++ b/Engine/Classes/GameReplicationInfo.uc @@ -0,0 +1,345 @@ +//============================================================================= +// GameReplicationInfo. +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +// +// Every GameInfo creates a GameReplicationInfo, which is always relevant, to replicate +// important game data to clients (as the GameInfo is not replicated). +//============================================================================= +class GameReplicationInfo extends ReplicationInfo + config(Game) + native(ReplicationInfo) + nativereplication; + +/** Class of the server's gameinfo, assigned by GameInfo. */ +var repnotify class GameClass; + +/** If true, stop RemainingTime countdown */ +var bool bStopCountDown; + +/** Match is in progress (replicated) */ +var repnotify bool bMatchHasBegun; + +/** Match is over (replicated) */ +var repnotify bool bMatchIsOver; + +//@HSL_BEGIN - JRO - 6/26/2016 - Moving this from KFGameReplicationInfoVersus so it can be used in OnlineSubsystem +/** Indicates that we are in the post-round waiting period */ +var repnotify bool bRoundIsOver; +//@HSL_END + +//@HSL_BEGIN - JRO - 6/15/2016 - Make sure we're still at full speed before the end of game menu shows up +/** Match is almost over, but not quite */ +var bool bWaitingForAAR; +//@HSL_END + +/** Used for counting down time in time limited games */ +var int RemainingTime, ElapsedTime, RemainingMinute; + +/** Replicates scoring goal for this match */ +var int GoalScore; + +/** Replicates time limit for this match */ +var int TimeLimit; + +/** Replicated list of teams participating in this match */ +var array Teams; + +/** Name of the server, i.e.: Bob's Server. */ +var() globalconfig string ServerName; + +/** Match winner. Set by gameinfo when game ends */ +var Actor Winner; + +/** Array of all PlayerReplicationInfos, maintained on both server and clients (PRIs are always relevant) */ +var array PRIArray; + +/** This list mirrors the GameInfo's list of inactive PRI objects */ +var array InactivePRIArray; + +`if(`__TW_) +/** Set when the exit cue of the current music track is hit */ +var bool bPendingMusicTrackChange; +`endif + +cpptext +{ + // AActor interface. + INT* GetOptimizedRepList( BYTE* InDefault, FPropertyRetirement* Retire, INT* Ptr, UPackageMap* Map, UActorChannel* Channel ); + + /** + * Builds a list of components that are hidden for scene capture + * + * @param HiddenComponents the list to add to/remove from + */ + virtual void UpdateHiddenComponentsForSceneCapture(TSet& HiddenComponents) {} + + /** + * Helper to return the default object of the GameInfo class corresponding to this GRI + */ + AGameInfo *GetDefaultGameInfo(); + +#if __TW_ + virtual UBOOL IsUnrankedGame() { return true; } + virtual FString GetGameBalanceCol1() { return TEXT(",,"); } + virtual int GetWaveNum() { return -1; } + virtual int GetWaveMax() { return -1; } + virtual UBOOL GetWon() { return false; } +#endif +} + +replication +{ + if ( bNetDirty ) + bStopCountDown, Winner, bMatchHasBegun, bMatchIsOver, bRoundIsOver; + + if ( !bNetInitial && bNetDirty ) + RemainingMinute; + + if ( bNetInitial ) + GameClass, RemainingTime, ElapsedTime, GoalScore, TimeLimit, ServerName; +} + + +simulated event PostBeginPlay() +{ + local PlayerReplicationInfo PRI; + local TeamInfo TI; + + if( WorldInfo.NetMode == NM_Client ) + { + // clear variables so we don't display our own values if the server has them left blank + ServerName = ""; + } + + SetTimer(WorldInfo.TimeDilation, true); + + WorldInfo.GRI = self; + + ForEach DynamicActors(class'PlayerReplicationInfo',PRI) + { + AddPRI(PRI); + } + foreach DynamicActors(class'TeamInfo', TI) + { + if (TI.TeamIndex >= 0) + { + SetTeam(TI.TeamIndex, TI); + } + } +} + +simulated event ReplicatedEvent(name VarName) +{ + if ( VarName == 'bMatchHasBegun' ) + { + if (bMatchHasBegun) + { + WorldInfo.NotifyMatchStarted(); + // @todo ib2merge - Chair added this - we could add a boolean to call this or not, set it to true in SwordGRI + // StartMatch(); + } + } + else if ( VarName == 'bMatchIsOver' ) + { + if ( bMatchIsOver ) + { + EndGame(); + } + } + else if ( VarName == 'GameClass' ) + { + ReceivedGameClass(); + } + else + { + Super.ReplicatedEvent(VarName); + } +} + + +/** Called when the GameClass property is set (at startup for the server, after the variable has been replicated on clients) */ +simulated function ReceivedGameClass() +{ + local PlayerController PC; + // Tell each PlayerController that the Game class is here + foreach LocalPlayerControllers(class'PlayerController',PC) + { + PC.ReceivedGameClass(GameClass); + } +} + +/* Reset() +reset actor to initial state - used when restarting level without reloading. +*/ +function Reset() +{ + Super.Reset(); + Winner = None; +} + +simulated event Timer() +{ + if ( (WorldInfo.Game == None) || WorldInfo.Game.MatchIsInProgress() ) + { + ElapsedTime++; + } + if ( WorldInfo.NetMode == NM_Client ) + { + // sync remaining time with server once a minute + if ( RemainingMinute != 0 ) + { + RemainingTime = RemainingMinute; + RemainingMinute = 0; + } + } + if ( (RemainingTime > 0) && !bStopCountDown ) + { + RemainingTime--; + if ( WorldInfo.NetMode != NM_Client ) + { + if ( RemainingTime % 60 == 0 ) + { + RemainingMinute = RemainingTime; + } + } + } + + SetTimer(WorldInfo.TimeDilation, true); +} + +/** + * Checks to see if two actors are on the same team. + * + * @return true if they are, false if they aren't + */ +simulated native function bool OnSameTeam(Actor A, Actor B); + + +simulated function AddPRI(PlayerReplicationInfo PRI) +{ + local int i; + + // Determine whether it should go in the active or inactive list + if (!PRI.bIsInactive) + { + // make sure no duplicates + for (i=0; i= 0 ) + { + Teams[Index] = TI; + } +} + +/** + * Called on the server when the match has begin + * + * Network - Server and Client (Via ReplicatedEvent) + */ + +simulated function StartMatch() +{ + bMatchHasBegun = true; +} + +/** + * Called on the server when the match is over + * + * Network - Server and Client (Via ReplicatedEvent) + */ + +simulated function EndGame() +{ + bMatchIsOver = true; +} + +/** Is the current gametype a multiplayer game? */ +simulated function bool IsMultiplayerGame() +{ + return (WorldInfo.NetMode != NM_Standalone); +} + +/** Is the current gametype a coop multiplayer game? */ +simulated function bool IsCoopMultiplayerGame() +{ + return FALSE; +} + +/** Should players show gore? */ +simulated event bool ShouldShowGore() +{ + return TRUE; +} + + +//@HSL_BEGIN - BWJ - 6-8-16 - Playfab hooks for server +simulated event PlayerReplicationInfo GetPRIByPlayfabId( const string InPlayfabPlayerId ) +{ + local int i; + + if( InPlayfabPlayerId != "" ) + { + for( i = 0; i < PRIArray.Length; i++ ) + { + if( PRIArray[i].PlayfabPlayerId == InPlayfabPlayerId ) + { + return PRIArray[i]; + } + } + } + + return none; +} +//@HSL_END + +//@HSL_BEGIN - AGM - 7-16-15 - Support for checking for valid stats session +simulated event bool IsStatsSessionValid(); +//@HSL_END + +defaultproperties +{ + TickGroup=TG_DuringAsyncWork + + bStopCountDown=true + RemoteRole=ROLE_SimulatedProxy + bAlwaysRelevant=True +} diff --git a/Engine/Classes/GameStats.uci b/Engine/Classes/GameStats.uci new file mode 100644 index 0000000..3536f72 --- /dev/null +++ b/Engine/Classes/GameStats.uci @@ -0,0 +1,202 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +// Global gameplay stat defines + +`if(`isdefined(INCLUDE_GAME_STATS)) + + /************************************* + GAME EVENTS + *************************************/ + /** Match has started */ + const GAMEEVENT_MATCH_STARTED = 0; + /** Match has ended */ + const GAMEEVENT_MATCH_ENDED = 1; + /** Round has started */ + const GAMEEVENT_ROUND_STARTED = 2; + /** Round has ended */ + const GAMEEVENT_ROUND_ENDED = 3; + /** Game type defined */ + const GAMEEVENT_GAME_CLASS = 6; + /** Game options defined */ + const GAMEEVENT_GAME_OPTION_URL = 7; + /** Map name defined */ + const GAMEEVENT_GAME_MAPNAME = 8; + + /************************************* + SYSTEM STATS + *************************************/ + /** Memory usage */ + const GAMEEVENT_MEMORYUSAGE_POLL = 35; + /** Frame rate */ + const GAMEEVENT_FRAMERATE_POLL = 36; + /** Network usage in */ + const GAMEEVENT_NETWORKUSAGEIN_POLL = 37; + /** Network usage out */ + const GAMEEVENT_NETWORKUSAGEOUT_POLL = 38; + /** Ping */ + const GAMEEVENT_PING_POLL = 39; + /** Render thread time */ + const GAMEEVENT_RENDERTHREAD_POLL = 40; + /** Game thread time */ + const GAMEEVENT_GAMETHREAD_POLL = 41; + /** GPU frame time */ + const GAMEEVENT_GPUFRAMETIME_POLL = 42; + /** Total frame time */ + const GAMEEVENT_FRAMETIME_POLL = 43; + + /************************************* + TEAM EVENTS + *************************************/ + /** Team created */ + const GAMEEVENT_TEAM_CREATED = 50; + /** Team score recorded */ + const GAMEEVENT_TEAM_GAME_SCORE = 51; + /** Match has been won */ + const GAMEEVENT_TEAM_MATCH_WON = 4; + /** Round has been won */ + const GAMEEVENT_TEAM_ROUND_WON = 5; + /** Round stalemate */ + const GAMEEVENT_TEAM_ROUND_STALEMATE = 52; + + /************************************* + PLAYER EVENTS + *************************************/ + /** Player logged in */ + const GAMEEVENT_PLAYER_LOGIN = 100; + /** Player logged out */ + const GAMEEVENT_PLAYER_LOGOUT = 101; + /** Player has just spawned in */ + const GAMEEVENT_PLAYER_SPAWN = 102; + /** Player on winning team */ + const GAMEEVENT_PLAYER_MATCH_WON = 103; + /** Player killed another player */ + const GAMEEVENT_PLAYER_KILL = 104; + /** Player location poll */ + const GAMEEVENT_PLAYER_LOCATION_POLL = 105; + /** Player has changed teams */ + const GAMEEVENT_PLAYER_TEAMCHANGE = 106; + /** Kill streak recorded */ + const GAMEEVENT_PLAYER_KILL_STREAK = 107; + /** Player died */ + const GAMEEVENT_PLAYER_DEATH = 108; + /** Player winning round */ + const GAMEEVENT_PLAYER_ROUND_WON = 109; + /** Player stalemate round */ + const GAMEEVENT_PLAYER_ROUND_STALEMATE = 110; + + /** Weapon damage has occurred */ + const GAMEEVENT_WEAPON_DAMAGE = 150; + /** Weapon melee damage has occurred */ + const GAMEEVENT_WEAPON_DAMAGE_MELEE = 151; + /** Weapon has been fired */ + const GAMEEVENT_WEAPON_FIRED = 152; + + /** Kill types (add others to derived class) */ + const GAMEEVENT_PLAYER_KILL_NORMAL = 200; + + /** generic param list event range (300-400) */ + const GAMEEVENT_GENERIC_PARAM_LIST_START = 300; + const GAMEEVENT_GENERIC_PARAM_LIST_END = 400; + + /** Game specific starts here */ + const GAMEEVENT_GAME_SPECIFIC = 1000; + + /** Only 16 bits of events are possible */ + const GAMEEVENT_MAX_EVENTID = 0x0000FFFF; +`endif + + +// these are defines so that we don't have to recompile every time one of these is added +`define GAMEEVENT_AI_PATH_FAILURE 302 +`define GAMEEVENT_AI_FIRELINK 305 + +// mirror the EGameplayEventType enum in GameplayEventsUtilities.h +`define GET_GameString 0 +`define GET_GameInt 1 +`define GET_TeamInt 2 +`define GET_PlayerInt 3 +`define GET_PlayerFloat 4 +`define GET_PlayerString 5 +`define GET_PlayerSpawn 6 +`define GET_PlayerLogin 7 +`define GET_PlayerLocationPoll 8 +`define GET_PlayerKillDeath 9 +`define GET_PlayerPlayer 10 +`define GET_WeaponInt 11 +`define GET_DamageInt 12 +`define GET_ProjectileInt 13 +`define GET_GenericParamList 14 +`define GET_GameFloat 15 +`define GET_TeamString 16 +`define GET_TeamFloat 17 +`define GET_GamePosition 18 +`define GET_GameAggregate 19 +`define GET_TeamAggregate 20 +`define GET_PlayerAggregate 21 +`define GET_WeaponAggregate 22 +`define GET_DamageAggregate 23 +`define GET_ProjectileAggregate 24 +`define GET_PawnAggregate 25 +`define GET_GameType 1000 // Game Specific Values start after this + + +// Change this or predefine it to your class type +`if(`notdefined(StatsClass)) + `define StatsClass class'GameplayEventsWriterBase' +`endif + +`define StatId(Id) `StatsClass.const.GAMEEVENT_`Id +`define TeamStatId(Id) `StatsClass.const.GAMEEVENT_TEAM_`Id +`define PlayerStatId(Id) `StatsClass.const.GAMEEVENT_PLAYER_`Id +`define KillStatType(Type) `StatsClass.const.GAMEEVENT_PLAYER_KILL_`Type + +`if(`notdefined(StatsContext)) + + `if(`isdefined(GAMEINFO)) + `define StatsContext GameplayEventsWriter + `define ValidStatsContext GameplayEventsWriter != None && GameplayEventsWriter.IsSessionInProgress() + `else + `define StatsContext WorldInfo.Game.GameplayEventsWriter + `define ValidStatsContext WorldInfo.Game != None && WorldInfo.Game.GameplayEventsWriter != None && WorldInfo.Game.GameplayEventsWriter.IsSessionInProgress() + `endif + +`endif + +// Macros for recording stats +`define RecordLoginChange(Id,Player,PlayerName,PlayerId,bSplitScreen) if(`ValidStatsContext){`StatsContext.LogPlayerLoginChange(`PlayerStatId(`Id),`Player,`PlayerName,`PlayerId,`bSplitScreen);} + +// Game stats +`define RecordGameIntStat(Id,Value) if(`ValidStatsContext){`StatsContext.LogGameIntEvent(`StatId(`Id),`Value);} +`define RecordGameStringStat(Id,Value) if(`ValidStatsContext){`StatsContext.LogGameStringEvent(`StatId(`Id),`Value);} +`define RecordGameFloatStat(Id,Value) if(`ValidStatsContext){`StatsContext.LogGameFloatEvent(`StatId(`Id),`Value);} +`define RecordGamePositionStat(Id,Position,Value) if(`ValidStatsContext){`StatsContext.LogGamePositionEvent(`StatId(`Id),`Position,`Value);} + +// Team stats +`define RecordTeamStringStat(Id, TeamInfo, Value) if(`ValidStatsContext){`StatsContext.LogTeamStringEvent(`TeamStatId(`Id),`TeamInfo,`Value);} +`define RecordTeamIntStat(Id, TeamInfo, Value) if(`ValidStatsContext){`StatsContext.LogTeamIntEvent(`TeamStatId(`Id),`TeamInfo,`Value);} +`define RecordTeamFloatStat(Id, TeamInfo, Value) if(`ValidStatsContext){`StatsContext.LogTeamFloatEvent(`TeamStatId(`Id),`TeamInfo,`Value);} + +// Player stats +`define RecordPlayerIntStat(Id,Player,Value) if(`ValidStatsContext){`StatsContext.LogPlayerIntEvent(`PlayerStatId(`Id),`Player,`Value);} +`define RecordPlayerIntStatRaw(Id,Player,Value) if(`ValidStatsContext){`StatsContext.LogPlayerIntEvent(`Id,`Player,`Value);} +`define RecordPlayerFloatStat(Id,Player,Value) if(`ValidStatsContext){`StatsContext.LogPlayerFloatEvent(`PlayerStatId(`Id),`Player,`Value);} +`define RecordPlayerSpawn(Player,PawnClass,Team) if(`ValidStatsContext){`StatsContext.LogPlayerSpawnEvent(`PlayerStatId(SPAWN),`Player,`PawnClass,`Team);} +`define RecordPlayerPlayerEvent(Id,Player,Target) if(`ValidStatsContext){`StatsContext.LogPlayerPlayerEvent(`PlayerStatId(`Id),`Player,`Target);} + +// Weapon stats +`define RecordKillEvent(KillType,Killer,DamageType,Dead) if(`ValidStatsContext){`StatsContext.LogPlayerKillDeath(`PlayerStatId(KILL),`KillStatType(`KillType),`Killer,`DamageType,`Dead);} +`define RecordDeathEvent(KillType,Killer,DamageType,Dead) if(`ValidStatsContext){`StatsContext.LogPlayerKillDeath(`PlayerStatId(DEATH),`KillStatType(`KillType),`Dead,`DamageType,`Killer);} + +`define RecordWeaponIntStat(Id,Player,Weapon,Value) if(`ValidStatsContext){`StatsContext.LogWeaponIntEvent(`StatId(`Id),`Player,`Weapon,`Value);} + +`define RecordProjectileIntStat(Id,Player,Proj,Value) if(`ValidStatsContext){`StatsContext.LogProjectileIntEvent(`StatId(`Id),`Player,`Proj,`Value);} + +`define RecordDamage(Id,Player,Damage,Target,Amount) if(`ValidStatsContext){`StatsContext.LogDamageEvent(`StatId(`Id),`Player,`Damage,`Target,`Amount);} + +`if(`notdefined(FINAL_RELEASE)) +`define RecordAIPathFailEvent(Bot,Reason,Dest) if(`ValidStatsContext){`StatsContext.RecordAIPathFail(`Bot,`Reason,`Dest);} +`else +`define RecordAIPathFailEvent(Bot,Reason,Dest) +`endif \ No newline at end of file diff --git a/Engine/Classes/GameUISceneClient.uc b/Engine/Classes/GameUISceneClient.uc new file mode 100644 index 0000000..b74292b --- /dev/null +++ b/Engine/Classes/GameUISceneClient.uc @@ -0,0 +1,328 @@ +/** + * UISceneClient used when playing a game. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class GameUISceneClient extends UISceneClient + within UIInteraction + native(UIPrivate) + config(UI); + +/** Cached DeltaTime value from the last Tick() call */ +var const transient float LatestDeltaTime; + +/** The time (in seconds) that the last "key down" event was recieved from a key that can trigger double-click events */ +var const transient double DoubleClickStartTime; + +/** + * The location of the mouse the last time a key press was received. Used to determine when to simulate a double-click + * event. + */ +var const transient IntPoint DoubleClickStartPosition; + +/** + * map of controllerID to list of keys which were pressed when the UI began processing input + * used to ignore the initial "release" key event from keys which were already pressed when the UI began processing input. + */ +var const transient native Map_Mirror InitialPressedKeys{TMap >}; + +/** + * Indicates that the input processing status of the UI has potentially changed; causes UpdateInputProcessingStatus to be called + * in the next Tick(). + */ +var const transient bool bUpdateInputProcessingStatus; + +/** + * Indicates that the viewport size being used by one or more scenes is out of date; triggers a call to NotifyViewportResized during the + * next tick. + */ +var transient bool bUpdateSceneViewportSizes; + +/** Controls whether debug input commands are accepted */ +var config bool bEnableDebugInput; +/** Controls whether debug information about the scene is rendered */ +var config bool bRenderDebugInfo; + +/** + * Controls whether the UI system should prevent the game from recieving input whenever it's active. For games with + * interactive menus that remain on-screen during gameplay, you'll want to change this value to FALSE. + */ +var const config bool bCaptureUnprocessedInput; + +/** The list of navigation aliases to check input support for */ +var const transient array NavAliases; + +/** The list of axis input keys to check input support for */ +var const transient array AxisInputKeys; + +cpptext +{ + /* ======================================= + FExec interface + ======================================= */ + virtual UBOOL Exec(const TCHAR* Cmd,FOutputDevice& Ar); + + /* ======================================= + UUISceneClient interface + ======================================= */ + /** + * Called when the UI controller receives a CALLBACK_ViewportResized notification. + * + * @param SceneViewport the viewport that was resized + */ + virtual void NotifyViewportResized( FViewport* SceneViewport ); + + /** + * Process an input event which interacts with the in-game scene debugging overlays + * + * @param Key the key that was pressed + * @param Event the type of event received + * + * @return TRUE if the input event was processed; FALSE otherwise. + */ + UBOOL DebugInputKey( FName Key, EInputEvent Event ); + + /** + * Check a key event received by the viewport. + * + * @param Viewport - The viewport which the key event is from. + * @param ControllerId - The controller which the key event is from. + * @param Key - The name of the key which an event occured for. + * @param Event - The type of event which occured. + * @param AmountDepressed - For analog keys, the depression percent. + * @param bGamepad - input came from gamepad (ie xbox controller) + * + * @return True to consume the key event, false to pass it on. + */ + virtual UBOOL InputKey(INT ControllerId,FName Key,EInputEvent Event,FLOAT AmountDepressed=1.f,UBOOL bGamepad=FALSE); + + /** + * Check an axis movement received by the viewport. + * + * @param Viewport - The viewport which the axis movement is from. + * @param ControllerId - The controller which the axis movement is from. + * @param Key - The name of the axis which moved. + * @param Delta - The axis movement delta. + * @param DeltaTime - The time since the last axis update. + * + * @return True to consume the axis movement, false to pass it on. + */ + virtual UBOOL InputAxis(INT ControllerId,FName Key,FLOAT Delta,FLOAT DeltaTime, UBOOL bGamepad=FALSE); + + /** + * Check a character input received by the viewport. + * + * @param Viewport - The viewport which the axis movement is from. + * @param ControllerId - The controller which the axis movement is from. + * @param Character - The character. + * + * @return True to consume the character, false to pass it on. + */ + virtual UBOOL InputChar(INT ControllerId,TCHAR Character); + + /* ======================================= + UGameUISceneClient interface + ======================================= */ + + /** + * Resets the time and mouse position values used for simulating double-click events to the current value or invalid values. + */ + void ResetDoubleClickTracking( UBOOL bClearValues ); + + /** + * Checks the current time and mouse position to determine whether a double-click event should be simulated. + */ + UBOOL ShouldSimulateDoubleClick() const; + + /** + * Determines whether the any active scenes process axis input. + * + * @param bProcessAxisInput receives the flags for whether axis input is needed for each player. + */ + virtual void CheckAxisInputSupport( UBOOL* bProcessAxisInput[UCONST_MAX_SUPPORTED_GAMEPADS] ) const; + + /** + * Called once a frame to update the UI's state. + * + * @param DeltaTime - The time since the last frame. + */ + virtual void Tick(FLOAT DeltaTime); + +private: + + #if WITH_GFx + /** + * @return TRUE if the scene meets the conditions defined by the bitmask specified. + */ + UBOOL GFxMovieMatchesFilter( DWORD FilterFlagMask, class FGFxMovie* TestMovie ) const; + #endif //WITH_GFx +public: + /** + * Returns true if there is an unhidden fullscreen UI active + * + * @param Flags modifies the logic which determines whether the UI is active + * + * @return TRUE if the UI is currently active + */ + virtual UBOOL IsUIActive( DWORD Flags=SCENEFILTER_Any ) const; + +protected: + + /** + * Updates the value of UIInteraction.bProcessingInput to reflect whether any scenes are capable of processing input. + */ + void UpdateInputProcessingStatus(); + + /** + * Clears the arrays of pressed keys for all local players in the game; used when the UI begins processing input. Also + * updates the InitialPressedKeys maps for all players. + */ + void FlushPlayerInput(); + +public: + /** + * Ensures that the game's paused state is appropriate considering the state of the UI. If any scenes are active which require + * the game to be paused, pauses the game...otherwise, unpauses the game. + * + * @param PlayerIndex the index of the player that owns the scene that was just added or removed, or 0 if the scene didn't have + * a player owner. + */ + virtual void UpdatePausedState( INT PlayerIndex ); +} + +/* == Delegates == */ + +/* == Natives == */ +/** + * @return the current netmode, or NM_MAX if there is no valid world + */ +native static final function WorldInfo.ENetMode GetCurrentNetMode(); + +/** + * Triggers a call to UpdateInputProcessingStatus on the next Tick(). + */ +native final function RequestInputProcessingUpdate(); + +/** + * Callback which allows the UI to prevent unpausing if scenes which require pausing are still active. + * @see PlayerController.SetPause + */ +native final function bool CanUnpauseInternalUI(); + +/* == Events == */ + +/** + * Wrapper for pausing the game. + * + * @param bDesiredPauseState TRUE indicates that the game should be paused. + * @param PlayerIndex the index [into Engine GamePlayers array] for the player that should be used for pausing the game; can + * affect whether the game is actually paused or not (i.e. if the player is an admin in a multi-player match, + * for example). + */ +event PauseGame( bool bDesiredPauseState, optional int PlayerIndex=0 ) +{ + local PlayerController PlayerOwner; + + if ( GamePlayers.Length > 0 ) + { + PlayerIndex = Clamp(PlayerIndex, 0, GamePlayers.Length - 1); + PlayerOwner = GamePlayers[PlayerIndex].Actor; + if ( PlayerOwner != None ) + { + PlayerOwner.SetPause(bDesiredPauseState, CanUnpauseInternalUI); + } + } +} + +/** + * Called when the local player is about to travel to a new URL. This callback should be used to perform any preparation + * tasks, such as updating status text and such. All cleanup should be done from NotifyGameSessionEnded, as that function + * will be called in some cases where NotifyClientTravel is not. + * + * @param TravellingPlayer the player that received the call to ClientTravel + * @param TravelURL a string containing the mapname (or IP address) to travel to, along with option key/value pairs + * @param TravelType indicates whether the player will clear previously added URL options or not. + * @param bIsSeamlessTravel indicates whether seamless travelling will be used. + */ +function NotifyClientTravel( PlayerController TravellingPlayer, string TravelURL, ETravelType TravelType, bool bIsSeamlessTravel ); + +/** + * Called when the current map is being unloaded. Cleans up any references which would prevent garbage collection. + */ +function NotifyGameSessionEnded(); + +/** + * Called when a new player has been added to the list of active players (i.e. split-screen join) + * + * @param PlayerIndex the index [into the GamePlayers array] where the player was inserted + * @param AddedPlayer the player that was added + */ +function NotifyPlayerAdded( int PlayerIndex, LocalPlayer AddedPlayer ) +{ + if ( IsUIActive(SCENEFILTER_InputProcessorOnly) ) + { + RequestInputProcessingUpdate(); + } +} + +/** + * Called when a player has been removed from the list of active players (i.e. split-screen players) + * + * @param PlayerIndex the index [into the GamePlayers array] where the player was located + * @param RemovedPlayer the player that was removed + */ +function NotifyPlayerRemoved( int PlayerIndex, LocalPlayer RemovedPlayer ) +{ + if ( IsUIActive(SCENEFILTER_InputProcessorOnly) ) + { + RequestInputProcessingUpdate(); + } +} + +/** + * Helper function to deduce the PlayerIndex of a Player + * + * @param P - The LocalPlayer for whom you wish to deduce their PlayerIndex + * + * @return Returns the index into the GamePlayers array that references this Player. If it cannot find the player, it returns 0. + */ +function int FindLocalPlayerIndex(Player P) +{ + local Engine Engine; + local int i; + + Engine = class'Engine'.static.GetEngine(); + for (i = 0; i < Engine.GamePlayers.length; i++) + { + if (Engine.GamePlayers[i] == P) + { + return i; + } + } + return 0; +} + +DefaultProperties +{ + NavAliases(0)="UIKEY_NavFocusUp" + NavAliases(1)="UIKEY_NavFocusDown" + NavAliases(2)="UIKEY_NavFocusLeft" + NavAliases(3)="UIKEY_NavFocusRight" + + AxisInputKeys(0)="KEY_Gamepad_LeftStick_Up" + AxisInputKeys(1)="KEY_Gamepad_LeftStick_Down" + AxisInputKeys(2)="KEY_Gamepad_LeftStick_Right" + AxisInputKeys(3)="KEY_Gamepad_LeftStick_Left" + AxisInputKeys(4)="KEY_Gamepad_RightStick_Up" + AxisInputKeys(5)="KEY_Gamepad_RightStick_Down" + AxisInputKeys(6)="KEY_Gamepad_RightStick_Right" + AxisInputKeys(7)="KEY_Gamepad_RightStick_Left" + AxisInputKeys(8)="KEY_SIXAXIS_AccelX" + AxisInputKeys(9)="KEY_SIXAXIS_AccelY" + AxisInputKeys(10)="KEY_SIXAXIS_AccelZ" + AxisInputKeys(11)="KEY_SIXAXIS_Gyro" + AxisInputKeys(12)="KEY_XboxTypeS_LeftX" + AxisInputKeys(13)="KEY_XboxTypeS_LeftY" + AxisInputKeys(14)="KEY_XboxTypeS_RightX" + AxisInputKeys(15)="KEY_XboxTypeS_RightY" +} diff --git a/Engine/Classes/GameViewportClient.uc b/Engine/Classes/GameViewportClient.uc new file mode 100644 index 0000000..5ad7a39 --- /dev/null +++ b/Engine/Classes/GameViewportClient.uc @@ -0,0 +1,1669 @@ +/** + * A game viewport (FViewport) is a high-level abstract interface for the + * platform specific rendering, audio, and input subsystems. + * GameViewportClient is the engine's interface to a game viewport. + * Exactly one GameViewportClient is created for each instance of the game. The + * only case (so far) where you might have a single instance of Engine, but + * multiple instances of the game (and thus multiple GameViewportClients) is when + * you have more than one PIE window running. + * + * Responsibilities: + * propagating input events to the global interactions list + * + * + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class GameViewportClient extends ScriptViewportClient + within Engine + transient + native + Inherits(FExec) + config(Engine) +; + +/** The platform-specific viewport which this viewport client is attached to. */ +var const pointer Viewport{FViewport}; + +/** The platform-specific viewport frame which this viewport is contained by. */ +var const pointer ViewportFrame{FViewportFrame}; + +/** A list of interactions which have a chance at all input before the player's interactions. */ +var init protected array GlobalInteractions; + +/** The class for the UI controller */ +var class UIControllerClass; + +/** The viewport's UI controller */ +var UIInteraction UIController; + +/** The viewport's console. Might be null on consoles */ +var Console ViewportConsole; + +/** This struct needs to be the same size as EShowFlags */ +struct native ShowFlags_Mirror +{ + var native const qword flags0; + var native const qword flags1; +}; + +/** This empty struct is here so we have a non-native struct that can be exported to the header properly */ +struct {EShowFlags} ExportShowFlags_Mirror extends ShowFlags_Mirror {}; + +/** The show flags used by the viewport's players. */ +var const ExportShowFlags_Mirror ShowFlags; + +/** @name Localized transition messages. */ +//@{ +var localized string LoadingMessage; +var localized string SavingMessage; +var localized string ConnectingMessage; +var localized string PausedMessage; +var localized string PrecachingMessage; +//@} + +/** if TRUE then the title safe border is drawn */ +var bool bShowTitleSafeZone; +/** Max/Recommended screen viewable extents as a percentage */ +struct native TitleSafeZoneArea +{ + var float MaxPercentX; + var float MaxPercentY; + var float RecommendedPercentX; + var float RecommendedPercentY; +}; +/** border of safe area */ +var TitleSafeZoneArea TitleSafeZone; + +//If true, this will cause the hardware mouse cursor to render +var transient bool bDisplayHardwareMouseCursor; + +var transient bool bOverrideDiffuseAndSpecular; + +/** If TRUE, this viewport is a play in editor viewport */ +var transient bool bIsPlayInEditorViewport; + +/** If TRUE, we will show the OS mouse cursor at all times (only applies to PIE viewports)*/ +var transient bool bShowSystemMouseCursor; + +/** + * Enum of the different splitscreen types + */ +enum ESplitScreenType +{ + eSST_NONE, // No split + eSST_2P_HORIZONTAL, // 2 player horizontal split + eSST_2P_VERTICAL, // 2 player vertical split + eSST_3P_FAVOR_TOP, // 3 Player split with 1 player on top and 2 on bottom + eSST_3P_FAVOR_BOTTOM, // 3 Player split with 1 player on bottom and 2 on top + eSST_4P, // 4 Player split +}; + +/** + * The 4 different kinds of safezones + */ +enum ESafeZoneType +{ + eSZ_TOP, + eSZ_BOTTOM, + eSZ_LEFT, + eSZ_RIGHT, +}; + +/** + * Specifies whether a setting should be toggled, enabled or disabled. + */ +enum ESetMode +{ + SetMode_Toggle, + SetMode_Enable, + SetMode_Disable, +}; + +/** + * Structure to store splitscreen data. + */ +struct native PerPlayerSplitscreenData +{ + var float SizeX; + var float SizeY; + var float OriginX; + var float OriginY; +}; + +/** + * Structure containing all the player splitscreen datas per splitscreen configuration. + */ +struct native SplitscreenData +{ + var array PlayerData; +}; + +/** Array of the screen data needed for all the different splitscreen configurations */ +var array SplitscreenInfo; + +/** + * The splitscreen layout type that the player wishes to use; this value usually comes from places like the player's profile + */ +var protected{protected} ESplitScreenType DesiredSplitscreenType; + +/** + * The splitscreen type that is actually being used; takes into account the number of players and other factors (such as cinematic mode) + * that could affect the splitscreen mode that is actually used. + */ +var protected{protected} ESplitscreenType ActiveSplitscreenType; + +/** Defaults for intances where there are multiple configs for a certain number of players */ +var const ESplitScreenType Default2PSplitType; +var const ESplitScreenType Default3PSplitType; + +/** Set to disable world rendering */ +var bool bDisableWorldRendering; + +/** Set to capture the world rendering into an offscreen target */ +var bool bCapturedWorldRendering; + +// Progress Indicator - used by the engine to provide status messages (see SetProgressMessage()) +var string ProgressMessage[2]; +var float ProgressTimeOut; +var float ProgressFadeTime; + +/** debug property display functionality + * to interact with this, use "display", "displayall", "displayclear" + */ +struct native DebugDisplayProperty +{ + /** the object whose property to display. If this is a class, all objects of that class are drawn. */ + var Object Obj; + /** name of the property to display */ + var name PropertyName; + /** whether PropertyName is a "special" value not directly mapping to a real property (e.g. state name) */ + var bool bSpecialProperty; +}; +var array DebugProperties; + +/** Stores the pointer to any data needed for scaleform (if defined)*/ +var native const pointer ScaleformInteraction { UGFxInteraction }; + +/** DEBUG: If TRUE, the GFx UI will NOT be rendered at runtime. Note that to REMOVE GFx functionality permanently, you should compile with WITH_GFx set to 0. This bool is for debugging only. */ +var config bool bDebugNoGFxUI; + +//@HSL_BEGIN - BWJ - Dingo controller support +/** TRUE if input is allowed from multiple controllers */ +var bool bAllowInputFromMultipleControllers; + +/** TRUE if we need to pair a new gamepad due a controller disconnect */ +var bool bNeedsNewGamepadPairingForControllerDisconnect; + +/** TRUE if we need to pair a new gamepad because of a new profile taking over. We aren't sure which gamepad to use */ +var bool bNeedsNewGamepadPairingForNewProfile; +//@HSL_END + +cpptext +{ + /** Make sure that the UC mirror struct matches the size of EShowFlags */ + checkAtCompileTime( sizeof(FShowFlags_Mirror) == sizeof(EShowFlags), ShowFlags_Mirror__MustMatchSizeOfEShowFlags ); + + // Constructor. + UGameViewportClient(); + + /** + * Cleans up all rooted or referenced objects created or managed by the GameViewportClient. This method is called + * when this GameViewportClient has been disassociated with the game engine (i.e. is no longer the engine's GameViewport). + */ + virtual void DetachViewportClient(); + + /** + * Called every frame to allow the game viewport to update time based state. + * @param DeltaTime The time since the last call to Tick. + */ + void Tick( FLOAT DeltaTime ); + + // FViewportClient interface. + virtual void RedrawRequested(FViewport* InViewport) {} + + /** + * Routes an input key event received from the viewport to the Interactions array for processing. + * + * @param Viewport the viewport the input event was received from + * @param ControllerId gamepad/controller that generated this input event + * @param Key the name of the key which an event occured for (KEY_Up, KEY_Down, etc.) + * @param EventType the type of event which occured (pressed, released, etc.) + * @param AmountDepressed (analog keys only) the depression percent. + * @param bGamepad - input came from gamepad (ie xbox controller) + * + * @return TRUE to consume the key event, FALSE to pass it on. + */ + virtual UBOOL InputKey(FViewport* Viewport,INT ControllerId,FName Key,EInputEvent EventType,FLOAT AmountDepressed=1.f,UBOOL bGamepad=FALSE); + + /** + * Routes an input axis (joystick, thumbstick, or mouse) event received from the viewport to the Interactions array for processing. + * + * @param Viewport the viewport the input event was received from + * @param ControllerId the controller that generated this input axis event + * @param Key the name of the axis that moved (KEY_MouseX, KEY_XboxTypeS_LeftX, etc.) + * @param Delta the movement delta for the axis + * @param DeltaTime the time (in seconds) since the last axis update. + * + * @return TRUE to consume the axis event, FALSE to pass it on. + */ + virtual UBOOL InputAxis(FViewport* Viewport,INT ControllerId,FName Key,FLOAT Delta,FLOAT DeltaTime, UBOOL bGamepad=FALSE); + + /** + * Routes a character input event (typing) received from the viewport to the Interactions array for processing. + * + * @param Viewport the viewport the input event was received from + * @param ControllerId the controller that generated this character input event + * @param Character the character that was typed + * + * @return TRUE to consume the key event, FALSE to pass it on. + */ + virtual UBOOL InputChar(FViewport* Viewport,INT ControllerId,TCHAR Character); + + /** + * Check a key event received by the viewport. + * If the viewport client uses the event, it should return true to consume it. + * @param Viewport - The viewport which the event is from. + * @param ControllerId - The controller which the key event is from. + * @param Handle - Identifier unique to this touch event + * @param Type - What kind of touch event this is (see ETouchType) + * @param TouchLocation - Screen position of the touch + * @param DeviceTimestamp - Timestamp of the event + * @param TouchpadIndex - For devices with multiple touchpads, this is the index of which one + * @return True to consume the key event, false to pass it on. + */ + virtual UBOOL InputTouch(FViewport* Viewport, INT ControllerId, UINT Handle, BYTE Type, FVector2D TouchLocation, DOUBLE DeviceTimestamp, UINT TouchpadIndex=0); + + /** + * Each frame, the input system will update the motion data. + * + * @param Viewport - The viewport which the key event is from. + * @param ControllerId - The controller which the key event is from. + * @param Tilt The current orientation of the device + * @param RotationRate How fast the tilt is changing + * @param Gravity Describes the current gravity of the device + * @param Acceleration Describes the acceleration of the device + * @return True to consume the motion event, false to pass it on. + */ + virtual UBOOL InputMotion(FViewport* Viewport, INT ControllerId, const FVector& Tilt, const FVector& RotationRate, const FVector& Gravity, const FVector& Acceleration); + + /** Returns the platform specific forcefeedback manager associated with this viewport */ + virtual class UForceFeedbackManager* GetForceFeedbackManager(INT ControllerId); + + /** + * @return the splitscreen type that is currently being used + */ + FORCEINLINE ESplitScreenType GetCurrentSplitscreenType() const + { + return static_cast(ActiveSplitscreenType); + } + + /** + * Retrieves the cursor that should be displayed by the OS + * + * @param Viewport the viewport that contains the cursor + * @param X the x position of the cursor + * @param Y the Y position of the cursor + * + * @return the cursor that the OS should display + */ + virtual EMouseCursor GetCursor( FViewport* Viewport, INT X, INT Y ); + + + virtual void Precache(); + virtual void Draw(FViewport* Viewport,FCanvas* Canvas); + virtual void LostFocus(FViewport* Viewport); + virtual void ReceivedFocus(FViewport* Viewport); + virtual UBOOL IsFocused(FViewport* Viewport); + virtual void CloseRequested(FViewport* Viewport); + virtual UBOOL RequiresHitProxyStorage() { return 0; } + + /** + * Determines whether this viewport client should receive calls to InputAxis() if the game's window is not currently capturing the mouse. + * Used by the UI system to easily receive calls to InputAxis while the viewport's mouse capture is disabled. + */ + virtual UBOOL RequiresUncapturedAxisInput() const; + + // FExec interface. + virtual UBOOL Exec(const TCHAR* Cmd,FOutputDevice& Ar); + + /** + * Helper function to toggles, enable or disable the specified show flag. Called by Exec(). + * + * @param Cmd Exec command line, as passed on from Exec(). + * @param Ar Output device used for reporting the result. + * @param SetMode Specifies whether the flag should be toggled, enabled or disabled. + * @return TRUE if the flag was modified. + */ + UBOOL SetShowFlags(const TCHAR* Cmd,FOutputDevice& Ar, ESetMode SetMode ); + + /** + * Set this GameViewportClient's viewport and viewport frame to the viewport specified + */ + virtual void SetViewportFrame( FViewportFrame* InViewportFrame ); + + /** + * Set this GameViewportClient's viewport to the viewport specified + */ + virtual void SetViewport( FViewport* InViewportFrame ); + + /** sets bDropDetail and other per-frame detail level flags on the current WorldInfo + * @param DeltaSeconds - amount of time passed since last tick + */ + virtual void SetDropDetail(FLOAT DeltaSeconds); + +#if __TW_ + /** Stub for KF2 level ShowSpawnVolumes (see KFGameViewportClient) */ + virtual void ShowSpawnVolumes( ESetMode SetMode ) { } +#endif + + #if WITH_GFx + virtual UObject* GetUObject() { return this; } + #endif + } + +/** + * Provides script-only child classes the opportunity to handle input key events received from the viewport. + * This delegate is called before the input key event is passed to the interactions array for processing. + * + * @param ControllerId the controller that generated this input key event + * @param Key the name of the key which an event occured for (KEY_Up, KEY_Down, etc.) + * @param EventType the type of event which occured (pressed, released, etc.) + * @param AmountDepressed for analog keys, the depression percent. + * @param bGamepad input came from gamepad (ie xbox controller) + * + * @return return TRUE to indicate that the input event was handled. if the return value is TRUE, this input event will not + * be passed to the interactions array. + */ +delegate bool HandleInputKey( int ControllerId, name Key, EInputEvent EventType, float AmountDepressed, optional bool bGamepad ); + +/** + * Provides script-only child classes the opportunity to handle input axis events received from the viewport. + * This delegate is called before the input axis event is passed to the interactions array for processing. + * + * @param ControllerId the controller that generated this input axis event + * @param Key the name of the axis that moved (KEY_MouseX, KEY_XboxTypeS_LeftX, etc.) + * @param Delta the movement delta for the axis + * @param DeltaTime the time (in seconds) since the last axis update. + * @param bGamepad input came from gamepad (ie xbox controller) + * + * @return return TRUE to indicate that the input event was handled. if the return value is TRUE, this input event will not + * be passed to the interactions array. + */ +delegate bool HandleInputAxis( int ControllerId, name Key, float Delta, float DeltaTime, bool bGamepad); + +/** + * Provides script-only child classes the opportunity to handle character input (typing) events received from the viewport. + * This delegate is called before the character event is passed to the interactions array for processing. + * + * @param ControllerId the controller that generated this character input event + * @param Unicode the character that was typed + * + * @return return TRUE to indicate that the input event was handled. if the return value is TRUE, this input event will not + * be passed to the interactions array. + */ +delegate bool HandleInputChar( int ControllerId, string Unicode ); + +/** + * Executes a console command in the context of this viewport. + * @param Command - The command to execute. + * @return The output of the command will be returned. + */ +native function string ConsoleCommand(string Command); + +/** + * Retrieve the size of the main viewport. + * + * @param out_ViewportSize [out] will be filled in with the size of the main viewport + */ +native final function GetViewportSize( out Vector2D out_ViewportSize ); + +/** @return Whether or not the main viewport is fullscreen or windowed. */ +native final function bool IsFullScreenViewport(); + +/** @return mouse position in game viewport coordinates (does not account for splitscreen) */ +native final function vector2D GetMousePosition(); + +/** + * Determine whether a fullscreen viewport should be used in cases where there are multiple players. + * + * @return TRUE to use a fullscreen viewport; FALSE to allow each player to have their own area of the viewport. + */ +native final function bool ShouldForceFullscreenViewport() const; + +/**Function that allow for custom numbers of interactions dictated in code*/ +native function int GetNumCustomInteractions(); +/**Defining the above mentioned custom interactions*/ +native function class GetCustomInteractionClass(int InIndex); +/**Passing the custom interaction object back to native code to do with it as it likes*/ +native function SetCustomInteractionObject(Interaction InInteraction); + +/** Function to notify GFx of a change in the splitscreen layout*/ +native function NotifySplitscreenLayoutChanged(); + +/** Force the mouse cursor to update */ +native function ForceUpdateMouseCursor(bool bSetCursor); + +/** Move the hardware mouse cursor to the designated location*/ +native function SetMouse(int X, int Y); + +/** + * Adds a new player. + * @param ControllerId - The controller ID the player should accept input from. + * @param OutError - If no player is returned, OutError will contain a string describing the reason. + * @param SpawnActor - True if an actor should be spawned for the new player. + * @return The player which was created. + */ +event LocalPlayer CreatePlayer(int ControllerId, out string OutError, bool bSpawnActor) +{ + local LocalPlayer NewPlayer; + local int InsertIndex; + + `log("Creating new player with ControllerId" @ ControllerId @ "(" $ GamePlayers.Length @ "existing players)",,'PlayerManagement'); + Assert(LocalPlayerClass != None); + + NewPlayer = new(Outer) LocalPlayerClass; + NewPlayer.ViewportClient = Self; + NewPlayer.ControllerId = ControllerId; + + InsertIndex = AddLocalPlayer(NewPlayer); + if ( bSpawnActor && InsertIndex != INDEX_NONE ) + { + if (GetCurrentWorldInfo().NetMode != NM_Client) + { + // server; spawn a new PlayerController immediately + if (!NewPlayer.SpawnPlayActor("", OutError)) + { + RemoveLocalPlayer(NewPlayer); + NewPlayer = None; + } + } + else + { + // client; ask the server to let the new player join + NewPlayer.SendSplitJoin(); + } + } + + if (OutError != "") + { + `Log("Player creation failed with error:" @ OutError); + } + else + { + `log("Successfully created new player with ControllerId" @ ControllerId $ ":" @ NewPlayer @ "- inserted into GamePlayers array at index" @ InsertIndex + @ "(" $ GamePlayers.Length @ "existing players)",,'PlayerManagement'); + + if ( NewPlayer != None && InsertIndex != INDEX_NONE ) + { + // let all interactions know about this + NotifyPlayerAdded(InsertIndex, NewPlayer); + } + } + return NewPlayer; +} + +/** + * Removes a player. + * @param Player - The player to remove. + * @return whether the player was successfully removed. Removal is not allowed while connected to a server. + */ +event bool RemovePlayer(LocalPlayer ExPlayer) +{ + local int OldIndex, i; + //Mapping of: index into array is new index, value is old index + local array IDMappings; + + // can't destroy viewports while connected to a server + if (ExPlayer.Actor.Role == ROLE_Authority) + { + `log("Removing player" @ ExPlayer @ " with ControllerId" @ ExPlayer.ControllerId @ "at index" @ GamePlayers.Find(ExPlayer)@ "(" $ GamePlayers.Length @ "existing players)",,'PlayerManagement'); + +`if(`isdefined(FIXING_SIGNIN_ISSUES)) +ScriptTrace(); +`endif + + // Disassociate this viewport client from the player. + ExPlayer.ViewportClient = None; + if ( ExPlayer.Actor != None ) + { + // Destroy the player's actors. + ExPlayer.Actor.Destroy(); + } + + // Remove the player from the global and viewport lists of players. + OldIndex = RemoveLocalPlayer(ExPlayer); + if ( OldIndex != INDEX_NONE ) + { + // let all interactions know about this + // NOTE: This is where GFx will clean up any movies that used to reference that index + NotifyPlayerRemoved(OldIndex, ExPlayer); + } + + //Now we need to handle the fact that we may have screwed up the player indices for other gfx movies + + //If they were equal we would have removed the last element, so we wouldn't need to do anything at all + if (OldIndex != GamePlayers.Length) + { + //Otherwise we have to cleanup + for (i = 0; i < GamePlayers.Length; i++) + { + //If it is below the removal, everything is the same + if (i < OldIndex) + { + IDMappings.AddItem(i); + } + else //If it is at the removal point or greater everything is one less than what it used to be + { + IDMappings.AddItem(i+1); + } + } + } + + //If we constructed any IDMappings, then something must be fixed up, so do so + if (IDMappings.Length > 0) + { + FixupOwnerReferences(IDMappings); + } + + `log("Finished removing player " @ ExPlayer @ " with ControllerId" @ ExPlayer.ControllerId @ "at index" @ OldIndex@ "(" $ GamePlayers.Length @ "remaining players)",,'PlayerManagement'); + return true; + } + else + { + `log("Not removing player" @ ExPlayer @ " with ControllerId" @ ExPlayer.ControllerId @ "because player does not have appropriate role (" $ GetEnum(enum'ENetRole',ExPlayer.Actor.Role) $ ")",,'PlayerManagement'); + return false; + } +} + +/** + * Finds a player by controller ID. + * @param ControllerId - The controller ID to search for. + * @return None or the player with matching controller ID. + */ +final event LocalPlayer FindPlayerByControllerId(int ControllerId) +{ + local int PlayerIndex; + for(PlayerIndex = 0;PlayerIndex < GamePlayers.Length;PlayerIndex++) + { + if(GamePlayers[PlayerIndex].ControllerId == ControllerId) + { + return GamePlayers[PlayerIndex]; + } + } + return None; +} + +`if(`notdefined(ShippingPC)) +/** + * Debug console command to create a player. + * @param ControllerId - The controller ID the player should accept input from. + */ +exec function DebugCreatePlayer(int ControllerId) +{ + local string Error; + + CreatePlayer(ControllerId, Error, TRUE); +} + +/** Rotates controller ids among gameplayers, useful for testing splitscreen with only one controller. */ +exec function SSSwapControllers() +{ + local int Idx, TmpControllerID; + TmpControllerID = GamePlayers[0].ControllerID; + + for (Idx=0; Idx= 0 && PlayerIndex < GamePlayers.Length) + { + ViewportConsole.ConsoleTargetPlayer = GamePlayers[PlayerIndex]; + } + else + { + ViewportConsole.ConsoleTargetPlayer = None; + } + } +} +`endif + +/** + * Initialize the game viewport. + * @param OutError - If an error occurs, returns the error description. + * @return False if an error occurred, true if the viewport was initialized successfully. + */ +event bool Init(out string OutError) +{ + local PlayerManagerInteraction PlayerInteraction; + local int NumCustomInteractions; + local class CustomInteractionClass; + local UIInteraction CustomInteraction; + local int Idx; + + assert(Outer.ConsoleClass != None); + + ActiveSplitscreenType = DesiredSplitscreenType; + +`if(`notdefined(FINAL_RELEASE)) + // Create the viewport's console. + ViewportConsole = new(Self) Outer.ConsoleClass; + if ( InsertInteraction(ViewportConsole) == -1 ) + { + OutError = "Failed to add interaction to GlobalInteractions array:" @ ViewportConsole; + return false; + } +`endif + + // Initialize custom interactions + NumCustomInteractions = GetNumCustomInteractions(); + for ( Idx = 0; Idx < NumCustomInteractions; Idx++ ) + { + CustomInteractionClass = GetCustomInteractionClass(Idx); + CustomInteraction = new(Self) CustomInteractionClass; + if ( InsertInteraction(CustomInteraction) == -1 ) + { + OutError = "Failed to add interaction to GlobalInteractions array:" @ CustomInteraction; + return false; + } + SetCustomInteractionObject(CustomInteraction); + } + + assert(UIControllerClass != None); + + // Create a interaction to handle UI input. + UIController = new(Self) UIControllerClass; + if ( InsertInteraction(UIController) == -1 ) + { + OutError = "Failed to add interaction to GlobalInteractions array:" @ UIController; + return false; + } + + // Create the viewport's player management interaction. + PlayerInteraction = new(Self) class'PlayerManagerInteraction'; + if ( InsertInteraction(PlayerInteraction) == -1 ) + { + OutError = "Failed to add interaction to GlobalInteractions array:" @ PlayerInteraction; + return false; + } + + // Disable the old UI system, if desired for debugging + if( bDebugNoGFxUI ) + { + DebugSetUISystemEnabled(TRUE, FALSE); + } + + // create the initial player - this is necessary or we can't render anything in-game. + return CreateInitialPlayer(OutError); +} + +/** + * Create the game's initial player at startup. First search for a player that is signed into the OnlineSubsystem; if none are found, + * create a player with a ControllerId of 0. + * + * @param OutError receives the error string if an error occurs while creating the player. + * + * @return TRUE if a player was successfully created. + */ +function bool CreateInitialPlayer( out string OutError ) +{ + local int ControllerId; + local bool bFoundInitialGamepad, bResult; + + for ( ControllerId = 0; ControllerId < class'UIRoot'.const.MAX_SUPPORTED_GAMEPADS; ControllerId++ ) + { + if ( UIController.IsLoggedIn(ControllerId) ) + { + bFoundInitialGamepad = true; + bResult = CreatePlayer(ControllerId, OutError, false) != None; + break; + } + } + + if ( !bFoundInitialGamepad || !bResult ) + { + // find the first connected gamepad + for ( ControllerId = 0; ControllerId < class'UIRoot'.const.MAX_SUPPORTED_GAMEPADS; ControllerId++ ) + { + if ( UIController.IsGamepadConnected(ControllerId) ) + { + bFoundInitialGamepad = true; + bResult = CreatePlayer(ControllerId, OutError, false) != None; + break; + } + } + } + + if ( !bFoundInitialGamepad || !bResult ) + { + bResult = CreatePlayer(0, OutError, false) != None; + } + + return bResult; +} + +/** + * Inserts an interaction into the GlobalInteractions array at the specified index + * + * @param NewInteraction the interaction that should be inserted into the array + * @param Index the position in the GlobalInteractions array to insert the element. + * if no value (or -1) is specified, inserts the interaction at the end of the array + * + * @return the position in the GlobalInteractions array where the element was placed, or -1 if the element wasn't + * added to the array for some reason + */ +event int InsertInteraction( Interaction NewInteraction, optional int InIndex = -1 ) +{ + local int Result; + + Result = -1; + if ( NewInteraction != None ) + { + // if the specified index is -1, assume that the item should be added to the end of the array + if ( InIndex == -1 ) + { + InIndex = GlobalInteractions.Length; + } + + // if the index is a negative value other than -1, don't add the element as someone made a mistake + if ( InIndex >= 0 ) + { + // clamp the Index to avoid expanding the array needlessly + Result = Clamp(InIndex, 0, GlobalInteractions.Length); + + // now insert the item + GlobalInteractions.Insert(Result, 1); + GlobalInteractions[Result] = NewInteraction; + NewInteraction.Init(); + NewInteraction.OnInitialize(); + } + else + { + `warn("Invalid insertion index specified:" @ InIndex); + } + } + + return Result; +} + +/** + * Called when the current map is being unloaded. Cleans up any references which would prevent garbage collection. + */ +event GameSessionEnded() +{ + local int i; + + for ( i = 0; i < GlobalInteractions.Length; i++ ) + { + GlobalInteractions[i].NotifyGameSessionEnded(); + } +} + +/** + * Sets the screen layout configuration that the player wishes to use when in split-screen mode. + */ +function SetSplitscreenConfiguration( ESplitScreenType SplitType ) +{ + DesiredSplitscreenType = SplitType; +} + +/** + * @return the actual splitscreen type being used, taking into account the number of players. + */ +function ESplitScreenType GetSplitscreenConfiguration() +{ + return ActiveSplitscreenType; +} + +/** + * Sets the value of ActiveSplitscreenConfiguration based on the desired split-screen layout type, current number of players, and any other + * factors that might affect the way the screen should be layed out. + */ +function UpdateActiveSplitscreenType() +{ + local ESplitScreenType SplitType; + + SplitType = DesiredSplitscreenType; + switch ( GamePlayers.Length ) + { + case 0: + case 1: + SplitType = eSST_NONE; + break; + + case 2: + if ( (SplitType != eSST_2P_HORIZONTAL) && (SplitType != eSST_2P_VERTICAL) ) + { + SplitType = Default2PSplitType; + } + break; + + case 3: + if ( (SplitType != eSST_3P_FAVOR_TOP) && (SplitType != eSST_3P_FAVOR_BOTTOM) ) + { + SplitType = Default3PSplitType; + } + break; + + default: + SplitType = eSST_4P; + break; + } + + ActiveSplitscreenType = SplitType; +} + +/** + * Called before rendering to allow the game viewport to allocate subregions to players. + */ +event LayoutPlayers() +{ + local int Idx; + local ESplitScreenType SplitType, PreviousSplitType; + + PreviousSplitType = GetSplitscreenConfiguration(); + UpdateActiveSplitscreenType(); + SplitType = GetSplitscreenConfiguration(); + // Initialize the players + for ( Idx = 0; Idx < GamePlayers.Length; Idx++ ) + { + if ( SplitType < SplitscreenInfo.Length && Idx < SplitscreenInfo[SplitType].PlayerData.Length ) + { + GamePlayers[Idx].Size.X = SplitscreenInfo[SplitType].PlayerData[Idx].SizeX; + GamePlayers[Idx].Size.Y = SplitscreenInfo[SplitType].PlayerData[Idx].SizeY; + GamePlayers[Idx].Origin.X = SplitscreenInfo[SplitType].PlayerData[Idx].OriginX; + GamePlayers[Idx].Origin.Y = SplitscreenInfo[SplitType].PlayerData[Idx].OriginY; + } + else + { + GamePlayers[Idx].Size.X = 0.f; + GamePlayers[Idx].Size.Y = 0.f; + GamePlayers[Idx].Origin.X = 0.f; + GamePlayers[Idx].Origin.Y = 0.f; + } + } + + //If splitscreen type has changed, update GFx + if (PreviousSplitType != SplitType) + { + NotifySplitscreenLayoutChanged(); + } +} + +/** called before rending subtitles to allow the game viewport to determine the size of the subtitle area + * @param Min top left bounds of subtitle region (0 to 1) + * @param Max bottom right bounds of subtitle region (0 to 1) + */ +event GetSubtitleRegion(out vector2D MinPos, out vector2D MaxPos) +{ + MaxPos.X = 1.0f; + MaxPos.Y = (GamePlayers.length == 1) ? 0.9f : 0.5f; +} + +/** +* Convert a LocalPlayer to it's index in the GamePlayer array +* Returns -1 if the index could not be found. +*/ +final function int ConvertLocalPlayerToGamePlayerIndex( LocalPlayer LPlayer ) +{ + return GamePlayers.Find( LPlayer ); +} + +/** + * Whether the player at LocalPlayerIndex's viewport has a "top of viewport" safezone or not. + */ +final function bool HasTopSafeZone( int LocalPlayerIndex ) +{ + switch ( GetSplitscreenConfiguration() ) + { + case eSST_NONE: + case eSST_2P_VERTICAL: + return true; + + case eSST_2P_HORIZONTAL: + case eSST_3P_FAVOR_TOP: + return (LocalPlayerIndex == 0) ? true : false; + + case eSST_3P_FAVOR_BOTTOM: + case eSST_4P: + return (LocalPlayerIndex < 2) ? true : false; + } + + return false; +} + +/** +* Whether the player at LocalPlayerIndex's viewport has a "bottom of viewport" safezone or not. +*/ +final function bool HasBottomSafeZone( int LocalPlayerIndex ) +{ + switch ( GetSplitscreenConfiguration() ) + { + case eSST_NONE: + case eSST_2P_VERTICAL: + return true; + + case eSST_2P_HORIZONTAL: + case eSST_3P_FAVOR_TOP: + return (LocalPlayerIndex == 0) ? false : true; + + case eSST_3P_FAVOR_BOTTOM: + case eSST_4P: + return (LocalPlayerIndex > 1) ? true : false; + } + + return false; +} + +/** + * Whether the player at LocalPlayerIndex's viewport has a "left of viewport" safezone or not. + */ +final function bool HasLeftSafeZone( int LocalPlayerIndex ) +{ + switch ( GetSplitscreenConfiguration() ) + { + case eSST_NONE: + case eSST_2P_HORIZONTAL: + return true; + + case eSST_2P_VERTICAL: + return (LocalPlayerIndex == 0) ? true : false; + + case eSST_3P_FAVOR_TOP: + return (LocalPlayerIndex < 2) ? true : false; + + case eSST_3P_FAVOR_BOTTOM: + case eSST_4P: + return (LocalPlayerIndex == 0 || LocalPlayerIndex == 2) ? true : false; + } + + return false; +} + +/** + * Whether the player at LocalPlayerIndex's viewport has a "right of viewport" safezone or not. + */ +final function bool HasRightSafeZone( int LocalPlayerIndex ) +{ + switch ( GetSplitscreenConfiguration() ) + { + case eSST_NONE: + case eSST_2P_HORIZONTAL: + return true; + + case eSST_2P_VERTICAL: + case eSST_3P_FAVOR_BOTTOM: + return (LocalPlayerIndex > 0) ? true : false; + + case eSST_3P_FAVOR_TOP: + return (LocalPlayerIndex == 1) ? false : true; + + case eSST_4P: + return (LocalPlayerIndex == 0 || LocalPlayerIndex == 2) ? false : true; + } + + return false; +} + +/** +* Get the total pixel size of the screen. +* This is different from the pixel size of the viewport since we could be in splitscreen +*/ +final function GetPixelSizeOfScreen( out float out_Width, out float out_Height, canvas Canvas, int LocalPlayerIndex ) +{ + switch ( GetSplitscreenConfiguration() ) + { + case eSST_NONE: + out_Width = Canvas.ClipX; + out_Height = Canvas.ClipY; + return; + case eSST_2P_HORIZONTAL: + out_Width = Canvas.ClipX; + out_Height = Canvas.ClipY * 2; + return; + case eSST_2P_VERTICAL: + out_Width = Canvas.ClipX * 2; + out_Height = Canvas.ClipY; + return; + case eSST_3P_FAVOR_TOP: + if ( LocalPlayerIndex == 0 ) + { + out_Width = Canvas.ClipX; + } + else + { + out_Width = Canvas.ClipX * 2; + } + out_Height = Canvas.ClipY * 2; + return; + case eSST_3P_FAVOR_BOTTOM: + if ( LocalPlayerIndex == 2 ) + { + out_Width = Canvas.ClipX; + } + else + { + out_Width = Canvas.ClipX * 2; + } + out_Height = Canvas.ClipY * 2; + return; + case eSST_4P: + out_Width = Canvas.ClipX * 2; + out_Height = Canvas.ClipY * 2; + return; + } +} + +/** +* Calculate the amount of safezone needed for a single side for both vertical and horizontal dimensions +*/ +final function CalculateSafeZoneValues( out float out_Horizontal, out float out_Vertical, canvas Canvas, int LocalPlayerIndex, bool bUseMaxPercent ) +{ + local float ScreenWidth, ScreenHeight, XSafeZoneToUse, YSafeZoneToUse; + + XSafeZoneToUse = bUseMaxPercent ? TitleSafeZone.MaxPercentX : TitleSafeZone.RecommendedPercentX; + YSafeZoneToUse = bUseMaxPercent ? TitleSafeZone.MaxPercentY : TitleSafeZone.RecommendedPercentY; + + GetPixelSizeOfScreen( ScreenWidth, ScreenHeight, Canvas, LocalPlayerIndex ); + out_Horizontal = (ScreenWidth * (1 - XSafeZoneToUse) / 2.0f); + out_Vertical = (ScreenHeight * (1 - YSafeZoneToUse) / 2.0); +} + +/* +* Return true if the safe zone exists +* pixel size of the deadzone for all sides (right/left/top/bottom) based on which local player it is +*/ +final function bool CalculateDeadZoneForAllSides( LocalPlayer LPlayer, Canvas Canvas, out float fTopSafeZone, out float fBottomSafeZone, out float fLeftSafeZone, out float fRightSafeZone, optional bool bUseMaxPercent ) +{ + // save separate - if the split screen is in bottom right, then + local bool bHasTopSafeZone, bHasBottomSafeZone, bHasRightSafeZone, bHasLeftSafeZone; + local int LocalPlayerIndex; + local float HorizSafeZoneValue, VertSafeZoneValue; + + if ( LPlayer != None ) + { + LocalPlayerIndex = ConvertLocalPlayerToGamePlayerIndex( LPlayer ); + + if ( LocalPlayerIndex != -1 ) + { + // see if this player should have a safe zone for any particular zonetype + bHasTopSafeZone = HasTopSafeZone( LocalPlayerIndex ); + bHasBottomSafeZone = HasBottomSafeZone( LocalPlayerIndex ); + bHasLeftSafeZone = HasLeftSafeZone( LocalPlayerIndex ); + bHasRightSafeZone = HasRightSafeZone( LocalPlayerIndex ); + + // if they need a safezone, then calculate it and save it + if ( bHasTopSafeZone || bHasBottomSafeZone || bHasLeftSafeZone || bHasRightSafeZone) + { + // calculate the safezones + CalculateSafeZoneValues( HorizSafeZoneValue, VertSafeZoneValue, Canvas, LocalPlayerIndex, bUseMaxPercent ); + + if (bHasTopSafeZone) + { + fTopSafeZone = VertSafeZoneValue; + } + else + { + fTopSafeZone = 0.f; + } + + if (bHasBottomSafeZone) + { + fBottomSafeZone = VertSafeZoneValue; + } + else + { + fBottomSafeZone = 0.f; + } + + if (bHasLeftSafeZone) + { + fLeftSafeZone = HorizSafeZoneValue; + } + else + { + fLeftSafeZone = 0.f; + } + + if (bHasRightSafeZone) + { + fRightSafeZone = HorizSafeZoneValue; + } + else + { + fRightSafeZone = 0.f; + } + + return TRUE; + } + } + } + + return FALSE; +} + +/** + * Called every frame to allow the game viewport to update time based state. + * @param DeltaTime - The time since the last call to Tick. + */ +event Tick(float DeltaTime); + +/** +* Draw the safe area using the current TitleSafeZone settings +*/ +function DrawTitleSafeArea( canvas Canvas ) +{ + // red colored max safe area box + Canvas.SetDrawColor(255,0,0,255); + Canvas.SetPos(Canvas.ClipX * (1 - TitleSafeZone.MaxPercentX) / 2.0, Canvas.ClipY * (1 - TitleSafeZone.MaxPercentY) / 2.0); + Canvas.DrawBox(Canvas.ClipX * TitleSafeZone.MaxPercentX, Canvas.ClipY * TitleSafeZone.MaxPercentY); + + // yellow colored recommended safe area box + Canvas.SetDrawColor(255,255,0,255); + Canvas.SetPos(Canvas.ClipX * (1 - TitleSafeZone.RecommendedPercentX) / 2.0, Canvas.ClipY * (1 - TitleSafeZone.RecommendedPercentY) / 2.0); + Canvas.DrawBox(Canvas.ClipX * TitleSafeZone.RecommendedPercentX, Canvas.ClipY * TitleSafeZone.RecommendedPercentY); +} + +/** + * Called after rendering the player views and HUDs to render menus, the console, etc. + * This is the last rendering call in the render loop + * @param Canvas - The canvas to use for rendering. + */ +event PostRender(Canvas Canvas) +{ + if( bShowTitleSafeZone ) + { + DrawTitleSafeArea(Canvas); + } + + if (ViewportConsole != none) + { + // Render the console. + ViewportConsole.PostRender_Console(Canvas); + } + + // Draw the transition screen. + DrawTransition(Canvas); +} + +/** + * display progress messages in center of screen + */ +function DisplayProgressMessage(Canvas Canvas) +{ + local int i, LineCount; + local float FontDX, FontDY; + local float X, Y; + local byte Alpha; + local float TimeLeft; + + TimeLeft = ProgressTimeOut - class'Engine'.static.GetCurrentWorldInfo().TimeSeconds; + Alpha = (TimeLeft >= ProgressFadeTime) ? 255 : byte((255 * TimeLeft) / ProgressFadeTime); + + LineCount = 0; + + for (i = 0; i < ArrayCount(ProgressMessage); i++) + { + if (ProgressMessage[i] != "") + { + LineCount++; + } + } + + Canvas.Font = class'Engine'.Static.GetMediumFont(); + Canvas.TextSize ("A", FontDX, FontDY); + + X = (0.5 * Canvas.SizeX); + Y = (0.5 * Canvas.SizeY); + + Y -= FontDY * (float(LineCount) / 2.0); + + Canvas.DrawColor.R = 255; + Canvas.DrawColor.G = 255; + Canvas.DrawColor.B = 255; + for (i = 0; i < ArrayCount(ProgressMessage); i++) + { + if (ProgressMessage[i] != "") + { + Canvas.DrawColor.A = Alpha; + + Canvas.TextSize(ProgressMessage[i], FontDX, FontDY); + Canvas.SetPos(X - (FontDX / 2.0), Y); + Canvas.DrawText(ProgressMessage[i]); + + Y += FontDY; + } + } +} + +/** + * Displays the transition screen. + * @param Canvas - The canvas to use for rendering. + */ +function DrawTransition(Canvas Canvas) +{ + switch(Outer.TransitionType) + { + case TT_Loading: + DrawTransitionMessage(Canvas,LoadingMessage); + break; + case TT_Saving: + DrawTransitionMessage(Canvas,SavingMessage); + break; + case TT_Connecting: + DrawTransitionMessage(Canvas,ConnectingMessage); + break; + case TT_Precaching: + DrawTransitionMessage(Canvas,PrecachingMessage); + break; + case TT_Paused: + DrawTransitionMessage(Canvas,PausedMessage); + break; + } +} + +/** + * Print a centered transition message with a drop shadow. + */ +function DrawTransitionMessage(Canvas Canvas,string Message) +{ + local float XL, YL; + + Canvas.Font = class'Engine'.Static.GetLargeFont(); + Canvas.bCenter = false; + Canvas.StrLen( Message, XL, YL ); + Canvas.SetPos(0.5 * (Canvas.ClipX - XL) + 1, 0.66 * Canvas.ClipY - YL * 0.5 + 1); + Canvas.SetDrawColor(0,0,0); + Canvas.DrawText( Message, false ); + Canvas.SetPos(0.5 * (Canvas.ClipX - XL), 0.66 * Canvas.ClipY - YL * 0.5); + Canvas.SetDrawColor(0,0,255);; + Canvas.DrawText( Message, false ); +} + +/** + * Notifies all interactions that a new player has been added to the list of active players. + * + * @param PlayerIndex the index [into the GamePlayers array] where the player was inserted + * @param AddedPlayer the player that was added + */ +final function NotifyPlayerAdded( int PlayerIndex, LocalPlayer AddedPlayer ) +{ + local int InteractionIndex; + + LayoutPlayers(); + for ( InteractionIndex = 0; InteractionIndex < GlobalInteractions.Length; InteractionIndex++ ) + { + if ( GlobalInteractions[InteractionIndex] != None ) + { + GlobalInteractions[InteractionIndex].NotifyPlayerAdded(PlayerIndex, AddedPlayer); + } + } +} + +/** + * Notifies all interactions that a new player has been added to the list of active players. + * + * @param PlayerIndex the index [into the GamePlayers array] where the player was located + * @param RemovedPlayer the player that was removed + */ +final function NotifyPlayerRemoved( int PlayerIndex, LocalPlayer RemovedPlayer ) +{ + local int InteractionIndex; + + LayoutPlayers(); + for ( InteractionIndex = GlobalInteractions.Length - 1; InteractionIndex >= 0; InteractionIndex-- ) + { + if ( GlobalInteractions[InteractionIndex] != None ) + { + GlobalInteractions[InteractionIndex].NotifyPlayerRemoved(PlayerIndex, RemovedPlayer); + } + } +} + +/** + * Adds a LocalPlayer to the local and global list of Players. + * + * @param NewPlayer the player to add + */ +private final function int AddLocalPlayer( LocalPlayer NewPlayer ) +{ + local int InsertIndex; + + InsertIndex = INDEX_NONE; + if ( NewPlayer != None ) + { + // add to list + InsertIndex = GamePlayers.Length; + GamePlayers[InsertIndex] = NewPlayer; + } + return InsertIndex; +} + +/** + * Removes a LocalPlayer from the local and global list of Players. + * + * @param ExistingPlayer the player to remove + */ +private final function int RemoveLocalPlayer( LocalPlayer ExistingPlayer ) +{ + local int Index; + + Index = GamePlayers.Find(ExistingPlayer); + if ( Index != INDEX_NONE ) + { + GamePlayers.Remove(Index,1); + } + + return Index; +} + +/** handler for global state messages, generally network connection related (failures, download progress, etc) */ +event SetProgressMessage(EProgressMessageType MessageType, string Message, optional string Title, optional bool bIgnoreFutureNetworkMessages) +{ + local WorldInfo WI; + + WI = class'Engine'.static.GetCurrentWorldInfo(); + + if (MessageType == PMT_Clear) + { + ClearProgressMessages(); + } + else + { + if (MessageType == PMT_ConnectionFailure || MessageType == PMT_SocketFailure) + { + // Attempt to start host migration on connection failure + if (WI != None && + WI.NetMode == NM_Client && + WI.BeginHostMigration()) + { + `Log(`location @ "MessageType="$MessageType @ "Message="$Message @ ": host migration started.. "$WI.PeerHostMigration.HostMigrationProgress,,'DevNet'); + } + //@FIXME: bIgnoreNetworkMessages needs to die + else if (!Outer.GamePlayers[0].Actor.bIgnoreNetworkMessages) + { + `Log(`location @ "MessageType="$MessageType @ "Message="$Message @ ": host migration not enabled.. handling connection error.",,'DevNet'); + + NotifyConnectionError(MessageType, Message, Title); + } + } + else if (MessageType == PMT_PeerHostMigrationFailure) + { + // Host migration was started but failed so just fallback to network error handling + Outer.GamePlayers[0].Actor.bIgnoreNetworkMessages = false; + NotifyConnectionError(MessageType, Message, Title); + } + else + { + if (Title != "") + { + ProgressMessage[0] = Title; + ProgressMessage[1] = Message; + } + else + { + ProgressMessage[1] = ""; + ProgressMessage[0] = Message; + } + } + } + //@FIXME: bIgnoreNetworkMessages needs to die + if (!Outer.GamePlayers[0].Actor.bIgnoreNetworkMessages) + { + Outer.GamePlayers[0].Actor.bIgnoreNetworkMessages = bIgnoreFutureNetworkMessages; + } +} + +/** + * Notifies the player that an attempt to connect to a remote server failed, or an existing connection was dropped. + * + * @param MessageType EProgressMessageType of current connection error + * @param Message a description of why the connection was lost + * @param Title the title to use in the connection failure message. + */ +function NotifyConnectionError(EProgressMessageType MessageType, optional string Message=Localize("Errors", "ConnectionFailed", "Engine"), optional string Title=Localize("Errors", "ConnectionFailed_Title", "Engine") ) +{ + local WorldInfo WI; + + WI = class'Engine'.static.GetCurrentWorldInfo(); + `log(`location @ `showvar(Title) @ `showvar(Message) @ `showenum(ENetMode,WI.NetMode,NetMode) @ `showvar(WI.GetURLMap(),Map) ,,'DevNet'); + if (WI.NetMode != NM_Standalone) + { + if ( WI.Game != None ) + { + // Mark the server as having a problem + WI.Game.bHasNetworkError = true; + } + + //@todo: should we have a Travel() function in this class? + ConsoleCommand("start ?failed"); + } +} + +exec event SetProgressTime(float T) +{ + ProgressTimeOut = T + class'Engine'.static.GetCurrentWorldInfo().TimeSeconds; +} + +exec function ClearProgressMessages() +{ + local int i; + + for (i=0; i IDMappings); + +/** Called after a new primary player has been made */ +function OnPrimaryPlayerSwitch(LocalPlayer OldPrimaryPlayer, LocalPlayer NewPrimaryPlayer); + +/** + * Makes a player the primary player + * @param PlayerIndex - The index of the player to be made into the primary player + */ +function BecomePrimaryPlayer(int PlayerIndex) +{ + local array OtherPlayers; + local LocalPlayer PlayerOwner, NextPlayer, OriginalPrimaryPlayer; + local int NumPlayersRemoved; + local int i, count; + //Mapping of: index into array is new index, value is old index + local array IDMappings; + + if (UIController != None && PlayerIndex > 0 && PlayerIndex < UIController.GetPlayerCount()) + { + OriginalPrimaryPlayer = GetPlayerOwner(0); + + // get the player that owns this scene + PlayerOwner = GetPlayerOwner(PlayerIndex); + if (PlayerOwner == None) + { + `log("GameViewportClient:BecomePrimaryPlayer has failed to find the player owner for index" @ PlayerIndex @ "ABORTING!!!"); + return; + } + + if (PlayerOwner != None) + { + NextPlayer = OriginalPrimaryPlayer; + NumPlayersRemoved = 0; + while (NextPlayer != None && NextPlayer != PlayerOwner) + { + // the easiest way to ensure that everything is updated properly is to simulate the player being removed; + // do it manually so that their PlayerController and stuff aren't destroyed. + UIController.NotifyPlayerRemoved(0, NextPlayer); + UIController.Outer.Outer.GamePlayers.Remove(0, 1); + + // we need to re-add the player so keep them in a temporary list + OtherPlayers.AddItem(NextPlayer); + + NextPlayer = GetPlayerOwner(0); + + NumPlayersRemoved++; + } + + //Update mapping for all movies that just got shifted downwards + for (i = 0; i < UIController.Outer.Outer.GamePlayers.length; i++) + { + IDMappings.AddItem(i+NumPlayersRemoved); + } + + // now re-add the previous players to the GamePlayers array. + count = 0; + while (OtherPlayers.Length > 0) + { + NextPlayer = OtherPlayers[0]; + + UIController.Outer.Outer.GamePlayers.AddItem(NextPlayer); + UIController.NotifyPlayerAdded(UIController.Outer.Outer.GamePlayers.length-1, NextPlayer); + + OtherPlayers.Remove(0, 1); + + IDMappings.AddItem(count); + count++; + } + } + + // if we have a new primary player, reload their profile so that their settings will be applied and fixup references + NextPlayer = GetPlayerOwner(0); + if (OriginalPrimaryPlayer != NextPlayer) + { + // Players switched so reevaluate the viewports + LayoutPlayers(); + FixupOwnerReferences(IDMappings); + NextPlayer.Actor.ReloadProfileSettings(); + OnPrimaryPlayerSwitch(OriginalPrimaryPlayer, NextPlayer); + } + } +} + +/** Function to enable Scaleform processing/rendering */ +native final function EnableScaleform(); + +/** Function to disable Scaleform processing/rendering */ +native final function DisableScaleform(); + +/** Function to find out if Scaleform is enabled/disabled */ +native final function bool IsScaleformEnabled(); + +/** DEBUG: function to easily allow script to turn on / off the two UI systems for developing during the transition from the old UI to the new GFx UI */ +native function DebugSetUISystemEnabled(bool bOldUISystemActive, bool bGFxUISystemActive); + +/** + * Function to set the hardware mouse cursor visibility + * + * @param bIsVisible - whether or not the cursor is visible + */ +simulated event SetHardwareMouseCursorVisibility(bool bIsVisible) +{ + local Vector2D ViewportSize; + + //If we are going to be turning on the hardware cursor when it was not already on, we will move the cursor to the middle of the screen + if (bIsVisible && !bDisplayHardwareMouseCursor) + { + GetViewportSize(ViewportSize); + SetMouse(ViewportSize.X/2,ViewportSize.Y/2); + } + bDisplayHardwareMouseCursor = bIsVisible; + + ForceUpdateMouseCursor(TRUE); +} + +defaultproperties +{ + UIControllerClass=class'Engine.UIInteraction' + TitleSafeZone=(MaxPercentX=0.9,MaxPercentY=0.9,RecommendedPercentX=0.8,RecommendedPercentY=0.8) + + Default2PSplitType=eSST_2P_HORIZONTAL + Default3PSplitType=eSST_3P_FAVOR_TOP + DesiredSplitscreenType=eSST_NONE + + bIsPlayInEditorViewport=False + bShowSystemMouseCursor=False + + ProgressFadeTime=1.0 + ProgressTimeOut=8.0 + + SplitscreenInfo(eSST_None)= (PlayerData=((SizeX=1.0f,SizeY=1.0f,OriginX=0.0f,OriginY=0.0f))) + + SplitscreenInfo(eSST_2P_HORIZONTAL)={(PlayerData=( + (SizeX=1.0f,SizeY=0.5f,OriginX=0.0f,OriginY=0.0f), + (SizeX=1.0f,SizeY=0.5f,OriginX=0.0f,OriginY=0.5f)) + )} + + SplitscreenInfo(eSST_2P_VERTICAL)={(PlayerData=( + (SizeX=0.5f,SizeY=1.0f,OriginX=0.0f,OriginY=0.0f), + (SizeX=0.5f,SizeY=1.0f,OriginX=0.5f,OriginY=0.0)) + )} + + SplitscreenInfo(eSST_3P_FAVOR_TOP)={(PlayerData=( + (SizeX=1.0f,SizeY=0.5f,OriginX=0.0f,OriginY=0.0f), + (SizeX=0.5f,SizeY=0.5f,OriginX=0.0f,OriginY=0.5f), + (SizeX=0.5f,SizeY=0.5f,OriginX=0.5f,OriginY=0.5f)) + )} + + SplitscreenInfo(eSST_3P_FAVOR_BOTTOM)={(PlayerData=( + (SizeX=0.5f,SizeY=0.5f,OriginX=0.0f,OriginY=0.0f), + (SizeX=0.5f,SizeY=0.5f,OriginX=0.5f,OriginY=0.0f), + (SizeX=1.0f,SizeY=0.5f,OriginX=0.0f,OriginY=0.5f)) + )} + + SplitscreenInfo(eSST_4P)={(PlayerData=( + (SizeX=0.5f,SizeY=0.5f,OriginX=0.0f,OriginY=0.0f), + (SizeX=0.5f,SizeY=0.5f,OriginX=0.5f,OriginY=0.0f), + (SizeX=0.5f,SizeY=0.5f,OriginX=0.0f,OriginY=0.5f), + (SizeX=0.5f,SizeY=0.5f,OriginX=0.5f,OriginY=0.5f)) + )} +} diff --git a/Engine/Classes/GameplayEvents.uc b/Engine/Classes/GameplayEvents.uc new file mode 100644 index 0000000..b204360 --- /dev/null +++ b/Engine/Classes/GameplayEvents.uc @@ -0,0 +1,403 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * Gameplay event interface + */ +class GameplayEvents extends Object + abstract + native; + +`include(Engine\Classes\GameStats.uci); + +// Bitmasks for flags stored on the MCP header +const HeaderFlags_NoEventStrings = 1; + +/** Stat verbosity level */ +enum EGameStatGroups +{ + GSG_EngineStats, + GSG_Game, + GSG_Team, + GSG_Player, + GSG_Weapon, + GSG_Damage, + GSG_Projectile, + GSG_Pawn, + GSG_GameSpecific, + GSG_Aggregate +}; + +struct native GameStatGroup +{ + /** Group stat belongs to*/ + var EGameStatGroups Group; + /** Level of the stat */ + var int Level; + + structcpptext + { + friend FArchive& operator<<( FArchive& Ar, FGameStatGroup& T ); + } +}; + +/** Basic file header when writing to disk */ +struct native GameplayEventsHeader +{ + /** Version of engine at the time of writing the file */ + var const int EngineVersion; + + /** Version of the stats format at the time of writing the file */ + var const int StatsWriterVersion; + + /** Offset into the file for the stream data */ + var const int StreamOffset; + + /** Offset into the file for aggregate data */ + var const int AggregateOffset; + + /** Offset into the file where the metadata is written */ + var const int FooterOffset; + + /** Amount of data in the stream (not including header/footer data) */ + var const int TotalStreamSize; + + /** File size on disk */ + var const int FileSize; + + /** What filter class is being used on the data, if any */ + var string FilterClass; + + /** Various settings */ + var int Flags; +}; + +/** Game stats session information recorded at log start */ +struct native GameSessionInformation +{ + /** Unique title identifier */ + var int AppTitleID; + + /** Platform the session was run on */ + var int PlatformType; + + /** Language the session was run in */ + var string Language; + + /** Time this session was begun (real time) */ + var const string GameplaySessionTimestamp; + + /** Time this session was started (game time) */ + var const float GameplaySessionStartTime; + + /** Time this session was ended (game time) */ + var const float GameplaySessionEndTime; + + /** Is a session currently in progress */ + var const bool bGameplaySessionInProgress; + + /** Unique session ID */ + var const string GameplaySessionID; + + /** Name of the game class used */ + var const string GameClassName; + + /** Name of map at time of session */ + var const string MapName; + + /** Game URL at time of session */ + var const string MapURL; + + /** Value used to distinguish between contiguous sections */ + var const int SessionInstance; + + /** Gametype ID */ + var const int GameTypeId; + + /** UniqueID of player logging stats */ + var const UniqueNetId OwningNetId; + + /** ID of the playlist in use */ + var int PlaylistId; + + structcpptext + { + /** Constructors */ + FGameSessionInformation() {} + FGameSessionInformation(EEventParm) + { + appMemzero(this, sizeof(FGameSessionInformation)); + } + + /** Return the unique key for this session */ + const FString GetSessionID() const { return FString::Printf(TEXT("%s:%d"), *GameplaySessionID, SessionInstance); } + } +}; + +/** List of team information cached during the play session */ +struct native TeamInformation +{ + /** Index of the team in game */ + var int TeamIndex; + + /** Name of the team */ + var string TeamName; + + /** Color of the team */ + var color TeamColor; + + /** Max size during the game */ + var int MaxSize; + + structcpptext + { + friend FArchive& operator<<( FArchive& Ar, FTeamInformation& T ); + } +}; + +/** List of player information cached in case the player logs out and GC collects the objects */ +struct native PlayerInformation +{ + /** Name of Controller object */ + var name ControllerName; + /** Controller.PlayerReplicationInfo.PlayerName */ + var string PlayerName; + /** UniqueID of the player */ + var UniqueNetId UniqueId; + /** Whether the player is a bot or not */ + var bool bIsBot; + + structcpptext + { + friend FArchive& operator<<( FArchive& Ar, FPlayerInformation& T ); + } +}; + +/** Holds the information describing a gameplay event */ +struct native GameplayEventMetaData +{ + /** The unique id of the event (16 bits clamped) */ + var const int EventID; + + /** Human readable name of the event */ + var const name EventName; + + /** Group that this stat belongs to, for filtering */ + var const GameStatGroup StatGroup; + + /** Type of data associated with this event */ + var const int EventDataType; + + structcpptext + { + friend FArchive& operator<<( FArchive& Ar, FGameplayEventMetaData& T ); + } +}; + +/** Metadata describing the weapon classes recorded during gameplay */ +struct native WeaponClassEventData +{ + /** Name of the weapon class used **/ + var name WeaponClassName; + + structcpptext + { + friend FArchive& operator<<( FArchive& Ar, FWeaponClassEventData& T ); + } +}; + +/** Metadata describing the damage classes recorded during gameplay */ +struct native DamageClassEventData +{ + /** Name of the damage class used **/ + var name DamageClassName; + + structcpptext + { + friend FArchive& operator<<( FArchive& Ar, FDamageClassEventData& T ); + } +}; + +/** Metadata describing the projectile classes recorded during gameplay */ +struct native ProjectileClassEventData +{ + /** name of the projectile class used **/ + var name ProjectileClassName; + + structcpptext + { + friend FArchive& operator<<( FArchive& Ar, FProjectileClassEventData& T ); + } +}; + +/** Metadata describing the pawn classes recorded during gameplay */ +struct native PawnClassEventData +{ + /** Name of the pawn class used **/ + var name PawnClassName; + + structcpptext + { + friend FArchive& operator<<( FArchive& Ar, FPawnClassEventData& T ); + } +}; + +cpptext +{ + /** Access the current session info */ + const FGameSessionInformation& GetSessionInfo() const + { + return CurrentSessionInfo; + } + + /** Returns the metadata associated with the given index */ + virtual const FGameplayEventMetaData& GetEventMetaData(INT EventID) const; + + /** Returns the metadata associated with the given index */ + const FTeamInformation& GetTeamMetaData(INT TeamIndex) const; + + /** Returns the metadata associated with the given index */ + const FPlayerInformation& GetPlayerMetaData(INT PlayerIndex) const; + + /** Returns the metadata associated with the given index */ + const FPawnClassEventData& GetPawnMetaData(INT PawnClassIndex) const; + + /** Returns the metadata associated with the given index */ + const FWeaponClassEventData& GetWeaponMetaData(INT WeaponClassIndex) const; + + /** Returns the metadata associated with the given index */ + const FDamageClassEventData& GetDamageMetaData(INT DamageClassIndex) const; + + /** Returns the metadata associated with the given index */ + const FProjectileClassEventData& GetProjectileMetaData(INT ProjectileClassIndex) const; + + /** + * Returns the metadata associated with the given index + * @param ActorIndex the index of the actor being looked up + * @return the name of the actor at that index + */ + const FString& GetActorMetaData(INT ActorIndex) const + { + return ActorArray(ActorIndex); + } + + /** + * Returns the metadata associated with the given index + * @param SoundIndex the index of the soundcue being looked up + * @return the name of the actor at that index + */ + const FString& GetSoundMetaData(INT SoundIndex) const + { + return SoundCueArray(SoundIndex); + } +}; + +/** FArchive pointer to serialize the data to/from disk */ +var const native pointer Archive{FArchive}; + +/** The name of the file we are writing the data to (const so set only upon create natively) */ +var const private string StatsFileName; + +/** Header of the gameplay events file */ +var GameplayEventsHeader Header; + +/** Information specific to the session when it was run */ +var GameSessionInformation CurrentSessionInfo; + +/** Array of all players 'seen' by the game in this session **/ +var const array PlayerList; + +/** Array of all teams 'seen' by the game in this session **/ +var const array TeamList; + +/** The set of events that the game supports writing to disk */ +var array SupportedEvents; + +/** The set of weapons recorded during gameplay */ +var array WeaponClassArray; + +/** The set of damage types recorded during gameplay */ +var array DamageClassArray; + +/** The set of projectiles recorded during gameplay */ +var array ProjectileClassArray; + +/** The set of pawns recorded during gameplay */ +var array PawnClassArray; + +/** The set of actors recorded during gameplay */ +var array ActorArray; + +/** The set of sound cues encountered during gameplay */ +var array SoundCueArray; + +/** + * Creates the archive that we are going to be manipulating + * @param Filename - name of the file that will be open for serialization + * @return TRUE if successful, else FALSE + */ +function bool OpenStatsFile(string Filename); + +/** + * Closes and deletes the archive created + * clearing all data stored within + */ +function CloseStatsFile(); + +/** Retrieve the name of the file last in use by the gameplay event serializer, possibly empty */ +event string GetFilename() +{ + return StatsFileName; +} + +defaultproperties +{ + SupportedEvents.Empty() + + //Must leave this first as a fallback for failed event retrieval + SupportedEvents(0)={(EventID=-1,EventName="UNKNOWN",StatGroup=(Group=GSG_EngineStats,Level=999),EventDataType=1)} + //Real events start here + SupportedEvents.Add((EventID=GAMEEVENT_MATCH_STARTED,EventName="Match Started",StatGroup=(Group=GSG_Game,Level=1),EventDataType=`GET_GameInt)) + SupportedEvents.Add((EventID=GAMEEVENT_MATCH_ENDED,EventName="Match Ended",StatGroup=(Group=GSG_Game,Level=1),EventDataType=`GET_GameInt)) + SupportedEvents.Add((EventID=GAMEEVENT_ROUND_STARTED,EventName="Round Started",StatGroup=(Group=GSG_Game,Level=1),EventDataType=`GET_GameInt)) + SupportedEvents.Add((EventID=GAMEEVENT_ROUND_ENDED,EventName="Round Ended",StatGroup=(Group=GSG_Game,Level=1),EventDataType=`GET_GameInt)) + SupportedEvents.Add((EventID=GAMEEVENT_GAME_CLASS,EventName="Game Class",StatGroup=(Group=GSG_Game,Level=1),EventDataType=`GET_GameString)) + SupportedEvents.Add((EventID=GAMEEVENT_GAME_OPTION_URL,EventName="Game Options",StatGroup=(Group=GSG_Game,Level=1),EventDataType=`GET_GameString)) + SupportedEvents.Add((EventID=GAMEEVENT_GAME_MAPNAME,EventName="Map Name",StatGroup=(Group=GSG_Game,Level=1),EventDataType=`GET_GameString)) + + SupportedEvents.Add((EventID=GAMEEVENT_TEAM_CREATED,EventName="Team Created",StatGroup=(Group=GSG_Team,Level=1),EventDataType=`GET_TeamInt)) + SupportedEvents.Add((EventID=GAMEEVENT_TEAM_GAME_SCORE,EventName="Team Score",StatGroup=(Group=GSG_Team,Level=1),EventDataType=`GET_TeamInt)) + SupportedEvents.Add((EventID=GAMEEVENT_TEAM_MATCH_WON,EventName="Match Won",StatGroup=(Group=GSG_Team,Level=1),EventDataType=`GET_TeamInt)) + SupportedEvents.Add((EventID=GAMEEVENT_TEAM_ROUND_WON,EventName="Round Won",StatGroup=(Group=GSG_Team,Level=1),EventDataType=`GET_TeamInt)) + SupportedEvents.Add((EventID=GAMEEVENT_TEAM_ROUND_STALEMATE,EventName="Round Stalemate",StatGroup=(Group=GSG_Team,Level=1),EventDataType=`GET_TeamInt)) + + SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_LOGIN,EventName="Player Login",StatGroup=(Group=GSG_Player,Level=1),EventDataType=`GET_PlayerLogin)) + SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_LOGOUT,EventName="Player Logout",StatGroup=(Group=GSG_Player,Level=1),EventDataType=`GET_PlayerLogin)) + SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_KILL,EventName="Player Killed",StatGroup=(Group=GSG_Player,Level=1),EventDataType=`GET_PlayerKillDeath)) + SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_DEATH,EventName="Player Death",StatGroup=(Group=GSG_Player,Level=1),EventDataType=`GET_PlayerKillDeath)) + + SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_TEAMCHANGE,EventName="Player Team Change",StatGroup=(Group=GSG_Player,Level=1),EventDataType=`GET_PlayerInt)) + SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_SPAWN,EventName="Player Spawn",StatGroup=(Group=GSG_Player,Level=1),EventDataType=`GET_PlayerSpawn)) + SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_LOCATION_POLL,EventName="Player Locations",StatGroup=(Group=GSG_Player,Level=10),EventDataType=`GET_PlayerLocationPoll)) + SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_KILL_STREAK,EventName="Kill Streak",StatGroup=(Group=GSG_Player,Level=1),EventDataType=`GET_PlayerInt)) + SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_MATCH_WON,EventName="Player Match Won",StatGroup=(Group=GSG_Player,Level=1),EventDataType=`GET_PlayerInt)) + SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_ROUND_WON,EventName="Player Round Won",StatGroup=(Group=GSG_Player,Level=1),EventDataType=`GET_PlayerInt)) + SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_ROUND_STALEMATE,EventName="Player Round Stalemate",StatGroup=(Group=GSG_Player,Level=1),EventDataType=`GET_PlayerInt)) + + SupportedEvents.Add((EventID=GAMEEVENT_WEAPON_DAMAGE,EventName="Weapon Damage",StatGroup=(Group=GSG_Weapon,Level=10),EventDataType=`GET_DamageInt)) + SupportedEvents.Add((EventID=GAMEEVENT_WEAPON_DAMAGE_MELEE,EventName="Melee Damage",StatGroup=(Group=GSG_Weapon,Level=10),EventDataType=`GET_DamageInt)) + SupportedEvents.Add((EventID=GAMEEVENT_WEAPON_FIRED,EventName="Weapon Fired",StatGroup=(Group=GSG_Weapon,Level=10),EventDataType=`GET_WeaponInt)) + + SupportedEvents.Add((EventID=GAMEEVENT_PLAYER_KILL_NORMAL,EventName="Normal Kill",StatGroup=(Group=GSG_Weapon,Level=1),EventDataType=`GET_PlayerKillDeath)) + + SupportedEvents.Add((EventID=GAMEEVENT_MEMORYUSAGE_POLL,EventName="Memory Usage",StatGroup=(Group=GSG_EngineStats,Level=10),EventDataType=`GET_GameInt)) + SupportedEvents.Add((EventID=GAMEEVENT_NETWORKUSAGEIN_POLL,EventName="Network Usage IN",StatGroup=(Group=GSG_EngineStats,Level=10),EventDataType=`GET_GameInt)) + SupportedEvents.Add((EventID=GAMEEVENT_NETWORKUSAGEOUT_POLL,EventName="Network Usage OUT",StatGroup=(Group=GSG_EngineStats,Level=10),EventDataType=`GET_GameInt)) + SupportedEvents.Add((EventID=GAMEEVENT_PING_POLL,EventName="Ping",StatGroup=(Group=GSG_EngineStats,Level=10),EventDataType=`GET_GameInt)) + SupportedEvents.Add((EventID=GAMEEVENT_FRAMERATE_POLL,EventName="Frame Rate",StatGroup=(Group=GSG_EngineStats,Level=10),EventDataType=`GET_GameInt)) + SupportedEvents.Add((EventID=GAMEEVENT_GAMETHREAD_POLL,EventName="Game thread time",StatGroup=(Group=GSG_EngineStats,Level=10),EventDataType=`GET_GamePosition)) + SupportedEvents.Add((EventID=GAMEEVENT_RENDERTHREAD_POLL,EventName="Render thread time",StatGroup=(Group=GSG_EngineStats,Level=10),EventDataType=`GET_GamePosition)) + SupportedEvents.Add((EventID=GAMEEVENT_GPUFRAMETIME_POLL,EventName="GPU render time",StatGroup=(Group=GSG_EngineStats,Level=10),EventDataType=`GET_GamePosition)) + SupportedEvents.Add((EventID=GAMEEVENT_FRAMETIME_POLL,EventName="Total frame time",StatGroup=(Group=GSG_EngineStats,Level=10),EventDataType=`GET_GamePosition)) + SupportedEvents.Add((EventID=`GAMEEVENT_AI_PATH_FAILURE,EventName="AI Path Failure",StatGroup=(Group=GSG_Game,Level=10),EventDataType=`GET_GenericParamList)) + SupportedEvents.Add((EventID=`GAMEEVENT_AI_FIRELINK,EventName="AI Firelink",StatGroup=(Group=GSG_Game,Level=10),EventDataType=`GET_GenericParamList)) +} \ No newline at end of file diff --git a/Engine/Classes/GameplayEventsHandler.uc b/Engine/Classes/GameplayEventsHandler.uc new file mode 100644 index 0000000..beef7f8 --- /dev/null +++ b/Engine/Classes/GameplayEventsHandler.uc @@ -0,0 +1,181 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * Interface for processing events as they are read out of the game stats stream + */ +class GameplayEventsHandler extends Object + abstract + config(GameStats) + native; + +cpptext +{ + /** The function that does the actual handling of data (override with particular implementation) */ + virtual void HandleEvent(struct FGameEventHeader& GameEvent, class IGameEvent* GameEventData); + + /** Handlers for parsing the game stats stream */ + + // Game Event Handling + virtual void HandleGameStringEvent(struct FGameEventHeader& GameEvent, struct FGameStringEvent* GameEventData) {} + virtual void HandleGameIntEvent(struct FGameEventHeader& GameEvent, struct FGameIntEvent* GameEventData) {} + virtual void HandleGameFloatEvent(struct FGameEventHeader& GameEvent, struct FGameFloatEvent* GameEventData) {} + virtual void HandleGamePositionEvent(struct FGameEventHeader& GameEvent, struct FGamePositionEvent* GameEventData) {} + + // Team Event Handling + virtual void HandleTeamStringEvent(struct FGameEventHeader& GameEvent, struct FTeamStringEvent* GameEventData) {} + virtual void HandleTeamIntEvent(struct FGameEventHeader& GameEvent, struct FTeamIntEvent* GameEventData) {} + virtual void HandleTeamFloatEvent(struct FGameEventHeader& GameEvent, struct FTeamFloatEvent* GameEventData) {} + + // Player Event Handling + virtual void HandlePlayerIntEvent(struct FGameEventHeader& GameEvent, struct FPlayerIntEvent* GameEventData) {} + virtual void HandlePlayerFloatEvent(struct FGameEventHeader& GameEvent, struct FPlayerFloatEvent* GameEventData) {} + virtual void HandlePlayerStringEvent(struct FGameEventHeader& GameEvent, struct FPlayerStringEvent* GameEventData) {} + virtual void HandlePlayerSpawnEvent(struct FGameEventHeader& GameEvent, struct FPlayerSpawnEvent* GameEventData) {} + virtual void HandlePlayerLoginEvent(struct FGameEventHeader& GameEvent, struct FPlayerLoginEvent* GameEventData) {} + virtual void HandlePlayerKillDeathEvent(struct FGameEventHeader& GameEvent, struct FPlayerKillDeathEvent* GameEventData) {} + virtual void HandlePlayerPlayerEvent(struct FGameEventHeader& GameEvent, struct FPlayerPlayerEvent* GameEventData) {} + virtual void HandlePlayerLocationsEvent(struct FGameEventHeader& GameEvent, struct FPlayerLocationsEvent* GameEventData) {} + virtual void HandleWeaponIntEvent(struct FGameEventHeader& GameEvent, struct FWeaponIntEvent* GameEventData) {} + virtual void HandleDamageIntEvent(struct FGameEventHeader& GameEvent, struct FDamageIntEvent* GameEventData) {} + virtual void HandleProjectileIntEvent(struct FGameEventHeader& GameEvent, struct FProjectileIntEvent* GameEventData) {} + + /** Access the current session info */ + const FGameSessionInformation& GetSessionInfo() const + { + check(Reader); + return Reader->CurrentSessionInfo; + } + + /** Returns the metadata associated with the given index */ + virtual const FGameplayEventMetaData& GetEventMetaData(INT EventID) const + { + check(Reader); + return Reader->GetEventMetaData(EventID); + } + + /** Returns the metadata associated with the given index */ + const FTeamInformation& GetTeamMetaData(INT TeamIndex) const + { + check(Reader); + return Reader->GetTeamMetaData(TeamIndex); + } + + /** Returns the metadata associated with the given index */ + const FPlayerInformation& GetPlayerMetaData(INT PlayerIndex) const + { + check(Reader); + return Reader->GetPlayerMetaData(PlayerIndex); + } + + /** Returns the metadata associated with the given index */ + const FPawnClassEventData& GetPawnMetaData(INT PawnClassIndex) const + { + check(Reader); + return Reader->GetPawnMetaData(PawnClassIndex); + } + + /** Returns the metadata associated with the given index */ + const FWeaponClassEventData& GetWeaponMetaData(INT WeaponClassIndex) const + { + check(Reader); + return Reader->GetWeaponMetaData(WeaponClassIndex); + } + + /** Returns the metadata associated with the given index */ + const FDamageClassEventData& GetDamageMetaData(INT DamageClassIndex) const + { + check(Reader); + return Reader->GetDamageMetaData(DamageClassIndex); + } + + /** Returns the metadata associated with the given index */ + const FProjectileClassEventData& GetProjectileMetaData(INT ProjectileClassIndex) const + { + check(Reader); + return Reader->GetProjectileMetaData(ProjectileClassIndex); + } + + /** + * Returns the metadata associated with the given index + * @param ActorIndex the index of the actor being looked up + * @return the name of the actor at that index + */ + const FString& GetActorMetaData(INT ActorIndex) const + { + check(Reader); + return Reader->GetActorMetaData(ActorIndex); + } + + /** + * Returns the metadata associated with the given index + * @param SoundIndex the index of the soundcue being looked up + * @return the name of the actor at that index + */ + const FString& GetSoundMetaData(INT SoundIndex) const + { + check(Reader); + return Reader->GetSoundMetaData(SoundIndex); + } + + /** Returns whether or not this processor handles this event */ + inline UBOOL IsEventFiltered(int EventID) const + { + return (EventIDFilter.FindItemIndex(EventID) != INDEX_NONE); + } +} + +/** Array of event types that will be ignored */ +var config array EventIDFilter; + +/** Array of groups to filter, expands out into EventIDFilter above */ +var config array GroupFilter; + +/** Reference to the reader for access to metadata, etc */ +var transient private{protected} GameplayEventsReader Reader; + +/** Set the reader on this handler */ +function SetReader(GameplayEventsReader NewReader) +{ + Reader = NewReader; +} + +/** A chance to do something before the stream starts */ +native event PreProcessStream(); + +/** A chance to do something after the stream ends */ +event PostProcessStream(); + +/** Iterate over all events, checking to see if they should be filtered out by their group */ +event ResolveGroupFilters() +{ + local int EventIdx, FilterIdx; + + for (EventIdx=0; EventIdx GroupFilter[FilterIdx].Level) + { + AddFilter(Reader.SupportedEvents[EventIdx].EventID); + } + } + } +} + +/** Add an event id to ignore while processing */ +function AddFilter(int EventID) +{ + if (EventIDFilter.Find(EventID) == INDEX_NONE) + { + EventIDFilter.AddItem(EventID); + } +} + +/** Remove an event id to ignore while processing */ +function RemoveFilter(int EventID) +{ + EventIDFilter.RemoveItem(EventID); +} \ No newline at end of file diff --git a/Engine/Classes/GameplayEventsReader.uc b/Engine/Classes/GameplayEventsReader.uc new file mode 100644 index 0000000..d7d5047 --- /dev/null +++ b/Engine/Classes/GameplayEventsReader.uc @@ -0,0 +1,86 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * Streams gameplay events recorded during a session to disk + */ +class GameplayEventsReader extends GameplayEvents + native; + +/** Array of handlers for this file when it processes */ +var transient array RegisteredHandlers; + +/** + * Loads a stat file from disk + * @param Filename - name of the file that will be open for serialization + * @return TRUE if successful, else FALSE + */ +native function bool OpenStatsFile(string Filename); + +/** + * Closes and deletes the archive being read from + * clearing all data stored within + */ +native function CloseStatsFile(); + +/** Serialize the contents of the file header */ +native protected function bool SerializeHeader(); + +/** Register a handler with this reader */ +event RegisterHandler(GameplayEventsHandler NewHandler) +{ + local int AddIndex; + if (RegisteredHandlers.Find(NewHandler) == INDEX_NONE) + { + AddIndex = RegisteredHandlers.Length; + RegisteredHandlers.Length = RegisteredHandlers.Length + 1; + RegisteredHandlers[AddIndex] = NewHandler; + NewHandler.SetReader(self); + } +} + +/** Unregister a handler with this reader */ +event UnregisterHandler(GameplayEventsHandler ExistingHandler) +{ + local int RemoveIndex; + RemoveIndex = RegisteredHandlers.Find(ExistingHandler); + // Verify that it is in the array + if (RemoveIndex != INDEX_NONE) + { + RegisteredHandlers.Remove(RemoveIndex,1); + ExistingHandler.SetReader(None); + } +} + +/** Signal start of stream processing */ +native private function ProcessStreamStart(); + +/** Read / process stream data from the file */ +native function ProcessStream(); + +/** Signal end of stream processing */ +native private function ProcessStreamEnd(); + +/** Return the unique session ID */ +native function string GetSessionID(); + +/** Return the title ID of the recorded session */ +native function int GetTitleID(); + +/** Return the platform the data was recorded on */ +native function int GetPlatform(); + +/** Return the timestamp the session started recording */ +native function string GetSessionTimestamp(); + +/** Get the time the session started */ +native function float GetSessionStart(); + +/** Get the time the session ended */ +native function float GetSessionEnd(); + +/** Return the total time the session lasted */ +native function float GetSessionDuration(); + +defaultproperties +{ +} \ No newline at end of file diff --git a/Engine/Classes/GameplayEventsUploadAnalytics.uc b/Engine/Classes/GameplayEventsUploadAnalytics.uc new file mode 100644 index 0000000..a4428bf --- /dev/null +++ b/Engine/Classes/GameplayEventsUploadAnalytics.uc @@ -0,0 +1,196 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * Uploads stream of gameplay events recorded during a session to analytics service + */ +class GameplayEventsUploadAnalytics extends GameplayEventsWriterBase + native; + +/** + * Mark a new session, clear existing events, etc + * + * @param HeartbeatDelta - polling frequency (0 turns it off) + */ +native function StartLogging(optional float HeartbeatDelta); + +/** + * Resets the session, clearing all event data, but keeps the session ID/Timestamp intact + * @param HeartbeatDelta - polling frequency (0 turns it off) + */ +native function ResetLogging(optional float HeartbeatDelta); + +/** + * Mark the end of a logging session + * closes file, stops polling, etc + */ +native function EndLogging(); + +/** +* Logs an int base game event +* +* @param EventId the event being logged +* @param Value the value associated with the event +*/ +native function LogGameIntEvent(int EventId, int Value); + +/** +* Logs a string based game event +* +* @param EventId the event being logged +* @param Value the value associated with the event +*/ +native function LogGameStringEvent(int EventId, string Value); + +/** +* Logs a float based game event +* +* @param EventId the event being logged +* @param Value the value associated with the event +*/ +native function LogGameFloatEvent(int EventId, float Value); + +/** +* Logs a position based game event +* +* @param EventId the event being logged +* @param Position the position of the event +* @param Value the value associated with the event +*/ +native function LogGamePositionEvent(int EventId, const out vector Position, float Value); + +/** +* Logs a int based team event +* +* @param EventId - the event being logged +* @param Team - the team associated with this event +* @param Value - the value associated with the event +*/ +native function LogTeamIntEvent(int EventId, TeamInfo Team, int Value); + +/** +* Logs a float based team event +* +* @param EventId - the event being logged +* @param Team - the team associated with this event +* @param Value - the value associated with the event +*/ +native function LogTeamFloatEvent(int EventId, TeamInfo Team, float Value); + +/** +* Logs a string based team event +* +* @param EventId - the event being logged +* @param Team - the team associated with this event +* @param Value - the value associated with the event +*/ +native function LogTeamStringEvent(int EventId, TeamInfo Team, string Value); + +/** +* Logs an event with an integer value associated with it +* +* @param EventId the event being logged +* @param Player the player that triggered the event +* @param Value the value for this event +*/ +native function LogPlayerIntEvent(int EventId, Controller Player, int Value); + +/** +* Logs an event with an float value associated with it +* +* @param EventId the event being logged +* @param Player the player that triggered the event +* @param Value the value for this event +*/ +native function LogPlayerFloatEvent(int EventId, Controller Player, float Value); + +/** +* Logs an event with an string value associated with it +* +* @param EventId the event being logged +* @param Player the player that triggered the event +* @param EventString the value for this event +*/ +native function LogPlayerStringEvent(int EventId, Controller Player, string EventString); + +/** +* Logs a spawn event for a player (team, class, etc) +* +* @param EventId the event being logged +* @param Player the player that triggered the event +* @param PawnClass the pawn this player spawned with +* @param Team the team the player is on +*/ +native function LogPlayerSpawnEvent(int EventId, Controller Player, class PawnClass, int TeamID); + +/** +* Logs when a player leaves/joins a session +* +* @param EventId the login/logout event for the player +* @param Player the player that joined/left +* @param PlayerName the name of the player in question +* @param PlayerId the net id of the player in question +* @param bSplitScreen whether the player is on splitscreen +*/ +native function LogPlayerLoginChange(int EventId, Controller Player, string PlayerName, UniqueNetId PlayerId, bool bSplitScreen); + +/** +* Logs the location of all players when this event occurred +* +* @param EventId the event being logged +*/ +native function LogAllPlayerPositionsEvent(int EventId); + +/** +* Logs a player killing and a player being killed +* +* @param EventId the event that should be written +* @param KillType the additional information about a kill +* @param Killer the player that did the killing +* @param DmgType the damage type that was done +* @param Dead the player that was killed +*/ +native function LogPlayerKillDeath(int EventId, int KillType, Controller Killer, class DmgType, Controller Dead); + +/** +* Logs a player to player event +* +* @param EventId the event that should be written +* @param Player the player that triggered the event +* @param Target the player that was the recipient +*/ +native function LogPlayerPlayerEvent(int EventId, Controller Player, Controller Target); + +/** +* Logs a weapon event with an integer value associated with it +* +* @param EventId the event being logged +* @param Player the player that triggered the event +* @param WeaponClass the weapon class associated with the event +* @param Value the value for this event +*/ +native function LogWeaponIntEvent(int EventId, Controller Player, class WeaponClass, int Value); + +/** +* Logs damage with the amount that was done and to whom it was done +* +* @param EventId the event being logged +* @param Player the player that triggered the event +* @param DmgType the damage type that was done +* @param Target the player being damaged +* @param Amount the amount of damage done +*/ +native function LogDamageEvent(int EventId, Controller Player, class DmgType, Controller Target, int Amount); + +/** +* Logs a projectile event with an integer value associated with it +* +* @param EventId the event being logged +* @param Player the player that triggered the event +* @param Proj the projectile class associated with the event +* @param Value the value for this event +*/ +native function LogProjectileIntEvent(int EventId, Controller Player, class Proj, int Value); + +function GenericParamListStatEntry GetGenericParamListEntry(); +function RecordAIPathFail(Controller AI, coerce string reason, vector dest); +function int RecordCoverLinkFireLinks(CoverLink Link,Controller Player); diff --git a/Engine/Classes/GameplayEventsWriter.uc b/Engine/Classes/GameplayEventsWriter.uc new file mode 100644 index 0000000..9f6be0c --- /dev/null +++ b/Engine/Classes/GameplayEventsWriter.uc @@ -0,0 +1,339 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * Streams gameplay events recorded during a session to disk + */ +class GameplayEventsWriter extends GameplayEventsWriterBase + native; + +`include(Engine\Classes\GameStats.uci); + +cpptext +{ + /** + * Turns a controller into a player index, possibly adding new information to the player array + * @param TeamInfo - TeamInfo class to resolve an index for + * @return Index of the team in the team metadata array + */ + virtual INT ResolveTeamIndex(class ATeamInfo *TeamInfo); + + /** Turns a weapon class into an index, possibly adding new information to the array **/ + INT ResolveWeaponClassIndex(UClass* WeaponClass); + + /** Turns a damage class into an index, possibly adding new information to the array **/ + INT ResolveDamageClassIndex(UClass* DamageClass); + + /** Turns a projectile class into an index, possibly adding new information to the array **/ + INT ResolveProjectileClassIndex(UClass* ProjectileClass); + + /** Turns a pawn class into an index, possibly adding new information to the array **/ + INT ResolvePawnIndex(UClass* PawnClass); + + /** + * Turns an actor into an index + * @param Actor the actor to find in the array + * @return the index in the array for that actor + */ + INT ResolveActorIndex(AActor* Actor); + + /** + * Turns an sound cue into an index + * + * @param Cue the sound cue to find in the array + * + * @return the index in the array for that sound cue + */ + INT ResolveSoundCueIndex(USoundCue* Cue); +}; + +/** Turns a controller into a player index, possibly adding new information to the player array **/ +function native int ResolvePlayerIndex(Controller Player); + +/** + * Creates the archive that we are going to write to + * @param Filename - name of the file that will be open for serialization + * @return TRUE if successful, else FALSE + */ +native function bool OpenStatsFile(string Filename); + +/** + * Closes and deletes the archive that was being written to + * clearing all data stored within + */ +native function CloseStatsFile(); + +/** Serialize the contents of the file header */ +native protected function bool SerializeHeader(); + +/** Serialize the contents of the file footer */ +native protected function bool SerializeFooter(); + +/** + * Mark a new session, clear existing events, etc + * + * @param HeartbeatDelta - polling frequency (0 turns it off) + */ +native function StartLogging(optional float HeartbeatDelta); + +/** + * Resets the session, clearing all event data, but keeps the session ID/Timestamp intact + * @param HeartbeatDelta - polling frequency (0 turns it off) + */ +native function ResetLogging(optional float HeartbeatDelta); + +/** + * Mark the end of a logging session + * closes file, stops polling, etc + */ +native function EndLogging(); + +/** +* Logs an int base game event +* +* @param EventId the event being logged +* @param Value the value associated with the event +*/ +native function LogGameIntEvent(int EventId, int Value); + +/** +* Logs a string based game event +* +* @param EventId the event being logged +* @param Value the value associated with the event +*/ +native function LogGameStringEvent(int EventId, string Value); + +/** +* Logs a float based game event +* +* @param EventId the event being logged +* @param Value the value associated with the event +*/ +native function LogGameFloatEvent(int EventId, float Value); + +/** +* Logs a position based game event +* +* @param EventId the event being logged +* @param Position the position of the event +* @param Value the value associated with the event +*/ +native function LogGamePositionEvent(int EventId, const out vector Position, float Value); + +/** +* Logs a int based team event +* +* @param EventId - the event being logged +* @param Team - the team associated with this event +* @param Value - the value associated with the event +*/ +native function LogTeamIntEvent(int EventId, TeamInfo Team, int Value); + +/** +* Logs a float based team event +* +* @param EventId - the event being logged +* @param Team - the team associated with this event +* @param Value - the value associated with the event +*/ +native function LogTeamFloatEvent(int EventId, TeamInfo Team, float Value); + +/** +* Logs a string based team event +* +* @param EventId - the event being logged +* @param Team - the team associated with this event +* @param Value - the value associated with the event +*/ +native function LogTeamStringEvent(int EventId, TeamInfo Team, string Value); + +/** +* Logs an event with an integer value associated with it +* +* @param EventId the event being logged +* @param Player the player that triggered the event +* @param Value the value for this event +*/ +native function LogPlayerIntEvent(int EventId, Controller Player, int Value); + +/** +* Logs an event with an float value associated with it +* +* @param EventId the event being logged +* @param Player the player that triggered the event +* @param Value the value for this event +*/ +native function LogPlayerFloatEvent(int EventId, Controller Player, float Value); + +/** +* Logs an event with an string value associated with it +* +* @param EventId the event being logged +* @param Player the player that triggered the event +* @param EventString the value for this event +*/ +native function LogPlayerStringEvent(int EventId, Controller Player, string EventString); + +/** +* Logs a spawn event for a player (team, class, etc) +* +* @param EventId the event being logged +* @param Player the player that triggered the event +* @param PawnClass the pawn this player spawned with +* @param Team the team the player is on +*/ +native function LogPlayerSpawnEvent(int EventId, Controller Player, class PawnClass, int TeamID); + +/** +* Logs when a player leaves/joins a session +* +* @param EventId the login/logout event for the player +* @param Player the player that joined/left +* @param PlayerName the name of the player in question +* @param PlayerId the net id of the player in question +* @param bSplitScreen whether the player is on splitscreen +*/ +native function LogPlayerLoginChange(int EventId, Controller Player, string PlayerName, UniqueNetId PlayerId, bool bSplitScreen); + +/** +* Logs the location of all players when this event occurred +* +* @param EventId the event being logged +*/ +native function LogAllPlayerPositionsEvent(int EventId); + +/** +* Logs a player killing and a player being killed +* +* @param EventId the event that should be written +* @param KillType the additional information about a kill +* @param Killer the player that did the killing +* @param DmgType the damage type that was done +* @param Dead the player that was killed +*/ +native function LogPlayerKillDeath(int EventId, int KillType, Controller Killer, class DmgType, Controller Dead); + +/** +* Logs a player to player event +* +* @param EventId the event that should be written +* @param Player the player that triggered the event +* @param Target the player that was the recipient +*/ +native function LogPlayerPlayerEvent(int EventId, Controller Player, Controller Target); + +/** +* Logs a weapon event with an integer value associated with it +* +* @param EventId the event being logged +* @param Player the player that triggered the event +* @param WeaponClass the weapon class associated with the event +* @param Value the value for this event +*/ +native function LogWeaponIntEvent(int EventId, Controller Player, class WeaponClass, int Value); + +/** +* Logs damage with the amount that was done and to whom it was done +* +* @param EventId the event being logged +* @param Player the player that triggered the event +* @param DmgType the damage type that was done +* @param Target the player being damaged +* @param Amount the amount of damage done +*/ +native function LogDamageEvent(int EventId, Controller Player, class DmgType, Controller Target, int Amount); + +/** +* Logs a projectile event with an integer value associated with it +* +* @param EventId the event being logged +* @param Player the player that triggered the event +* @param Proj the projectile class associated with the event +* @param Value the value for this event +*/ +native function LogProjectileIntEvent(int EventId, Controller Player, class Proj, int Value); + + +/** Log various system properties like memory usage, network usage, etc. */ +native function LogSystemPollEvents(); + +/** will return a generic param list entry that can then have params set on it before commiting to disk */ +native function GenericParamListStatEntry GetGenericParamListEntry(); + +function RecordAIPathFail(Controller AI, coerce string reason, vector dest) +{ +`if(`notdefined(FINAL_RELEASE)) + local GenericParamListStatEntry PLE; + + if( AI.Pawn != none ) + { + PLE = GetGenericParamListEntry(); + PLE.AddInt('EventID',`GAMEEVENT_AI_PATH_FAILURE); + PLE.AddString('Name',AI.Name); + PLE.AddVector('BaseLocation',AI.Pawn.Location); + PLE.AddString('Sprite',"Texture2D'EditorResources.BadPylon'"); + PLE.AddString('Text',reason); + PLE.AddVector('LineStart',AI.Pawn.Location); + PLE.AddVector('LineEnd',dest); + PLE.AddVector('BoxLoc',dest); + PLE.AddVector('BoxExtent',vect(5,5,5)); + PLE.AddInt('PlayerIndex',ResolvePlayerIndex(AI)); + PLE.CommitToDisk(); + } +`endif +} + +function int RecordCoverLinkFireLinks(CoverLink Link,Controller Player) +{ +`if(`notdefined(FINAL_RELEASE)) + local GenericParamListStatEntry PLE; + local int SlotIdx; + local int FireLinkIdx; + local vector SlotLoc; + local vector DestLoc; + local int Recorded; + local CoverInfo DestInfo; + + for(SlotIdx=0;SlotIdx PawnClass, int TeamID); + +/** +* Logs when a player leaves/joins a session +* +* @param EventId the login/logout event for the player +* @param Player the player that joined/left +* @param PlayerName the name of the player in question +* @param PlayerId the net id of the player in question +* @param bSplitScreen whether the player is on splitscreen +*/ +function LogPlayerLoginChange(int EventId, Controller Player, string PlayerName, UniqueNetId PlayerId, bool bSplitScreen); + +/** +* Logs the location of all players when this event occurred +* +* @param EventId the event being logged +*/ +function LogAllPlayerPositionsEvent(int EventId); + +/** +* Logs a player killing and a player being killed +* +* @param EventId the event that should be written +* @param KillType the additional information about a kill +* @param Killer the player that did the killing +* @param DmgType the damage type that was done +* @param Dead the player that was killed +*/ +function LogPlayerKillDeath(int EventId, int KillType, Controller Killer, class DmgType, Controller Dead); + +/** +* Logs a player to player event +* +* @param EventId the event that should be written +* @param Player the player that triggered the event +* @param Target the player that was the recipient +*/ +function LogPlayerPlayerEvent(int EventId, Controller Player, Controller Target); + +/** +* Logs a weapon event with an integer value associated with it +* +* @param EventId the event being logged +* @param Player the player that triggered the event +* @param WeaponClass the weapon class associated with the event +* @param Value the value for this event +*/ +function LogWeaponIntEvent(int EventId, Controller Player, class WeaponClass, int Value); + +/** +* Logs damage with the amount that was done and to whom it was done +* +* @param EventId the event being logged +* @param Player the player that triggered the event +* @param DmgType the damage type that was done +* @param Target the player being damaged +* @param Amount the amount of damage done +*/ +function LogDamageEvent(int EventId, Controller Player, class DmgType, Controller Target, int Amount); + +/** +* Logs a projectile event with an integer value associated with it +* +* @param EventId the event being logged +* @param Player the player that triggered the event +* @param Proj the projectile class associated with the event +* @param Value the value for this event +*/ +function LogProjectileIntEvent(int EventId, Controller Player, class Proj, int Value); + +/** Log various system properties like memory usage, network usage, etc. */ +function LogSystemPollEvents(); + +/** AI pathfinding failure event */ +function RecordAIPathFail(Controller AI, coerce string reason, vector dest); + +/** Coverlink fire event */ +function int RecordCoverLinkFireLinks(CoverLink Link,Controller Player); \ No newline at end of file diff --git a/Engine/Classes/GeneratedMeshAreaLight.uc b/Engine/Classes/GeneratedMeshAreaLight.uc new file mode 100644 index 0000000..0bd5fa2 --- /dev/null +++ b/Engine/Classes/GeneratedMeshAreaLight.uc @@ -0,0 +1,19 @@ +/** + * GeneratedMeshAreaLight - A light type that is created after a lighting build with Lightmass and handles mesh area light influence on dynamic objects. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class GeneratedMeshAreaLight extends SpotLight + native(Light) + notplaceable; + +defaultproperties +{ + // Don't want these to be modified by users since they will all be regenerated on the next lighting build + bEditable=false + Begin Object Name=SpotLightComponent0 + // By default only affect light environments + LightingChannels=(BSP=FALSE,Static=FALSE,Dynamic=FALSE,CompositeDynamic=TRUE,bInitialized=TRUE) + CastStaticShadows=FALSE + End Object +} diff --git a/Engine/Classes/GenericParamListStatEntry.uc b/Engine/Classes/GenericParamListStatEntry.uc new file mode 100644 index 0000000..e859a5e --- /dev/null +++ b/Engine/Classes/GenericParamListStatEntry.uc @@ -0,0 +1,30 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class GenericParamListStatEntry extends Object + native; + +cpptext +{ + // don't leak the stat event if we get destroyed before disk-commit for some reason + virtual void BeginDestroy(); +}; + +var native transient pointer StatEvent{struct FGenericParamListEvent}; +var protected transient GameplayEventsWriter Writer; + +// setters for supported data types +function native AddFloat(name ParamName, float Value); +function native AddInt(name ParamName, Int Value); +function native AddVector(name ParamName, Vector Value); +function native AddString(name ParamName, coerce String Value); + +// getters for supported data types +function native bool GetFloat(name ParamName, out float out_Float); +function native bool GetInt(name ParamName, out int out_int); +function native bool GetVector(name ParamName, out vector out_vector); +function native bool GetString(name ParamName, out string out_string); + +// will write this event to disk +function native CommitToDisk(); + diff --git a/Engine/Classes/Goal_AtActor.uc b/Engine/Classes/Goal_AtActor.uc new file mode 100644 index 0000000..43f62b8 --- /dev/null +++ b/Engine/Classes/Goal_AtActor.uc @@ -0,0 +1,96 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class Goal_AtActor extends PathGoalEvaluator + native(AI); + +cpptext +{ + // Interface + virtual UBOOL InitialAbortCheck( ANavigationPoint* Start, APawn* Pawn ); + virtual UBOOL EvaluateGoal(ANavigationPoint*& PossibleGoal, APawn* Pawn); + virtual void NotifyExceededMaxPathVisits( ANavigationPoint* BestGuess ); +} + +/** Actor to reach */ +var Actor GoalActor; +/** Within this acceptable distance */ +var float GoalDist; +/** Should keep track of cheapest path even if don't reach goal */ +var bool bKeepPartial; + +static function bool AtActor( Pawn P, Actor Goal, optional float Dist, optional bool bReturnPartial ) +{ + local Goal_AtActor Eval; + local Pawn GoalPawn; + local Controller GoalController; + local float AnchorDist; + + if( P != None ) + { + GoalPawn = Pawn(Goal); + GoalController = Controller(Goal); + if( GoalController != None ) + { + if( GoalController.Pawn != None ) + { + GoalPawn = GoalController.Pawn; + } + else + { + Goal = None; + } + } + // redirect to best nav point if possible + if( GoalPawn != None ) + { + // If moving to a pawn with a valid anchor, make sure the anchor can support the searching pawn + if( GoalPawn.ValidAnchor() && GoalPawn.Anchor.IsUsableAnchorFor( P ) ) + { + Goal = GoalPawn.Anchor; + } + else + { + Goal = P.GetBestAnchor(GoalPawn, GoalPawn.Location, FALSE, FALSE, AnchorDist); + } + } + else if (NavigationPoint(Goal) == None) + { + Goal = P.GetBestAnchor(Goal, Goal.Location, false, false, AnchorDist); + if(Goal == none) + { + `log("PATHWARNING: Not pushing AtActor goal constraint because we couldn't find an anchor for goal!"); + } + } + + if( Goal != None ) + { + Eval = Goal_AtActor(P.CreatePathGoalEvaluator(default.class)); + + if( Eval != None ) + { + Eval.GoalActor = Goal; + Eval.GoalDist = Dist; + Eval.bKeepPartial = bReturnPartial; + P.AddGoalEvaluator( Eval ); + return TRUE; + } + } + } + + return FALSE; +} + +function Recycle() +{ + GoalActor = none; + GoalDist = default.GoalDist; + bKeepPartial = default.bKeepPartial; + Super.Recycle(); +} + +defaultproperties +{ + CacheIdx=0 + MaxPathVisits=1024 +} diff --git a/Engine/Classes/Goal_Null.uc b/Engine/Classes/Goal_Null.uc new file mode 100644 index 0000000..36aeca6 --- /dev/null +++ b/Engine/Classes/Goal_Null.uc @@ -0,0 +1,47 @@ +/** +* Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +* this goal eval will not stop until its out of paths, and will simply return the node with the least cost +*/ +class Goal_Null extends PathGoalEvaluator + native(AI); + +cpptext +{ + // Interface + virtual UBOOL EvaluateGoal(ANavigationPoint*& PossibleGoal, APawn* Pawn); + virtual void NotifyExceededMaxPathVisits( ANavigationPoint* BestGuess ){/*don't care about best guess.. just ignore this*/} +} + +static function bool GoUntilBust( Pawn P, optional int InMaxPathVisits=-1 ) +{ + local Goal_Null Eval; + + if( P != None ) + { + Eval = Goal_Null(P.CreatePathGoalEvaluator(default.class)); + + if( Eval != None ) + { + if(InMaxPathVisits > 0) + { + Eval.MaxPathVisits = InMaxPathVisits; + } + P.AddGoalEvaluator( Eval ); + return TRUE; + } + } + + return FALSE; +} + +function Recycle() +{ + Super.Recycle(); + MaxPathVisits=default.maxPathVisits; +} + +defaultproperties +{ + CacheIdx=5 + MaxPathVisits=2048 +} diff --git a/Engine/Classes/GravityVolume.uc b/Engine/Classes/GravityVolume.uc new file mode 100644 index 0000000..6b405c3 --- /dev/null +++ b/Engine/Classes/GravityVolume.uc @@ -0,0 +1,23 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class GravityVolume extends PhysicsVolume + native + placeable; + +/** + * Simple PhysicsVolume that modifies the gravity inside it. + */ + +/** Gravity along Z axis applied to objects inside this volume. */ +var() float GravityZ; + +cpptext +{ + virtual FLOAT GetGravityZ() { return GravityZ; } +} + +defaultproperties +{ + GravityZ = -520.0 +} diff --git a/Engine/Classes/HUD.uc b/Engine/Classes/HUD.uc new file mode 100644 index 0000000..0165615 --- /dev/null +++ b/Engine/Classes/HUD.uc @@ -0,0 +1,994 @@ +//============================================================================= +// HUD: Superclass of the heads-up display. +// +//Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class HUD extends Actor + native + config(Game) + transient + dependson(Canvas); + +//============================================================================= +// Variables. + +var const color WhiteColor, GreenColor, RedColor; + +var PlayerController PlayerOwner; // always the actual owner + +/** Tells whether the game was paused due to lost focus */ +var transient bool bLostFocusPaused; + +// Visibility flags + +var config bool bShowHUD; // Is the hud visible +var bool bShowScores; // Is the Scoreboard visible +var bool bShowDebugInfo; // If true, show properties of current ViewTarget +var() bool bShowBadConnectionAlert; // Display indication of bad connection (set in C++ based on lag and packetloss). + +var config bool bShowDirectorInfoDebug; // If true matinee/director information will be visible in the HUD in DebugText +var config bool bShowDirectorInfoHUD; // If true matinee/director information will be visible in the HUD (using KismetTextInfo) + +var globalconfig bool bMessageBeep; // If true, any console messages will make a beep + +var globalconfig float HudCanvasScale; // Specifies amount of screen-space to use (for TV's). + +/** Use the full screen extents for the canvas. Ignores splitscreen and cinematic mode scaling. */ +var bool bRenderFullScreen; + +/** Scale the canvas in with the cinematic black bars. Default behavior. */ +var bool bScaleCanvasForCinematicMode; + +/** If true, render actor overlays */ +var bool bShowOverlays; + +/** Holds a list of Actors that need PostRender calls */ +var array PostRenderedActors; + +// Console Messages + +struct native ConsoleMessage +{ + var string Text; + var color TextColor; + var float MessageLife; + var PlayerReplicationInfo PRI; +}; + +var array ConsoleMessages; +var const Color ConsoleColor; + +var config int ConsoleMessageCount; +var globalconfig int ConsoleFontSize; +var globalconfig int MessageFontOffset; + +var int MaxHUDAreaMessageCount; + +// Localized Messages +struct native HudLocalizedMessage +{ + // The following block of variables are set when the message is entered; + // (Message being set indicates that a message is in the list). + + var class Message; + var String StringMessage; + var int Switch; + var float EndOfLife; + var float Lifetime; + var float PosY; + var Color DrawColor; + var int FontSize; + + // The following block of variables are cached on first render; + // (StringFont being set indicates that they've been rendered). + + var Font StringFont; + var float DX, DY; + var bool Drawn; + var int Count; + var object OptionalObject; +}; +var() transient HudLocalizedMessage LocalMessages[8]; + +var() float ConsoleMessagePosX, ConsoleMessagePosY; // DP_LowerLeft + +/** + * Canvas to Draw HUD on. + * NOTE: a new Canvas is given every frame, only draw on it from the HUD::PostRender() event */ +var /*const*/ Canvas Canvas; + +// +// Useful variables +// + +/** Used to create DeltaTime */ +var transient float LastHUDRenderTime; +/** Time since last render */ +var transient float RenderDelta; +/** Size of ViewPort in pixels */ +var transient float SizeX, SizeY; +/** Center of Viewport */ +var transient float CenterX, CenterY; +/** Ratio of viewport compared to native resolution 1024x768 */ +var transient float RatioX, RatioY; + +var globalconfig array DebugDisplay; // array of strings specifying what debug info to display for viewtarget actor + // base engine types include "AI", "physics", "weapon", "net", "camera", and "collision" + +struct native KismetDrawTextInfo +{ + var() string MessageText; + var string AppendedText; + var() Font MessageFont; + var() vector2d MessageFontScale; + var() vector2d MessageOffset; + var() Color MessageColor; + var float MessageEndTime; +}; +var array KismetTextInfo; + +//============================================================================= +// Utils +//============================================================================= + +// Draw3DLine - draw line in world space. +native final function Draw3DLine(vector Start, vector End, color LineColor); +native final function Draw2DLine(int X1, int Y1, int X2, int Y2, color LineColor); + +event PostBeginPlay() +{ + super.PostBeginPlay(); + + PlayerOwner = PlayerController(Owner); + + // e.g. getting material pointers to control effects for gameplay + NotifyBindPostProcessEffects(); +} + +/* DrawActorOverlays() +draw overlays for actors that were rendered this tick and have added themselves to the PostRenderedActors array +*/ +native function DrawActorOverlays(vector Viewpoint, rotator ViewRotation); + +/************************************************************************************************************ + Actor Render - These functions allow for actors in the world to gain access to the hud and render + information on it. +************************************************************************************************************/ + +/** RemovePostRenderedActor() +remove an actor from the PostRenderedActors array +*/ +function RemovePostRenderedActor(Actor A) +{ + local int i; + + for ( i=0; i 0 ) + { + FirstRouteCache = C.RouteCache[0]; + } + + // show where pawn is going + if ( (C == PlayerOwner) + || (C.MoveTarget == FirstRouteCache) && (C.MoveTarget != None) ) + { + if ( (C == PlayerOwner) && (Dest != vect(0,0,0)) ) + { + if ( C.PointReachable(Dest) ) + { + Draw3DLine(C.Pawn.Location, Dest, MakeColor(255,255,255,255)); + return; + } + C.FindPathTo(Dest); + } + if( C.RouteCache.Length > 0 ) + { + for ( i=0; i InMessageClass, PlayerReplicationInfo PRI, optional float LifeTime) +{ + local int Idx, MsgIdx; + MsgIdx = -1; + // check for beep on message receipt + if( bMessageBeep && InMessageClass.default.bBeep ) + { + PlayerOwner.PlayBeepSound(); + } + // find the first available entry + if (ConsoleMessages.Length < ConsoleMessageCount) + { + MsgIdx = ConsoleMessages.Length; + } + else + { + // look for an empty entry + for (Idx = 0; Idx < ConsoleMessages.Length && MsgIdx == -1; Idx++) + { + if (ConsoleMessages[Idx].Text == "") + { + MsgIdx = Idx; + } + } + } + if( MsgIdx == ConsoleMessageCount || MsgIdx == -1) + { + // push up the array + for(Idx = 0; Idx < ConsoleMessageCount-1; Idx++ ) + { + ConsoleMessages[Idx] = ConsoleMessages[Idx+1]; + } + MsgIdx = ConsoleMessageCount - 1; + } + // fill in the message entry + if (MsgIdx >= ConsoleMessages.Length) + { + ConsoleMessages.Length = MsgIdx + 1; + } + + ConsoleMessages[MsgIdx].Text = M; + if (LifeTime != 0.f) + { + ConsoleMessages[MsgIdx].MessageLife = WorldInfo.TimeSeconds + LifeTime; + } + else + { + ConsoleMessages[MsgIdx].MessageLife = WorldInfo.TimeSeconds + InMessageClass.default.LifeTime; + } + + ConsoleMessages[MsgIdx].TextColor = InMessageClass.static.GetConsoleColor(PRI); + ConsoleMessages[MsgIdx].PRI = PRI; +} + +//=============================================== +// Localized Message rendering + +function LocalizedMessage +( + class InMessageClass, + PlayerReplicationInfo RelatedPRI_1, + PlayerReplicationInfo RelatedPRI_2, + string CriticalString, + int Switch, + float Position, + float LifeTime, + int FontSize, + color DrawColor, + optional object OptionalObject +) +{ + local int i, LocalMessagesArrayCount, MessageCount; + + if( InMessageClass == None || CriticalString == "" ) + { + return; + } + + if( bMessageBeep && InMessageClass.default.bBeep ) + PlayerOwner.PlayBeepSound(); + + if( !InMessageClass.default.bIsSpecial ) + { + AddConsoleMessage( CriticalString, InMessageClass, RelatedPRI_1 ); + return; + } + + LocalMessagesArrayCount = ArrayCount(LocalMessages); + i = LocalMessagesArrayCount; + if( InMessageClass.default.bIsUnique ) + { + for( i = 0; i < LocalMessagesArrayCount; i++ ) + { + if( LocalMessages[i].Message == InMessageClass ) + { + if ( InMessageClass.default.bCountInstances && (LocalMessages[i].StringMessage ~= CriticalString) ) + { + MessageCount = (LocalMessages[i].Count == 0) ? 2 : LocalMessages[i].Count + 1; + } + break; + } + } + } + else if ( InMessageClass.default.bIsPartiallyUnique ) + { + for( i = 0; i < LocalMessagesArrayCount; i++ ) + { + if( ( LocalMessages[i].Message == InMessageClass ) + && InMessageClass.static.PartiallyDuplicates(Switch, LocalMessages[i].Switch, OptionalObject, LocalMessages[i].OptionalObject) ) + break; + } + } + + if( i == LocalMessagesArrayCount ) + { + for( i = 0; i < LocalMessagesArrayCount; i++ ) + { + if( LocalMessages[i].Message == None ) + break; + } + } + + if( i == LocalMessagesArrayCount ) + { + for( i = 0; i < LocalMessagesArrayCount - 1; i++ ) + LocalMessages[i] = LocalMessages[i+1]; + } + + ClearMessage( LocalMessages[i] ); + + // Add the local message to the spot. + AddLocalizedMessage(i, InMessageClass, CriticalString, Switch, Position, LifeTime, FontSize, DrawColor, MessageCount, OptionalObject); + +} + +/** + * Add the actual message to the array. Made easier to tweak in a subclass + * + * @Param Index The index in to the LocalMessages array to place it. + * @Param InMessageClass Class of the message + * @Param CriticialString String of the message + * @Param Switch The message switch + * @Param Position Where on the screen is the message + * @Param LifeTime How long does this message live + * @Param FontSize How big is the message + * @Param DrawColor The Color of the message + */ +function AddLocalizedMessage +( + int Index, + class InMessageClass, + string CriticalString, + int Switch, + float Position, + float LifeTime, + int FontSize, + color DrawColor, + optional int MessageCount, + optional object OptionalObject +) +{ + LocalMessages[Index].Message = InMessageClass; + LocalMessages[Index].Switch = Switch; + LocalMessages[Index].EndOfLife = LifeTime + WorldInfo.TimeSeconds; + LocalMessages[Index].StringMessage = CriticalString; + LocalMessages[Index].LifeTime = LifeTime; + LocalMessages[Index].PosY = Position; + LocalMessages[Index].DrawColor = DrawColor; + LocalMessages[Index].FontSize = FontSize; + LocalMessages[Index].Count = MessageCount; + LocalMessages[Index].OptionalObject = OptionalObject; +} + + +function GetScreenCoords(float PosY, out float ScreenX, out float ScreenY, out HudLocalizedMessage InMessage ) +{ + ScreenX = 0.5 * Canvas.ClipX; + ScreenY = (PosY * HudCanvasScale * Canvas.ClipY) + (((1.0f - HudCanvasScale) * 0.5f) * Canvas.ClipY); + + ScreenX -= InMessage.DX * 0.5; + ScreenY -= InMessage.DY * 0.5; +} + +function DrawMessage(int i, float PosY, out float DX, out float DY ) +{ + local float FadeValue; + local float ScreenX, ScreenY; + + FadeValue = FMin(1.0, LocalMessages[i].EndOfLife - WorldInfo.TimeSeconds); + + Canvas.DrawColor = LocalMessages[i].DrawColor; + Canvas.DrawColor.A = FadeValue * Canvas.DrawColor.A; + Canvas.Font = LocalMessages[i].StringFont; + GetScreenCoords( PosY, ScreenX, ScreenY, LocalMessages[i] ); + DX = LocalMessages[i].DX / Canvas.ClipX; + DY = LocalMessages[i].DY / Canvas.ClipY; + + DrawMessageText(LocalMessages[i], ScreenX, ScreenY); + LocalMessages[i].Drawn = true; +} + +function DrawMessageText(HudLocalizedMessage LocalMessage, float ScreenX, float ScreenY) +{ + local FontRenderInfo FontInfo; + + Canvas.SetPos(ScreenX, ScreenY); + FontInfo.bClipText = true; + Canvas.DrawText(LocalMessage.StringMessage, FALSE,,, FontInfo); +} + +function DisplayLocalMessages() +{ + local float PosY, DY, DX; + local int i, j, LocalMessagesArrayCount, AreaMessageCount; + local float FadeValue; + local int FontSize; + + // early out + if ( LocalMessages[0].Message == None ) + return; + + Canvas.Reset(true); + LocalMessagesArrayCount = ArrayCount(LocalMessages); + + // Pass 1: Layout anything that needs it and cull dead stuff. + for( i = 0; i < LocalMessagesArrayCount; i++ ) + { + if( LocalMessages[i].Message == None ) + { + break; + } + + LocalMessages[i].Drawn = false; + + if( LocalMessages[i].StringFont == None ) + { + FontSize = LocalMessages[i].FontSize + MessageFontOffset; + LocalMessages[i].StringFont = GetFontSizeIndex(FontSize); + Canvas.Font = LocalMessages[i].StringFont; + Canvas.TextSize( LocalMessages[i].StringMessage, DX, DY ); + LocalMessages[i].DX = DX; + LocalMessages[i].DY = DY; + + if( LocalMessages[i].StringFont == None ) + { +// `warn( "LayoutMessage("$LocalMessages[i].Message$") failed!" ); + + for( j = i; j < LocalMessagesArrayCount - 1; j++ ) + LocalMessages[j] = LocalMessages[j+1]; + ClearMessage( LocalMessages[j] ); + i--; + continue; + } + } + + FadeValue = (LocalMessages[i].EndOfLife - WorldInfo.TimeSeconds); + + if( FadeValue <= 0.0 ) + { + for( j = i; j < LocalMessagesArrayCount - 1; j++ ) + LocalMessages[j] = LocalMessages[j+1]; + ClearMessage( LocalMessages[j] ); + i--; + continue; + } + } + + // Pass 2: Go through the list and draw each stack: + for( i = 0; i < LocalMessagesArrayCount; i++ ) + { + if( LocalMessages[i].Message == None ) + break; + + if( LocalMessages[i].Drawn ) + continue; + + PosY = LocalMessages[i].PosY; + AreaMessageCount = 0; + + for( j = i; j < LocalMessagesArrayCount; j++ ) + { + if( LocalMessages[j].Drawn || (LocalMessages[i].PosY != LocalMessages[j].PosY) ) + { + continue; + } + + DrawMessage( j, PosY, DX, DY ); + + PosY += DY; + AreaMessageCount++; + } + if ( AreaMessageCount > MaxHUDAreaMessageCount ) + { + LocalMessages[i].EndOfLife = WorldInfo.TimeSeconds; + } + } +} + +function DisplayKismetMessages() +{ + local int KismetTextIdx; + + KismetTextIdx = 0; + while( KismetTextIdx < KismetTextInfo.length ) + { + if( KismetTextInfo[KismetTextIdx].MessageEndTime > 0 && KismetTextInfo[KismetTextIdx].MessageEndTime <= WorldInfo.TimeSeconds) + { + KismetTextInfo.Remove(KismetTextIdx,1); + } + else + { + DrawText(KismetTextInfo[KismetTextIdx].MessageText$KismetTextInfo[KismetTextIdx].AppendedText, + KismetTextInfo[KismetTextIdx].MessageOffset, KismetTextInfo[KismetTextIdx].MessageFont, KismetTextInfo[KismetTextIdx].MessageFontScale, KismetTextInfo[KismetTextIdx].MessageColor); + ++KismetTextIdx; + } + } +} + + +function DrawText(string Text, vector2d Position, Font TextFont, vector2d FontScale, Color TextColor, optional const out FontRenderInfo RenderInfo) +{ + local float XL, YL; + + Canvas.Font = TextFont; + Canvas.TextSize(Text, XL, YL); + Canvas.SetPos(Canvas.ClipX/2 - XL/2 + Position.X, Canvas.ClipY/3 - YL/2 + Position.Y); + Canvas.SetDrawColor(TextColor.R, TextColor.G, TextColor.B, TextColor.A); + Canvas.DrawText(Text, FALSE, FontScale.X, FontScale.Y, RenderInfo); +} + +static function Font GetFontSizeIndex(int FontSize) +{ + if ( FontSize == 0 ) + { + return class'Engine'.Static.GetTinyFont(); + } + else if ( FontSize == 1 ) + { + return class'Engine'.Static.GetSmallFont(); + } + else if ( FontSize == 2 ) + { + return class'Engine'.Static.GetMediumFont(); + } + else if ( FontSize == 3 ) + { + return class'Engine'.Static.GetLargeFont(); + } + else + { + return class'Engine'.Static.GetLargeFont(); + } +} + +/** + * Called when the player owner has died. + */ +function PlayerOwnerDied() +{ +} + +/** + * Called in PostBeginPlay or postprocessing chain has changed (happens because of the worldproperties can define it's own chain and this one is set late). + */ +function NotifyBindPostProcessEffects() +{ + // overload with custom code e.g. getting material pointers to control effects for gameplay. +} + +/** + * Pauses or unpauses the game due to main window's focus being lost. + * @param Enable tells whether to enable or disable the pause state + */ +event OnLostFocusPause(bool bEnable) +{ + if ( bLostFocusPaused == bEnable ) + return; + + if ( WorldInfo.NetMode != NM_Client ) + { + bLostFocusPaused = bEnable; + PlayerOwner.SetPause(bEnable); + } +} + +defaultproperties +{ + TickGroup=TG_DuringAsyncWork + + bHidden=true + RemoteRole=ROLE_None + + WhiteColor=(R=255,G=255,B=255,A=255) + ConsoleColor=(R=153,G=216,B=253,A=255) + GreenColor=(R=0,G=255,B=0,A=255) + RedColor=(R=255,G=0,B=0,A=255) + + ConsoleMessagePosY=0.8 + MaxHUDAreaMessageCount=3 + + bLostFocusPaused=false + + bScaleCanvasForCinematicMode=true + bRenderFullScreen=false +} diff --git a/Engine/Classes/HeadTrackingComponent.uc b/Engine/Classes/HeadTrackingComponent.uc new file mode 100644 index 0000000..a07be4d --- /dev/null +++ b/Engine/Classes/HeadTrackingComponent.uc @@ -0,0 +1,128 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * When you attach this class, make sure you don't have any other HeadTrackingComponent + * That will create conflict. It will warn if it already has headtrackingcomponent + */ +class HeadTrackingComponent extends ActorComponent + native(Anim); + +/** SkelControlLookAt name in the AnimTree of the SkeletalMesh **/ +var() array TrackControllerName; + +/** Will pick up actor within this radius **/ +var() float LookAtActorRadius; + +/** Interp back to zero strength if limit surpassed */ +var() bool bDisableBeyondLimit; + +/** How long can one person to look at one **/ +var() float MaxLookAtTime; + +/** At least this time to look at one **/ +var() float MinLookAtTime; + +/** Once entered the radius, how long do I really care to look ? This affects rating. It will give benefit to the person who just entered **/ +var() float MaxInterestTime; + +/** Actor classes to look at as 0 index being the highest priority if you have anything specific **/ +var(Target) array< class > ActorClassesToLookAt; + +/** Target Bone Names, where to look at - priority from top to bottom, if not found, it will continue search **/ +var(Target) array TargetBoneNames; + +/** Actor to look at information **/ +struct native ActorToLookAt +{ + var Actor Actor; + var float Rating; + var float EnteredTime; + var float LastKnownDistance; + var float StartTimeBeingLookedAt; + var bool CurrentlyBeingLookedAt; +}; + +/** Array of actor information **/ +var private const transient native map{class AActor*,struct FActorToLookAt* } CurrentActorMap; + +/** SkeletalMeshComponent who owns this **/ +var SkeletalMeshComponent SkeletalMeshComp; + +/** Look at control **/ +var private transient array TrackControls; + +/** Cached value for where mesh location/rotation is at this tick **/ +var private transient vector RootMeshLocation; +var private transient rotator RootMeshRotation; +cpptext +{ +public: + /** Enable/Disable HeadTracking **/ + void EnableHeadTracking(UBOOL bEnable); + + /** + * Attaches the component to a ParentToWorld transform, owner and scene. + * Requires IsValidComponent() == true. + */ + virtual void Attach(); + + /** + * Detaches the component from the scene it is in. + * Requires bAttached == true + * + * @param bWillReattach TRUE is passed if Attach will be called immediately afterwards. This can be used to + * preserve state between reattachments. + */ + virtual void Detach( UBOOL bWillReattach = FALSE ); + + /** + * Updates time dependent state for this component. + * Requires bAttached == true. + * @param DeltaTime - The time since the last tick. + */ + virtual void Tick(FLOAT DeltaTime); + + /** Clear list **/ + virtual void BeginDestroy(); + + /** Make sure CurrentActorMap is referenced */ + void AddReferencedObjects( TArray& ObjectArray ); + +private: + /** + * Update Acotr Map + * returns # of actors in the map + */ + INT UpdateActorMap(FLOAT CurrentTime); + /** + * Find Best Candidate from the current listing + */ + FActorToLookAt * FindBestCandidate(FLOAT CurrentTime); + /** + * Update Head Tracking + */ + void UpdateHeadTracking(FLOAT DeltaTime); + + /** + * Refresh Head Tracking Skel Control List + */ + void RefreshTrackControls(); +} + +defaultproperties +{ + TrackControllerName.Add("HeadLook") + TrackControllerName.Add("LeftEyeLook") + TrackControllerName.Add("RightEyeLook") + + ActorClassesToLookAt.Empty + + MinLookAtTime = 3.f + MaxLookAtTime = 5.f + MaxInterestTime = 7.f + + LookAtActorRadius = 500.f + + TargetBoneNames.Empty + TargetBoneNames.Add("b_MF_Head") + TargetBoneNames.Add("b_MF_Neck") +} diff --git a/Engine/Classes/HeightFog.uc b/Engine/Classes/HeightFog.uc new file mode 100644 index 0000000..a49f905 --- /dev/null +++ b/Engine/Classes/HeightFog.uc @@ -0,0 +1,89 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class HeightFog extends Info + showcategories(Movement) + ClassGroup(Fog) + placeable; + +var() const editconst HeightFogComponent Component; + +/** replicated copy of HeightFogComponent's bEnabled property */ +var repnotify bool bEnabled; + +replication +{ + if (Role == ROLE_Authority) + bEnabled; +} + +event PostBeginPlay() +{ + Super.PostBeginPlay(); + + bEnabled = Component.bEnabled; +} + +simulated event ReplicatedEvent(name VarName) +{ + if (VarName == 'bEnabled') + { + Component.SetEnabled(bEnabled); + } + else + { + Super.ReplicatedEvent(VarName); + } +} + +/* epic =============================================== +* ::OnToggle +* +* Scripted support for toggling height fog, checks which +* operation to perform by looking at the action input. +* +* Input 1: turn on +* Input 2: turn off +* Input 3: toggle +* +* ===================================================== +*/ +simulated function OnToggle(SeqAct_Toggle action) +{ + if (action.InputLinks[0].bHasImpulse) + { + // turn on + Component.SetEnabled(TRUE); + } + else if (action.InputLinks[1].bHasImpulse) + { + // turn off + Component.SetEnabled(FALSE); + } + else if (action.InputLinks[2].bHasImpulse) + { + // toggle + Component.SetEnabled(!Component.bEnabled); + } + bEnabled = Component.bEnabled; + ForceNetRelevant(); + SetForcedInitialReplicatedProperty(Property'Engine.HeightFog.bEnabled', (bEnabled == default.bEnabled)); +} + +defaultproperties +{ + TickGroup=TG_DuringAsyncWork + + Begin Object Class=HeightFogComponent Name=HeightFogComponent0 + End Object + Component=HeightFogComponent0 + Components.Add(HeightFogComponent0) + + Begin Object Name=Sprite + SpriteCategoryName="Fog" + End Object + + bStatic=FALSE + bNoDelete=true + DrawScale=5 +} diff --git a/Engine/Classes/HeightFogComponent.uc b/Engine/Classes/HeightFogComponent.uc new file mode 100644 index 0000000..60a705f --- /dev/null +++ b/Engine/Classes/HeightFogComponent.uc @@ -0,0 +1,52 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class HeightFogComponent extends ActorComponent + native + collapsecategories + hidecategories(Object) + editinlinenew; + +/** True if the fog is enabled. */ +var() const bool bEnabled; +/** z-height for the fog plane - updated by the owning actor */ +var const float Height; +/** affects the scale for the fog layer's thickness */ +var() const interp float Density; +/** affects the inscattering color */ +var() const interp float LightBrightness; +/** Fog color to blend with the scene */ +var() const interp color LightColor; +/** The distance at which light passing through the fog is 100% extinguished. */ +var() const interp float ExtinctionDistance; +/** distance at which fog starts affecting the scene */ +var() const interp float StartDistance; + +cpptext +{ +protected: + // ActorComponent interface. + virtual void SetParentToWorld(const FMatrix& ParentToWorld); + virtual void Attach(); + virtual void UpdateTransform(); + virtual void Detach( UBOOL bWillReattach = FALSE ); +public: +} + +/** + * Changes the enabled state of the height fog component. + * @param bSetEnabled - The new value for bEnabled. + */ +final native function SetEnabled(bool bSetEnabled); + +defaultproperties +{ + TickGroup=TG_DuringAsyncWork + + bEnabled=TRUE + Density=0.00005 + LightBrightness=0.1 + LightColor=(R=255,G=255,B=255) + ExtinctionDistance=100000000 + StartDistance=0 +} diff --git a/Engine/Classes/HttpBaseInterface.uc b/Engine/Classes/HttpBaseInterface.uc new file mode 100644 index 0000000..113df2f --- /dev/null +++ b/Engine/Classes/HttpBaseInterface.uc @@ -0,0 +1,68 @@ +/** + * Base interface for HttpRequests and Responses. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class HttpBaseInterface extends Object + abstract + native; + +/** + * Gets the value of a header, or empty string if not found. + * + * @todo HTML supports multiple header names + * so this function needs to support returning multiple values + * or define how it concatenates those values. + * + * @todo Also, I'd like a version that returns the value as an int + * if possible, zero otherwise. + * + * @param HeaderName - name of the header to set. + */ +native function String GetHeader(String HeaderName); + +/** + * Return all headers in an array in "Name: Value" format. + * + * @return the header array + */ +native function array GetHeaders(); + +/** Gets a URL parameter. + * expected format is ?Key=Value&Key=Value... + * If that format is not used, this function will not work. + * + * @param ParameterName - the parameter to request. + * + * @return The parameter value. + */ +native function String GetURLParameter(String ParameterName); + +/** + * Shortcut to get the Content-Type header value (if available) + * + * @return the content type. + */ +native function String GetContentType(); + +/** + * Shortcut to get the Content-Length header value. Will not always return non-zero. + * If you want the real length of the payload, get the payload and check it's length. + * + * @return The content length (if available) + */ +native function int GetContentLength(); + +/** + * Get the URL used to send the request. + * + * @return The URL. + */ +native function String GetURL(); + +/** + * Get the content of the request or response. + * + * @param Content - array that will be filled with the content. + */ +native function GetContent(out array Content); diff --git a/Engine/Classes/HttpFactory.uc b/Engine/Classes/HttpFactory.uc new file mode 100644 index 0000000..03a4fe2 --- /dev/null +++ b/Engine/Classes/HttpFactory.uc @@ -0,0 +1,27 @@ +/** + * Factory class for creating HttpRequests and Responses. + * Clients don't generally create responses, they are created + * internally by the Request handling system. + * Expected usage is to call CreateRequest() and use the + * returned interface. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class HttpFactory extends Object + config(Engine); + +/** Configurable class to use to make requests. This is platform specific. */ +var config string HttpRequestClassName; + +/** Static function to create a web request. */ +static function HttpRequestInterface CreateRequest() +{ + local class HttpRequestClass; + local Object HttpReq; + + HttpRequestClass = class(DynamicLoadObject(default.HttpRequestClassName,class'Class')); + + HttpReq = new HttpRequestClass; + + return HttpRequestInterface(HttpReq); +} diff --git a/Engine/Classes/HttpRequestInterface.uc b/Engine/Classes/HttpRequestInterface.uc new file mode 100644 index 0000000..898d120 --- /dev/null +++ b/Engine/Classes/HttpRequestInterface.uc @@ -0,0 +1,98 @@ +/** + * Base interface for HttpRequests. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class HttpRequestInterface + extends HttpBaseInterface + native + abstract; + +/** + * Gets the verb (GET, PUT, POST) used by the request. + * + * @return The verb + */ +native function String GetVerb(); + +/** + * Sets the verb (GET, PUT, POST) used by the request. + * Should be set before calling ProcessRequest. + * Defaults to GET. + * + * @param Verb - Verb to use. + * @return this + */ +native function HttpRequestInterface SetVerb(String Verb); + +/** + * Sets the URL for the request (http://my.domain.com/something.ext?key=value&key2=value). + * Must be set before calling ProcessRequest. + * + * @param URL - URL to use + * @return this + */ +native function HttpRequestInterface SetURL(String URL); + +/** + * Sets the content of the request (optional data). + * Usually only set for POST requests. + * + * @param ContentPayload - payload to set. + * @return this + */ +native function HttpRequestInterface SetContent(const out array ContentPayload); + +/** + * Sets the content of the request as a string encoded as UTF8. + * + * @param ContentString - payload to set. + * @return this + */ +native function HttpRequestInterface SetContentAsString(String ContentString); + +/** + * Sets optional header info. + * Content-Length is the only header set for you. + * Required headers depends on the request itself. + * + * @param HeaderName - Name of the header (ie, Content-Type) + * @param HeaderValue - Value of the header + * @return this + */ +native function HttpRequestInterface SetHeader(String HeaderName, String HeaderValue); + +/** + * Called to begin processing the request. + * When a response is recevied, the OnProcessRequestComplete + * delegate is called with the response. + * Even if the request is invalid, the OnProcessRequestComplete delegate is still called. + * In that case, the HttpResponse parameter will be None. + * + * @return if the request was successfully sent. If false, the delegate will not fire. + */ +native function bool ProcessRequest(); + +/** + * Delegate called when the request is complete. + * + * @param OriginalRequest - The original request object that spawned the response + * @param HttpResponse - The response object. Could be None if the request failed spectacularly. If the request failed to receive a complete + * response for some reason, this could contain a valid Response object with as much info as could be retrieved. + * Always use the bDidSucceed parameter to determine if the entire response was received successfully. + * @param bSucceeded - whether the response succeeded. If it did not, you should not trust the payload or headers. + * Basically indicates a net failure occurred while receiving the response. + */ +delegate OnProcessRequestComplete(HttpRequestInterface OriginalRequest, HttpResponseInterface InHttpResponse, bool bDidSucceed); + +/** + * Sets the delegate as a convenience function for chaining expressions. + * + * @param ProcessRequestCompleteDelegate - the delegate to set + * @return self + */ +function HttpRequestInterface SetProcessRequestCompleteDelegate(delegate ProcessRequestCompleteDelegate) +{ + OnProcessRequestComplete = ProcessRequestCompleteDelegate; + return self; +} diff --git a/Engine/Classes/HttpResponseInterface.uc b/Engine/Classes/HttpResponseInterface.uc new file mode 100644 index 0000000..f3b79ef --- /dev/null +++ b/Engine/Classes/HttpResponseInterface.uc @@ -0,0 +1,27 @@ +/** + * Base interface for HttpResponses. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class HttpResponseInterface + extends HttpBaseInterface + native + abstract; + +// Contains defines for all the possible status codes that can be returned. +`include(HttpStatusCodes.uci) + +/** + * Returns the response code returned by the requested server. + * See HttpStatusCodes.uci for a complete list. + * + * @return the response code. + */ +native function int GetResponseCode(); + +/** + * Returns the payload as a string, assuming the payload is UTF8. + * + * @return The payload as a string. + */ +native function String GetContentAsString(); \ No newline at end of file diff --git a/Engine/Classes/HttpStatusCodes.uci b/Engine/Classes/HttpStatusCodes.uci new file mode 100644 index 0000000..aa1863c --- /dev/null +++ b/Engine/Classes/HttpStatusCodes.uci @@ -0,0 +1,84 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +/** + * Http Status Codes + */ +// The request can be continued. +`define HTTP_STATUS_CONTINUE 100 +// The server has switched protocols in an upgrade header. +`define HTTP_STATUS_SWITCH_PROTOCOLS 101 +// The request completed successfully. +`define HTTP_STATUS_OK 200 +// The request has been fulfilled and resulted in the creation of a new resource. +`define HTTP_STATUS_CREATED 201 +// The request has been accepted for processing, but the processing has not been completed. +`define HTTP_STATUS_ACCEPTED 202 +// The returned meta information in the entity-header is not the definitive set available from the origin server. +`define HTTP_STATUS_PARTIAL 203 +// The server has fulfilled the request, but there is no new information to send back. +`define HTTP_STATUS_NO_CONTENT 204 +// The request has been completed, and the client program should reset the document view that caused the request to be sent to allow the user to easily initiate another input action. +`define HTTP_STATUS_RESET_CONTENT 205 +// The server has fulfilled the partial GET request for the resource. +`define HTTP_STATUS_PARTIAL_CONTENT 206 +// The server couldn't decide what to return. +`define HTTP_STATUS_AMBIGUOUS 300 +// The requested resource has been assigned to a new permanent URI (Uniform Resource Identifier), and any future references to this resource should be done using one of the returned URIs. +`define HTTP_STATUS_MOVED 301 +// The requested resource resides temporarily under a different URI (Uniform Resource Identifier). +`define HTTP_STATUS_REDIRECT 302 +// The response to the request can be found under a different URI (Uniform Resource Identifier) and should be retrieved using a GET HTTP verb on that resource. +`define HTTP_STATUS_REDIRECT_METHOD 303 +// The requested resource has not been modified. +`define HTTP_STATUS_NOT_MODIFIED 304 +// The requested resource must be accessed through the proxy given by the location field. +`define HTTP_STATUS_USE_PROXY 305 +// The redirected request keeps the same HTTP verb. HTTP/1.1 behavior. +`define HTTP_STATUS_REDIRECT_KEEP_VERB 307 +// The request could not be processed by the server due to invalid syntax. +`define HTTP_STATUS_BAD_REQUEST 400 +// The requested resource requires user authentication. +`define HTTP_STATUS_DENIED 401 +// Not currently implemented in the HTTP protocol. +`define HTTP_STATUS_PAYMENT_REQ 402 +// The server understood the request, but is refusing to fulfill it. +`define HTTP_STATUS_FORBIDDEN 403 +// The server has not found anything matching the requested URI (Uniform Resource Identifier). +`define HTTP_STATUS_NOT_FOUND 404 +// The HTTP verb used is not allowed. +`define HTTP_STATUS_BAD_METHOD 405 +// No responses acceptable to the client were found. +`define HTTP_STATUS_NONE_ACCEPTABLE 406 +// Proxy authentication required. +`define HTTP_STATUS_PROXY_AUTH_REQ 407 +// The server timed out waiting for the request. +`define HTTP_STATUS_REQUEST_TIMEOUT 408 +// The request could not be completed due to a conflict with the current state of the resource. The user should resubmit with more information. +`define HTTP_STATUS_CONFLICT 409 +// The requested resource is no longer available at the server, and no forwarding address is known. +`define HTTP_STATUS_GONE 410 +// The server refuses to accept the request without a defined content length. +`define HTTP_STATUS_LENGTH_REQUIRED 411 +// The precondition given in one or more of the request header fields evaluated to false when it was tested on the server. +`define HTTP_STATUS_PRECOND_FAILED 412 +// The server is refusing to process a request because the request entity is larger than the server is willing or able to process. +`define HTTP_STATUS_REQUEST_TOO_LARGE 413 +// The server is refusing to service the request because the request URI (Uniform Resource Identifier) is longer than the server is willing to interpret. +`define HTTP_STATUS_URI_TOO_LONG 414 +// The server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method. +`define HTTP_STATUS_UNSUPPORTED_MEDIA 415 +// The request should be retried after doing the appropriate action. +`define HTTP_STATUS_RETRY_WITH 449 +// The server encountered an unexpected condition that prevented it from fulfilling the request. +`define HTTP_STATUS_SERVER_ERROR 500 +// The server does not support the functionality required to fulfill the request. +`define HTTP_STATUS_NOT_SUPPORTED 501 +// The server, while acting as a gateway or proxy, received an invalid response from the upstream server it accessed in attempting to fulfill the request. +`define HTTP_STATUS_BAD_GATEWAY 502 +// The service is temporarily overloaded. +`define HTTP_STATUS_SERVICE_UNAVAIL 503 +// The request was timed out waiting for a gateway. +`define HTTP_STATUS_GATEWAY_TIMEOUT 504 +// The server does not support, or refuses to support, the HTTP protocol version that was used in the request message. +`define HTTP_STATUS_VERSION_NOT_SUP 505 diff --git a/Engine/Classes/ImageBasedReflectionComponent.uc b/Engine/Classes/ImageBasedReflectionComponent.uc new file mode 100644 index 0000000..ede637f --- /dev/null +++ b/Engine/Classes/ImageBasedReflectionComponent.uc @@ -0,0 +1,74 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ImageBasedReflectionComponent extends StaticMeshComponent + native(Mesh) + hidecategories(StaticMeshComponent) + placeable + editinlinenew; + +/** Whether to render the reflection. */ +var() bool bEnabled; + +/** Whether the reflection should be visible from the back. */ +var() bool bTwoSided; + +/** + * Texture that will be applied to this reflection. + * This texture will be used in a texture array and therefore must have the same size, number of mips, texture group settings and format + * As the ReflectionTexture of every ImageBasedReflectionComponent that can be loaded at the same time. + */ +var() Texture2D ReflectionTexture; + +/** Color that will be multiplied against ReflectionTexture. Alpha is a brightness control. */ +var() interp LinearColor ReflectionColor; + +cpptext +{ +protected: + // ActorComponent interface. + virtual UBOOL IsValidComponent() const { return ReflectionTexture != NULL; } + virtual void Attach(); + virtual void UpdateTransform(); + virtual void Detach( UBOOL bWillReattach = FALSE ); + virtual FPrimitiveSceneProxy* CreateSceneProxy(); + + virtual void PostLoad(); + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); +} + +/** +* Changes the enabled state of the image reflection component. +* @param bSetEnabled - The new value for bEnabled. +*/ +native final function SetEnabled(bool bSetEnabled); + +native final function UpdateImageReflectionParameters(); + +/** Called from matinee code when ReflectionColor property changes. */ +function OnUpdatePropertyReflectionColor() +{ + UpdateImageReflectionParameters(); +} + +defaultproperties +{ + bEnabled=true + ReflectionTexture=Texture2D'Engine_MI_Shaders.Textures.DefaultReflectionTexture_IBR' + Materials(0)=Material'EditorMaterials.Utilities.ImageReflectionPreview' + ReflectionColor=(R=1.0f, G=1.0f, B=1.0f, A=1.0f) + StaticMesh=StaticMesh'EditorMeshes.TexPropPlane' + bCastDynamicShadow=FALSE + BlockRigidBody=FALSE + CollideActors=FALSE + bForceDirectLightMap=FALSE + bAcceptsDynamicLights=FALSE + bAcceptsLights=FALSE + CastShadow=FALSE + bUsePrecomputedShadows=FALSE + bAcceptsStaticDecals=FALSE + bAcceptsDynamicDecals=FALSE + bUseAsOccluder=FALSE + HiddenGame=true + WireframeColor=(R=100,G=100,B=200,A=255) +} diff --git a/Engine/Classes/ImageReflection.uc b/Engine/Classes/ImageReflection.uc new file mode 100644 index 0000000..fb54f4b --- /dev/null +++ b/Engine/Classes/ImageReflection.uc @@ -0,0 +1,102 @@ +/** + * An actor which specifies a reflection primitive used by materials that use image based reflections. + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ImageReflection extends Actor + showcategories(Movement) + AutoExpandCategories(ImageReflection) + AutoExpandCategories(ImageBasedReflectionComponent) + native(Mesh) + placeable; + +/** replicated copy of ImageBasedReflectionComponent's bEnabled property */ +var repnotify bool bEnabled; + +/** Image reflection component */ +var deprecated ImageReflectionComponent ReflectionComponent; + +/** Image reflection component */ +var() ImageBasedReflectionComponent ImageReflectionComponent; + +replication +{ + if (Role == ROLE_Authority) + bEnabled; +} + +event PostBeginPlay() +{ + Super.PostBeginPlay(); + + bEnabled = ImageReflectionComponent.bEnabled; +} + +simulated event ReplicatedEvent(name VarName) +{ + if (VarName == 'bEnabled') + { + ImageReflectionComponent.SetEnabled(bEnabled); + } + else + { + Super.ReplicatedEvent(VarName); + } +} + +/* epic =============================================== +* ::OnToggle +* +* Scripted support for toggling image reflections, checks which +* operation to perform by looking at the action input. +* +* Input 1: turn on +* Input 2: turn off +* Input 3: toggle +* +* ===================================================== +*/ +simulated function OnToggle(SeqAct_Toggle action) +{ + if (action.InputLinks[0].bHasImpulse) + { + // turn on + ImageReflectionComponent.SetEnabled(TRUE); + } + else if (action.InputLinks[1].bHasImpulse) + { + // turn off + ImageReflectionComponent.SetEnabled(FALSE); + } + else if (action.InputLinks[2].bHasImpulse) + { + // toggle + ImageReflectionComponent.SetEnabled(!ImageReflectionComponent.bEnabled); + } + bEnabled = ImageReflectionComponent.bEnabled; + ForceNetRelevant(); + SetForcedInitialReplicatedProperty(Property'Engine.ImageReflection.bEnabled', (bEnabled == default.bEnabled)); +} + +cpptext +{ +protected: + virtual void PostLoad(); +} + +defaultproperties +{ + bEnabled=true + bStatic=FALSE + bNoDelete=true + + // Network settings taken from AInfo + RemoteRole=ROLE_None + NetUpdateFrequency=10 + bOnlyDirtyReplication=TRUE + bSkipActorPropertyReplication=TRUE + + Begin Object Class=ImageBasedReflectionComponent Name=ReflectionComponent0 + End Object + ImageReflectionComponent=ReflectionComponent0 + Components.Add(ReflectionComponent0) +} diff --git a/Engine/Classes/ImageReflectionComponent.uc b/Engine/Classes/ImageReflectionComponent.uc new file mode 100644 index 0000000..26812f6 --- /dev/null +++ b/Engine/Classes/ImageReflectionComponent.uc @@ -0,0 +1,14 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ImageReflectionComponent extends ActorComponent + native(Mesh) + hidecategories(Object) + deprecated + editinlinenew; + +var() Texture2D ReflectionTexture; + +defaultproperties +{ +} diff --git a/Engine/Classes/ImageReflectionSceneCapture.uc b/Engine/Classes/ImageReflectionSceneCapture.uc new file mode 100644 index 0000000..d73519f --- /dev/null +++ b/Engine/Classes/ImageReflectionSceneCapture.uc @@ -0,0 +1,33 @@ +/** + * An actor which specifies a reflection primitive used by materials that use image based reflections. + * This actor also captures the scene in a texture at lighting build time and uses that texture for image reflections. + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ImageReflectionSceneCapture extends ImageReflection + showcategories(Movement) + AutoExpandCategories(ImageReflectionSceneCapture) + AutoExpandCategories(ImageBasedReflectionComponent) + native(Mesh) + placeable; + +/** + * Distance in world units from the image plane that defines the depth range that will be captured. + * Anything outside of the depth range will be clipped away. + * Changes will be propagated on the next lighting build. + */ +var() float DepthRange; + +/** Maximum linear space color value that will be stored in the generated texture. */ +var() float ColorRange; + +cpptext +{ +protected: + virtual void PostDuplicate(); +} + +defaultproperties +{ + DepthRange=200 + ColorRange=4 +} diff --git a/Engine/Classes/ImageReflectionShadowPlane.uc b/Engine/Classes/ImageReflectionShadowPlane.uc new file mode 100644 index 0000000..a7b7170 --- /dev/null +++ b/Engine/Classes/ImageReflectionShadowPlane.uc @@ -0,0 +1,102 @@ +/** + * An actor which specifies a reflection plane used to render dynamic shadows for image reflections. + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ImageReflectionShadowPlane extends Actor + showcategories(Movement) + native(Mesh) + placeable; + +/** replicated copy of ImageReflectionShadowPlaneComponent's bEnabled property */ +var repnotify bool bEnabled; + +/** Image reflection component */ +var() ImageReflectionShadowPlaneComponent ReflectionShadowComponent; + +replication +{ + if (Role == ROLE_Authority) + bEnabled; +} + +event PostBeginPlay() +{ + Super.PostBeginPlay(); + + bEnabled = ReflectionShadowComponent.bEnabled; +} + +simulated event ReplicatedEvent(name VarName) +{ + if (VarName == 'bEnabled') + { + ReflectionShadowComponent.SetEnabled(bEnabled); + } + else + { + Super.ReplicatedEvent(VarName); + } +} + +/* epic =============================================== +* ::OnToggle +* +* Scripted support for toggling image reflections, checks which +* operation to perform by looking at the action input. +* +* Input 1: turn on +* Input 2: turn off +* Input 3: toggle +* +* ===================================================== +*/ +simulated function OnToggle(SeqAct_Toggle action) +{ + if (action.InputLinks[0].bHasImpulse) + { + // turn on + ReflectionShadowComponent.SetEnabled(TRUE); + } + else if (action.InputLinks[1].bHasImpulse) + { + // turn off + ReflectionShadowComponent.SetEnabled(FALSE); + } + else if (action.InputLinks[2].bHasImpulse) + { + // toggle + ReflectionShadowComponent.SetEnabled(!ReflectionShadowComponent.bEnabled); + } + bEnabled = ReflectionShadowComponent.bEnabled; + ForceNetRelevant(); + SetForcedInitialReplicatedProperty(Property'Engine.ImageReflectionShadowPlane.bEnabled', (bEnabled == default.bEnabled)); +} + +defaultproperties +{ + bEnabled=true + bStatic=FALSE + bNoDelete=true + + // Network settings taken from AInfo + RemoteRole=ROLE_None + NetUpdateFrequency=10 + bOnlyDirtyReplication=TRUE + bSkipActorPropertyReplication=TRUE + + Physics=PHYS_Interpolating + + Begin Object Class=ImageReflectionShadowPlaneComponent Name=ReflectionComponent0 + End Object + ReflectionShadowComponent=ReflectionComponent0 + Components.Add(ReflectionComponent0) + + Begin Object Class=SpriteComponent Name=Sprite + Sprite=Texture2D'EditorResources.S_Actor' + HiddenGame=TRUE + AlwaysLoadOnClient=FALSE + AlwaysLoadOnServer=FALSE + SpriteCategoryName="ImageReflection" + End Object + Components.Add(Sprite) +} diff --git a/Engine/Classes/ImageReflectionShadowPlaneComponent.uc b/Engine/Classes/ImageReflectionShadowPlaneComponent.uc new file mode 100644 index 0000000..b419cb8 --- /dev/null +++ b/Engine/Classes/ImageReflectionShadowPlaneComponent.uc @@ -0,0 +1,46 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class ImageReflectionShadowPlaneComponent extends PrimitiveComponent + native(Mesh) + placeable + editinlinenew; + +/** Whether to render the reflection. */ +var() bool bEnabled; + +var plane ReflectionPlane; + +cpptext +{ +protected: + // ActorComponent interface. + virtual void SetParentToWorld(const FMatrix& ParentToWorld); + virtual void Attach(); + virtual void UpdateTransform(); + virtual void Detach( UBOOL bWillReattach = FALSE ); +} + +/** +* Changes the enabled state of the image reflection component. +* @param bSetEnabled - The new value for bEnabled. +*/ +final native function SetEnabled(bool bSetEnabled); + +defaultproperties +{ + bEnabled=true + ReflectionPlane=(X=0.0,Y=0.0,Z=1.0,W=86.0) + bCastDynamicShadow=FALSE + BlockRigidBody=FALSE + CollideActors=FALSE + bForceDirectLightMap=FALSE + bAcceptsDynamicLights=FALSE + bAcceptsLights=FALSE + CastShadow=FALSE + bUsePrecomputedShadows=FALSE + bAcceptsStaticDecals=FALSE + bAcceptsDynamicDecals=FALSE + bUseAsOccluder=FALSE + HiddenGame=true +} diff --git a/Engine/Classes/InAppMessageBase.uc b/Engine/Classes/InAppMessageBase.uc new file mode 100644 index 0000000..084925c --- /dev/null +++ b/Engine/Classes/InAppMessageBase.uc @@ -0,0 +1,37 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * This is the base class for In App Message integration (each platform has a subclass) + */ +class InAppMessageBase extends PlatformInterfaceBase + native(PlatformInterface) + config(Engine); + +enum EInAppMessageInterfaceDelegate +{ + IAMD_InAppSMSUIComplete, + IAMD_InAppEmailComplete, +}; + +/** + * Perform any needed initialization + */ +native event Init(); + +/** + * Kicks off an in app SMS, using the platform to show the UI. If this returns FALSE system was unable to do this + * + * @param InitialMessage [optional] Initial message to show + * + * @return TRUE if a UI was displayed for the user to interact with, and a IAMD_InAppSMSUIComplete will be sent when done + */ +native event bool ShowInAppSMSUI(optional string InitialMessage); + +/** + * Kicks off a in app email, using the platform to show the UI. If this returns FALSE system was unable to do this + * + * @param InitialMessage [optional] Initial message to show + * + * @return TRUE if a UI was displayed for the user to interact with, and a IAMD_InAppEmailComplete will be sent when done + */ +native event bool ShowInAppEmailUI(optional string InitialSubject, optional string InitialMessage); diff --git a/Engine/Classes/InGameAdManager.uc b/Engine/Classes/InGameAdManager.uc new file mode 100644 index 0000000..c192e88 --- /dev/null +++ b/Engine/Classes/InGameAdManager.uc @@ -0,0 +1,74 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * This object is responsible for the display and callbacks associated + * with handling ingame advertisements + */ +class InGameAdManager extends PlatformInterfaceBase + native(PlatformInterface); + +cpptext +{ + /** + * Called by platform when the user clicks on the ad banner. Will pause the game before + * calling the delegates + */ + void OnUserClickedBanner(); + + /** + * Called by platform when an opened ad is closed. Will unpause the game before + * calling the delegates + */ + void OnUserClosedAd(); +} + + +enum EAdManagerDelegate +{ + AMD_ClickedBanner, + AMD_UserClosedAd, +}; + +/** If true, the game will pause when the user clicks on the ad, which could take over the screen */ +var bool bShouldPauseWhileAdOpen; + + +/** + * Perform any needed initialization + */ +native event Init(); + +/** + * Allows the platform to put up an advertisement on top of the viewport. Note that + * this will not resize the viewport, simply cover up a portion of it. + * + * @param bShowOnBottomOfScreen If TRUE, advertisement will be shown on the bottom, otherwise, the top + */ +native function ShowBanner(bool bShowBottomOfScreen); + +/** + * Hides the advertisement banner shown with ShowInGameAdvertisementBanner. If the ad is currently open + * (ie, the user is interacting with the ad), the ad will be forcibly closed (see ForceCloseInGameAdvertisement) + */ +native function HideBanner(); + +/** + * If the game absolutely must close an opened (clicked on) advertisement, call this function. + * This may lead to loss of revenue, so don't do it unnecessarily. + */ +native function ForceCloseAd(); + + + +/** + * Sets the value of bShouldPauseWhileAdOpen + */ +function SetPauseWhileAdOpen(bool bShouldPause) +{ + bShouldPauseWhileAdOpen = bShouldPause; +} + +defaultproperties +{ + bShouldPauseWhileAdOpen=true +} \ No newline at end of file diff --git a/Engine/Classes/Info.uc b/Engine/Classes/Info.uc new file mode 100644 index 0000000..ca3389e --- /dev/null +++ b/Engine/Classes/Info.uc @@ -0,0 +1,68 @@ +/** + * Info, the root of all information holding classes. + * Doesn't have any movement / collision related code. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class Info extends Actor + abstract + hidecategories(Movement,Collision) + native; + +//------------------------------------------------------------------------------ +// Structs for reporting server state data + +struct transient native export KeyValuePair +{ + var() string Key; + var() string Value; +}; + +struct transient native export PlayerResponseLine +{ + var() int PlayerNum; + var() int PlayerID; + var() string PlayerName; + var() int Ping; + var() int Score; + var() int StatsID; + var() array PlayerInfo; + +}; + +struct transient native export ServerResponseLine +{ + var() int ServerID; + var() string IP; + var() int Port; + var() int QueryPort; + var() string ServerName; + var() string MapName; + var() string GameType; + var() int CurrentPlayers; + var() int MaxPlayers; + var() int Ping; + + var() array ServerInfo; + var() array PlayerInfo; +}; + + +defaultproperties +{ + Begin Object Class=SpriteComponent Name=Sprite + Sprite=Texture2D'EditorResources.S_Actor' + HiddenGame=TRUE + AlwaysLoadOnClient=FALSE + AlwaysLoadOnServer=FALSE + SpriteCategoryName="Info" + End Object + Components.Add(Sprite) + + RemoteRole=ROLE_None + NetUpdateFrequency=10 + bHidden=TRUE + bOnlyDirtyReplication=TRUE + bSkipActorPropertyReplication=TRUE +} diff --git a/Engine/Classes/IniLocPatcher.uc b/Engine/Classes/IniLocPatcher.uc new file mode 100644 index 0000000..c523c64 --- /dev/null +++ b/Engine/Classes/IniLocPatcher.uc @@ -0,0 +1,559 @@ +/** +* Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +*/ + +/** +* This class reads a set of files from Live/NP servers and uses it to +* update the game. +*/ +class IniLocPatcher extends Object + native + config(Engine); + +/** Holds the list of files to download and their download state */ +struct native IniLocFileEntry +{ + /** The file to read from the online service */ + var string Filename; + /** Unique name of file only used for downloading */ + var string DLName; + /** Hash to verify integrity of file against cached version */ + var string HashCode; + /** Whether the file should be treated as unicode or not */ + var bool bIsUnicode; + /** The state of that read */ + var EOnlineEnumerationReadState ReadState; +}; + +/** The list of files to request from the online service */ +var config array Files; + +/** if TRUE Then file list is downloaded from EMS otherwise it comes from config */ +var config bool bRequestEmsFileList; +/** Max age in seconds to keep cached EMS files */ +var config int MaxCachedFileAge; + +/** Interface for downloading files */ +var transient OnlineTitleFileInterface TitleFileInterface; +/** Interface for caching files to/from disk */ +var transient OnlineTitleFileCacheInterface TitleFileCacheInterface; + +/** list of delegates that get called whenever a file is downloaded or loaded from cache */ +var array > ReadTitleFileCompleteDelegates; +// @ZOMBIE_FOXTROT_BEGIN - ccooper 1/9/2014 - Adding delegate container for OnAllTitleFilesCompleted +var array > AllTitleFilesCompletedDelegates; +// @ZOMBIE_FOXTROT_END +/** +* Delegate fired when a file read from the network platform's title specific storage is complete +* +* @param bWasSuccessful whether the file read was successful or not +* @param FileName the name of the file this was for +*/ +delegate OnReadTitleFileComplete(bool bWasSuccessful,string FileName); + +/** +* Delegate fired when all title files have completed processing +*/ +delegate OnAllTitleFilesCompleted(); + +/** +* Initializes the patcher, sets delegates, vars, etc. +*/ +function Init() +{ + local OnlineSubsystem OnlineSub; + local int Index; + + OnlineSub = class'GameEngine'.static.GetOnlineSubsystem(); + if (OnlineSub != None) + { + TitleFileInterface = OnlineSub.TitleFileInterface; + if (TitleFileInterface != None) + { + // Set the callback for notifications of files completing download + TitleFileInterface.AddReadTitleFileCompleteDelegate(OnDownloadFileComplete); + } + else + { + // Mark all as failed to be read since there is no way to read them + for (Index = 0; Index < Files.Length; Index++) + { + Files[Index].ReadState = OERS_Failed; + } + } + // Hook up the caching interface + TitleFileCacheInterface = OnlineSub.TitleFileCacheInterface; + if (TitleFileCacheInterface != None) + { + // Set the callback for notifications of files completing a load + TitleFileCacheInterface.AddLoadTitleFileCompleteDelegate(OnFileCacheLoadComplete); + TitleFileCacheInterface.AddSaveTitleFileCompleteDelegate(OnFileCacheSaveComplete); + } + } +} + +/** +* Reads the set of files from the online service +*/ +function DownloadFiles() +{ + local int FileIdx; + + if (bRequestEmsFileList) + { + // Delete stale files + if (MaxCachedFileAge > 0 && + TitleFileCacheInterface != None) + { + TitleFileCacheInterface.DeleteTitleFiles(MaxCachedFileAge); + } + // Get a list of files that should be downloaded + TitleFileInterface.AddRequestTitleFileListCompleteDelegate(OnRequestTitleFileListComplete); + TitleFileInterface.RequestTitleFileList(); + } + else + { + // config DLNames and Filenames are expected to match unless requested + for (FileIdx = 0; FileIdx < Files.Length; FileIdx++) + { + Files[FileIdx].DLName = Files[FileIdx].Filename; + } + StartLoadingFiles(); + } +} + +/** +* Delegate fired when the request for a list of files completes +* +* @param bWasSuccessful whether the request completed successfully +* @param ResultStr contains the list of files and associated meta data +*/ +function OnRequestTitleFileListComplete(bool bWasSuccessful, array ResultStr) +{ + local JsonObject Root; + local int JsonObjectIdx; + local IniLocFileEntry RequestFileEntry; + local int Index; + + TitleFileInterface.ClearRequestTitleFileListCompleteDelegate(OnRequestTitleFileListComplete); + if (bWasSuccessful) + { + Root = class'JsonObject'.static.DecodeJson(ResultStr[0]); + if (Root != None) + { + Files.Length = 0; + // fill in the list of RequestFiles + for (JsonObjectIdx=0; JsonObjectIdx < Root.ObjectArray.Length; JsonObjectIdx++) + { + RequestFileEntry.Filename = Root.ObjectArray[JsonObjectIdx].GetStringValue("file_name"); + RequestFileEntry.DLName = Root.ObjectArray[JsonObjectIdx].GetStringValue("dl_name"); + RequestFileEntry.HashCode = Root.ObjectArray[JsonObjectIdx].GetStringValue("hash_code"); + // Any file that is not INT or INI should be Unicode + RequestFileEntry.bIsUnicode = InStr(RequestFileEntry.FileName,".ini",,true) == INDEX_NONE && InStr(RequestFileEntry.FileName,".int",,true) == INDEX_NONE; + Files.AddItem(RequestFileEntry); + } + // Determine which files can be loaded from the cache that don't require downloading + StartLoadingFiles(); + } + else + { + `log(`location @ "Download of file list failed. Bad json." + @"ResultStr="$ResultStr[0]); + + // @ZOMBIE_FOXTROT_BEGIN - ccooper 1/13/2014 - Changed code to call the completed delegate if the title list fails since the client still wants to know about it + for(Index = 0; Index < AllTitleFilesCompletedDelegates.Length; ++Index) + { + if(AllTitleFilesCompletedDelegates[Index] != none) + { + OnAllTitleFilesCompleted = AllTitleFilesCompletedDelegates[Index]; + OnAllTitleFilesCompleted(); + OnAllTitleFilesCompleted = none; + } + } + // @ZOMBIE_FOXTROT_END + } + + } + else + { + `log(`location@"Download of file list failed.",, 'DevConfig'); + + // @ZOMBIE_FOXTROT_BEGIN - ccooper 1/13/2014 - Changed code to call the completed delegate if the title list fails since the client still wants to know about it + for(Index = 0; Index < AllTitleFilesCompletedDelegates.Length; ++Index) + { + if(AllTitleFilesCompletedDelegates[Index] != none) + { + OnAllTitleFilesCompleted = AllTitleFilesCompletedDelegates[Index]; + OnAllTitleFilesCompleted(); + OnAllTitleFilesCompleted = none; + } + } + // @ZOMBIE_FOXTROT_END + } +} + +/** +* Kick off the cache/download requests +*/ +function StartLoadingFiles() +{ + local int Index; + + // If there is online interface, then try to download the files + if (bRequestEmsFileList && TitleFileCacheInterface != None) + { + `log(`location@"if (bRequestEmsFileList && TitleFileCacheInterface != None)"@`showvar(Files.Length),, 'DevConfig'); + // Iterate through files trying to download them + for (Index = 0; Index < Files.Length; Index++) + { + // Kick off the read of that file if not already started or failed + if (Files[Index].ReadState == OERS_NotStarted) + { + Files[Index].ReadState = OERS_InProgress; + if (!TitleFileCacheInterface.LoadTitleFile(Files[Index].DLName)) + { + Files[Index].ReadState = OERS_Failed; + } + } + } + } + else if (TitleFileInterface != None) + { + `log(`location@"else if (TitleFileInterface != None)"@`showvar(Files.Length),, 'DevConfig'); + // Iterate through files trying to download them + for (Index = 0; Index < Files.Length; Index++) + { + // Kick off the read of that file if not already started or failed + if (Files[Index].ReadState == OERS_NotStarted) + { + // If this is a loc file name, make sure we are getting the right language + Files[Index].Filename = UpdateLocFileName(Files[Index].Filename); + // @ZOMBIE_FOXTROT_BEGIN - vspencer 11/26/2014 - The file to download should be localized also + Files[Index].DLName = UpdateLocFileName(Files[Index].DLName); + // @ZOMBIE_FOXTROT_END + if (TitleFileInterface.ReadTitleFile(Files[Index].DLName)) + { + Files[Index].ReadState = OERS_InProgress; + } + else + { + Files[Index].ReadState = OERS_Failed; + } + } + } + } +} + +/** +* Notifies us when the download of a file is complete +* +* @param bWasSuccessful true if the download completed ok, false otherwise +* @param FileName the file that was downloaded (or failed to) +*/ +function OnDownloadFileComplete(bool bWasSuccessful,string FileName) +{ + local bool bSuccessLoad; + local int Index; + local array FileData; + + // Iterate through files to verify that this is one that we requested + for (Index = 0; Index < Files.Length; Index++) + { + if (Files[Index].DLName == FileName) + { + if (bWasSuccessful) + { + // Read the contents so that they can be processed + if (TitleFileInterface.GetTitleFileContents(FileName,FileData) && + FileData.Length > 0) + { + bSuccessLoad = true; + Files[Index].ReadState = OERS_Done; + // Cache it so that the file doesn't need to be downloaded next time + if (bRequestEmsFileList && + TitleFileCacheInterface != None) + { + TitleFileCacheInterface.SaveTitleFile(Files[Index].DLName,Files[Index].Filename,FileData); + } + // Clear memory copy of file from title file downloader + TitleFileInterface.ClearDownloadedFile(FileName); + // patch loc and class + ProcessIniLocFile(Files[Index].Filename,Files[Index].bIsUnicode,FileData); + } + else + { + Files[Index].ReadState = OERS_Failed; + } + } + else + { + `Log("Failed to download the file from system interface." + @"DLName="$Files[Index].DLName + @"Filename="$Files[Index].Filename); + Files[Index].ReadState = OERS_Failed; + } + break; + } + } + // Notify that download complete + TriggerDownloadCompleteDelegates(bSuccessLoad,FileName); +} + +/** +* Delegate fired when a file read from the local cache is complete +* +* @param bWasSuccessful whether the file read was successful or not +* @param FileName the name of the file this was for +*/ +function OnFileCacheLoadComplete(bool bWasSuccessful,string FileName) +{ + local int Index; + local array FileData; + local bool bRequiresDownload; + + bRequiresDownload = true; + // Iterate through files to verify that this is one that we requested + for (Index = 0; Index < Files.Length; Index++) + { + if (Files[Index].DLName == FileName) + { + if (bWasSuccessful) + { + // Compare requested hash vs the one from the cache + if (TitleFileCacheInterface.GetTitleFileHash(FileName) == Files[Index].HashCode) + { + // Read the contents so that they can be processed + if (TitleFileCacheInterface.GetTitleFileContents(FileName,FileData) && + FileData.Length > 0) + { + Files[Index].ReadState = OERS_Done; + bRequiresDownload = false; + // patch loc and class + ProcessIniLocFile(Files[Index].Filename,Files[Index].bIsUnicode,FileData); + // Clear memory copy of file from title file downloader + TitleFileCacheInterface.ClearCachedFile(FileName); + } + } + else + { + `Log("Hash for file cache entry not valid." + @"DLName="$Files[Index].DLName + @"Filename="$Files[Index].Filename); + } + } + break; + } + } + // File could not be loaded from cache or hash was invalid. so, download it + if (bRequiresDownload) + { + // File was invalid so delete it + TitleFileCacheInterface.DeleteTitleFile(FileName); + // Start the download + if (TitleFileInterface != None && + TitleFileInterface.ReadTitleFile(FileName)) + { + Files[Index].ReadState = OERS_InProgress; + } + else + { + Files[Index].ReadState = OERS_Failed; + } + } + else + { + // Notify that load completed + TriggerDownloadCompleteDelegates(true,FileName); + } +} + +/** +* Delegate fired when a file save to the local cache is complete +* +* @param bWasSuccessful whether the file read was successful or not +* @param FileName the name of the file this was for +*/ +function OnFileCacheSaveComplete(bool bWasSuccessful,string FileName) +{ + // clear the memory for the entry that was saved + TitleFileCacheInterface.ClearCachedFile(FileName); +} + +/** +* Triggers list of delegates whenever a file has been loaded +*/ +function TriggerDownloadCompleteDelegates(bool bSuccess,string FileName) +{ + local int Index; + local delegate OnReadTitleFileComplete; + + // Call delegates for file completion + for (Index=0; Index < ReadTitleFileCompleteDelegates.Length; Index++) + { + if (ReadTitleFileCompleteDelegates[Index] != None) + { + OnReadTitleFileComplete = ReadTitleFileCompleteDelegates[Index]; + OnReadTitleFileComplete(bSuccess,FileName); + } + } + // See if all files are done + CheckForAllFilesComplete(); +} + +/** +* Triggers the final delegate if all files have been processed +*/ +function CheckForAllFilesComplete() +{ + local int Index; + local bool bAllFilesComplete; + + bAllFilesComplete = true; + for (Index = 0; Index < Files.Length; Index++) + { + if (Files[Index].ReadState == OERS_NotStarted || + Files[Index].ReadState == OERS_InProgress) + { + bAllFilesComplete = false; + } + } + if (bAllFilesComplete) + { + // @ZOMBIE_FOXTROT_BEGIN - ccooper 1/9/2014 - Changed delegate call to delegate container calls + for(Index = 0; Index < AllTitleFilesCompletedDelegates.Length; ++Index) + { + if(AllTitleFilesCompletedDelegates[Index] != none) + { + OnAllTitleFilesCompleted = AllTitleFilesCompletedDelegates[Index]; + OnAllTitleFilesCompleted(); + OnAllTitleFilesCompleted = none; + } + } + // @ZOMBIE_FOXTROT_END + } +} + +/** +* Takes the data, merges with the INI/Loc system, and then reloads the config for the +* affected objects +* +* @param FileName the name of the file being merged +* @param bIsUnicode whether the file should be treated as unicode or not +* @param FileData the file data to merge with the config cache +*/ +native function ProcessIniLocFile(string FileName,bool bIsUnicode,const out array FileData); + +/** +* Adds a loc/ini file to download +* +* @param FileName the file to download +*/ +function AddFileToDownload(string FileName) +{ + local int FileIndex; + + FileIndex = Files.Find('FileName',FileName); + // Don't add more than once + if (FileIndex == INDEX_NONE) + { + // Add a new entry which will default to not started + FileIndex = Files.Length; + Files.Length = FileIndex + 1; + Files[FileIndex].FileName = FileName; + Files[FileIndex].DLName = FileName; + // Any file that is not INT or INI should be Unicode + Files[FileIndex].bIsUnicode = InStr(FileName,".ini",,true) == INDEX_NONE && InStr(FileName,".int",,true) == INDEX_NONE; + //`log("Files["$FileIndex$"].bIsUnicode = "$Files[FileIndex].bIsUnicode,, 'DevConfig'); + } + else + { + Files[FileIndex].ReadState = OERS_NotStarted; + } + // Kick off the download + DownloadFiles(); +} + +/** +* Adds the specified delegate to the registered downloader. Since the file read can come from +* different objects, this method hides that detail, but still lets callers get notifications +* +* @param ReadTitleFileCompleteDelegate the delegate to set +*/ +function AddReadFileDelegate(delegate ReadTitleFileCompleteDelegate) +{ + // Add the delegate if not None and not found + if (ReadTitleFileCompleteDelegate != None && + ReadTitleFileCompleteDelegates.Find(ReadTitleFileCompleteDelegate) == INDEX_NONE) + { + ReadTitleFileCompleteDelegates.AddItem(ReadTitleFileCompleteDelegate); + } +} + +/** +* Clears the specified delegate from any registered downloaders +* +* @param ReadTitleFileCompleteDelegate the delegate to remove from the downloader +*/ +function ClearReadFileDelegate(delegate ReadTitleFileCompleteDelegate) +{ + local int RemoveIndex; + + RemoveIndex = ReadTitleFileCompleteDelegates.Find(ReadTitleFileCompleteDelegate); + if (RemoveIndex != INDEX_NONE) + { + ReadTitleFileCompleteDelegates.Remove(RemoveIndex,1); + } +} + +// @ZOMBIE_FOXTROT_BEGIN - ccooper 1/9/2014 - Adding function to add delegates for all files downloads and patching complete +function AddAllTitleFilesCompletedDelegate(delegate InDelegate) +{ + if (AllTitleFilesCompletedDelegates.Find(InDelegate) == INDEX_NONE) + { + AllTitleFilesCompletedDelegates[AllTitleFilesCompletedDelegates.Length] = InDelegate; + } +} +function ClearAllTitleFilesCompletedDelegate(delegate InDelegate) +{ + local int RemoveIndex; + RemoveIndex = AllTitleFilesCompletedDelegates.Find(InDelegate); + if (RemoveIndex != INDEX_NONE) + { + AllTitleFilesCompletedDelegates.Remove(RemoveIndex,1); + } +} +// @ZOMBIE_FOXTROT_END + +/** +* Tells any subclasses to clear their cached file data +*/ +function ClearCachedFiles() +{ + local int Index; + + // Iterate through files trying to download them + for (Index = 0; Index < Files.Length; Index++) + { + // Reset their status + Files[Index].ReadState = OERS_NotStarted; + } + if (TitleFileInterface != None) + { + // memory copy of downloaded files + TitleFileInterface.ClearDownloadedFiles(); + } + if (TitleFileCacheInterface != None) + { + // memory copy of cached files + TitleFileCacheInterface.ClearCachedFiles(); + } +} + +/** +* Gets the proper language extension for the loc file +* +* @param FileName the file name being modified +* +* @return the modified file name for this language setting +*/ +native function string UpdateLocFileName(string FileName); \ No newline at end of file diff --git a/Engine/Classes/Input.uc b/Engine/Classes/Input.uc new file mode 100644 index 0000000..c3562f4 --- /dev/null +++ b/Engine/Classes/Input.uc @@ -0,0 +1,153 @@ +//============================================================================= +// Input +// Object that maps key events to key bindings +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= + +class Input extends Interaction + native(UserInterface) + config(Input) + transient; + +struct native KeyBind +{ + var config name Name; + var config string Command; + var config bool Control, + Shift, + Alt; + + /** if true, the bind will not be activated if the corresponding key is held down */ + var config bool bIgnoreCtrl, bIgnoreShift, bIgnoreAlt; + +structcpptext +{ + FKeyBind() + : Name() + , Control(FALSE), Shift(FALSE), Alt(FALSE) + , bIgnoreCtrl(FALSE), bIgnoreShift(FALSE), bIgnoreAlt(FALSE) + {} +} +}; + + +var config array Bindings; + +/** list of keys which this interaction handled a pressed event for */ +var protectedwrite array PressedKeys; + +var const int CurrentControllerId; +var const EInputEvent CurrentEvent; +var const float CurrentDelta; +var const float CurrentDeltaTime; + +var native const Map{FName,void*} NameToPtr; +var native const init array AxisArray{FLOAT}; + +/** A cached list of input kisment events, this greatly reduces overhead on each button press */ +var const array CachedInputEvents; +var const array CachedAnalogInputEvents; +var const array CachedTouchInputEvents; + +struct native TouchTracker +{ + /** Handle of this touch event */ + var int Handle; + + /** Handle of this touch event */ + var int TouchpadIndex; + + /** Handle of this touch event */ + var Vector2D Location; + + /** Current event type, used during Tick to decice what to do */ + var EInputEvent EventType; + + /** If TRUE, a Kismet node was determined to trap all input for this touch, so InputTouch will return TRUE if this is set */ + var bool bTrapInput; +}; +var const array CurrentTouches; + +cpptext +{ + // UInteraction interface. + + virtual UBOOL InputKey(INT ControllerId, FName Key, enum EInputEvent Event, FLOAT AmountDepressed = 1.f, UBOOL bGamepad = FALSE ); + virtual UBOOL InputAxis(INT ControllerId, FName Key, FLOAT Delta, FLOAT DeltaTime, UBOOL bGamepad=FALSE); + virtual void Tick(FLOAT DeltaTime); + UBOOL IsPressed( FName InKey ) const; + UBOOL IsCtrlPressed() const; + UBOOL IsShiftPressed() const; + UBOOL IsAltPressed() const; + + // UInput interface. + virtual UBOOL Exec(const TCHAR* Cmd,FOutputDevice& Ar); + + /** + * Clears the PressedKeys array. Should be called when another interaction which swallows some (but perhaps not all) input is activated. + */ + virtual void FlushPressedKeys() + { + PressedKeys.Empty(); + } + + // Protected. + + BYTE* FindButtonName(const TCHAR* ButtonName); + FLOAT* FindAxisName(const TCHAR* ButtonName); + /** + * Returns the Name of a bind using the bind's Command as the key + * StartBind Index is where the search will start from and where the index result will be stored + * -- If you don't where to start your search from (as the list will search backwards), set the StartBindIndex to -1 before passing it in + */ +//@zombie_ps4_begin - Adding support for getting gamepad bind + FString GetBindNameFromCommand(const FString& KeyCommand, INT* StartBindIndex = NULL, UBOOL bForGamepad = FALSE ) const; +//@zombie_ps4_end + void ExecInputCommands(const TCHAR* Cmd,class FOutputDevice& Ar); + virtual void UpdateAxisValue( FLOAT* Axis, FLOAT Delta ); + + /** + * Processes any kismet events looking for this input + * + * @return TRUE if the input was absorbed - the caller MUST NOT CONTINUE processing this input if TRUE is returned + */ + UBOOL ProcessInputKismetEvents(INT ControllerId, FName InputName, EInputEvent Event); + UBOOL ProcessAnalogKismetEvents(INT ControllerId, FName InputName, const FLOAT* FloatValue, const FVector* VectorValue); + UBOOL ProcessTouchKismetEvents(INT ControllerId, INT TouchIndex, EInputEvent Event); +} + +/** + * Resets this input object, flushing all pressed keys and clearing all player 'input' variables. + */ +native function ResetInput(); + +native function string GetBind(const out Name Key); + +exec function SetBind(const out name BindName, string Command) +{ + local KeyBind NewBind; + local int BindIndex; + + if ( Left(Command,1) == "\"" && Right(Command,1) == "\"" ) + { + Command = Mid(Command, 1, Len(Command) - 2); + } + + for(BindIndex = Bindings.Length-1;BindIndex >= 0;BindIndex--) + { + if(Bindings[BindIndex].Name == BindName) + { + Bindings[BindIndex].Command = Command; + // `log("Binding '"@BindName@"' found, setting command '"@Command@"'"); + SaveConfig(); + return; + } + } + + // `log("Binding '"@BindName@"' NOT found, adding new binding with command '"@Command@"'"); + NewBind.Name = BindName; + NewBind.Command = Command; + Bindings[Bindings.Length] = NewBind; + SaveConfig(); +} + diff --git a/Engine/Classes/InstancedFoliageActor.uc b/Engine/Classes/InstancedFoliageActor.uc new file mode 100644 index 0000000..69869d0 --- /dev/null +++ b/Engine/Classes/InstancedFoliageActor.uc @@ -0,0 +1,55 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InstancedFoliageActor extends Actor + native(Foliage) + hidecategories(Object); + +var const native Map_Mirror FoliageMeshes{TMap}; + +/** The static mesh type that will be used to show the widget */ +var const transient StaticMesh SelectedMesh; + +/* Used during gameplay to simplify RTGC */ +var const transient array InstancedStaticMeshComponents; + +cpptext +{ + // UObject interface + virtual void Serialize(FArchive& Ar); + virtual void PostLoad(); + + // AActor interface + virtual void UpdateComponentsInternal(UBOOL bCollisionUpdate = FALSE); + virtual void ClearComponents(); + + // AInstancedFoliageActor interface +#if WITH_EDITOR + // Called from editor code to manage instances for components + void SnapInstancesForLandscape( class ULandscapeHeightfieldCollisionComponent* InComponent, const FBox& InInstanceBox ); + void MoveInstancesForComponentToCurrentLevel( class UActorComponent* InComponent ); + void MoveInstancesForMovedComponent( class UActorComponent* InComponent ); + TMap > GetInstancesForComponent( class UActorComponent* InComponent ); + void DeleteInstancesForComponent( class UActorComponent* InComponent ); + + // Addition, removal and selection + struct FFoliageMeshInfo* AddMesh( class UStaticMesh* InMesh ); + void RemoveMesh( class UStaticMesh* InMesh ); + void SelectInstance( class UInstancedStaticMeshComponent* InComponent, INT InComponentInstanceIndex, UBOOL bToggle ); + void ApplySelectionToComponents( UBOOL bApply ); + void CheckSelection(); + FVector GetSelectionLocation(); + + // Get the instanced foliage actor for the current streaming level. + static AInstancedFoliageActor* GetInstancedFoliageActor(UBOOL bCreateIfNone=TRUE); + // Get the instanced foliage actor for the specified streaming level. Never creates a new IFA. + static AInstancedFoliageActor* GetInstancedFoliageActorForLevel(ULevel* Level); +#endif +} + +defaultproperties +{ + bStatic=true + bCollideActors=true + bBlockActors=true +} \ No newline at end of file diff --git a/Engine/Classes/InstancedFoliageSettings.uc b/Engine/Classes/InstancedFoliageSettings.uc new file mode 100644 index 0000000..aadfc96 --- /dev/null +++ b/Engine/Classes/InstancedFoliageSettings.uc @@ -0,0 +1,123 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InstancedFoliageSettings extends Object + native(Foliage) + hidecategories(Object) + editinlinenew; + +var(Painting) float Density; +var(Painting) float Radius; +var(Painting) float ScaleMinX; +var(Painting) float ScaleMinY; +var(Painting) float ScaleMinZ; +var(Painting) float ScaleMaxX; +var(Painting) float ScaleMaxY; +var(Painting) float ScaleMaxZ; +var(Painting) bool LockScaleX; +var(Painting) bool LockScaleY; +var(Painting) bool LockScaleZ; +var(Painting) float AlignMaxAngle; +var(Painting) float RandomPitchAngle; +var(Painting) float GroundSlope; +var(Painting) float HeightMin; +var(Painting) float HeightMax; +var(Painting) Name LandscapeLayer; +var(Painting) bool AlignToNormal; +var(Painting) bool RandomYaw; +var(Painting) bool UniformScale; +var(Painting) float ZOffsetMin; +var(Painting) float ZOffsetMax; + +var(Clustering) int MaxInstancesPerCluster; +var(Clustering) float MaxClusterRadius; + +var float ReapplyDensityAmount; +var bool ReapplyDensity; +var bool ReapplyRadius; +var bool ReapplyAlignToNormal; +var bool ReapplyRandomYaw; +var bool ReapplyScaleX; +var bool ReapplyScaleY; +var bool ReapplyScaleZ; +var bool ReapplyRandomPitchAngle; +var bool ReapplyGroundSlope; +var bool ReapplyHeight; +var bool ReapplyLandscapeLayer; +var bool ReapplyZOffset; + +enum FoliageCullOption +{ + FOLIAGECULL_Cull, + FOLIAGECULL_ScaleZ, + FOLIAGECULL_ScaleXYZ, + FOLIAGECULL_TranslateZ +}; + +var(Culling) int StartCullDistance; +var(Culling) int EndCullDistance; +var(Culling) FoliageCullOption CullOption; +var(Culling) EDetailMode DetailMode; + +var(Lighting) bool CastShadow; +var(Lighting) bool bCastDynamicShadow; +var(Lighting) bool bCastStaticShadow; +var(Lighting) bool bSelfShadowOnly; +var(Lighting) bool bNoModSelfShadow; +var(Lighting) bool bAcceptsDynamicDominantLightShadows; +var(Lighting) bool bCastHiddenShadow; +var(Lighting) bool bCastShadowAsTwoSided; +var(Lighting) const bool bAcceptsLights; +var(Lighting) const bool bAcceptsDynamicLights; +var(Lighting) const bool bUseOnePassLightingOnTranslucency; +var(Lighting) const bool bUsePrecomputedShadows; + +var(Collision) bool bCollideActors; +var(Collision) bool bBlockActors; +var(Collision) bool bBlockNonZeroExtent; +var(Collision) bool bBlockZeroExtent; + +var int DisplayOrder; +var bool IsSelected; +var bool ShowNothing; +var bool ShowPaintSettings; +var bool ShowInstanceSettings; + +defaultproperties +{ + Density=100.0 + Radius=0.0 + AlignToNormal=true + RandomYaw=true + UniformScale=true + ScaleMinX=1.0 + ScaleMinY=1.0 + ScaleMinZ=1.0 + ScaleMaxX=1.0 + ScaleMaxY=1.0 + ScaleMaxZ=1.0 + AlignMaxAngle=0.0 + RandomPitchAngle=0.0 + GroundSlope=45.0 + HeightMin=-262144.0 + HeightMax=262144.0 + ZOffsetMin=0.0 + ZOffsetMax=0.0 + LandscapeLayer=None + MaxInstancesPerCluster=100 + MaxClusterRadius=10000.0 + DisplayOrder=0 + IsSelected=false + ShowNothing=false + ShowPaintSettings=true + ShowInstanceSettings=false + ReapplyDensityAmount=1.0 + + CastShadow=TRUE + bCastDynamicShadow=TRUE + bCastStaticShadow=TRUE + bAcceptsDynamicDominantLightShadows=TRUE + bAcceptsLights=TRUE + bAcceptsDynamicLights=TRUE + bUsePrecomputedShadows=TRUE +} diff --git a/Engine/Classes/InstancedStaticMeshComponent.uc b/Engine/Classes/InstancedStaticMeshComponent.uc new file mode 100644 index 0000000..240e124 --- /dev/null +++ b/Engine/Classes/InstancedStaticMeshComponent.uc @@ -0,0 +1,175 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InstancedStaticMeshComponent extends StaticMeshComponent + native(Mesh); + +struct immutablewhencooked native InstancedStaticMeshInstanceData +{ + var matrix Transform; + var vector2d LightmapUVBias; + var vector2d ShadowmapUVBias; + + structcpptext + { + // Serialization + friend FArchive& operator<<(FArchive& Ar, FInstancedStaticMeshInstanceData& InstanceData) + { + // @warning BulkSerialize: FInstancedStaticMeshInstanceData is serialized as memory dump + // See TArray::BulkSerialize for detailed description of implied limitations. + Ar << InstanceData.Transform << InstanceData.LightmapUVBias << InstanceData.ShadowmapUVBias; + return Ar; + } + } +}; + +struct native InstancedStaticMeshMappingInfo +{ + var native pointer Mapping{class FInstancedStaticMeshStaticLightingTextureMapping}; + var native pointer Lightmap{class FInstancedLightMap2D}; + var texture2d LightmapTexture; + var shadowmap2d ShadowmapTexture; +}; + +/** Deprecated array of instances, script serialized */ +var deprecated array PerInstanceData; + +/** Array of instances, bulk serialized */ +var native array PerInstanceSMData; + +/** Number of pending lightmaps still to be calculated (Apply()'d) */ +var transient int NumPendingLightmaps; + +/** + * A key for deciding which components are compatible when joining components together after a lighting build. + * Will default to the staticmesh pointer when SetStaticMesh is called, so this must be set after calling + * SetStaticMesh on the component + */ +var int ComponentJoinKey; + +/** The mappings for all the instances of this component */ +var transient array CachedMappings; + +/** Value used to seed the random number stream that generates random numbers for each of this mesh's instances. + The random number is stored in a buffer accessible to materials through the PerInstanceRandom expression. If + this is set to zero (default), it will be populated automatically by the editor */ +var() int InstancingRandomSeed; + +/** Distance from camera at which each instance begins to fade out */ +var(Culling) int InstanceStartCullDistance; + +/** Distance from camera at which each instance completely fades out */ +var(Culling) int InstanceEndCullDistance; + +/** One bit per instance to show selection in the editor */ +var editoronly native const BitArray_Mirror SelectedInstances{TBitArray<>}; + +/** Flag to prevent split up/join components into multiple components after building lighting */ +var bool bDontResolveInstancedLightmaps; + +cpptext +{ + virtual FPrimitiveSceneProxy* CreateSceneProxy(); + virtual void UpdateBounds(); + virtual void GetStaticLightingInfo(FStaticLightingPrimitiveInfo& OutPrimitiveInfo,const TArray& InRelevantLights,const FLightingBuildOptions& Options); + + void UpdateInstances(); + void ApplyAllMappings(); + + static TSet ActorsWithInstancedComponents; + static void ResolveInstancedLightmaps(UBOOL bWasLightingSuccessful, UBOOL bIgnoreTextureForBatching=FALSE); + static void ResolveInstancedLightmapsForActor(AActor* InActor, UBOOL bWasLightingSuccessful, UBOOL bIgnoreTextureForBatching=FALSE); + + virtual void GetLightAndShadowMapMemoryUsage( INT& LightMapMemoryUsage, INT& ShadowMapMemoryUsage ) const; + + /** + * Serialize function. + * + * @param Ar Archive to serialize with + */ + virtual void Serialize(FArchive& Ar); + + /** + * Returns whether or not this component is instanced. + * + * @return TRUE if this component represents multiple instances of a primitive. + */ + virtual UBOOL IsPrimitiveInstanced() const + { + return TRUE; + } + + /** + * For instanced components, returns the number of instances. + * + * @return Number of instances + */ + virtual INT GetInstanceCount() const + { + return PerInstanceSMData.Num(); + } + + /** + * Returns whether this primitive should render selection. + */ + virtual UBOOL ShouldRenderSelected() const + { + return UPrimitiveComponent::ShouldRenderSelected() +#if WITH_EDITORONLY_DATA + // Also render selected if we have an array of selected instances + || SelectedInstances.Num() > 0 +#endif + ; + } + + /** + * For instanced components, returns the Local -> World transform for the specific instance number. + * If the function is called on non-instanced components, the component's LocalToWorld will be returned. + * You should override this method in derived classes that support instancing. + * + * @param InInstanceIndex The index of the instance to return the Local -> World transform for + * + * @return Number of instances + */ + virtual const FMatrix GetInstanceLocalToWorld( INT InInstanceIndex ) const + { + return PerInstanceSMData( InInstanceIndex ).Transform * LocalToWorld; + } + + virtual void InitComponentRBPhys(UBOOL bFixed); + + +#if STATS + /** + * Called after all objects referenced by this object have been serialized. Order of PostLoad routed to + * multiple objects loaded in one set is not deterministic though ConditionalPostLoad can be forced to + * ensure an object has been "PostLoad"ed. + */ + virtual void PostLoad(); + + /** + * Informs object of pending destruction via GC. + */ + void BeginDestroy(); + + /** + * Attaches the component to a ParentToWorld transform, owner and scene. + * Requires IsValidComponent() == true. + */ + virtual void Attach(); + + /** + * Detaches the component from the scene it is in. + * Requires bAttached == true + * + * @param bWillReattach TRUE is passed if Attach will be called immediately afterwards. This can be used to + * preserve state between reattachments. + */ + virtual void Detach( UBOOL bWillReattach = FALSE ); +#endif +} + +defaultproperties +{ + bSupportedOnMobile=FALSE +} diff --git a/Engine/Classes/Interaction.uc b/Engine/Classes/Interaction.uc new file mode 100644 index 0000000..8bfbe11 --- /dev/null +++ b/Engine/Classes/Interaction.uc @@ -0,0 +1,214 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class Interaction extends UIRoot + native(UserInterface) + transient; + +/** + * The types of touch inputs we could get queued from the OS + */ +enum ETouchType +{ + Touch_Began, + Touch_Moved, + Touch_Stationary, + Touch_Ended, + Touch_Cancelled, +}; + +cpptext +{ + /** + * Minimal initialization constructor. + */ + UInteraction(); + + /** + * Called once a frame to update the interaction's state. + * @param DeltaTime - The time since the last frame. + */ + virtual void Tick(FLOAT DeltaTime) + { + eventTick(DeltaTime); + } + + /** + * Process an input key event received from the viewport. + * + * @param Viewport the viewport the input event was received from + * @param ControllerId gamepad/controller that generated this input event + * @param Key the name of the key which an event occured for (KEY_Up, KEY_Down, etc.) + * @param EventType the type of event which occured (pressed, released, etc.) + * @param AmountDepressed (analog keys only) the depression percent. + * @param bGamepad - input came from gamepad (ie xbox controller) + * + * @return TRUE to consume the key event, FALSE to pass it on. + */ + virtual UBOOL InputKey(INT ControllerId,FName Key,EInputEvent Event,FLOAT AmountDepressed=1.f,UBOOL bGamepad=FALSE) + { + return FALSE; + } + + /** + * Process an input axis (joystick, thumbstick, or mouse) event received from the viewport. + * + * @param Viewport the viewport the input event was received from + * @param ControllerId the controller that generated this input axis event + * @param Key the name of the axis that moved (KEY_MouseX, KEY_XboxTypeS_LeftX, etc.) + * @param Delta the movement delta for the axis + * @param DeltaTime the time (in seconds) since the last axis update. + * + * @return TRUE to consume the axis event, FALSE to pass it on. + */ + virtual UBOOL InputAxis(INT ControllerId,FName Key,FLOAT Delta,FLOAT DeltaTime, UBOOL bGamepad=FALSE) + { + return FALSE; + } + + /** + * Process a character input event (typing) received from the viewport. + * + * @param Viewport the viewport the input event was received from + * @param ControllerId the controller that generated this character input event + * @param Character the character that was typed + * + * @return TRUE to consume the key event, FALSE to pass it on. + */ + virtual UBOOL InputChar(INT ControllerId,TCHAR Character) + { + return FALSE; + } + + + /** + * Process a touchpad touch input event received from the viewport. + * + * @param ControllerId - The controller which the key event is from. + * @param Handle - Identifier unique to this touch event + * @param TouchLocation - Screen position of the touch + * @param DeviceTimestamp - Timestamp of the event + * @param TouchpadIndex - For devices with multiple touchpads, this is the index of which one + * @return True to consume the key event, false to pass it on. + */ + virtual UBOOL InputTouch(INT ControllerId, UINT Handle, ETouchType Type, FVector2D TouchLocation, DOUBLE DeviceTimestamp, UINT TouchpadIndex=0) + { + return FALSE; + } + + /** + * Process a motion event received from the viewport. + * + * @param ControllerId - The controller which the key event is from. + * @param Tilt The current orientation of the device + * @param RotationRate How fast the tilt is changing + * @param Gravity Describes the current gravity of the device + * @param Acceleration Describes the acceleration of the device + * @return True to consume the motion event, false to pass it on. + */ + virtual UBOOL InputMotion(INT ControllerId, const FVector& Tilt, const FVector& RotationRate, const FVector& Gravity, const FVector& Acceleration) + { + return FALSE; + } + + +public: +} + +/** + * Provides script-only child classes the opportunity to handle input key events received from the viewport. + * This delegate is ONLY called when input is being routed natively from the GameViewportClient + * (i.e. NOT when unrealscript calls the InputKey native unrealscript function on this Interaction). + * + * @param ControllerId the controller that generated this input key event + * @param Key the name of the key which an event occured for (KEY_Up, KEY_Down, etc.) + * @param EventType the type of event which occured (pressed, released, etc.) + * @param AmountDepressed for analog keys, the depression percent. + * @param bGamepad input came from gamepad (ie xbox controller) + * + * @return return TRUE to indicate that the input event was handled. if the return value is TRUE, the input event will not + * be processed by this Interaction's native code. + */ +delegate bool OnReceivedNativeInputKey( int ControllerId, name Key, EInputEvent EventType, optional float AmountDepressed=1.f, optional bool bGamepad ); + +/** + * Provides script-only child classes the opportunity to handle input axis events received from the viewport. + * This delegate is ONLY called when input is being routed natively from the GameViewportClient + * (i.e. NOT when unrealscript calls the InputKey native unrealscript function on this Interaction). + * + * @param ControllerId the controller that generated this input axis event + * @param Key the name of the axis that moved (KEY_MouseX, KEY_XboxTypeS_LeftX, etc.) + * @param Delta the movement delta for the axis + * @param DeltaTime the time (in seconds) since the last axis update. + * @param bGamepad input came from gamepad (ie xbox controller) + * + * @return return TRUE to indicate that the input event was handled. if the return value is TRUE, the input event will not + * be processed by this Interaction's native code. + */ +delegate bool OnReceivedNativeInputAxis( int ControllerId, name Key, float Delta, float DeltaTime, optional bool bGamepad ); + +/** + * Provides script-only child classes the opportunity to handle character input (typing) events received from the viewport. + * This delegate is ONLY called when input is being routed natively from the GameViewportClient + * (i.e. NOT when unrealscript calls the InputKey native unrealscript function on this Interaction). + * + * @param ControllerId the controller that generated this character input event + * @param Unicode the character that was typed + * + * @return return TRUE to indicate that the input event was handled. if the return value is TRUE, the input event will not + * be processed by this Interaction's native code. + */ +delegate bool OnReceivedNativeInputChar( int ControllerId, string Unicode ); + +/** + * Called once a frame to update the interaction's state. + * @param DeltaTime - The time since the last frame. + */ +event Tick(float DeltaTime); + +/** + * Called once a frame to allow the interaction to draw to the canvas + * @param Canvas Canvas object to draw to + */ +event PostRender(Canvas Canvas); + +/** + * Called when the interaction is added to the GlobalInteractions array. + */ +native final virtual function Init(); + +/** + * Called from native Init() after native initialization has been performed. + */ +delegate OnInitialize(); + +/** + * default handler for OnInitialize delegate. Here so that child classes can override the default behavior easily + */ +function Initialized(); + +/** + * Called when the current map is being unloaded. Cleans up any references which would prevent garbage collection. + */ +function NotifyGameSessionEnded(); + +/** + * Called when a new player has been added to the list of active players (i.e. split-screen join) + * + * @param PlayerIndex the index [into the GamePlayers array] where the player was inserted + * @param AddedPlayer the player that was added + */ +function NotifyPlayerAdded( int PlayerIndex, LocalPlayer AddedPlayer ); + +/** + * Called when a player has been removed from the list of active players (i.e. split-screen players) + * + * @param PlayerIndex the index [into the GamePlayers array] where the player was located + * @param RemovedPlayer the player that was removed + */ +function NotifyPlayerRemoved( int PlayerIndex, LocalPlayer RemovedPlayer ); + +defaultproperties +{ + OnInitialize=Initialized +} diff --git a/Engine/Classes/InteractiveFoliageActor.uc b/Engine/Classes/InteractiveFoliageActor.uc new file mode 100644 index 0000000..d6ba67b --- /dev/null +++ b/Engine/Classes/InteractiveFoliageActor.uc @@ -0,0 +1,125 @@ +//============================================================================= +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class InteractiveFoliageActor extends StaticMeshActor + native(Foliage) + placeable; + +/** Collision cylinder */ +var private{private} CylinderComponent CylinderComponent; + +/** + * Position of the last actor to enter the collision cylinder. + * This currently does not handle multiple actors affecting the foliage simultaneously. + */ +var private{private} transient vector TouchingActorEntryPosition; + +/** Simulated physics state */ +var private{private} transient vector FoliageVelocity; +var private{private} transient vector FoliageForce; +var private{private} transient vector FoliagePosition; + +/** Scales forces applied from damage events. */ +var(FoliagePhysics) float FoliageDamageImpulseScale; + +/** Scales forces applied from touch events. */ +var(FoliagePhysics) float FoliageTouchImpulseScale; + +/** Determines how strong the force that pushes toward the spring's center will be. */ +var(FoliagePhysics) float FoliageStiffness; + +/** + * Same as FoliageStiffness, but the strength of this force increases with the square of the distance to the spring's center. + * This force is used to prevent the spring from extending past a certain point due to touch and damage forces. + */ +var(FoliagePhysics) float FoliageStiffnessQuadratic; + +/** + * Determines the amount of energy lost by the spring as it oscillates. + * This force is similar to air friction. + */ +var(FoliagePhysics) float FoliageDamping; + +/** Clamps the magnitude of each damage force applied. */ +var(FoliagePhysics) float MaxDamageImpulse; + +/** Clamps the magnitude of each touch force applied. */ +var(FoliagePhysics) float MaxTouchImpulse; + +/** Clamps the magnitude of combined forces applied each update. */ +var(FoliagePhysics) float MaxForce; + +//@todo - hook this up +var float Mass; + +cpptext +{ +protected: + void SetupCollisionCylinder(); +public: + virtual void TickSpecial(FLOAT DeltaSeconds); + virtual void Spawned(); + virtual void PostLoad(); +}; + +native simulated event TakeDamage(int Damage, Controller EventInstigator, vector HitLocation, vector Momentum, class DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser); +native simulated event Touch( Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal ); + +defaultproperties +{ + Begin Object Class=InteractiveFoliageComponent Name=FoliageMeshComponent0 + bAllowApproximateOcclusion=TRUE + bForceDirectLightMap=TRUE + bUsePrecomputedShadows=TRUE + // Foliage actors are usually animated using vertex position offset, which does not work correctly with decals + bAcceptsStaticDecals=FALSE + bAcceptsDynamicDecals=FALSE + End Object + StaticMeshComponent=FoliageMeshComponent0 + Components.Remove(StaticMeshComponent0) + Components.Add(FoliageMeshComponent0) + + // Needs to receive Touch and TakeDamage + bCollideActors=true + // Don't want to block actors, just be notified when they are touching + bBlockActors=false + // Block bullets so we can receive TakeDamage from them, the damage will be passed through with PassThroughDamage + bProjTarget=true + BlockRigidBody=false + + // Add a cylinder component to be used for collision + Begin Object Class=CylinderComponent Name=CollisionCylinder + // These get overwritten on load or spawn + CollisionRadius=+00060.000000 + CollisionHeight=+00200.000000 + CollideActors=true + BlockActors=false + // Don't want the cylinder to block bullets + BlockZeroExtent=false + BlockNonZeroExtent=true + End Object + CollisionComponent=CollisionCylinder + CylinderComponent=CollisionCylinder + Components.Add(CollisionCylinder) + + bWorldGeometry=false + // Has to be dynamic to get ticked + bStatic=false + bMovable=false + bNoDelete=true + // Visual effects should tick during async work + TickGroup=TG_DuringAsyncWork + + FoliageDamageImpulseScale=20 + FoliageTouchImpulseScale=10 + FoliageStiffness=10 + FoliageStiffnessQuadratic=.3 + FoliageDamping=2 + MaxDamageImpulse=100000 + MaxTouchImpulse=1000 + MaxForce=100000 + Mass=1 +`if(`__TW_PERFORMANCE_) + bSkipPostTickComponentUpdate=TRUE +`endif +} diff --git a/Engine/Classes/InteractiveFoliageComponent.uc b/Engine/Classes/InteractiveFoliageComponent.uc new file mode 100644 index 0000000..55c4d96 --- /dev/null +++ b/Engine/Classes/InteractiveFoliageComponent.uc @@ -0,0 +1,24 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InteractiveFoliageComponent extends StaticMeshComponent + native(Foliage) + hidecategories(Object); + +var protected{protected} const native duplicatetransient pointer FoliageSceneProxy{class FInteractiveFoliageSceneProxy}; + +cpptext +{ + virtual FPrimitiveSceneProxy* CreateSceneProxy(); + /** + * Detach the component from the scene and remove its render proxy + * @param bWillReattach TRUE if the detachment will be followed by an attachment + */ + virtual void Detach( UBOOL bWillReattach = FALSE ); + + friend class AInteractiveFoliageActor; +} + +defaultproperties +{ +} diff --git a/Engine/Classes/Interface_NavMeshPathObject.uc b/Engine/Classes/Interface_NavMeshPathObject.uc new file mode 100644 index 0000000..fafc02b --- /dev/null +++ b/Engine/Classes/Interface_NavMeshPathObject.uc @@ -0,0 +1,357 @@ +/** + * Interface for path objects which need to interface with the navmesh + * - mostly provides a linkage from edges in the mesh to an object in the game. Useful for specifc edges which + * need special handling (e.g. ladders). This interface does not provide methods for altaring the mesh at runtime, for that + * see Interface_navMeshPathObstacle (which can be used in conjunction with this interface) + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +interface Interface_NavMeshPathObject + native(AI); + +cpptext +{ + /************************************************************************ + * Runtime Edge Query interface * + ************************************************************************/ + + virtual void InitGuid( TArray& ExistingNavGuids ) + { + AActor* Actor = Cast(GetUObjectInterfaceInterface_NavMeshPathObject()); + if( Actor != NULL ) + { + FGuid* pGuid = Actor->GetGuid(); + if( pGuid ) + { + if( !pGuid->IsValid() || ExistingNavGuids.ContainsItem(*pGuid) ) + { + *pGuid = appCreateGuid(); + } + else + { + // save the existing guid to check for duplicates + ExistingNavGuids.AddItem(*pGuid); + } + } + } + } + + /** + * Called from edges linked to this PO + * @param Interface - the navhandle interface of the entity pathing + * @param PreviousPoint - the previous point in the path search (e.g. the point along the predecessor edge) + * @param out_PathEdgePoint - the point we used along this edge to determine the cost + * @param Edge - the edge linked to this PO which needs to compute cost + * @return - the cost for traversing this edge + */ + virtual INT CostFor( const FNavMeshPathParams& PathParams, const FVector& PreviousPoint, FVector& out_PathEdgePoint, FNavMeshPathObjectEdge* Edge, FNavMeshPolyBase* SourcePoly ) + { + return Edge->FNavMeshEdgeBase::CostFor(PathParams, PreviousPoint, out_PathEdgePoint, SourcePoly); + } + + /** + * passthru function from edge to determine if the passed searcher supports this pathobject's movement + * @param Interface - the interface of the searcher + * @param CurPoly - the poly being checked for support + * @param Edge - the edge linked to this path object which is being considered + * @param PredecessorEdge - the edge we are coming from to get to 'Edge' + * @return TRUE if this path object supports the searcher + */ + virtual UBOOL Supports( const FNavMeshPathParams& PathParams, + FNavMeshPolyBase* CurPoly, + FNavMeshPathObjectEdge* Edge, + FNavMeshEdgeBase* PredecessorEdge) + { + return Edge->FNavMeshEdgeBase::Supports(PathParams,CurPoly,PredecessorEdge); + } + + /** + * called when an entity is about to move through an edge linked to this path object. Allows the path object to + * trigger animations, etc related to this PO + * @param Interface - the entity which is traversing this PO + * @param out_MovePt - the point generated by GetEdgeDestination which the entity is moving toward + * @param Edge - the edge linked to this PathObject which is being moved through + * @return - whether or not the move was successful (true means we're done with this edge, remove it from path) + */ + virtual UBOOL PrepareMoveThru( class IInterface_NavigationHandle* Interface, + FVector& out_MovePt, + FNavMeshPathObjectEdge* Edge ) + { + return FALSE; + } + + /** + * called to determine the optimal position along this edge for the passed parameters (e.g. string pulling) + * @param EntityRadius - the radius of the entity we are computing the position for + * @param InfluencePosition - the position we are trying to get close to (e.g. previous point in path) + * @param EntityPosition - the current position of the entity (e.g. starting position of bot) + * @param Edge - the edge which is associated with this PO which we're being asked about + * @param out_EdgeDest - the destination we want to use + * @return whether this PO modified the destination or not (FALSE indicates the default edge functionality should be used) + */ + virtual UBOOL GetEdgeDestination( const FNavMeshPathParams& PathParams, + FLOAT EntityRadius, + const FVector& InfluencePosition, + const FVector& EntityPosition, + FVector& out_EdgeDest, + FNavMeshPathObjectEdge* Edge, + UNavigationHandle* Handle) + { + return FALSE; + } + + /** + * called to allow this PO to draw custom stuff for edges linked to it + * @param DRSP - the sceneproxy we're drawing for + * @param DrawOffset - offset from the actual location we should be drawing + * @param Edge - the edge we're drawing + * @return - whether this PO is doing custom drawing for the passed edge (FALSE indicates the default edge drawing functionality should be used) + */ + virtual UBOOL DrawEdge( FDebugRenderSceneProxy* DRSP, FColor C, FVector DrawOffset, FNavMeshPathObjectEdge* Edge ) + { + return FALSE; + } + + /** + * allows path objects to dictate when it's OK for GetNextMoveLocation to push the current edge past this one in the AI's path. + * (normally the edge the AI is running to is figured out automatically based on which polygon the AI is in) + * @param PathParams - the parameters associated with the AI wondering if it is OK to run normal behavior + * @param bInPoly0 - whether the AI is currently in poly0 of this edge + * @param bInPoly1 - whether the AI is currently in poly1 of this edge + * @return - TRUE if it's OK to automatically progress the edge past this one + */ + virtual UBOOL AllowMoveToNextEdge(FNavMeshPathParams& PathParams, UBOOL bInPoly0, UBOOL bInPoly1){ return TRUE; } + + /** + * this function is called after a poly linked to this edge is replaced with a submesh for a pathobstacle + * allows special edges to have a chance to add extra data after the mesh is split + * @params Edge - the edge that we are updating for + * @param Poly - the poly that was just disabled and replaced with a submesh + * @param NewSubMesh - the submesh that now represents the poly + */ + virtual void PostSubMeshUpdateForOwningPoly(FNavMeshPathObjectEdge* Edge, FNavMeshPolyBase* Poly, UNavigationMeshBase* New_SubMesh){} + + /** + * This is a helper function which is useful when this pathobject is being used in conjunction with the pathobstacle interface + * - just does all the work normally done in AddObstacleEdge, except convenienty tuned for use with pathobjects + * @param Status - current status of edges (e.g. what still needs adding) + * @param inV1 - vertex location of first vert in the edge + * @param inV2 - vertex location of second vert in the edge + * @param ConnectedPolys - the polys this edge links + * @param bEdgesNeedToBeDynamic - whether or not added edges need to be dynamic (e.g. we're adding edges between meshes) + * @param PolyAssocatedWithThisPO - the index into the connected polys array of the poly which is associated with this path object + * @param POOwner - the owner of the pathobject interface (e.g. the actor that implements interface) + * @param SupportedEdgeWidth - widht of unit this edge supports (defaults to -1.0 in which case the length of the edge will be used) + * @(optional) param EdgeGroupID - ID of the edgegroup this edge is a part of (defaults to no group) + * @return returns an enum describing what just happened (what actions did we take) - used to determien what accompanying actions need to be taken + * by other obstacles and calling code + */ + EEdgeHandlingStatus AddObstacleEdgeForObstacle( EEdgeHandlingStatus Status, const FVector& inV1, const FVector& inV2, TArray& ConnectedPolys, UBOOL bEdgesNeedToBeDynamic, INT PolyAssocatedWithThisPO, AActor* POOwner, FLOAT SupportedEdgeWidth=-1.0f, BYTE EdgeGroupID=MAXBYTE) + { + // if an edge has already been added in the direction we want to add an edge then there is probably a conflicting pathobstacle (e.g. we're butted + // up against another obstacle which has already added an edge.. so just bail) + if(Status == EHS_AddedBothDirs) + { + return Status; + } + + // if there is already an edge point back into this PO from the other poly, bail + if( (PolyAssocatedWithThisPO == 0 && Status == EHS_Added1to0) || + (PolyAssocatedWithThisPO == 1 && Status == EHS_Added0to1) ) + { + return Status; + } + + TArray ReversedConnectedPolys=ConnectedPolys; + + // so we want to add an edge back into the poly associated with this PO, so swap the order if we need to + if(PolyAssocatedWithThisPO == 0) + { + ReversedConnectedPolys.SwapItems(0,1); + } + + UNavigationMeshBase* Mesh = ReversedConnectedPolys(0)->NavMesh; + + if( Mesh == NULL ) + { + return Status; + } + + FNavMeshPathObjectEdge* NewEdge = NULL; + if( bEdgesNeedToBeDynamic ) + { + TArray CreatedEdges; + Mesh->AddDynamicCrossPylonEdge(inV1,inV2,ReversedConnectedPolys,SupportedEdgeWidth,EdgeGroupID,TRUE, &CreatedEdges); + + NewEdge = (CreatedEdges.Num() > 0) ? CreatedEdges(0) : NULL; + checkSlowish(CreatedEdges.Num() <2); + } + else + { + if (! Mesh->AddOneWayCrossPylonEdgeToMesh(inV1,inV2,ReversedConnectedPolys,SupportedEdgeWidth,EdgeGroupID,&NewEdge) ) + { + // we failed to add an edge for some reason.. if it returns true, we added an edge or there was already an identical edge there + return Status; + } + + } + + // bind new edge to this avoidance vol + if(NewEdge != NULL) + { + NewEdge->PathObject = POOwner; + NewEdge->InternalPathObjectID = 0; + } + + // indicate that we added an edge from dest poly to src poly + if(Status == EHS_AddedNone) + { + if(PolyAssocatedWithThisPO == 0) + { + return EHS_Added1to0; + } + else + { + return EHS_Added0to1; + } + } + else + { + // if we get here that means someone should have already added an edge in the opposite direction + return EHS_AddedBothDirs; + } + } + + + /************************************************************************ + * Mesh generation interface * + ************************************************************************/ + + /** + * this function describes a 'cookie cutter' edge that will be used to split the mesh beneath it + * for example if you have a cost inflicting volume that needs to conform the mesh to itself + * you could return an array of verts along the bottom boundary of the volume, and a height up to the top of the volume + * and then you have poly boundaries exactly along the border of the volume with which you can add + * edges which affect cost + * @param Poly - array of vectors that describe bottom of 'cookie cutter' volume (should be CW and convex) + * @param PolyHeight - height above the poly within which polys should be split (extrude passed poly up by this amount and use faces for clip) + * @return - TRUE if this shape should be used to split the mesh FALSE if no splitting is necessary + */ + virtual UBOOL GetMeshSplittingPoly( TArray& Poly, FLOAT& PolyHeight ){ return FALSE; } + + /** + * called for each pylon's exploration to see if this path object needs to be consulted during exploration + * @param Py - the pylon being explored that we need to know if this PO should be asked about + * @return - TRUE if this path object needs to have its IsExplorationAllowed function considered during path exploration + */ + virtual UBOOL NeedsForbidExploreCheck(APylon* Py) { return FALSE; } + + /** + * called during mesh exploration, allows this PO to forbid exploration through specific areas + * @param Py - the pylon being explored right now + * @param TestPosition - the position of the new poly we are asking about + * @return - TRUE if exploration is allowed + */ + virtual UBOOL IsExplorationAllowed( APylon* Py, const FVector& TestPosition) { return TRUE; } + + /** + * called after initial exploration, gives this PO a chance to add seeds to the exploration process + * @param SeedPointList - reference to the main array of seeds that need to be expanded after initial explore + * @param Py - the pylon which is being expanded + */ + virtual void AddAuxSeedPoints( APylon* Py ){} + + /** + * called after edge creation is complete for each pylon to allow this PO to add edges for itself + * @param Py - the pylon which we are creating edges for + */ + virtual void CreateEdgesForPathObject( APylon* Py ){} + + /** + * Function to be used from within CreateEdgesForPathObject + * @param Interface_Owner - the actor which owns this interface + * @param StartPoly - Source poly for edge + * @param EndPoly - Destination poly for edge + * @param Vert0 - One end point of the edge + * @param Vert1 - Another end point of the edge + * @param InternalPOID - optional param for extra identifier which is attached to the edge being added (to distinguish between edges linked to this PO) + * @return - T/F indicating success + */ + UBOOL AddEdgeForThisPO(AActor* Interface_Owner, + APylon* Py, + FNavMeshPolyBase* StartPoly, + FNavMeshPolyBase* EndPoly, + const FVector& Vert0, + const FVector& Vert1, + INT InternalPOID=-1, + UBOOL bForce=FALSE) + { + UNavigationMeshBase* Mesh = Py->GetNavMesh(); + if( Mesh == NULL ) + { + return FALSE; + } + + if( StartPoly == EndPoly || StartPoly == NULL || EndPoly == NULL ) + { + warnf(NAME_Warning,TEXT("WARNING! A pathobject (%s) tried to add an edge that links a poly to itself, or links a poly to nothing. This add is being IGNORED!"), *Interface_Owner->GetName()); + return FALSE; + } + TArray ConnectedPolys; + ConnectedPolys.AddItem(StartPoly); + ConnectedPolys.AddItem(EndPoly); + + FNavMeshPathObjectEdge* NewEdge = NULL; + if( Mesh->AddOneWayCrossPylonEdgeToMesh(Vert0,Vert1,ConnectedPolys,-1.0f,MAXBYTE,&NewEdge,bForce) ) + { + if(NewEdge != NULL) + { + NewEdge->PathObject = Interface_Owner; + NewEdge->InternalPathObjectID = InternalPOID; + } + + // still want to return true if newedge is null, false indicates we ran out of vert indices + return TRUE; + } + + return FALSE; + } + + /** + * This is called offline when edges are about to be added from the exterior of the pathobject to the interior or vice versa + * Default behavior just a normal edge, override to add special costs or behavior + * @param Status - current status of edges (e.g. what still needs adding) + * @param inV1 - vertex location of first vert in the edge + * @param inV2 - vertex location of second vert in the edge + * @param ConnectedPolys - the polys this edge links + * @param PolyAssocatedWithThisPO - the index into the connected polys array parmaeter which tells us which poly from that array is associated with this path object + * @(optional) param SupportedEdgeWidth - width of unit that this edge supports, defaults to -1.0f meaning the length of the edge itself will be used + * @(optional) param EdgeGroupID - ID of the edgegroup this edge is a part of (defaults to no group) + * @return returns an enum describing what just happened (what actions did we take) - used to determien what accompanying actions need to be taken + * by other obstacles and calling code + */ + virtual EEdgeHandlingStatus AddStaticEdgeIntoThisPO( EEdgeHandlingStatus Status, const FVector& inV1, const FVector& inV2, TArray& ConnectedPolys, INT PolyAssocatedWithThisPO, FLOAT SupportedEdgeWidth=-1.0f, BYTE EdgeGroupID=MAXBYTE); + + + /** + * Allows this path object to modify the final path generated for a bot when the path + * uses an edge linked to this path object.. default is to do nothing + * @param Handle - the navigation handle whose path we are molesting + * @param Idx - the index into the pathcache that the edge associated with this path object is at + * @return - TRUE if we modified the path + */ + virtual UBOOL ModifyFinalPath( UNavigationHandle* Handle, INT Idx ) + { + return FALSE; + } + + /** + * For debugging. Verifies that this pathobject is still alive and well and not orphaned or deleted + * @return - TRUE If this path object is in good working order + */ + virtual UBOOL Verify() + { + return FALSE; + } +} + diff --git a/Engine/Classes/Interface_NavMeshPathObstacle.uc b/Engine/Classes/Interface_NavMeshPathObstacle.uc new file mode 100644 index 0000000..6e75bd0 --- /dev/null +++ b/Engine/Classes/Interface_NavMeshPathObstacle.uc @@ -0,0 +1,133 @@ +/** + * Interface for (primarily) dynamic objects which should affect the navigation mesh at runtime. + * + * Used to split the navmesh poly with the shape provided. And then Interface_NavMeshPathObject will do the + * work for determining whether or not a path is valid IF you have PreserveInternalPolys returning TRUE. + * Otherwise those polys have been removed from the navmesh (e.g. a giant metal cube landing on the ground). + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +interface Interface_NavMeshPathObstacle + native(AI); + +// enum used to describe what this path obstacle did WRT to edges being added for it +enum EEdgeHandlingStatus +{ + EHS_AddedBothDirs, // added edges for both directions (nothing further needed) + EHS_Added0to1, // added edge from source poly to dest poly (poly 0 -> poly 1) + EHS_Added1to0, // added edge from dest poly to source poly (Poly 1 -> Poly 0) + EHS_AddedNone // didn't add anything +}; + +cpptext +{ + /** + * this will register the passed shape/bounds with the passed polys + * @param BoundingShape - bounding shape of the obstacle + * @param Bounds - bounds of the bounding shape (for octree queries) + * @param Polys - polys to register this obstacle with + * @return - TRUE If registration was succesful + */ + UBOOL RegisterObstacleWithPolys( const TArray& BoundingShape, const TArray& Polys); + + /** + * Rebuilds all submesh data for any submeshes within the passed top level polygons + * @param Polys - polys to trigger rebuild for + */ + static void TriggerRebuildForPassedTLPolys( const TArray& Polys ); + + /** + * this is called on polys which have just had all obstacles cleared and won't get a normal build step + * and thus need to have edges created to adjacent sub-meshes + */ + UBOOL DoEdgeFixupForNewlyClearedPolys(const TArray PolysThatNeedFixup); + + /** + * given a list of pylons will update all the obstacles that need updating within it + * also does post steps after update is finished + * @param Pylons - list of pylons to update obstacles for + */ + static void UpdateAllDynamicObstaclesInPylonList(TArray& Pylons); + + /** + * this will register this shape with the obstacle mesh, indicating it should be considered + * when generating paths + * @return - TRUE If registration was successful + */ + UBOOL RegisterObstacleWithNavMesh(); + + /** + * this will register the passed list of obstacles, and then perform a build at the end. + * useful for registering a big list of obstacles all at once and paying much less cost (mesh doesn't have to be rebuilt each registration, only at the end) + * @param ObstaclesToRegister - list of obstacles to register + * @return - TRUE if registration and build was successful + */ + static UBOOL RegisterObstacleListWithNavMesh(TArray& Obstacles); + + /** + * this will remove this shape from the obstacle mesh, indicating it is no longer relevant to + * generating paths + * @return TRUE if unregistration was successful + */ + UBOOL UnregisterObstacleWithNavMesh(); + + /** + * called when the owner of this interface is being unloaded or destroyed and this obstacle needs to be cleaned up + */ + virtual void CleanupOnRemoval(); + + /** + * this function should populate out_polyshape with a list of verts which describe this object's + * convex bounding shape + * (verts should be clockwise wound) + * @param out_PolyShape - output array which holds the vertex buffer for this obstacle's bounding polyshape + * @param ShapeIdx - index of the shape being requested + * @return TRUE if this object should block things right now (FALSE means this obstacle shouldn't affect the mesh) + */ + virtual UBOOL GetBoundingShape(TArray& out_PolyShape,INT ShapeIdx)=0; + + /** + * return the number of shapes this obstacle needs to represent itself + */ + virtual INT GetNumBoundingShapes(){ return 1; } + + /** + * when TRUE polys internal to this obstacle will be preserved, but still split. (useful for things like cost volumes that + * need to adjust cost but not completely destroy parts of the mesh + * @return TRUE if polys should be preserved internal to this obstacle + */ + virtual UBOOL PreserveInternalPolys() { return FALSE; } + + /** + * This function is called when an edge is going to be added connecting a polygon internal to this obstacle to another polygon which is not + * Default behavior just a normal edge, override to add special costs or behavior (e.g. link a pathobject to the obstacle) + * @param Status - current status of edges (e.g. what still needs adding) + * @param inV1 - vertex location of first vert in the edge + * @param inV2 - vertex location of second vert in the edge + * @param ConnectedPolys - the polys this edge links + * @param bEdgesNeedToBeDynamic - whether or not added edges need to be dynamic (e.g. we're adding edges between meshes) + * @param PolyAssocatedWithThisPO - the index into the connected polys array parmaeter which tells us which poly from that array is associated with this path object + * @(optional) param SupportedEdgeWidth - width of unit that this edge supports, defaults to -1.0f meaning the length of the edge itself will be used + * @(optional) param EdgeGroupID - ID of the edgegroup this edge is a part of (defaults to no group) + * @return returns an enum describing what just happened (what actions did we take) - used to determien what accompanying actions need to be taken + * by other obstacles and calling code + */ + virtual EEdgeHandlingStatus AddObstacleEdge( EEdgeHandlingStatus Status, const FVector& inV1, const FVector& inV2, TArray& ConnectedPolys, UBOOL bEdgesNeedToBeDynamic, INT PolyAssocatedWithThisPO, FLOAT SupportedEdgeWidth=-1.0f, BYTE EdgeGroupID=MAXBYTE); + + /** + * this function is called after a top level mesh's submeshes have all been built (e.g. at the end of UNavigationMeshBase::UpdateDynamicObstacles) + * and that mesh is affected by this obstacle + * and it gives this obstacle a chance to do any extra work after the mesh is built (e.g. add specialized edges) + * @param MeshThatWasUpdated - the top level navmesh that just had all submeshes built + */ + virtual void PostSubMeshUpdateForTopLevelMesh(UNavigationMeshBase* MeshThatWasUpdated) {} + + /** + * For debugging. Verifies that this pathobject is still alive and well and not orphaned or deleted + * @return - TRUE If this path object is in good working order + */ + virtual UBOOL VerifyObstacle() + { + return FALSE; + } +} diff --git a/Engine/Classes/Interface_NavMeshPathSwitch.uc b/Engine/Classes/Interface_NavMeshPathSwitch.uc new file mode 100644 index 0000000..a227312 --- /dev/null +++ b/Engine/Classes/Interface_NavMeshPathSwitch.uc @@ -0,0 +1,71 @@ +/** + * Interface for path objects which need to interface with the navmesh + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +interface Interface_NavMeshPathSwitch extends Interface_NavMeshPathObject + native(AI); + + +cpptext +{ + // cost slightly more then normal edges so other edges are preferred unless this one is needed + virtual INT CostFor( const FNavMeshPathParams& PathParams, const FVector& PreviousPoint, FVector& out_PathEdgePoint, FNavMeshPathObjectEdge* Edge, FNavMeshPolyBase* SourcePoly ); + + // call the switch's support function + virtual UBOOL Supports( const FNavMeshPathParams& PathParams, + struct FNavMeshPolyBase* CurPoly, + struct FNavMeshPathObjectEdge* Edge, + struct FNavMeshEdgeBase* PredecessorEdge); + + // if bot is in the same poly as the trigger, go to the trigger itself + virtual UBOOL GetEdgeDestination( const FNavMeshPathParams& PathParams, + FLOAT EntityRadius, + const FVector& InfluencePosition, + const FVector& EntityPosition, + FVector& out_EdgeDest, + struct FNavMeshPathObjectEdge* Edge, + UNavigationHandle* Handle); + + // overidden to activate the switch when the bot needs to + virtual UBOOL PrepareMoveThru( class IInterface_NavigationHandle* Interface, + FVector& out_MovePt, + struct FNavMeshPathObjectEdge* Edge ); + + /** + * called to allow this PO to draw custom stuff for edges linked to it + * @param DRSP - the sceneproxy we're drawing for + * @param DrawOffset - offset from the actual location we should be drawing + * @param Edge - the edge we're drawing + * @return - whether this PO is doing custom drawing for the passed edge (FALSE indicates the default edge drawing functionality should be used) + */ + virtual UBOOL DrawEdge( FDebugRenderSceneProxy* DRSP, FColor C, FVector DrawOffset, FNavMeshPathObjectEdge* Edge ); + + /** + * called after edge creation is complete for each pylon to allow this PO to add edges for itself + * @param Py - the pylon which we are creating edges for + */ + virtual void CreateEdgesForPathObject( APylon* Py ); + + // returns the spot that an AI should run to to operate this switch + virtual FVector GetDestination(FLOAT EntityRadius){return FVector(0.f);} + + // returns TRUE if the passed bot is able to operate this switch + virtual UBOOL CanBotUseThisSwitch(AAIController* AI){return TRUE;} + + // returns TRUE if this switch is 'open' in that the fence/gate it controls is pathable right now + virtual UBOOL IsSwitchOpen(){return TRUE;} + + // returns TRUE if this switch is linked (e.g. opens) the passed switchable pylon + virtual UBOOL IsLinkedTo(AAISwitchablePylon* Py){return FALSE;} + + virtual INT GetNumLinkedPylons() const{return 0;} + virtual class AAISwitchablePylon* GetLinkedPylonAtIdx(INT Idx){return NULL;} +} + + + +// called to tell the AI to do wahtever it needs to to activate this switch +event bool AIActivateSwitch(AIController AI); + + diff --git a/Engine/Classes/Interface_NavigationHandle.uc b/Engine/Classes/Interface_NavigationHandle.uc new file mode 100644 index 0000000..9b5a480 --- /dev/null +++ b/Engine/Classes/Interface_NavigationHandle.uc @@ -0,0 +1,62 @@ +/** + * Interface for actors that use NavigationHandle + * - implementations of this interface describe what constraints and parameters to use when searching for a path across the nav mesh + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +interface Interface_NavigationHandle + native; + +cpptext +{ + /** >>>>> here lie functions which take input, and thus can not be cached */ + virtual UBOOL CanCoverSlip(class ACoverLink* Link, INT SlotIdx) { return FALSE; } + + /** + * returns the offset from the edge move point this entity should move toward (e.g. how high off the ground we should move to) + * @param Edge - the edge we're moving to + * @return - the offset to use + */ + virtual FVector GetEdgeZAdjust(struct FNavMeshEdgeBase* Edge)=0; + + /** + * allows entities to do custom validation before OK'ing mantle edges + * @param Edge - the edge we're verifying + * @return TRUE if the passed edge is OK to traverse + */ + virtual UBOOL CheckMantleValidity(struct FNavMeshMantleEdge* Edge){ return TRUE; } + /*** <<<<<< */ + + + /** + * this function is responsible for setting all the relevant parmeters used for pathfinding + * @param out_ParamCache - the output struct to populate params in + * @NOTE: ALL Params FNavMeshPathParams should be populated + * + */ + virtual void SetupPathfindingParams( struct FNavMeshPathParams& out_ParamCache )=0; + + /** + * Called from FindPath() at the beginning of a path search to give this entity a chance to initialize transient data + */ + virtual void InitForPathfinding()=0; + + + /** + * when this entity is using an edge (e.g. it has been marked active and is in this handle's pathcache) this function allows + * extra cost to be added for other entities trying to use that edge. (e.g. to keep guys from using the same path) + * @param Edge - the edge we're about to mark as active + */ + virtual INT ExtraEdgeCostToAddWhenActive(FNavMeshEdgeBase* Edge) { return 0; } + + /** + * DebugLog function which is called to log information specific to this AI (call NAVHANDLE_DEBUG_LOG macro, don't call this directly) + * @param LogText - text to log for this AI + */ + virtual void DebugLogInternal(const TCHAR* LogText) {} +} + +/** + * this event is called when an edge is deleted that this handle is actively using + */ +event NotifyPathChanged(); + diff --git a/Engine/Classes/Interface_PylonGeometryProvider.uc b/Engine/Classes/Interface_PylonGeometryProvider.uc new file mode 100644 index 0000000..2330eed --- /dev/null +++ b/Engine/Classes/Interface_PylonGeometryProvider.uc @@ -0,0 +1,17 @@ +/** + * Geometry exporter interface used for navmesh generation (Recast) + */ + +interface Interface_PylonGeometryProvider + native(AI); + +cpptext +{ + /** + * Exports all path colliding geometry within pylon's bounds + * @param Pylon - bounding pylon + * @param Verts - list of exported vertices + * @param Faces - list of exported triangles, 3 indices to Verts array for each item + */ + virtual void GetPathCollidingGeometry(APylon* Pylon, TArray& Verts, TArray& Faces) {}; +} diff --git a/Engine/Classes/Interface_RVO.uc b/Engine/Classes/Interface_RVO.uc new file mode 100644 index 0000000..01b0519 --- /dev/null +++ b/Engine/Classes/Interface_RVO.uc @@ -0,0 +1,28 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +interface Interface_RVO + native(AI); + +cpptext +{ + virtual FLOAT GetAvoidRadius()=0; + virtual INT GetInfluencePriority()=0; + virtual UBOOL IsActiveObstacle()=0; + virtual FColor GetDebugAgentColor()=0; + + FORCEINLINE AActor* GetActor() + { + return Cast(GetUObjectInterfaceInterface_RVO()); + } + FORCEINLINE FVector GetLocation() + { + return GetActor()->Location; + } + FORCEINLINE FVector GetVelocity() + { + return GetActor()->Velocity; + } + + virtual void GetVelocityObstacleStats( TArray& out_Array, AActor* RelActor ); +} diff --git a/Engine/Classes/Interface_Speaker.uc b/Engine/Classes/Interface_Speaker.uc new file mode 100644 index 0000000..24bf872 --- /dev/null +++ b/Engine/Classes/Interface_Speaker.uc @@ -0,0 +1,10 @@ +/** + * Interface for actors that can Speak + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +interface Interface_Speaker + native; + +/** Very simple for now. */ +simulated event Speak(SoundCue Cue); diff --git a/Engine/Classes/InterpActor.uc b/Engine/Classes/InterpActor.uc new file mode 100644 index 0000000..367b936 --- /dev/null +++ b/Engine/Classes/InterpActor.uc @@ -0,0 +1,516 @@ +/** + * Dynamic static mesh actor intended to be used with Matinee replaces movers + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpActor extends DynamicSMActor + native + ClassGroup(Common) + placeable; + +cpptext +{ + UBOOL ShouldTrace(UPrimitiveComponent* Primitive, AActor *SourceActor, DWORD TraceFlags); + virtual void TickSpecial(FLOAT DeltaSeconds); + virtual FLOAT GetNetPriority(const FVector& ViewPos, const FVector& ViewDir, APlayerController* Viewer, UActorChannel* InChannel, FLOAT Time, UBOOL bLowBandwidth); + + /** + * Function that gets called from within Map_Check to allow this actor to check itself + * for any potential errors and register them with map check dialog. + */ +#if WITH_EDITOR + virtual void CheckForErrors(); +#endif +} + +/** Data relevant to checkpoint save/load, see CreateCheckpointRecord/ApplyCheckpointRecord below */ +struct CheckpointRecord +{ + var vector Location; + var rotator Rotation; + var ECollisionType CollisionType; + var bool bHidden; + var bool bIsShutdown; + var bool bNeedsPositionReplication; +}; +/** whether this should be saved in checkpoints */ +var bool bShouldSaveForCheckpoint; + +/** NavigationPoint associated with this actor for sending AI related notifications (could be a LiftCenter or DoorMarker) */ +var NavigationPoint MyMarker; +/** true when AI is waiting for us to finish moving */ +var bool bMonitorMover; +/** if true, call MoverFinished() event on all Controllers with us as their PendingMover when we reach peak Z velocity */ +var bool bMonitorZVelocity; +/** set while monitoring lift movement */ +var float MaxZVelocity; +/** delay after mover finishes interpolating before it notifies any mover events */ +var float StayOpenTime; +/** sound played when the mover is interpolated forward */ +var() AkBaseSoundObject OpenSound; +/** looping sound while opening */ +var() SoundCue OpeningAmbientSound; +/** sound played when mover finished moving forward */ +var() AkBaseSoundObject OpenedSound; +/** sound played when the mover is interpolated in reverse */ +var() AkBaseSoundObject CloseSound; +/** looping sound while closing */ +var() SoundCue ClosingAmbientSound; +/** sound played when mover finished moving backward */ +var() AkBaseSoundObject ClosedSound; +/** component for looping sounds */ +var AudioComponent AmbientSoundComponent; + +/** if set this mover blows up projectiles when it encroaches them */ +var() bool bDestroyProjectilesOnEncroach; +/** if set, this mover keeps going if it encroaches an Actor in PHYS_RigidBody. */ +var() bool bContinueOnEncroachPhysicsObject; +/** true by default, prevents mover from completing the movement that would leave it encroaching another actor */ +var() bool bStopOnEncroach; + +/** + * This is used for having the Actor ShadowParent all of the components that are "SetBased" onto it. This allows LDs to + * take InterpActors in the level and then SetBase a ton of other meshes to them and not incur multiple shadow casters. + **/ +var() bool bShouldShadowParentAllAttachedActors; + +/** If true, have a liftcenter associated with this interpactor, so it is being used as a lift */ +var bool bIsLift; + +simulated event PostBeginPlay() +{ + Super.PostBeginPlay(); + + if (bShouldShadowParentAllAttachedActors) + { + SetShadowParentOnAllAttachedComponents(StaticMeshComponent, LightEnvironment); + } + + // create ambient sound component if needed + if (OpeningAmbientSound != None || ClosingAmbientSound != None) + { + AmbientSoundComponent = new(self) class'AudioComponent'; + AttachComponent(AmbientSoundComponent); + } + + // by default don't save InterpActors that are based on a skeletal mesh bone + if (Base != None && (bHardAttach || (BaseSkelComponent != None && BaseBoneName != 'None'))) + { + bShouldSaveForCheckpoint = false; + } +} + + +event bool EncroachingOn(Actor Other) +{ + local int i; + local SeqEvent_Mover MoverEvent; + local Pawn P; + local vector Height, HitLocation, HitNormal; + local bool bLandingPawn; + + // Allow move into rigid bodies - should just push them out of the way. + if(bContinueOnEncroachPhysicsObject && (Other.Physics == PHYS_RigidBody)) + { + return FALSE; + } + + // Check if this is something that should be destroyed when mover runs into it + if(Other.bDestroyedByInterpActor) + { + Other.Destroy(); + return FALSE; + } + + // if we're moving towards the actor + if ( (Other.Base == self) || (Normal(Velocity) Dot Normal(Other.Location - Location) >= 0.f) ) + { + // if we're moving up into a pawn, ignore it so it can land on us instead + P = Pawn(Other); + if (P != None) + { + if (P.Physics == PHYS_Falling && Velocity.Z > 0.f) + { + Height = P.GetCollisionHeight() * vect(0,0,1); + // @note: only checking against our StaticMeshComponent, assumes we have no other colliding components + if (TraceComponent(HitLocation, HitNormal, StaticMeshComponent, P.Location - Height, P.Location + Height, P.GetCollisionExtent())) + { + // make sure the pawn doesn't fall through us + if (P.Location.Z < Location.Z) + { + P.SetLocation(HitLocation + Height); + } + bLandingPawn = true; + } + } + else if (P.Base != self && P.Controller != None && P.Controller.PendingMover != None && P.Controller.PendingMover == self) + { + P.Controller.UnderLift(LiftCenter(MyMarker)); + } + } + else if (bDestroyProjectilesOnEncroach && Other.IsA('Projectile')) + { + Projectile(Other).Explode(Other.Location, -Normal(Velocity)); + return false; + } + + if ( !bLandingPawn ) + { + // search for any mover events + for (i = 0; i < GeneratedEvents.Length; i++) + { + MoverEvent = SeqEvent_Mover(GeneratedEvents[i]); + if (MoverEvent != None) + { + // notify the event that we encroached something + MoverEvent.NotifyEncroachingOn(Other); + } + } + return bStopOnEncroach; + } + } + + return false; +} + +/* + * called for encroaching actors which successfully moved the other actor out of the way + */ +event RanInto( Actor Other ) +{ + local int i; + local SeqEvent_Mover MoverEvent; + + if (bDestroyProjectilesOnEncroach && Other.IsA('Projectile')) + { + Projectile(Other).Explode(Other.Location, -Normal(Velocity)); + } + // Check if this is something that should be destroyed when mover runs into it + else if(Other.bDestroyedByInterpActor) + { + Other.Destroy(); + } + else if ( bIsLift ) + { + // no encroach event if have liftcenter based on me + // keeps lifts from returning when object/player based on them bounces/jumps and then runs into lift + return; + } + else + { + // search for any mover events + for (i = 0; i < GeneratedEvents.Length; i++) + { + MoverEvent = SeqEvent_Mover(GeneratedEvents[i]); + if (MoverEvent != None) + { + // notify the event that we encroached something + MoverEvent.NotifyEncroachingOn(Other); + } + } + } +} + + +event Attach(Actor Other) +{ + local int i; + local SeqEvent_Mover MoverEvent; + + if (!IsTimerActive('FinishedOpen')) + { + // search for any mover events + for (i = 0; i < GeneratedEvents.Length; i++) + { + MoverEvent = SeqEvent_Mover(GeneratedEvents[i]); + if (MoverEvent != None) + { + // notify the event that an Actor has been attached + MoverEvent.NotifyAttached(Other); + } + } + } +} + +event Detach(Actor Other) +{ + local int i; + local SeqEvent_Mover MoverEvent; + + // search for any mover events + for (i = 0; i < GeneratedEvents.Length; i++) + { + MoverEvent = SeqEvent_Mover(GeneratedEvents[i]); + if (MoverEvent != None) + { + // notify the event that an Actor has been detached + MoverEvent.NotifyDetached(Other); + } + } +} + +/** checks if anything is still attached to the mover, and if so notifies Kismet so that it may restart it if desired */ +function Restart() +{ + local Actor A; + + foreach BasedActors(class'Actor', A) + { + Attach(A); + } +} + +/** called on a timer StayOpenTime seconds after the mover has finished opening (forward matinee playback) */ +function FinishedOpen() +{ + local int i; + local SeqEvent_Mover MoverEvent; + + // search for any mover events + for (i = 0; i < GeneratedEvents.Length; i++) + { + MoverEvent = SeqEvent_Mover(GeneratedEvents[i]); + if (MoverEvent != None) + { + // notify the event that all opening and associated delays are finished and it may now reverse our direction + // (or do any other actions as set up in Kismet) + MoverEvent.NotifyFinishedOpen(); + } + } +} + +simulated function PlayMovingSound(bool bClosing) +{ + local AkBaseSoundObject SoundToPlay; + local SoundCue AmbientToPlay; + + if (bClosing) + { + SoundToPlay = CloseSound; + AmbientToPlay = OpeningAmbientSound; + } + else + { + SoundToPlay = OpenSound; + AmbientToPlay = ClosingAmbientSound; + } + if (SoundToPlay != None) + { + PlaySoundBase(SoundToPlay, true); + } + if (AmbientToPlay != None) + { + AmbientSoundComponent.Stop(); + AmbientSoundComponent.SoundCue = AmbientToPlay; + AmbientSoundComponent.Play(); + } +} + +simulated event InterpolationStarted(SeqAct_Interp InterpAction, InterpGroupInst GroupInst) +{ + ClearTimer('Restart'); + ClearTimer('FinishedOpen'); + + PlayMovingSound(InterpAction.bReversePlayback); + + // we need to save it if it's affected by a matinee + bShouldSaveForCheckpoint = true; +} + +simulated event InterpolationFinished(SeqAct_Interp InterpAction) +{ + local DoorMarker DoorNav; + local Controller C; + local AkBaseSoundObject StoppedSound; + + if (AmbientSoundComponent != None) + { + AmbientSoundComponent.Stop(); + } + + StoppedSound = InterpAction.bReversePlayback ? ClosedSound : OpenedSound; + if (StoppedSound != None) + { + PlaySoundBase(StoppedSound, true); + } + + DoorNav = DoorMarker(MyMarker); + if (InterpAction.bReversePlayback) + { + // we are done; if something is still attached, set timer to try restart + if (Attached.length > 0) + { + SetTimer( StayOpenTime, false, nameof(Restart) ); + } + if (DoorNav != None) + { + DoorNav.MoverClosed(); + } + } + else + { + // set timer to notify any mover events + SetTimer( StayOpenTime, false, nameof(FinishedOpen) ); + + if (DoorNav != None) + { + DoorNav.MoverOpened(); + } + } + + if (bMonitorMover) + { + // notify any Controllers with us as PendingMover that we have finished moving + foreach WorldInfo.AllControllers(class'Controller', C) + { + if (C.PendingMover == self) + { + C.MoverFinished(); + } + } + } + + //@hack: force location update on clients if future matinee actions rely on it + if (InterpAction.bNoResetOnRewind && InterpAction.bRewindOnPlay) + { + ForceNetRelevant(); + bUpdateSimulatedPosition = true; + bReplicateMovement = true; + } +} + +simulated event InterpolationChanged(SeqAct_Interp InterpAction) +{ + PlayMovingSound(InterpAction.bReversePlayback); +} + +simulated function ShutDown() +{ + Super.ShutDown(); + + // safe to save regardless of other factors because it's going to be invisible/uncollidable on load + bShouldSaveForCheckpoint = true; +} + +function bool ShouldSaveForCheckpoint() +{ + return bShouldSaveForCheckpoint || RemoteRole == ROLE_SimulatedProxy; +} + +/** Called when this actor is being saved in a checkpoint, records pertinent information for restoration via ApplyCheckpointRecord. */ +function CreateCheckpointRecord(out CheckpointRecord Record) +{ + Record.Location = Location; + Record.Rotation = Rotation; + Record.bHidden = bHidden; + Record.CollisionType = ReplicatedCollisionType; + Record.bNeedsPositionReplication = (RemoteRole == ROLE_SimulatedProxy && bUpdateSimulatedPosition); + //@fixme - is there a more reliable way to detect this? maybe add a bIsShutDown flag to actor? + Record.bIsShutdown = (Physics == PHYS_None && bHidden); +} + +function ApplyCheckpointRecord(const out CheckpointRecord Record) +{ + local Actor OldBase; + local SkeletalMeshComponent OldBaseComp; + local name OldBaseBoneName; + local array OldAttached; + local array OldLocations; + local int i; + + if (Record.bIsShutdown) + { + ShutDown(); + } + else + { + // store and recover the location of other checkpoint saved actors + // as they may have already been processed + // otherwise their post-checkpoint location will be based on our pre-checkpoint location + // which will put them out of position + OldAttached = Attached; + while (i < OldAttached.length) + { + // checkpoint code clears bJustTeleported, so checking it only gets actors teleported by checkpoint loading + if (OldAttached[i] != None && OldAttached[i].bJustTeleported) + { + OldLocations[i] = OldAttached[i].Location; + i++; + } + else + { + OldAttached.Remove(i, 1); + } + } + // SetLocation() will clear our base, so we need to restore it + OldBase = Base; + OldBaseComp = BaseSkelComponent; + OldBaseBoneName = BaseBoneName; + SetLocation(Record.Location); + SetRotation(Record.Rotation); + SetBase(OldBase,, OldBaseComp, OldBaseBoneName); + // restore attached actors + for (i = 0; i < OldAttached.length; i++) + { + if (OldAttached[i] != None) + { + OldAttached[i].SetLocation(OldLocations[i]); + OldAttached[i].SetBase(self); + } + } + + if (Record.CollisionType != ReplicatedCollisionType) + { + SetCollisionType(Record.CollisionType); + ForceNetRelevant(); + } + if (Record.bHidden != bHidden) + { + SetHidden(Record.bHidden); + SetForcedInitialReplicatedProperty(Property'Engine.Actor.bHidden', (bHidden == default.bHidden)); + ForceNetRelevant(); + } + if (Record.bNeedsPositionReplication) + { + bUpdateSimulatedPosition = true; + bReplicateMovement = true; + ForceNetRelevant(); + } + } + + bShouldSaveForCheckpoint = true; +} + +defaultproperties +{ + bShouldShadowParentAllAttachedActors=TRUE + + Begin Object Name=StaticMeshComponent0 + WireframeColor=(R=255,G=0,B=255,A=255) + AlwaysLoadOnClient=true + AlwaysLoadOnServer=true + RBCollideWithChannels=(Default=TRUE,BlockingVolume=TRUE) + End Object + + bStatic=false + bWorldGeometry=false + Physics=PHYS_Interpolating + + bNoDelete=true + bAlwaysRelevant=true + bSkipActorPropertyReplication=false + bUpdateSimulatedPosition=false + bOnlyDirtyReplication=true + RemoteRole=ROLE_None + NetPriority=2.7 + NetUpdateFrequency=1.0 + bDestroyProjectilesOnEncroach=true + bStopOnEncroach=true + bContinueOnEncroachPhysicsObject=TRUE + bCollideWhenPlacing=FALSE + bBlocksTeleport=true + bShouldSaveForCheckpoint=true + + SupportedEvents.Add(class'SeqEvent_Mover') +} + diff --git a/Engine/Classes/InterpActor_ForCinematic.uc b/Engine/Classes/InterpActor_ForCinematic.uc new file mode 100644 index 0000000..fce8b8b --- /dev/null +++ b/Engine/Classes/InterpActor_ForCinematic.uc @@ -0,0 +1,14 @@ +/** + * This actor is meant to be used by Matinee for all of the usage scenerios where you have an invisible + * InterpActor moving around some track that the camera is eventually attached to. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpActor_ForCinematic extends InterpActor + placeable; + + + +defaultproperties +{ +} \ No newline at end of file diff --git a/Engine/Classes/InterpCurveEdSetup.uc b/Engine/Classes/InterpCurveEdSetup.uc new file mode 100644 index 0000000..41b3732 --- /dev/null +++ b/Engine/Classes/InterpCurveEdSetup.uc @@ -0,0 +1,67 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpCurveEdSetup extends Object + native; + +// Information about a particule curve being viewed. +// Property could be an FInterpCurve, a DistributionFloat or a DistributionVector +struct native CurveEdEntry +{ + var Object CurveObject; + + var color CurveColor; + var string CurveName; + + var int bHideCurve; + var int bColorCurve; + var int bFloatingPointColorCurve; + var int bClamp; + var float ClampLow; + var float ClampHigh; +}; + +struct native CurveEdTab +{ + var string TabName; + + var array Curves; + + // Remember the view setting for each tab. + var float ViewStartInput; + var float ViewEndInput; + var float ViewStartOutput; + var float ViewEndOutput; +}; + + +var array Tabs; +var int ActiveTab; + +cpptext +{ + // UObject interface + void PostLoad(); + void Serialize(FArchive& Ar); + + // InterpCurveEdSetup interface + static FCurveEdInterface* GetCurveEdInterfacePointer(const FCurveEdEntry& Entry); + void AddCurveToCurrentTab(UObject* InCurve, const FString& CurveName, const FColor& CurveColor, + UBOOL bInColorCurve=false, UBOOL bInFloatingPointColor=false, UBOOL bInClamp=false, + FLOAT InClampLow=0.f, FLOAT InClampHigh=0.f); + void RemoveCurve(UObject* InCurve); + void ReplaceCurve(UObject* RemoveCurve, UObject* AddCurve); + void CreateNewTab(const FString& InTabName); + void RemoveTab(const FString& InTabName); + UBOOL ShowingCurve(UObject* InCurve); + + void ChangeCurveColor(UObject* InCurve, const FColor& CurveColor); + void ChangeCurveName(UObject* InCurve, const FString& NewCurveName); + + void ResetTabs(); +} + +defaultproperties +{ + Tabs(0)=(TabName="Default",ViewStartInput=0.0,ViewEndInput=1.0,ViewStartOutput=-1.0,ViewEndOutput=1.0) +} diff --git a/Engine/Classes/InterpData.uc b/Engine/Classes/InterpData.uc new file mode 100644 index 0000000..6586038 --- /dev/null +++ b/Engine/Classes/InterpData.uc @@ -0,0 +1,138 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +/** + * InterpData + * + * + * Actual interpolation data, containing keyframe tracks, event tracks etc. + * This does not contain any Actor references or state, so can safely be stored in + * packages, shared between multiple Actors/SeqAct_Interps etc. + */ + +class InterpData extends SequenceVariable + native(Sequence); + + + +/** Duration of interpolation sequence - in seconds. */ +var float InterpLength; + +/** Position in Interp to move things to for path-building in editor. */ +var float PathBuildTime; + +/** Actual interpolation data. Groups of InterpTracks. */ +var export array InterpGroups; + +/** Used for curve editor to remember curve-editing setup. Only loaded in editor. */ +var export InterpCurveEdSetup CurveEdSetup; + +/** Used for filtering which tracks are currently visible. */ +var editoronly array InterpFilters; + +/** The currently selected filter. */ +var editoronly InterpFilter SelectedFilter; + +/** Array of default filters. */ +var editoronly transient array DefaultFilters; + +/** Used in editor for defining sections to loop, stretch etc. */ +var float EdSectionStart; + +/** Used in editor for defining sections to loop, stretch etc. */ +var float EdSectionEnd; + +/** If TRUE, then the matinee should be baked and pruned at cook time. */ +var() bool bShouldBakeAndPrune; + +struct native AnimSetBakeAndPruneStatus +{ + /** Name of the anim set referenced in Matinee */ + var() editconst string AnimSetName; + /** If TRUE, the animation is in a GroupAnimSets array, but is unused */ + var() editconst bool bReferencedButUnused; + /** If TRUE, skip BakeAndPrune on this anim set during cooking */ + var() bool bSkipBakeAndPrune; + /** If TRUE, skip this set entirely when cooking, as it for previewing only */ + var() bool bSkipCooking; +}; + +/** AnimSets referenced by this matinee, and whether to allow bake and prune on them during cooking. */ +var() editfixedsize array BakeAndPruneStatus; + +/** Cached version of the director group, if any, for easy access while in game */ +var transient InterpGroupDirector CachedDirectorGroup; + +cpptext +{ + // UObject interface + /** + * This function is being called after all objects referenced by this object have been serialized. + */ + virtual void PostLoad(void); + + // SequenceVariable interface + virtual FString GetValueStr(); + + /** Search through all InterpGroups in this InterpData to find a group whose GroupName matches the given name. Returns INDEX_NONE if group not found. */ + INT FindGroupByName( FName GroupName ); + INT FindGroupByName( const FString& InGroupName ); + + void FindTracksByClass(UClass* TrackClass, TArray& OutputTracks); + class UInterpGroupDirector* FindDirectorGroup(); + void GetAllEventNames(TArray& OutEventNames); + +#if WITH_EDITOR + void UpdateBakeAndPruneStatus(); +#endif +} + +defaultproperties +{ + InterpLength=5.0 + EdSectionStart=0.0 + EdSectionEnd=1.0 + PathBuildTime=0.0 + + bShouldBakeAndPrune=false + + ObjName="Matinee Data" + ObjColor=(R=255,G=128,B=0,A=255) // orange + + Begin Object Class=InterpFilter Name=FilterAll + Caption="All" + End Object + + Begin Object Class=InterpFilter_Classes Name=FilterCameras + Caption="Cameras" + ClassToFilterBy=CameraActor + End Object + + Begin Object Class=InterpFilter_Classes Name=FilterSkeletalMeshes + Caption="Skeletal Meshes" + ClassToFilterBy=SkeletalMeshActor + End Object + + Begin Object Class=InterpFilter_Classes Name=FilterLighting + Caption="Lights" + ClassToFilterBy=Light + End Object + + Begin Object Class=InterpFilter_Classes Name=FilterEmitters + Caption="Particles" + ClassToFilterBy=Emitter + End Object + + Begin Object Class=InterpFilter_Classes Name=FilterSounds + Caption="Sounds" + TrackClasses=(InterpTrackSound) + End Object + + Begin Object Class=InterpFilter_Classes Name=FilterEvents + Caption="Events" + TrackClasses=(InterpTrackEvent) + End Object + + DefaultFilters=(FilterAll, FilterCameras, FilterSkeletalMeshes, FilterLighting, FilterEmitters, FilterSounds, FilterEvents) +} diff --git a/Engine/Classes/InterpFilter.uc b/Engine/Classes/InterpFilter.uc new file mode 100644 index 0000000..fcbb4a7 --- /dev/null +++ b/Engine/Classes/InterpFilter.uc @@ -0,0 +1,22 @@ +/** + * InterpFilter.uc: Filter class for filtering matinee groups. + * By default no groups are filtered. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class InterpFilter extends Object + native(Interpolation); + +cpptext +{ + /** + * Given a interpdata object, updates visibility of groups and tracks based on the filter settings + * + * @param InData Data to filter. + */ + virtual void FilterData(class USeqAct_Interp* InData); +} + +/** Caption for this filter. */ +var string Caption; diff --git a/Engine/Classes/InterpFilter_Classes.uc b/Engine/Classes/InterpFilter_Classes.uc new file mode 100644 index 0000000..69488a5 --- /dev/null +++ b/Engine/Classes/InterpFilter_Classes.uc @@ -0,0 +1,26 @@ +/** + * InterpFilter_Classes.uc: Filter class for filtering matinee groups. + * Used by the matinee editor to filter groups to specific classes of attached actors. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class InterpFilter_Classes extends InterpFilter + native(Interpolation); + +cpptext +{ + /** + * Given a interpdata object, updates visibility of groups and tracks based on the filter settings + * + * @param InData Data to filter. + */ + virtual void FilterData(class USeqAct_Interp* InData); +} + +/** Which class to filter groups by. */ +var editoronly class ClassToFilterBy; + +/** List of allowed track classes. If empty, then all track classes will be included. Only groups that + contain at least one of these types of tracks will be displayed. */ +var editoronly array< class > TrackClasses; \ No newline at end of file diff --git a/Engine/Classes/InterpFilter_Custom.uc b/Engine/Classes/InterpFilter_Custom.uc new file mode 100644 index 0000000..2c942ac --- /dev/null +++ b/Engine/Classes/InterpFilter_Custom.uc @@ -0,0 +1,22 @@ +/** + * InterpFilter_Custom.uc: Filter class for filtering matinee groups. + * Used by the matinee editor to let users organize tracks/groups. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class InterpFilter_Custom extends InterpFilter + native(Interpolation); + +cpptext +{ + /** + * Given a interpdata object, updates visibility of groups and tracks based on the filter settings + * + * @param InData Data to filter. + */ + virtual void FilterData(class USeqAct_Interp* InData); +} + +/** Which groups are included in this filter. */ +var editoronly array GroupsToInclude; \ No newline at end of file diff --git a/Engine/Classes/InterpGroup.uc b/Engine/Classes/InterpGroup.uc new file mode 100644 index 0000000..168ea29 --- /dev/null +++ b/Engine/Classes/InterpGroup.uc @@ -0,0 +1,96 @@ +class InterpGroup extends Object + native(Interpolation) + collapsecategories + inherits(FInterpEdInputInterface) + hidecategories(Object); + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * A group, associated with a particular Actor or set of Actors, which contains a set of InterpTracks for interpolating + * properties of the Actor over time. + * The Outer of an InterpGroup is an InterpData. + */ + +cpptext +{ + // UObject interface + virtual void PostLoad(); + + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + // UInterpGroup interface + + /** Iterate over all InterpTracks in this InterpGroup, doing any actions to bring the state to the specified time. */ + virtual void UpdateGroup(FLOAT NewPosition, class UInterpGroupInst* GrInst, UBOOL bPreview, UBOOL bJump); + + /** Ensure this group name is unique within this InterpData (its Outer). */ + void EnsureUniqueName(); + + /** + * Find all the tracks in this group of a specific class. + * Tracks are in the output array in the order they appear in the group. + */ + void FindTracksByClass(UClass* TrackClass, TArray& OutputTracks); + + /** Returns whether this Group contains at least one AnimControl track. */ + UBOOL HasAnimControlTrack() const; + + /** Returns whether this Group contains a movement track. */ + UBOOL HasMoveTrack() const; + + /** Iterate over AnimControl tracks in this Group, build the anim blend info structures, and pass to the Actor via (Preview)SetAnimWeights. */ + void UpdateAnimWeights(FLOAT NewPosition, class UInterpGroupInst* GrInst, UBOOL bPreview, UBOOL bJump); + + /** Util for determining how many AnimControl tracks within this group are using the Slot with the supplied name. */ + INT GetAnimTracksUsingSlot(FName InSlotName); +} + +struct InterpEdSelKey +{ + var InterpGroup Group; + var InterpTrack Track; + var int KeyIndex; + var float UnsnappedPosition; +}; + + +var export array InterpTracks; + +/** + * Within an InterpData, all GroupNames must be unique. + * Used for naming Variable connectors on the Action in Kismet and finding each groups object. + */ +var name GroupName; + +/** Colour used for drawing tracks etc. related to this group. */ +var() color GroupColor; + +/** + * The AnimSets that are used by any AnimControl tracks. + * These will be passed to the Actor when the cinematic begins, and sequences named in the tracks should be found in them. + */ +var() array GroupAnimSets; + +/** Whether or not this group is folded away in the editor. */ +var bool bCollapsed; + +/** Whether or not this group is visible in the editor. */ +var transient bool bVisible; + +/** When enabled, this group is treated like a folder in the editor, which should only be used for organization. Folders are never associated with actors and don't have a presence in the Kismet graph. */ +var bool bIsFolder; + +/** When true, this group is considered a 'visual child' of another group. This doesn't at all affect the behavior of the group, it's only for visual organization. Also, it's implied that the parent is the next prior group in the array that doesn't have a parent. */ +var bool bIsParented; + +/** When enabled, this group will be selected in the interp editor. */ +var transient bool bIsSelected; + +defaultproperties +{ + GroupName="InterpGroup" + GroupColor=(R=100,G=80,B=200,A=255) + bVisible=true + bIsSelected=false +} diff --git a/Engine/Classes/InterpGroupAI.uc b/Engine/Classes/InterpGroupAI.uc new file mode 100644 index 0000000..41a36e0 --- /dev/null +++ b/Engine/Classes/InterpGroupAI.uc @@ -0,0 +1,49 @@ +class InterpGroupAI extends InterpGroup + native(Interpolation) + collapsecategories + hidecategories(Object); + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * Group for controlling properties of a 'player' in the game. This includes switching the player view between different cameras etc. + */ + +cpptext +{ + // Post edit + // Need to refresh skelmesh if that changes + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + // UInterpGroup interface + virtual void UpdateGroup(FLOAT NewPosition, class UInterpGroupInst* GrInst, UBOOL bPreview, UBOOL bJump); +} + +/** + * Preview Pawn class for this track + */ +var() editoronly class PreviewPawnClass; + +/** + * Name of Stage Mark Group - used for locator + */ +var() Name StageMarkGroup; + +/** Snap AI to root bone location when finished **/ +var() bool SnapToRootBoneLocationWhenFinished; + +/** Disable Collision Check when initializing first time**/ +var() bool bNoEncroachmentCheck; +/** Disable World Collision during Matinee**/ +var() bool bDisableWorldCollision; +/** Ignore old legacy height adjust for pawn - TODO: REMOVE THIS BEFORE 2012 **/ +var() bool bIgnoreLegacyHeightAdjust; + +/** Editor only variable to mark dirty for instance to update when needed**/ +var editoronly transient bool bRecreatePreviewPawn; +var editoronly transient bool bRefreshStageMarkGroup; + +defaultproperties +{ + GroupName="AIGroup" +} diff --git a/Engine/Classes/InterpGroupCamera.uc b/Engine/Classes/InterpGroupCamera.uc new file mode 100644 index 0000000..91db264 --- /dev/null +++ b/Engine/Classes/InterpGroupCamera.uc @@ -0,0 +1,49 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * Group for controlling properties of a 'CameraAnim' in the game. Used for CameraAnim Previews + */ +class InterpGroupCamera extends InterpGroup + native(Interpolation) + collapsecategories + hidecategories(Object); + +var transient CameraAnim CameraAnimInst; + +/** + * Preview Pawn class for this track + */ + +struct native CameraPreviewInfo +{ + var() class PawnClass; + var() array PreviewAnimSets; + var() name AnimSeqName; + /* for now this is read-only. It has maintenance issue to be resolved if I enable this.*/ + var editconst vector Location; + var editconst rotator Rotation; + /** Pawn Inst - CameraAnimInst doesn't really exist in editor **/ + var transient Pawn PawnInst; +}; + +// this is interaction property info for CameraAnim +// this information isn't really saved with it +var() editoronly CameraPreviewInfo Target; +//var() editoronly bool EnableInteractionTarget; +//var() editoronly CameraAnim.CameraPreviewInfo InteractionTarget; + +/** When compress, tolerance option **/ +var() float CompressTolerance; + +cpptext +{ + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); +} + +defaultproperties +{ + Target = (Location = (X=140, Y=0, Z=-40)) +// InteractionTarget = (Location = (X=200, Y=0, Z=-40), Rotation=(Yaw=180)) + + CompressTolerance = 5.f +} diff --git a/Engine/Classes/InterpGroupDirector.uc b/Engine/Classes/InterpGroupDirector.uc new file mode 100644 index 0000000..fc3f188 --- /dev/null +++ b/Engine/Classes/InterpGroupDirector.uc @@ -0,0 +1,29 @@ +class InterpGroupDirector extends InterpGroup + native(Interpolation) + collapsecategories + hidecategories(Object); + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * Group for controlling properties of a 'player' in the game. This includes switching the player view between different cameras etc. + */ + +cpptext +{ + // UInterpGroup interface + virtual void UpdateGroup(FLOAT NewPosition, class UInterpGroupInst* GrInst, UBOOL bPreview, UBOOL bJump); + + // UInterpGroupDirector interface + class UInterpTrackDirector* GetDirectorTrack(); + class UInterpTrackFade* GetFadeTrack(); + class UInterpTrackSlomo* GetSlomoTrack(); + class UInterpTrackColorScale* GetColorScaleTrack(); + class UInterpTrackAudioMaster* GetAudioMasterTrack(); +} + + +defaultproperties +{ + GroupName="DirGroup" +} diff --git a/Engine/Classes/InterpGroupInst.uc b/Engine/Classes/InterpGroupInst.uc new file mode 100644 index 0000000..0f71ed5 --- /dev/null +++ b/Engine/Classes/InterpGroupInst.uc @@ -0,0 +1,72 @@ +class InterpGroupInst extends Object + native(Interpolation); + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * + * An instance of an InterpGroup for a particular Actor. There may be multiple InterpGroupInsts for a single + * InterpGroup in the InterpData, if multiple Actors are connected to the same InterpGroup. + * The Outer of an InterpGroupInst is the SeqAct_Interp + */ + +cpptext +{ + /** + * Returns the Actor that this GroupInstance is working on. + * Should use this instead of just referencing GroupActor, as it check bDeleteMe for you. + */ + virtual AActor* GetGroupActor(); + + /** Called before Interp editing to save original state of Actor. @see UInterpTrackInst::SaveActorState */ + virtual void SaveGroupActorState(); + + /** Called after Interp editing to put object back to its original state. @see UInterpTrackInst::RestoreActorState */ + virtual void RestoreGroupActorState(); + + /** + * Returns if this group contains this Actor + */ + virtual UBOOL HasActor(AActor * InActor) + { + return (GetGroupActor() == InActor); + }; + + /** + * Initialse this Group instance. Called from USeqAct_Interp::InitInterp before doing any interpolation. + * Save the Actor for the group and creates any needed InterpTrackInsts + */ + virtual void InitGroupInst(UInterpGroup* InGroup, AActor* InGroupActor); + + /** + * Called when done with interpolation sequence. Cleans up InterpTrackInsts etc. + * Do not do anything further with the Interpolation after this. + */ + virtual void TermGroupInst(UBOOL bDeleteTrackInst); + + /** Force any actors attached to this group's actor to update their position using their relative location/rotation. */ + void UpdateAttachedActors(); + + /** Caches or Restores the PPS at the Start/End of the matinee sequence */ + UBOOL HasPPS( void ); + void CreatePPS( void ); + void CachePPS( const FPostProcessSettings& PPSettings ); + void RestorePPS( FPostProcessSettings& PPSettings ); + void DestroyPPS( void ); + void FreePPS( void ); +} + +/** InterpGroup within the InterpData that this is an instance of. */ +var InterpGroup Group; + +/** + * Actor that this Group instance is acting upon. + * NB: that this may be set to NULL at any time as a result of the Actor being destroyed. + */ +var Actor GroupActor; + +/** Array if InterpTrack instances. TrackInst.Num() == InterpGroup.InterpTrack.Num() must be true. */ +var array TrackInst; + +/** A cached copy of the group actor's pps (if it's a CameraActor) to prevent overwriting defaults */ +var private native transient pointer CachedCamOverridePostProcess{FPostProcessSettings}; // Just need to cache the bOverride_* flags \ No newline at end of file diff --git a/Engine/Classes/InterpGroupInstAI.uc b/Engine/Classes/InterpGroupInstAI.uc new file mode 100644 index 0000000..b17579f --- /dev/null +++ b/Engine/Classes/InterpGroupInstAI.uc @@ -0,0 +1,84 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpGroupInstAI extends InterpGroupInst + native(Interpolation); + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * + * An instance of an InterpGroup for a particular Actor. There may be multiple InterpGroupInsts for a single + * InterpGroup in the InterpData, if multiple Actors are connected to the same InterpGroup. + * The Outer of an InterpGroupInst is the SeqAct_Interp + */ + +cpptext +{ + /** + * Returns the Actor that this GroupInstance is working on. + * Should use this instead of just referencing GroupActor, as it check bDeleteMe for you. + */ + virtual AActor* GetGroupActor(); + + virtual UBOOL HasActor(AActor * InActor); + + /** + * Initialze this Group instance. Called from USeqAct_Interp::InitInterp before doing any interpolation. + * Save the Actor for the group and creates any needed InterpTrackInsts + */ + virtual void InitGroupInst( UInterpGroup* InGroup, AActor* InGroupActor ); + + /** + * Initialze this Group instance from Seq Variable + */ + void UpdatePreviewPawnFromSeqVarCharacter( UInterpGroup* InGroup, const USeqVar_Character* InGroupObject ); + + /** + * Create Preview Pawn/Destroy Preview Pawn + */ + void CreatePreviewPawn(); + void DestroyPreviewPawn(); + + /** + * Get Stage Mark Actor ground position & rotation + */ + FVector GetStageMarkPosition(FRotator* Rotation = NULL); + + /** + * Update Stage Mark Group Actor + */ + void UpdateStageMarkGroupActor(USeqAct_Interp * Seq); + + + /** + * Called when done with interpolation sequence. Cleans up InterpTrackInsts etc. + * Do not do anything further with the Interpolation after this. + */ + virtual void TermGroupInst(UBOOL bDeleteTrackInst); + + /** + * Update Physics state if it includes Movement Track + * Or terminate if bInit = FALSE + */ + void UpdatePhysics(UBOOL bInit); +} + +/** Cache data to AIGroup **/ +var transient InterpGroupAI AIGroup; + +/** Saved Physics state to go back to **/ +var EPhysics SavedPhysics; +var bool bSavedNoEncroachCheck; +var bool bSavedCollideActors; +var bool bSavedBlockActors; + +/** Preview Pawn for only editor - in game it should be AI **/ +var editoronly transient Pawn PreviewPawn; + +/** Stage Mark Actor - from StageMark Group **/ +var transient Actor StageMarkActor; + +defaultproperties +{ +} diff --git a/Engine/Classes/InterpGroupInstCamera.uc b/Engine/Classes/InterpGroupInstCamera.uc new file mode 100644 index 0000000..aa81041 --- /dev/null +++ b/Engine/Classes/InterpGroupInstCamera.uc @@ -0,0 +1,6 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpGroupInstCamera extends InterpGroupInst + native(Interpolation); + diff --git a/Engine/Classes/InterpGroupInstDirector.uc b/Engine/Classes/InterpGroupInstDirector.uc new file mode 100644 index 0000000..06fc95c --- /dev/null +++ b/Engine/Classes/InterpGroupInstDirector.uc @@ -0,0 +1,6 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpGroupInstDirector extends InterpGroupInst + native(Interpolation); + diff --git a/Engine/Classes/InterpTrack.uc b/Engine/Classes/InterpTrack.uc new file mode 100644 index 0000000..8f20ca3 --- /dev/null +++ b/Engine/Classes/InterpTrack.uc @@ -0,0 +1,114 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * Abstract base class for a track of interpolated data. Contains the actual data. + * The Outer of an InterpTrack is the InterpGroup. + */ + +class InterpTrack extends Object + native + noexport + collapsecategories + hidecategories(Object) + inherits(FInterpEdInputInterface) + abstract; + + +/** FCurveEdInterface virtual function table. */ +var private native noexport pointer CurveEdVTable; + +/** Helper struct for creating sub tracks supported by this track */ +struct native SupportedSubTrackInfo +{ + /** The sub track class which is supported by this track */ + var class SupportedClass; + /** The name of the subtrack */ + var String SubTrackName; + /** Index into the any subtrack group this subtrack belongs to (can be -1 for no group) */ + var int GroupIndex; +}; + +/** A small structure holding data for grouping subtracks. (For UI drawing purposes) */ +struct native SubTrackGroup +{ + /** Name of the subtrack group */ + var string GroupName; + /** Indices to tracks in the parent track subtrack array. */ + var array TrackIndices; + /** If this group is collapsed */ + var bool bIsCollapsed; + /** If this group is selected */ + var transient bool bIsSelected; +}; + +/** A list of subtracks that belong to this track */ +var array SubTracks; + +/** A list of subtrack groups (for editor UI organization only) */ +var editoronly array SubTrackGroups; + +/** A list of supported tracks that can be a subtrack of this track. */ +var transient editoronly array< SupportedSubTrackInfo > SupportedSubTracks; + +var class TrackInstClass; + +/** Required condition for this track to be enabled */ +enum ETrackActiveCondition +{ + /** Track is always active */ + ETAC_Always, + + /** Track is active when extreme content (gore) is enabled */ + ETAC_GoreEnabled, + + /** Track is active when extreme content (gore) is disabled */ + ETAC_GoreDisabled +}; + + +/** Sets the condition that must be met for this track to be enabled */ +var() ETrackActiveCondition ActiveCondition; + +/** Title of track type. */ +var string TrackTitle; + +/** Whether there may only be one of this track in an InterpGroup. */ +var bool bOnePerGroup; + +/** If this track can only exist inside the Director group. */ +var bool bDirGroupOnly; + +/** Whether or not this track should actually update the target actor. */ +var bool bDisableTrack; + +/** If true, the Actor this track is working on will have BeginAnimControl/FinishAnimControl called on it. */ +var bool bIsAnimControlTrack; + +/** If this track can only exist as a sub track. */ +var bool bSubTrackOnly; + +/** Whether or not this track is visible in the editor. */ +var transient bool bVisible; + +/** Whether or not this track is selected in the editor. */ +var transient bool bIsSelected; + +/** Whether or not this track is recording in the editor. */ +var transient bool bIsRecording; + +/** If this track is collapsed. (Only applies to tracks with subtracks). */ +var editoronly bool bIsCollapsed; + + +defaultproperties +{ + TrackInstClass=class'Engine.InterpTrackInst' + + ActiveCondition=ETAC_Always + TrackTitle="Track" + bVisible=true + bIsSelected=false + bIsRecording=false + bIsCollapsed=false + +} diff --git a/Engine/Classes/InterpTrackAnimControl.uc b/Engine/Classes/InterpTrackAnimControl.uc new file mode 100644 index 0000000..5fc6ae3 --- /dev/null +++ b/Engine/Classes/InterpTrackAnimControl.uc @@ -0,0 +1,145 @@ +class InterpTrackAnimControl extends InterpTrackFloatBase + native(Interpolation); + +/** + * InterpTrackAnimControl + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + + +cpptext +{ + // UObject interface + virtual void PostLoad(); + + // InterpTrack interface + virtual INT GetNumKeyframes() const; + virtual void GetTimeRange(FLOAT& StartTime, FLOAT& EndTime) const; + virtual FLOAT GetTrackEndTime() const; + virtual FLOAT GetKeyframeTime(INT KeyIndex) const; + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual INT SetKeyframeTime(INT KeyIndex, FLOAT NewKeyTime, UBOOL bUpdateOrder=true); + virtual void RemoveKeyframe(INT KeyIndex); + virtual INT DuplicateKeyframe(INT KeyIndex, FLOAT NewKeyTime); + virtual UBOOL GetClosestSnapPosition(FLOAT InPosition, TArray &IgnoreKeys, FLOAT& OutPosition); + virtual FColor GetKeyframeColor(INT KeyIndex) const; + + virtual void PreviewUpdateTrack(FLOAT NewPosition, class UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + + /** + * Calculates the reversed time for a sequence key, if the key has bReverse set. + * + * @param SeqKey Key that is reveresed and we are trying to find a position for. + * @param Seq Anim sequence the key represents. If NULL, the function will lookup the sequence. + * @param InPosition Timeline position that we are currently at. + * + * @return Returns the position in the specified seq key. + */ + FLOAT ConditionallyReversePosition(FAnimControlTrackKey &SeqKey, UAnimSequence* Seq, FLOAT InPosition); + + /** Get the name of the class used to help out when adding tracks, keys, etc. in UnrealEd. + * @return String name of the helper class.*/ + virtual const FString GetEdHelperClassName() const; + + virtual class UMaterial* GetTrackIcon() const; + virtual void DrawTrack( FCanvas* Canvas, UInterpGroup* Group, const FInterpTrackDrawParams& Params ); + + // InterpTrackAnimControl interface + class UAnimSequence* FindAnimSequenceFromName(FName InName); + const class UAnimSequence* FindAnimSequenceFromName(FName InName) const; + /** Get Animation for the given Time + * @return TRUE if it needs the animation to advance timer (from Previous to Current Time for Root Motion + */ + UBOOL GetAnimForTime(FLOAT InTime, FName& OutAnimSeqName, FLOAT& OutPosition, UBOOL& bOutLooping); + FLOAT GetWeightForTime(FLOAT InTime); + INT SplitKeyAtPosition(FLOAT InPosition); + + /** + * Crops the key at the position specified, by deleting the area of the key before or after the position. + * + * @param InPosition Position to use as a crop point. + * @param bCutAreaBeforePosition Whether we should delete the area of the key before the position specified or after. + * + * @return Returns the index of the key that was cropped. + */ + INT CropKeyAtPosition(FLOAT InPosition, UBOOL bCutAreaBeforePosition); + + // FInterpEdInputInterface + + /** + * Lets the interface object know that we are beginning a drag operation. + */ + virtual void BeginDrag(FInterpEdInputData &InputData); + + /** + * Lets the interface object know that we are ending a drag operation. + */ + virtual void EndDrag(FInterpEdInputData &InputData); + + /** + * @return Returns the mouse cursor to display when this input interface is moused over. + */ + EMouseCursor GetMouseCursor(FInterpEdInputData &InputData); + + /** + * Called when an object is dragged. + */ + void ObjectDragged(FInterpEdInputData& InputData); + + /** Calculate the index of this Track within its Slot (for when multiple tracks are using same slot). */ + INT CalcChannelIndex(); +} + +/** + * DEPRECATED! USE UInterpGroup::GroupAnimSets instead now. + */ +var array AnimSets; + +/** + * Name of slot to use when playing animation. Passed to Actor. + * When multiple tracks use the same slot name, they are each given a different ChannelIndex when SetAnimPosition is called. + */ +var() name SlotName; + +/** Structure used for holding information for one animation played on the Anim Control track. */ +struct native AnimControlTrackKey +{ + /** Position in the Matinee sequence to start playing this animation. */ + var float StartTime; + + /** Name of AnimSequence to play. */ + var name AnimSeqName; + + /** Time to start playing AnimSequence at. */ + var float AnimStartOffset; + + /** Time to end playing the AnimSequence at. */ + var float AnimEndOffset; + + /** Playback speed of this animation. */ + var float AnimPlayRate; + + /** Should this animation loop. */ + var bool bLooping; + + /** Whether to play the animation in reverse or not. */ + var bool bReverse; +}; + +/** Track of different animations to play and when to start playing them. */ +var array AnimSeqs; + +/** Enable root motion. This only works if you delete Movement Track to avoid conflicts **/ +var() bool bEnableRootMotion; + +/** Skip all anim notifiers **/ +var() bool bSkipAnimNotifiers; + +defaultproperties +{ + TrackInstClass=class'Engine.InterpTrackInstAnimControl' + TrackTitle="Anim" + bIsAnimControlTrack=true +} diff --git a/Engine/Classes/InterpTrackAudioMaster.uc b/Engine/Classes/InterpTrackAudioMaster.uc new file mode 100644 index 0000000..df10941 --- /dev/null +++ b/Engine/Classes/InterpTrackAudioMaster.uc @@ -0,0 +1,31 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackAudioMaster extends InterpTrackVectorBase + native(Interpolation); + +cpptext +{ + // InterpTrack interface + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual void UpdateKeyframe(INT KeyIndex, UInterpTrackInst* TrInst); + virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + virtual void SetTrackToSensibleDefault(); + + /** Return the sound volume scale for the specified time */ + FLOAT GetVolumeScaleForTime( FLOAT Time ) const; + + /** Return the sound pitch scale for the specified time */ + FLOAT GetPitchScaleForTime( FLOAT Time ) const; + + virtual class UMaterial* GetTrackIcon() const; +} + +defaultproperties +{ + bOnePerGroup=true + bDirGroupOnly=true + TrackInstClass=class'Engine.InterpTrackInstAudioMaster' + TrackTitle="Audio Master" +} diff --git a/Engine/Classes/InterpTrackBoolProp.uc b/Engine/Classes/InterpTrackBoolProp.uc new file mode 100644 index 0000000..c8480f1 --- /dev/null +++ b/Engine/Classes/InterpTrackBoolProp.uc @@ -0,0 +1,146 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackBoolProp extends InterpTrack + native(Interpolation); + +/** Information for one event in the track. */ +struct native BoolTrackKey +{ + var float Time; + var() bool Value; +}; + +/** Array of booleans to set. */ +var array BoolTrack; + +/** Name of property in Group Actor which this track will modify over time. */ +var() editconst name PropertyName; + +cpptext +{ + /** Returns the property name */ + virtual UBOOL GetPropertyName( FName& PropertyNameOut ) const { PropertyNameOut = PropertyName; return TRUE; } + + /** + * @return The number of keyframes currently in this track. + */ + virtual INT GetNumKeyframes() const; + + /** + * Gathers the range that spans all keyframes. + * + * @param StartTime [out] The time of the first keyframe on this track. + * @param EndTime [out] The time of the last keyframe on this track. + */ + virtual void GetTimeRange( FLOAT& StartTime, FLOAT& EndTime ) const; + + /** + * @return The ending time of the track. + */ + virtual FLOAT GetTrackEndTime() const; + + /** + * @param KeyIndex The index of the key to retrieve the time in the track's key array. + * + * @return The time of the given key in the track on the timeline. + */ + virtual FLOAT GetKeyframeTime( INT KeyIndex ) const; + + /** + * Changes the time of the given key with the new given time. + * + * @param KeyIndex The index key to change in the track's key array. + * @param NewKeyTime The new time for the given key in the timeline. + * @param bUpdateOrder When TRUE, moves the key to be in chronological order in the array. + * + * @return The new index for the given key. + */ + virtual INT SetKeyframeTime( INT KeyIndex, FLOAT NewKeyTime, UBOOL bUpdateOrder = TRUE ); + + /** + * Removes the given key from the array of keys in the track. + * + * @param KeyIndex The index of the key to remove in this track's array of keys. + */ + virtual void RemoveKeyframe( INT KeyIndex ); + + /** + * Duplicates the given key. + * + * @param KeyIndex The index of the key to duplicate in this track's array of keys. + * @param NewKeyTime The time to assign to the duplicated key. + * + * @return The new index for the given key. + */ + virtual INT DuplicateKeyframe( INT KeyIndex, FLOAT NewKeyTime ); + + /** + * Gets the position of the closest key with snapping incorporated. + * + * @param InPosition The current position in the timeline. + * @param IgnoreKeys The set of keys to ignore when searching for the closest key. + * @param OutPosition The position of the closest key with respect to snapping and ignoring the given set of keys. + * + * @return TRUE if a keyframe was found; FALSE if no keyframe was found. + */ + virtual UBOOL GetClosestSnapPosition( FLOAT InPosition, TArray& IgnoreKeys, FLOAT& OutPosition ); + + /** + * Adds a keyframe at the given time to the track. + * + * @param Time The time to place the key in the track timeline. + * @param TrackInst The instance of this track. + * @param InitInterpMode The interp mode of the newly-added keyframe. + */ + virtual INT AddKeyframe( FLOAT Time, UInterpTrackInst* TrackInst, EInterpCurveMode InitInterpMode ); + + /** + * Changes the value of an existing keyframe. + * + * @param KeyIndex The index of the key to update in the track's key array. + * @param TrackInst The instance of this track to update. + */ + virtual void UpdateKeyframe( INT KeyIndex, UInterpTrackInst* TrackInst ); + + /** + * Updates the instance of this track based on the new position. This is for editor preview. + * + * @param NewPosition The position of the track in the timeline. + * @param TrackInst The instance of this track to update. + */ + virtual void PreviewUpdateTrack( FLOAT NewPosition, UInterpTrackInst* TrackInst ); + + /** + * Updates the instance of this track based on the new position. This is called in the game, when USeqAct_Interp is ticked. + * + * @param NewPosition The position of the track in the timeline. + * @param TrackInst The instance of this track to update. + * @param bJump Indicates if this is a sudden jump instead of a smooth move to the new position. + */ + virtual void UpdateTrack( FLOAT NewPosition, UInterpTrackInst* TrackInst, UBOOL bJump ); + + /** + * @return TRUE if this track type works with static actors; FALSE, otherwise. + */ + virtual UBOOL AllowStaticActors() { return TRUE; } + + /** + * Get the name of the class used to help out when adding tracks, keys, etc. in UnrealEd. + * + * @return String name of the helper class. + */ + virtual const FString GetEdHelperClassName() const; + + /** + * @return The icon to draw for this track in Matinee. + */ + virtual class UMaterial* GetTrackIcon() const; +} + + +defaultproperties +{ + TrackInstClass=class'Engine.InterpTrackInstBoolProp' + TrackTitle="Bool Property" +} diff --git a/Engine/Classes/InterpTrackColorProp.uc b/Engine/Classes/InterpTrackColorProp.uc new file mode 100644 index 0000000..54541ff --- /dev/null +++ b/Engine/Classes/InterpTrackColorProp.uc @@ -0,0 +1,32 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackColorProp extends InterpTrackVectorBase + native(Interpolation); + +cpptext +{ + /** Returns the property name */ + virtual UBOOL GetPropertyName( FName& PropertyNameOut ) const { PropertyNameOut = PropertyName; return TRUE; } + + // InterpTrack interface + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual void UpdateKeyframe(INT KeyIndex, UInterpTrackInst* TrInst); + virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + + /** Get the name of the class used to help out when adding tracks, keys, etc. in UnrealEd. + * @return String name of the helper class.*/ + virtual const FString GetEdHelperClassName() const; + + virtual class UMaterial* GetTrackIcon() const; +} + +/** Name of property in Group Actor which this track mill modify over time. */ +var() editconst name PropertyName; + +defaultproperties +{ + TrackInstClass=class'Engine.InterpTrackInstColorProp' + TrackTitle="Color Property" +} diff --git a/Engine/Classes/InterpTrackColorScale.uc b/Engine/Classes/InterpTrackColorScale.uc new file mode 100644 index 0000000..3794348 --- /dev/null +++ b/Engine/Classes/InterpTrackColorScale.uc @@ -0,0 +1,31 @@ +class InterpTrackColorScale extends InterpTrackVectorBase + native(Interpolation); + +/** + * InterpTrackColorScale + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +cpptext +{ + // InterpTrack interface + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual void UpdateKeyframe(INT KeyIndex, UInterpTrackInst* TrInst); + virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + virtual void SetTrackToSensibleDefault(); + + virtual class UMaterial* GetTrackIcon() const; + + // InterpTrackColorScale interface + FVector GetColorScaleAtTime(FLOAT Time); +} + +defaultproperties +{ + bOnePerGroup=true + bDirGroupOnly=true + TrackInstClass=class'Engine.InterpTrackInstColorScale' + TrackTitle="Color Scale" +} diff --git a/Engine/Classes/InterpTrackDirector.uc b/Engine/Classes/InterpTrackDirector.uc new file mode 100644 index 0000000..7f0f38e --- /dev/null +++ b/Engine/Classes/InterpTrackDirector.uc @@ -0,0 +1,75 @@ +class InterpTrackDirector extends InterpTrack + native(Interpolation); + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * A track type used for binding the view of a Player (attached to this tracks group) to the actor of a different group. + * + */ + +cpptext +{ + // UObject interface + virtual void PostLoad(); + + // InterpTrack interface + virtual INT GetNumKeyframes() const; + virtual void GetTimeRange(FLOAT& StartTime, FLOAT& EndTime) const; + virtual FLOAT GetTrackEndTime() const; + virtual FLOAT GetKeyframeTime(INT KeyIndex) const; + virtual INT GetKeyframeIndex( FLOAT KeyTime ) const; + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual INT SetKeyframeTime(INT KeyIndex, FLOAT NewKeyTime, UBOOL bUpdateOrder=true); + virtual void RemoveKeyframe(INT KeyIndex); + virtual INT DuplicateKeyframe(INT KeyIndex, FLOAT NewKeyTime); + virtual UBOOL GetClosestSnapPosition(FLOAT InPosition, TArray &IgnoreKeys, FLOAT& OutPosition); + + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + + /** Get the name of the class used to help out when adding tracks, keys, etc. in UnrealEd. + * @return String name of the helper class.*/ + virtual const FString GetEdHelperClassName() const; + + virtual class UMaterial* GetTrackIcon() const; + virtual void DrawTrack( FCanvas* Canvas, UInterpGroup* Group, const FInterpTrackDrawParams& Params ); + + // InterpTrackDirector interface + FName GetViewedGroupName(FLOAT CurrentTime, FLOAT& CutTime, FLOAT& CutTransitionTime); + const FString GetViewedCameraShotName(FLOAT CurrentTime) const; + + const INT GenerateCameraShotNumber(INT KeyIndex) const; + const FString GetFormattedCameraShotName(INT KeyIndex) const; + void DisplayShotNamesInHUD(UInterpGroupInst* GrInst, APlayerController* PC, FLOAT Time); +} + +/** Information for one cut in this track. */ +struct native DirectorTrackCut +{ + /** Time to perform the cut. */ + var float Time; + + /** Time taken to move view to new camera. */ + var float TransitionTime; + + /** GroupName of InterpGroup to cut viewpoint to. */ + var() name TargetCamGroup; + + /** Shot number for developer reference */ + var int ShotNumber; +}; + +/** Array of cuts between cameras. */ +var array CutTrack; + +/** True to allow clients to simulate their own camera cuts. Can help with latency-induced timing issues. */ +var() bool bSimulateCameraCutsOnClients; + +defaultproperties +{ + bOnePerGroup=true + bDirGroupOnly=true + TrackInstClass=class'Engine.InterpTrackInstDirector' + TrackTitle="Director" + bSimulateCameraCutsOnClients=TRUE +} diff --git a/Engine/Classes/InterpTrackEvent.uc b/Engine/Classes/InterpTrackEvent.uc new file mode 100644 index 0000000..b70cb5f --- /dev/null +++ b/Engine/Classes/InterpTrackEvent.uc @@ -0,0 +1,65 @@ +class InterpTrackEvent extends InterpTrack + native(Interpolation); + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * + * A track containing discrete events that are triggered as its played back. + * Events correspond to Outputs of the SeqAct_Interp in Kismet. + * There is no PreviewUpdateTrack function for this type - events are not triggered in editor. + */ + +cpptext +{ + // InterpTrack interface + virtual INT GetNumKeyframes() const; + virtual void GetTimeRange(FLOAT& StartTime, FLOAT& EndTime) const; + virtual FLOAT GetTrackEndTime() const; + virtual FLOAT GetKeyframeTime(INT KeyIndex) const; + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual INT SetKeyframeTime(INT KeyIndex, FLOAT NewKeyTime, UBOOL bUpdateOrder=true); + virtual void RemoveKeyframe(INT KeyIndex); + virtual INT DuplicateKeyframe(INT KeyIndex, FLOAT NewKeyTime); + virtual UBOOL GetClosestSnapPosition(FLOAT InPosition, TArray &IgnoreKeys, FLOAT& OutPosition); + + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + + /** Get the name of the class used to help out when adding tracks, keys, etc. in UnrealEd. + * @return String name of the helper class.*/ + virtual const FString GetEdHelperClassName() const; + + virtual class UMaterial* GetTrackIcon() const; + + /** Whether or not this track is allowed to be used on static actors. */ + virtual UBOOL AllowStaticActors() { return TRUE; } + + virtual void DrawTrack( FCanvas* Canvas, UInterpGroup* Group, const FInterpTrackDrawParams& Params ); +} + +/** Information for one event in the track. */ +struct native EventTrackKey +{ + var float Time; + var() name EventName; +}; + +/** Array of events to fire off. */ +var array EventTrack; + +/** If events should be fired when passed playing the sequence forwards. */ +var() bool bFireEventsWhenForwards; + +/** If events should be fired when passed playing the sequence backwards. */ +var() bool bFireEventsWhenBackwards; + +/** If true, events on this track are fired even when jumping forwads through a sequence - for example, skipping a cinematic. */ +var() bool bFireEventsWhenJumpingForwards; + +defaultproperties +{ + TrackInstClass=class'Engine.InterpTrackInstEvent' + TrackTitle="Event" + bFireEventsWhenForwards=true + bFireEventsWhenBackwards=true +} diff --git a/Engine/Classes/InterpTrackFaceFX.uc b/Engine/Classes/InterpTrackFaceFX.uc new file mode 100644 index 0000000..4d907dd --- /dev/null +++ b/Engine/Classes/InterpTrackFaceFX.uc @@ -0,0 +1,98 @@ +class InterpTrackFaceFX extends InterpTrack + native(Interpolation); + +/** + * InterpTrackFaceFX + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + + +cpptext +{ + // UObject interface + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + // InterpTrack interface + virtual INT GetNumKeyframes() const; + virtual void GetTimeRange(FLOAT& StartTime, FLOAT& EndTime) const; + virtual FLOAT GetTrackEndTime() const; + virtual FLOAT GetKeyframeTime(INT KeyIndex) const; + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual INT SetKeyframeTime(INT KeyIndex, FLOAT NewKeyTime, UBOOL bUpdateOrder=true); + virtual void RemoveKeyframe(INT KeyIndex); + virtual INT DuplicateKeyframe(INT KeyIndex, FLOAT NewKeyTime); + //virtual UBOOL GetClosestSnapPosition(FLOAT InPosition, TArray &IgnoreKeys, FLOAT& OutPosition); + //virtual FColor GetKeyframeColor(INT KeyIndex) const; + + virtual void PreviewUpdateTrack(FLOAT NewPosition, class UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + virtual void PreviewStopPlayback(class UInterpTrackInst* TrInst); + + /** Get the name of the class used to help out when adding tracks, keys, etc. in UnrealEd. + * @return String name of the helper class.*/ + virtual const FString GetEdHelperClassName() const; + + virtual class UMaterial* GetTrackIcon() const; + virtual void DrawTrack( FCanvas* Canvas, UInterpGroup* Group, const FInterpTrackDrawParams& Params ); + + // InterpTrackFaceFX interface +// WWISEMODIF_START, alessard, nov-28-2008, WwiseAudioIntegration + void GetSeqInfoForTime( FLOAT InTime, FString& OutGroupName, FString& OutSeqName, FLOAT& OutPosition, FLOAT& OutSeqStart, USoundCue*& OutSoundCue, UAkEvent*& OutAkEvent ); +// WWISEMODIF_END + + /** Updates references to sound cues for all of this track's FaceFX animation keys. Should be called at + load time in the editor as well as whenever the track's data is changed. */ + void UpdateFaceFXSoundCueReferences( class UFaceFXAsset* FaceFXAsset ); +} + +/** Structure used for holding information for one FaceFX animation played by the track. */ +struct native FaceFXTrackKey +{ + /** Position in the Matinee sequence to start playing this FaceFX animation. */ + var float StartTime; + + /** Name of FaceFX group containing sequence to play. */ + var string FaceFXGroupName; + + /** Name of FaceFX sequence to play. */ + var string FaceFXSeqName; +}; + +/** Extra sets of animation that you wish to use on this Group's Actor during the matinee sequence. */ +var() array FaceFXAnimSets; + +/** Track of different animations to play and when to start playing them. */ +var array FaceFXSeqs; + +/** In Matinee, cache a pointer to the Actor's FaceFXAsset, so we can get info like anim lengths. */ +var transient FaceFXAsset CachedActorFXAsset; + + +/** Structure used for holding information for one FaceFX animation played by the track. */ +struct native FaceFXSoundCueKey +{ + /** Sound cue associated with this key's FaceFX sequence. Currently this is maintained automatically by + the editor and saved out when the map is saved to disk. The game requires the sound cue reference + in order to play FaceFX animations with audio. */ + var private const SoundCue FaceFXSoundCue; + +// WWISEMODIF_START + /** AkEvent associated with this key's FaceFX sequence. Currently this is maintained automatically by + the editor and saved out when the map is saved to disk. The game requires the AkEvent reference + in order to play FaceFX animations with audio. */ + var private const AkEvent FaceFXAkEvent; +// WWISEMODIF_END +}; + + +/** One key for each key in the associated FaceFX track's array of keys */ +var private const array< FaceFXSoundCueKey > FaceFXSoundCueKeys; + + +defaultproperties +{ + TrackInstClass=class'Engine.InterpTrackInstFaceFX' + TrackTitle="FaceFX" + bOnePerGroup=true +} diff --git a/Engine/Classes/InterpTrackFade.uc b/Engine/Classes/InterpTrackFade.uc new file mode 100644 index 0000000..cceff96 --- /dev/null +++ b/Engine/Classes/InterpTrackFade.uc @@ -0,0 +1,35 @@ +class InterpTrackFade extends InterpTrackFloatBase + native(Interpolation); + +/** + * InterpTrackFade + * + * Special float property track that controls camera fading over time. + * Should live in a Director group. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +cpptext +{ + // InterpTrack interface + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual void UpdateKeyframe(INT KeyIndex, UInterpTrackInst* TrInst); + virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + + virtual class UMaterial* GetTrackIcon() const; + + // InterpTrackFade interface + FLOAT GetFadeAmountAtTime(FLOAT Time); +} + +var() bool bPersistFade; + +defaultproperties +{ + bOnePerGroup=true + bDirGroupOnly=true + TrackInstClass=class'Engine.InterpTrackInstFade' + TrackTitle="Fade" +} diff --git a/Engine/Classes/InterpTrackFloatBase.uc b/Engine/Classes/InterpTrackFloatBase.uc new file mode 100644 index 0000000..f6d6ba0 --- /dev/null +++ b/Engine/Classes/InterpTrackFloatBase.uc @@ -0,0 +1,63 @@ +class InterpTrackFloatBase extends InterpTrack + native(Interpolation) + abstract; + +/** + * InterpTrackFloatBase + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +cpptext +{ + // UObject interface + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + // InterpTrack interface + virtual INT GetNumKeyframes() const; + virtual void GetTimeRange(FLOAT& StartTime, FLOAT& EndTime) const; + virtual FLOAT GetTrackEndTime() const; + virtual FLOAT GetKeyframeTime(INT KeyIndex) const; + virtual INT SetKeyframeTime(INT KeyIndex, FLOAT NewKeyTime, UBOOL bUpdateOrder=true); + virtual void RemoveKeyframe(INT KeyIndex); + virtual INT DuplicateKeyframe(INT KeyIndex, FLOAT NewKeyTime); + virtual UBOOL GetClosestSnapPosition(FLOAT InPosition, TArray &IgnoreKeys, FLOAT& OutPosition); + virtual FColor GetKeyframeColor(INT KeyIndex) const; + + // FCurveEdInterface interface + virtual INT GetNumKeys(); + virtual INT GetNumSubCurves() const; + virtual FLOAT GetKeyIn(INT KeyIndex); + virtual FLOAT GetKeyOut(INT SubIndex, INT KeyIndex); + virtual void GetInRange(FLOAT& MinIn, FLOAT& MaxIn); + virtual void GetOutRange(FLOAT& MinOut, FLOAT& MaxOut); + virtual BYTE GetKeyInterpMode(INT KeyIndex); + virtual void GetTangents(INT SubIndex, INT KeyIndex, FLOAT& ArriveTangent, FLOAT& LeaveTangent); + virtual FLOAT EvalSub(INT SubIndex, FLOAT InVal); + + virtual INT CreateNewKey(FLOAT KeyIn); + virtual void DeleteKey(INT KeyIndex); + + virtual INT SetKeyIn(INT KeyIndex, FLOAT NewInVal); + virtual void SetKeyOut(INT SubIndex, INT KeyIndex, FLOAT NewOutVal); + virtual void SetKeyInterpMode(INT KeyIndex, EInterpCurveMode NewMode); + virtual void SetTangents(INT SubIndex, INT KeyIndex, FLOAT ArriveTangent, FLOAT LeaveTangent); + + /** Returns TRUE if this curve uses legacy tangent/interp algorithms and may be 'upgraded' */ + virtual UBOOL UsingLegacyInterpMethod() const; + + /** 'Upgrades' this curve to use the latest tangent/interp algorithms (usually, will 'bake' key tangents.) */ + virtual void UpgradeInterpMethod(); +} + +/** Actually track data containing keyframes of float as it varies over time. */ +var InterpCurveFloat FloatTrack; + +/** Tension of curve, used for keypoints using automatic tangents. */ +var() float CurveTension; + +defaultproperties +{ + TrackTitle="Generic Float Track" + CurveTension=0.0 +} diff --git a/Engine/Classes/InterpTrackFloatMaterialParam.uc b/Engine/Classes/InterpTrackFloatMaterialParam.uc new file mode 100644 index 0000000..fbbfbde --- /dev/null +++ b/Engine/Classes/InterpTrackFloatMaterialParam.uc @@ -0,0 +1,41 @@ +class InterpTrackFloatMaterialParam extends InterpTrackFloatBase + native(Interpolation); + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +cpptext +{ + virtual void PreSave(); + virtual void PostLoad(); + virtual void PreEditChange(UProperty* PropertyThatWillChange); + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual void PostDuplicate(); + + // InterpTrack interface + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + + //virtual class UMaterial* GetTrackIcon() const; +} + +/** materials whose parameters we want to change and the references to those materials + * that need to be given MICs in the same level, compiled at save time + */ +var() const array Materials; +var deprecated const MaterialInterface Material; +/** Name of parameter in the MaterialInstance which this track will modify over time. */ +var() name ParamName; + +/** @compatibility: indicates we need to gather material references on first use + * (can't do in PostLoad() because Actors initialize components array in their own PostLoad() which might not have been called yet) + */ +var transient bool bNeedsMaterialRefsUpdate; + +defaultproperties +{ + TrackInstClass=class'Engine.InterpTrackInstFloatMaterialParam' + TrackTitle="Float Material Param" +} diff --git a/Engine/Classes/InterpTrackFloatParticleParam.uc b/Engine/Classes/InterpTrackFloatParticleParam.uc new file mode 100644 index 0000000..6c0551b --- /dev/null +++ b/Engine/Classes/InterpTrackFloatParticleParam.uc @@ -0,0 +1,25 @@ +class InterpTrackFloatParticleParam extends InterpTrackFloatBase + native(Interpolation); + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +cpptext +{ + // InterpTrack interface + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + + //virtual class UMaterial* GetTrackIcon() const; +} + +/** Name of property in the Emitter which this track mill modify over time. */ +var() name ParamName; + +defaultproperties +{ + TrackInstClass=class'Engine.InterpTrackInstFloatParticleParam' + TrackTitle="Float Particle Param" +} diff --git a/Engine/Classes/InterpTrackFloatProp.uc b/Engine/Classes/InterpTrackFloatProp.uc new file mode 100644 index 0000000..005336a --- /dev/null +++ b/Engine/Classes/InterpTrackFloatProp.uc @@ -0,0 +1,42 @@ +class InterpTrackFloatProp extends InterpTrackFloatBase + native(Interpolation); + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +cpptext +{ + /** Returns the property name */ + virtual UBOOL GetPropertyName( FName& PropertyNameOut ) const { PropertyNameOut = PropertyName; return TRUE; } + + // InterpTrack interface + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual void UpdateKeyframe(INT KeyIndex, UInterpTrackInst* TrInst); + virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + + /** Get the name of the class used to help out when adding tracks, keys, etc. in UnrealEd. + * @return String name of the helper class.*/ + virtual const FString GetEdHelperClassName() const; + + virtual class UMaterial* GetTrackIcon() const; + + /** + * Reduce Keys within Tolerance + * + * @param bIntervalStart start of the key to reduce + * @param bIntervalEnd end of the key to reduce + * @param Tolerance tolerance + */ + virtual void ReduceKeys( FLOAT IntervalStart, FLOAT IntervalEnd, FLOAT Tolerance ); +} + +/** Name of property in Group Actor which this track mill modify over time. */ +var() editconst name PropertyName; + +defaultproperties +{ + TrackInstClass=class'Engine.InterpTrackInstFloatProp' + TrackTitle="Float Property" +} diff --git a/Engine/Classes/InterpTrackHeadTracking.uc b/Engine/Classes/InterpTrackHeadTracking.uc new file mode 100644 index 0000000..afb887a --- /dev/null +++ b/Engine/Classes/InterpTrackHeadTracking.uc @@ -0,0 +1,110 @@ +class InterpTrackHeadTracking extends InterpTrack + native(Interpolation); + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * + * This track implements support for setting or toggling the visibility of the associated actor + */ + +cpptext +{ + // InterpTrack interface + virtual INT GetNumKeyframes() const; + virtual void GetTimeRange(FLOAT& StartTime, FLOAT& EndTime) const; + virtual FLOAT GetTrackEndTime() const; + virtual FLOAT GetKeyframeTime(INT KeyIndex) const; + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual INT SetKeyframeTime(INT KeyIndex, FLOAT NewKeyTime, UBOOL bUpdateOrder=true); + virtual void RemoveKeyframe(INT KeyIndex); + virtual INT DuplicateKeyframe(INT KeyIndex, FLOAT NewKeyTime); + virtual UBOOL GetClosestSnapPosition(FLOAT InPosition, TArray &IgnoreKeys, FLOAT& OutPosition); + + virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + + /** Get the name of the class used to help out when adding tracks, keys, etc. in UnrealEd. + * @return String name of the helper class.*/ + virtual const FString GetEdHelperClassName() const; + + virtual class UMaterial* GetTrackIcon() const; + + /** Whether or not this track is allowed to be used on static actors. */ + virtual UBOOL AllowStaticActors() { return TRUE; } + + virtual void DrawTrack( FCanvas* Canvas, UInterpGroup* Group, const FInterpTrackDrawParams& Params ); + +private: + /** Update Actor List for look at candidate **/ + void UpdateHeadTracking(AActor* Actor, UInterpTrackInst* TrInst, FLOAT DeltaTime); +} + + +/** HeadTracking actions */ +enum EHeadTrackingAction +{ + /** Disable Head Tracking */ + EHTA_DisableHeadTracking, + + /** Enable Head Tracking */ + EHTA_EnableHeadTracking, +}; + +/** Information for one toggle in the track. */ +struct native HeadTrackingKey +{ + var float Time; + var() EHeadTrackingAction Action; +}; + +/** Array of keys . */ +var array HeadTrackingTrack; + +/** SkelControlLookAt name in the AnimTree of the SkeletalMesh **/ +var() array TrackControllerName; + +/** Will pick up actor within this radius **/ +var() float LookAtActorRadius; + +/** Interp back to zero strength if limit surpassed */ +var() bool bDisableBeyondLimit; + +/** How long can one person to look at one **/ +var() float MaxLookAtTime; +/** At least this time to look at one **/ +var() float MinLookAtTime; + +/** Once entered the radius, how long do I really care to lok ? This affects rating. It will give benefit to the person who just entered **/ +var() float MaxInterestTime; + +/** Quick check box for allowing it to look Pawn - due to Pawn not being listed in the Actor class **/ +var(Target) bool bLookAtPawns; + +/** Actor classes to look at as 0 index being the highest priority if you have anything specific **/ +var(Target) array< class > ActorClassesToLookAt; + +/** Target Bone Names, where to look at - priority from top to bottom, if not found, it will continue search **/ +var(Target) array TargetBoneNames; + +defaultproperties +{ + TrackInstClass=class'Engine.InterpTrackInstHeadTracking' + TrackTitle="HeadTracking" + TrackControllerName.Add("HeadLook") + TrackControllerName.Add("LeftEyeLook") + TrackControllerName.Add("RightEyeLook") + + ActorClassesToLookAt.Empty + + MinLookAtTime = 3.f + MaxLookAtTime = 5.f + MaxInterestTime = 7.f + + LookAtActorRadius = 500.f + bLookAtPawns = TRUE + + TargetBoneNames.Empty + TargetBoneNames.Add("b_MF_Head") + TargetBoneNames.Add("b_MF_Neck") +} diff --git a/Engine/Classes/InterpTrackInst.uc b/Engine/Classes/InterpTrackInst.uc new file mode 100644 index 0000000..38d1672 --- /dev/null +++ b/Engine/Classes/InterpTrackInst.uc @@ -0,0 +1,31 @@ +class InterpTrackInst extends Object + native(Interpolation); + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * + * The Outer of an InterpTrackInst is the InterpGroupInst. + */ + +cpptext +{ + /** + * Return the Actor associated with this instance of a Group. + * Note that all Groups have at least 1 instance, even if no Actor variable is attached, so this may return NULL. + */ + AActor* GetGroupActor(); + + /** Called before Interp editing to put object back to its original state. */ + virtual void SaveActorState(UInterpTrack* Track) {} + + /** Restore the saved state of this Actor. */ + virtual void RestoreActorState(UInterpTrack* Track) {} + + /** Initialise this Track instance. Called in-game before doing any interpolation. */ + virtual void InitTrackInst(UInterpTrack* Track); + + /** Called when interpolation is done. Should not do anything else with this TrackInst after this. */ + virtual void TermTrackInst(UInterpTrack* Track) {} +} + diff --git a/Engine/Classes/InterpTrackInstAnimControl.uc b/Engine/Classes/InterpTrackInstAnimControl.uc new file mode 100644 index 0000000..ca9384e --- /dev/null +++ b/Engine/Classes/InterpTrackInstAnimControl.uc @@ -0,0 +1,21 @@ +class InterpTrackInstAnimControl extends InterpTrackInst + native(Interpolation); + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +cpptext +{ + /** Initialise this Track instance. Called in-game before doing any interpolation. */ + virtual void InitTrackInst(UInterpTrack* Track); + + /** Called when interpolation is done. Should not do anything else with this TrackInst after this. */ + virtual void TermTrackInst(UInterpTrack* Track); +} + +var transient float LastUpdatePosition; + +var editoronly transient vector InitPosition; +var editoronly transient rotator InitRotation; + diff --git a/Engine/Classes/InterpTrackInstAudioMaster.uc b/Engine/Classes/InterpTrackInstAudioMaster.uc new file mode 100644 index 0000000..65cf6c7 --- /dev/null +++ b/Engine/Classes/InterpTrackInstAudioMaster.uc @@ -0,0 +1,13 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstAudioMaster extends InterpTrackInst + native(Interpolation); + + +cpptext +{ + // InterpTrackInst interface + virtual void InitTrackInst(UInterpTrack* Track); + virtual void TermTrackInst(UInterpTrack* Track); +} diff --git a/Engine/Classes/InterpTrackInstBoolProp.uc b/Engine/Classes/InterpTrackInstBoolProp.uc new file mode 100644 index 0000000..db0e2f9 --- /dev/null +++ b/Engine/Classes/InterpTrackInstBoolProp.uc @@ -0,0 +1,38 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstBoolProp extends InterpTrackInstProperty + native(Interpolation); + +cpptext +{ + /** + * Initialize the track instance. + * + * @param Track The track associated to this instance. + */ + virtual void InitTrackInst( UInterpTrack* Track ); + + /** + * Save any variables from the actor that will be modified by this instance. + * + * @param Track The track associated to this instance. + */ + virtual void SaveActorState( UInterpTrack* Track ); + + /** + * Restores any variables modified on the actor by this instance. + * + * @param Track The track associated to this instance. + */ + virtual void RestoreActorState( UInterpTrack* Track ); +} + +/** Pointer to boolean property in TrackObject. */ +var pointer BoolProp; + +/** Mask that indicates which bit the boolean property actually uses of the value pointed to by BoolProp. */ +var int BitMask; + +/** Saved value for restoring state when exiting Matinee. */ +var bool ResetBool; diff --git a/Engine/Classes/InterpTrackInstColorProp.uc b/Engine/Classes/InterpTrackInstColorProp.uc new file mode 100644 index 0000000..e48b63a --- /dev/null +++ b/Engine/Classes/InterpTrackInstColorProp.uc @@ -0,0 +1,20 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstColorProp extends InterpTrackInstProperty + native(Interpolation); + + +cpptext +{ + virtual void SaveActorState(UInterpTrack* Track); + virtual void RestoreActorState(UInterpTrack* Track); + + virtual void InitTrackInst(UInterpTrack* Track); +} + +/** Pointer to color property in TrackObject. */ +var pointer ColorProp; + +/** Saved value for restoring state when exiting Matinee. */ +var color ResetColor; \ No newline at end of file diff --git a/Engine/Classes/InterpTrackInstColorScale.uc b/Engine/Classes/InterpTrackInstColorScale.uc new file mode 100644 index 0000000..661c9f9 --- /dev/null +++ b/Engine/Classes/InterpTrackInstColorScale.uc @@ -0,0 +1,12 @@ +class InterpTrackInstColorScale extends InterpTrackInst + native(Interpolation); + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +cpptext +{ + // InterpTrackInst interface + virtual void TermTrackInst(UInterpTrack* Track); +} diff --git a/Engine/Classes/InterpTrackInstDirector.uc b/Engine/Classes/InterpTrackInstDirector.uc new file mode 100644 index 0000000..bc184ed --- /dev/null +++ b/Engine/Classes/InterpTrackInstDirector.uc @@ -0,0 +1,23 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstDirector extends InterpTrackInst + native(Interpolation); + + +var Actor OldViewTarget; + +/** Rendering overrides that were active on the player camera, used to restore settings when the director track ends in game. */ +var RenderingPerformanceOverrides OldRenderingOverrides; + +cpptext +{ + /** Initialise this Track instance. Called in-game before doing any interpolation. */ + virtual void InitTrackInst(UInterpTrack* Track); + /** Called when interpolation is done. Should not do anything else with this TrackInst after this. */ + virtual void TermTrackInst(UInterpTrack* Track); +} + +defaultproperties +{ +} diff --git a/Engine/Classes/InterpTrackInstEvent.uc b/Engine/Classes/InterpTrackInstEvent.uc new file mode 100644 index 0000000..8d420b3 --- /dev/null +++ b/Engine/Classes/InterpTrackInstEvent.uc @@ -0,0 +1,25 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstEvent extends InterpTrackInst + native(Interpolation); + + +cpptext +{ + /** + * This will initialise LastUpdatePosition to whatever position the SeqAct_Interp is in, + * so we don't play a bunch of events straight away! + */ + virtual void InitTrackInst(UInterpTrack* Track); +} + +/** + * Position we were in last time we evaluated Events. + * During UpdateTrack, events between this time and the current time will be fired. + */ +var float LastUpdatePosition; + +defaultproperties +{ +} diff --git a/Engine/Classes/InterpTrackInstFaceFX.uc b/Engine/Classes/InterpTrackInstFaceFX.uc new file mode 100644 index 0000000..e6f77b1 --- /dev/null +++ b/Engine/Classes/InterpTrackInstFaceFX.uc @@ -0,0 +1,19 @@ +class InterpTrackInstFaceFX extends InterpTrackInst + native(Interpolation); + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +cpptext +{ + virtual void InitTrackInst(UInterpTrack* Track); + virtual void TermTrackInst(UInterpTrack* Track); + virtual void SaveActorState(UInterpTrack* Track); + virtual void RestoreActorState(UInterpTrack* Track); +} + +var transient bool bFirstUpdate; +var float LastUpdatePosition; + + diff --git a/Engine/Classes/InterpTrackInstFade.uc b/Engine/Classes/InterpTrackInstFade.uc new file mode 100644 index 0000000..27523be --- /dev/null +++ b/Engine/Classes/InterpTrackInstFade.uc @@ -0,0 +1,12 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstFade extends InterpTrackInst + native(Interpolation); + + +cpptext +{ + // InterpTrackInst interface + virtual void TermTrackInst(UInterpTrack* Track); +} diff --git a/Engine/Classes/InterpTrackInstFloatMaterialParam.uc b/Engine/Classes/InterpTrackInstFloatMaterialParam.uc new file mode 100644 index 0000000..8b91acc --- /dev/null +++ b/Engine/Classes/InterpTrackInstFloatMaterialParam.uc @@ -0,0 +1,28 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstFloatMaterialParam extends InterpTrackInst + native(Interpolation); + +cpptext +{ + virtual void InitTrackInst(UInterpTrack* Track); + virtual void TermTrackInst(UInterpTrack* Track); + virtual void SaveActorState(UInterpTrack* Track); + virtual void RestoreActorState(UInterpTrack* Track); +} + +/** list of MICs we are using and optionally also the original value of the parameter we're editing + * array size should match owner track's Materials array + */ +struct native FloatMaterialParamMICData +{ + /** MICs we're using to set the desired parameter on PrimitiveComponents - size of array should match track's AffectedMaterialRefs */ + var const array MICs; + /** saved values for restoring state when exiting Matinee - size of array should match MICs */ + var const array MICResetFloats; +}; +var array MICInfos; + +/** track we are an instance of - used in the editor to propagate changes to the track's Materials array immediately */ +var InterpTrackFloatMaterialParam InstancedTrack; diff --git a/Engine/Classes/InterpTrackInstFloatParticleParam.uc b/Engine/Classes/InterpTrackInstFloatParticleParam.uc new file mode 100644 index 0000000..9b47212 --- /dev/null +++ b/Engine/Classes/InterpTrackInstFloatParticleParam.uc @@ -0,0 +1,14 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstFloatParticleParam extends InterpTrackInst + native(Interpolation); + +cpptext +{ + virtual void SaveActorState(UInterpTrack* Track); + virtual void RestoreActorState(UInterpTrack* Track); +} + +/** Saved value for restoring state when exiting Matinee. */ +var float ResetFloat; diff --git a/Engine/Classes/InterpTrackInstFloatProp.uc b/Engine/Classes/InterpTrackInstFloatProp.uc new file mode 100644 index 0000000..56ea43a --- /dev/null +++ b/Engine/Classes/InterpTrackInstFloatProp.uc @@ -0,0 +1,23 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstFloatProp extends InterpTrackInstProperty + native(Interpolation); + +cpptext +{ + virtual void SaveActorState(UInterpTrack* Track); + virtual void RestoreActorState(UInterpTrack* Track); + + virtual void InitTrackInst(UInterpTrack* Track); + virtual void TermTrackInst(UInterpTrack* Track); +} + +/** Pointer to float property in TrackObject. */ +var pointer FloatProp; + +/** Saved value for restoring state when exiting Matinee. */ +var float ResetFloat; + +/** Pointer to FMatineeRawFloatDistribution if the FloatProp pointer belongs to one, NULL otherwise. */ +var pointer DistributionProp; diff --git a/Engine/Classes/InterpTrackInstHeadTracking.uc b/Engine/Classes/InterpTrackInstHeadTracking.uc new file mode 100644 index 0000000..2e58f83 --- /dev/null +++ b/Engine/Classes/InterpTrackInstHeadTracking.uc @@ -0,0 +1,49 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstHeadTracking extends InterpTrackInst + dependson(HeadTrackingComponent) + native(Interpolation); + +var() EHeadTrackingAction Action; + +/** Actor to look at information **/ +// struct native ActorToLookAt +// { +// var Actor Actor; +// var float Rating; +// var float EnteredTime; +// var float LastKnownDistance; +// var float StartTimeBeingLookedAt; +// var bool CurrentlyBeingLookedAt; +// }; + +/** Array of actor information **/ +var const transient native map{class AActor*,struct FActorToLookAt* } CurrentActorMap; +/** SkeletalMeshComponent who owns this **/ +var transient SkeletalMeshComponent Mesh; +/** Look at control **/ +var transient array TrackControls; + +/** + * Position we were in last time we evaluated. + * During UpdateTrack, events between this time and the current time will be processed. + */ +var float LastUpdatePosition; + +cpptext +{ + /** + */ + virtual void InitTrackInst(UInterpTrack* Track); + + /** Called when interpolation is done. Should not do anything else with this TrackInst after this. */ + virtual void TermTrackInst(UInterpTrack* Track); + + /** Make sure CurrentActorMap is referenced */ + void AddReferencedObjects( TArray& ObjectArray ); +} + +defaultproperties +{ +} diff --git a/Engine/Classes/InterpTrackInstLinearColorProp.uc b/Engine/Classes/InterpTrackInstLinearColorProp.uc new file mode 100644 index 0000000..4cb4ebd --- /dev/null +++ b/Engine/Classes/InterpTrackInstLinearColorProp.uc @@ -0,0 +1,20 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstLinearColorProp extends InterpTrackInstProperty + native(Interpolation); + + +cpptext +{ + virtual void SaveActorState(UInterpTrack* Track); + virtual void RestoreActorState(UInterpTrack* Track); + + virtual void InitTrackInst(UInterpTrack* Track); +} + +/** Pointer to color property in TrackObject. */ +var pointer ColorProp; + +/** Saved value for restoring state when exiting Matinee. */ +var linearcolor ResetColor; \ No newline at end of file diff --git a/Engine/Classes/InterpTrackInstMorphWeight.uc b/Engine/Classes/InterpTrackInstMorphWeight.uc new file mode 100644 index 0000000..3be3ee3 --- /dev/null +++ b/Engine/Classes/InterpTrackInstMorphWeight.uc @@ -0,0 +1,10 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstMorphWeight extends InterpTrackInst + native(Interpolation); + +cpptext +{ + virtual void RestoreActorState(UInterpTrack* Track); +} \ No newline at end of file diff --git a/Engine/Classes/InterpTrackInstMove.uc b/Engine/Classes/InterpTrackInstMove.uc new file mode 100644 index 0000000..de17782 --- /dev/null +++ b/Engine/Classes/InterpTrackInstMove.uc @@ -0,0 +1,27 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstMove extends InterpTrackInst + native(Interpolation); + + +cpptext +{ + /** Will save the current position of the Actor as the 'initial position', used if MoveFrame == IMF_RelativeToInitial. */ + virtual void InitTrackInst(UInterpTrack* Track); + + /** Initialise InitialTMand InitialQuat. */ + void CalcInitialTransform(UInterpTrack* Track, UBOOL bZeroFromHere); +} + +/** Saved position. Used in editor for resetting when quitting Matinee. */ +var vector ResetLocation; + +/** Saved rotation. Used in editor for resetting when quitting Matinee. */ +var rotator ResetRotation; + +/** Transform of group's actor when sequence was started. This is used to reset sequence and also as basis when using IMF_RelativeToInitial. */ +var matrix InitialTM; + +/** Orientation of group's actor when sequence was started. @see InitialTM */ +var quat InitialQuat; diff --git a/Engine/Classes/InterpTrackInstNotify.uc b/Engine/Classes/InterpTrackInstNotify.uc new file mode 100644 index 0000000..ae3b5e4 --- /dev/null +++ b/Engine/Classes/InterpTrackInstNotify.uc @@ -0,0 +1,13 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class InterpTrackInstNotify extends InterpTrackInst + native(Interpolation); + +cpptext +{ + virtual void InitTrackInst(UInterpTrack* Track); +} + +var float LastUpdatePosition; diff --git a/Engine/Classes/InterpTrackInstParticleReplay.uc b/Engine/Classes/InterpTrackInstParticleReplay.uc new file mode 100644 index 0000000..7ca978e --- /dev/null +++ b/Engine/Classes/InterpTrackInstParticleReplay.uc @@ -0,0 +1,24 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstParticleReplay extends InterpTrackInst + native(Interpolation); + +/** + * Position we were in last time we evaluated. + * During UpdateTrack, events between this time and the current time will be processed. + */ +var float LastUpdatePosition; + +cpptext +{ + /** Initialise this Track instance. Called in-game before doing any interpolation. */ + virtual void InitTrackInst(UInterpTrack* Track); + + /** Restore the saved state of this Actor. */ + virtual void RestoreActorState(UInterpTrack* Track); +} + +defaultproperties +{ +} diff --git a/Engine/Classes/InterpTrackInstProperty.uc b/Engine/Classes/InterpTrackInstProperty.uc new file mode 100644 index 0000000..567c759 --- /dev/null +++ b/Engine/Classes/InterpTrackInstProperty.uc @@ -0,0 +1,33 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstProperty extends InterpTrackInst + native(Interpolation); + +cpptext +{ + /** + * Retrieves the update callback from the interp property's metadata and stores it. + * + * @param InActor Actor we are operating on. + * @param TrackProperty Property we are interpolating. + */ + void SetupPropertyUpdateCallback(AActor* InActor, const FName& TrackPropertyName); + + /** + * Tries to call the property update callback. + * + * @return TRUE if the callback existed and was called, FALSE otherwise. + */ + UBOOL CallPropertyUpdateCallback(); + + /** Called when interpolation is done. Should not do anything else with this TrackInst after this. */ + virtual void TermTrackInst(UInterpTrack* Track); +} + + +/** Function to call after updating the value of the color property. */ +var function PropertyUpdateCallback; + +/** Pointer to the UObject instance that is the outer of the color property we are interpolating on, this is used to process the property update callback. */ +var object PropertyOuterObjectInst; \ No newline at end of file diff --git a/Engine/Classes/InterpTrackInstSkelControlScale.uc b/Engine/Classes/InterpTrackInstSkelControlScale.uc new file mode 100644 index 0000000..964098e --- /dev/null +++ b/Engine/Classes/InterpTrackInstSkelControlScale.uc @@ -0,0 +1,11 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstSkelControlScale extends InterpTrackInst + native(Interpolation); + +cpptext +{ + virtual void RestoreActorState(UInterpTrack* Track); +} + diff --git a/Engine/Classes/InterpTrackInstSkelControlStrength.uc b/Engine/Classes/InterpTrackInstSkelControlStrength.uc new file mode 100644 index 0000000..f8e2eef --- /dev/null +++ b/Engine/Classes/InterpTrackInstSkelControlStrength.uc @@ -0,0 +1,20 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstSkelControlStrength extends InterpTrackInst + native(Interpolation); + +/** Save ControlledByAnimMetaData **/ +var transient bool bSavedControlledByAnimMetaData; + +cpptext +{ + virtual void RestoreActorState(UInterpTrack* Track); + + /** Initialise this Track instance. Called in-game before doing any interpolation. */ + virtual void InitTrackInst(UInterpTrack* Track); + + /** Called when interpolation is done. Should not do anything else with this TrackInst after this. */ + virtual void TermTrackInst(UInterpTrack* Track); +} + diff --git a/Engine/Classes/InterpTrackInstSlomo.uc b/Engine/Classes/InterpTrackInstSlomo.uc new file mode 100644 index 0000000..26813f4 --- /dev/null +++ b/Engine/Classes/InterpTrackInstSlomo.uc @@ -0,0 +1,24 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstSlomo extends InterpTrackInst + native(Interpolation); + + +/** Backup of initial LevelInfo TimeDilation setting when interpolation started. */ +var float OldTimeDilation; + +cpptext +{ + // InterpTrackInst interface + virtual void SaveActorState(UInterpTrack* Track); + virtual void RestoreActorState(UInterpTrack* Track); + virtual void InitTrackInst(UInterpTrack* Track); + virtual void TermTrackInst(UInterpTrack* Track); + + /** @return whether the slomo track's effects should actually be applied. We want to only do this once for the server + * and not at all for the clients regardless of the number of instances created for the various players + * to avoid collisions and replication issues + */ + UBOOL ShouldBeApplied(); +} diff --git a/Engine/Classes/InterpTrackInstSound.uc b/Engine/Classes/InterpTrackInstSound.uc new file mode 100644 index 0000000..6584bee --- /dev/null +++ b/Engine/Classes/InterpTrackInstSound.uc @@ -0,0 +1,18 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstSound extends InterpTrackInst + native(Interpolation); + +cpptext +{ + virtual void InitTrackInst(UInterpTrack* Track); + virtual void TermTrackInst(UInterpTrack* Track); +} + +var float LastUpdatePosition; +var transient AudioComponent PlayAudioComp; + +defaultproperties +{ +} diff --git a/Engine/Classes/InterpTrackInstToggle.uc b/Engine/Classes/InterpTrackInstToggle.uc new file mode 100644 index 0000000..25f33c8 --- /dev/null +++ b/Engine/Classes/InterpTrackInstToggle.uc @@ -0,0 +1,33 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstToggle extends InterpTrackInst + native(Interpolation); + +var() ETrackToggleAction Action; +/** + * Position we were in last time we evaluated. + * During UpdateTrack, toggles between this time and the current time will be processed. + */ +var float LastUpdatePosition; + +/** Cached 'active' state for the toggleable actor before we possessed it; restored when Matinee exits */ +var bool bSavedActiveState; + + +cpptext +{ + /** + */ + virtual void InitTrackInst(UInterpTrack* Track); + + /** Called before Interp editing to put object back to its original state. */ + virtual void SaveActorState(UInterpTrack* Track); + + /** Restore the saved state of this Actor. */ + virtual void RestoreActorState(UInterpTrack* Track); +} + +defaultproperties +{ +} diff --git a/Engine/Classes/InterpTrackInstVectorMaterialParam.uc b/Engine/Classes/InterpTrackInstVectorMaterialParam.uc new file mode 100644 index 0000000..0165b1c --- /dev/null +++ b/Engine/Classes/InterpTrackInstVectorMaterialParam.uc @@ -0,0 +1,28 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstVectorMaterialParam extends InterpTrackInst + native(Interpolation); + +cpptext +{ + virtual void InitTrackInst(UInterpTrack* Track); + virtual void TermTrackInst(UInterpTrack* Track); + virtual void SaveActorState(UInterpTrack* Track); + virtual void RestoreActorState(UInterpTrack* Track); +} + +/** list of MICs we are using and optionally also the original value of the parameter we're editing + * array size should match owner track's Materials array + */ +struct native VectorMaterialParamMICData +{ + /** MICs we're using to set the desired parameter on PrimitiveComponents - size of array should match track's AffectedMaterialRefs */ + var const array MICs; + /** saved values for restoring state when exiting Matinee - size of array should match MICs */ + var const array MICResetVectors; +}; +var array MICInfos; + +/** track we are an instance of - used in the editor to propagate changes to the track's Materials array immediately */ +var InterpTrackVectorMaterialParam InstancedTrack; diff --git a/Engine/Classes/InterpTrackInstVectorProp.uc b/Engine/Classes/InterpTrackInstVectorProp.uc new file mode 100644 index 0000000..24d6918 --- /dev/null +++ b/Engine/Classes/InterpTrackInstVectorProp.uc @@ -0,0 +1,20 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstVectorProp extends InterpTrackInstProperty + native(Interpolation); + + +cpptext +{ + virtual void SaveActorState(UInterpTrack* Track); + virtual void RestoreActorState(UInterpTrack* Track); + + virtual void InitTrackInst(UInterpTrack* Track); +} + +/** Pointer to vector property in TrackObject. */ +var pointer VectorProp; + +/** Saved value for restoring state when exiting Matinee. */ +var vector ResetVector; diff --git a/Engine/Classes/InterpTrackInstVisibility.uc b/Engine/Classes/InterpTrackInstVisibility.uc new file mode 100644 index 0000000..2306d74 --- /dev/null +++ b/Engine/Classes/InterpTrackInstVisibility.uc @@ -0,0 +1,23 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackInstVisibility extends InterpTrackInst + native(Interpolation); + +var() EVisibilityTrackAction Action; +/** + * Position we were in last time we evaluated. + * During UpdateTrack, events between this time and the current time will be processed. + */ +var float LastUpdatePosition; + +cpptext +{ + /** + */ + virtual void InitTrackInst(UInterpTrack* Track); +} + +defaultproperties +{ +} diff --git a/Engine/Classes/InterpTrackLinearColorBase.uc b/Engine/Classes/InterpTrackLinearColorBase.uc new file mode 100644 index 0000000..b138739 --- /dev/null +++ b/Engine/Classes/InterpTrackLinearColorBase.uc @@ -0,0 +1,87 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackLinearColorBase extends InterpTrack + native(Interpolation) + abstract; + +cpptext +{ + // UObject interface + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + void Serialize(FArchive& Ar) + { + Super::Serialize(Ar); + } + + // InterpTrack interface + virtual INT GetNumKeyframes() const; + virtual void GetTimeRange(FLOAT& StartTime, FLOAT& EndTime) const; + virtual FLOAT GetTrackEndTime() const; + virtual FLOAT GetKeyframeTime(INT KeyIndex) const; + virtual INT SetKeyframeTime(INT KeyIndex, FLOAT NewKeyTime, UBOOL bUpdateOrder=true); + virtual void RemoveKeyframe(INT KeyIndex); + virtual INT DuplicateKeyframe(INT KeyIndex, FLOAT NewKeyTime); + virtual UBOOL GetClosestSnapPosition(FLOAT InPosition, TArray &IgnoreKeys, FLOAT& OutPosition); + + virtual FColor GetKeyframeColor(INT KeyIndex) const; + + // FCurveEdInterface interface + virtual INT GetNumKeys(); + virtual INT GetNumSubCurves() const; + + /** + * Provides the color for the sub-curve button that is present on the curve tab. + * + * @param SubCurveIndex The index of the sub-curve. Cannot be negative nor greater or equal to the number of sub-curves. + * @param bIsSubCurveHidden Is the curve hidden? + * @return The color associated to the given sub-curve index. + */ + virtual FColor GetSubCurveButtonColor(INT SubCurveIndex, UBOOL bIsSubCurveHidden) const; + + virtual FLOAT GetKeyIn(INT KeyIndex); + virtual FLOAT GetKeyOut(INT SubIndex, INT KeyIndex); + virtual void GetInRange(FLOAT& MinIn, FLOAT& MaxIn); + virtual void GetOutRange(FLOAT& MinOut, FLOAT& MaxOut); + + /** + * Provides the color for the given key at the given sub-curve. + * + * @param SubIndex The index of the sub-curve + * @param KeyIndex The index of the key in the sub-curve + * @param[in] CurveColor The color of the curve + * @return The color that is associated the given key at the given sub-curve + */ + virtual FColor GetKeyColor(INT SubIndex, INT KeyIndex, const FColor& CurveColor); + + virtual BYTE GetKeyInterpMode(INT KeyIndex); + virtual void GetTangents(INT SubIndex, INT KeyIndex, FLOAT& ArriveTangent, FLOAT& LeaveTangent); + virtual FLOAT EvalSub(INT SubIndex, FLOAT InVal); + + virtual INT CreateNewKey(FLOAT KeyIn); + virtual void DeleteKey(INT KeyIndex); + + virtual INT SetKeyIn(INT KeyIndex, FLOAT NewInVal); + virtual void SetKeyOut(INT SubIndex, INT KeyIndex, FLOAT NewOutVal); + virtual void SetKeyInterpMode(INT KeyIndex, EInterpCurveMode NewMode); + virtual void SetTangents(INT SubIndex, INT KeyIndex, FLOAT ArriveTangent, FLOAT LeaveTangent); + + /** Returns TRUE if this curve uses legacy tangent/interp algorithms and may be 'upgraded' */ + virtual UBOOL UsingLegacyInterpMethod() const; + + /** 'Upgrades' this curve to use the latest tangent/interp algorithms (usually, will 'bake' key tangents.) */ + virtual void UpgradeInterpMethod(); +} + +/** Actually track data containing keyframes of a vector as it varies over time. */ +var InterpCurveLinearColor LinearColorTrack; + +/** Tension of curve, used for keypoints using automatic tangents. */ +var() float CurveTension; + +defaultproperties +{ + TrackTitle="Generic LinearColor Track" + CurveTension=0.0 +} diff --git a/Engine/Classes/InterpTrackLinearColorProp.uc b/Engine/Classes/InterpTrackLinearColorProp.uc new file mode 100644 index 0000000..7a77974 --- /dev/null +++ b/Engine/Classes/InterpTrackLinearColorProp.uc @@ -0,0 +1,34 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackLinearColorProp extends InterpTrackLinearColorBase + native(Interpolation); + +cpptext +{ + /** Returns the property name */ + virtual UBOOL GetPropertyName( FName& PropertyNameOut ) const { PropertyNameOut = PropertyName; return TRUE; } + + // InterpTrack interface + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual void UpdateKeyframe(INT KeyIndex, UInterpTrackInst* TrInst); + virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + + /** Get the name of the class used to help out when adding tracks, keys, etc. in UnrealEd. + * + * @return String name of the helper class. + */ + virtual const FString GetEdHelperClassName() const; + + virtual class UMaterial* GetTrackIcon() const; +} + +/** Name of property in Group Actor which this track mill modify over time. */ +var() editconst name PropertyName; + +defaultproperties +{ + TrackInstClass=class'Engine.InterpTrackInstLinearColorProp' + TrackTitle="LinearColor Property" +} \ No newline at end of file diff --git a/Engine/Classes/InterpTrackMorphWeight.uc b/Engine/Classes/InterpTrackMorphWeight.uc new file mode 100644 index 0000000..7e09eda --- /dev/null +++ b/Engine/Classes/InterpTrackMorphWeight.uc @@ -0,0 +1,24 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class InterpTrackMorphWeight extends InterpTrackFloatBase + native(Interpolation); + +cpptext +{ + // InterpTrack interface + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); +} + +/** Name of property in Group Actor which this track mill modify over time. */ +var() name MorphNodeName; + +defaultproperties +{ + TrackInstClass=class'Engine.InterpTrackInstMorphWeight' + TrackTitle="Morph Weight" + bIsAnimControlTrack=true +} diff --git a/Engine/Classes/InterpTrackMove.uc b/Engine/Classes/InterpTrackMove.uc new file mode 100644 index 0000000..91ba9ed --- /dev/null +++ b/Engine/Classes/InterpTrackMove.uc @@ -0,0 +1,359 @@ +class InterpTrackMove extends InterpTrack + native(Interpolation); + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * Track containing data for moving an actor around over time. + * There is no UpdateTrack function. In the game, its the PHYS_Interpolating physics mode which + * updates the position based on the interp track. + */ + +cpptext +{ + // UObject interface + virtual void PostLoad(); + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual void PostEditImport(); + + // InterpTrack interface + virtual INT GetNumKeyframes() const; + virtual void GetTimeRange(FLOAT& StartTime, FLOAT& EndTime) const; + virtual FLOAT GetTrackEndTime() const; + virtual FLOAT GetKeyframeTime(INT KeyIndex) const; + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + + /** + * Adds a keyframe to a child track + * + * @param ChildTrack The child track where the keyframe should be added + * @param Time What time the keyframe is located at + * @param TrackInst The track instance of the parent track(this track) + * @param InitInterpMode The initial interp mode for the keyframe? + */ + virtual INT AddChildKeyframe(class UInterpTrack* ChildTrack, FLOAT Time, UInterpTrackInst* TrackInst, EInterpCurveMode InitInterpMode); + + virtual void UpdateKeyframe(INT KeyIndex, UInterpTrackInst* TrInst); + + /** + * Updates a child track keyframe + * + * @param ChildTrack The child track with keyframe to update + * @param KeyIndex The index of the key to be updated + * @param TrackInst The track instance of the parent track(this track) + */ + virtual void UpdateChildKeyframe( class UInterpTrack* ChildTrack, INT KeyIndex, UInterpTrackInst* TrackInst ); + + virtual INT SetKeyframeTime(INT KeyIndex, FLOAT NewKeyTime, UBOOL bUpdateOrder=true); + virtual void RemoveKeyframe(INT KeyIndex); + virtual INT DuplicateKeyframe(INT KeyIndex, FLOAT NewKeyTime); + virtual UBOOL GetClosestSnapPosition(FLOAT InPosition, TArray &IgnoreKeys, FLOAT& OutPosition); + + virtual void ConditionalPreviewUpdateTrack(FLOAT NewPosition, class UInterpTrackInst* TrInst); + virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst); + + virtual class UMaterial* GetTrackIcon() const; + virtual FColor GetKeyframeColor(INT KeyIndex) const; + virtual void DrawTrack( FCanvas* Canvas, UInterpGroup* Group, const FInterpTrackDrawParams& Params ); + virtual void Render3DTrack(UInterpTrackInst* TrInst, const FSceneView* View, FPrimitiveDrawInterface* PDI, INT TrackIndex, const FColor& TrackColor, TArray& SelectedKeys); + virtual void SetTrackToSensibleDefault(); + + // FCurveEdInterface interface + virtual INT GetNumKeys(); + virtual INT GetNumSubCurves() const; + + /** + * Provides the color for the sub-curve button that is present on the curve tab. + * + * @param SubCurveIndex The index of the sub-curve. Cannot be negative nor greater or equal to the number of sub-curves. + * @param bIsSubCurveHidden Is the curve hidden? + * @return The color associated to the given sub-curve index. + */ + virtual FColor GetSubCurveButtonColor(INT SubCurveIndex, UBOOL bIsSubCurveHidden) const; + + virtual FLOAT GetKeyIn(INT KeyIndex); + virtual FLOAT GetKeyOut(INT SubIndex, INT KeyIndex); + virtual void GetInRange(FLOAT& MinIn, FLOAT& MaxIn); + virtual void GetOutRange(FLOAT& MinOut, FLOAT& MaxOut); + + /** + * Provides the color for the given key at the given sub-curve. + * + * @param SubIndex The index of the sub-curve + * @param KeyIndex The index of the key in the sub-curve + * @param[in] CurveColor The color of the curve + * @return The color that is associated the given key at the given sub-curve + */ + virtual FColor GetKeyColor(INT SubIndex, INT KeyIndex, const FColor& CurveColor); + + virtual BYTE GetKeyInterpMode(INT KeyIndex); + virtual void GetTangents(INT SubIndex, INT KeyIndex, FLOAT& ArriveTangent, FLOAT& LeaveTangent); + virtual FLOAT EvalSub(INT SubIndex, FLOAT InVal); + + virtual INT CreateNewKey(FLOAT KeyIn); + virtual void DeleteKey(INT KeyIndex); + + virtual INT SetKeyIn(INT KeyIndex, FLOAT NewInVal); + virtual void SetKeyOut(INT SubIndex, INT KeyIndex, FLOAT NewOutVal); + virtual void SetKeyInterpMode(INT KeyIndex, EInterpCurveMode NewMode); + virtual void SetTangents(INT SubIndex, INT KeyIndex, FLOAT ArriveTangent, FLOAT LeaveTangent); + + /** Returns TRUE if this curve uses legacy tangent/interp algorithms and may be 'upgraded' */ + virtual UBOOL UsingLegacyInterpMethod() const; + + /** 'Upgrades' this curve to use the latest tangent/interp algorithms (usually, will 'bake' key tangents.) */ + virtual void UpgradeInterpMethod(); + + + // InterpTrackMove interface + virtual FName GetLookupKeyGroupName(INT KeyIndex); + virtual void SetLookupKeyGroupName(INT KeyIndex, const FName &NewGroupName); + virtual void ClearLookupKeyGroupName(INT KeyIndex); + + /** + * Replacement for the PosTrack eval function that uses GetKeyframePosition. This is so we can replace keyframes that get their information from other tracks. + * + * @param TrInst TrackInst to use for looking up groups. + * @param Time Time to evaluate position at. + * @return Final position at the specified time. + */ + FVector EvalPositionAtTime(UInterpTrackInst* TrInst, FLOAT Time); + + /** + * Replacement for the EulerTrack eval function that uses GetKeyframeRotation. This is so we can replace keyframes that get their information from other tracks. + * + * @param TrInst TrackInst to use for looking up groups. + * @param Time Time to evaluate rotation at. + * @return Final rotation at the specified time. + */ + FVector EvalRotationAtTime(UInterpTrackInst* TrInst, FLOAT Time); + + /** + * Gets the position of a keyframe given its key index. Also optionally retrieves the Arrive and Leave tangents for the key. + * This function respects the LookupTrack. + * + * @param TrInst TrackInst to use for lookup track positions. + * @param KeyIndex Index of the keyframe to get the position of. + * @param OutTime Final time of the keyframe. + * @param OutPos Final position of the keyframe. + * @param OutArriveTangent Pointer to a vector to store the arrive tangent in, can be NULL. + * @param OutLeaveTangent Pointer to a vector to store the leave tangent in, can be NULL. + */ + void GetKeyframePosition(UInterpTrackInst* TrInst, INT KeyIndex, FLOAT& OutTime, FVector &OutPos, FVector *OutArriveTangent, FVector *OutLeaveTangent); + + /** + * Gets the rotation of a keyframe given its key index. Also optionally retrieves the Arrive and Leave tangents for the key. + * This function respects the LookupTrack. + * + * @param TrInst TrackInst to use for lookup track rotations. + * @param KeyIndex Index of the keyframe to get the rotation of. + * @param OutTime Final time of the keyframe. + * @param OutRot Final rotation of the keyframe. + * @param OutArriveTangent Pointer to a vector to store the arrive tangent in, can be NULL. + * @param OutLeaveTangent Pointer to a vector to store the leave tangent in, can be NULL. + */ + void GetKeyframeRotation(UInterpTrackInst* TrInst, INT KeyIndex, FLOAT& OutTime, FVector &OutRot, FVector *OutArriveTangent, FVector *OutLeaveTangent); + + /** + * Computes the world space coordinates for a key; handles keys that use IMF_RelativeToInitial, basing, etc. + * + * @param MoveTrackInst An instance of this movement track + * @param RelativeSpacePos Key position value from curve + * @param RelativeSpaceRot Key rotation value from curve + * @param OutPos Output world space position + * @param OutRot Output world space rotation + */ + void ComputeWorldSpaceKeyTransform( UInterpTrackInstMove* MoveTrackInst, + const FVector& RelativeSpacePos, + const FRotator& RelativeSpaceRot, + FVector& OutPos, + FRotator& OutRot ); + + virtual void GetKeyTransformAtTime(UInterpTrackInst* TrInst, FLOAT Time, FVector& OutPos, FRotator& OutRot); + virtual UBOOL GetLocationAtTime(UInterpTrackInst* TrInst, FLOAT Time, FVector& OutPos, FRotator& OutRot); + virtual FMatrix GetMoveRefFrame(UInterpTrackInstMove* MoveTrackInst); + /** + * Find Best Matching Time From Position + * This function simply try to find Time from input Position using simple Lerp + * + * @param : Pos - input position + * @param : StartKeyIndex - optional + * + * @return : Interp Time + */ + FLOAT FindBestMatchingTimefromPosition(UInterpTrackInst* TrInst, const FVector& Pos, INT StartKeyIndex=0, EAxis WeightAxis = AXIS_XY); + + INT CalcSubIndex(UBOOL bPos, INT InIndex) const; + + /** + * Creates and adds subtracks to this track + * + * @param bCopy If subtracks are being added as a result of a copy + */ + virtual void CreateSubTracks( UBOOL bCopy ); + + /** + * Splits this movment track in to seperate tracks for translation and rotation + */ + void SplitTranslationAndRotation(); + + /** + * Reduce Keys within Tolerance + * + * @param bIntervalStart start of the key to reduce + * @param bIntervalEnd end of the key to reduce + * @param Tolerance tolerance + */ + virtual void ReduceKeys( FLOAT IntervalStart, FLOAT IntervalEnd, FLOAT Tolerance ); +} + +/** Actual position keyframe data. */ +var InterpCurveVector PosTrack; + +/** Actual rotation keyframe data, stored as Euler angles in degrees, for easy editing on curve. */ +var InterpCurveVector EulerTrack; + +/** + * Array of group names to retrieve position and rotation data from instead of using the datastored in the keyframe. + * A value of NAME_None means to use the PosTrack and EulerTrack data for the keyframe. + * There needs to be the same amount of elements in this array as there are keyframes. + */ +struct native InterpLookupPoint +{ + var name GroupName; + var float Time; +}; + +struct native InterpLookupTrack +{ + structcpptext + { + /** Add a new keypoint to the LookupTrack. Returns the index of the new key.*/ + INT AddPoint( const FLOAT InTime, FName &InGroupName ) + { + INT PointIdx=0; + + for( PointIdx=0; PointIdx= Points.Num() ) + { + return PointIndex; + } + + FName GroupName = Points(PointIndex).GroupName; + + Points.Remove(PointIndex); + + const INT NewPointIndex = AddPoint( NewTime, GroupName ); + + return NewPointIndex; + } + } + + var array Points; +}; + +var InterpLookupTrack LookupTrack; + +/** When using IMR_LookAtGroup, specifies the Group which this track should always point its actor at. */ +var() name LookAtGroupName; + +/** Controls the tightness of the curve for the translation path. */ +var() float LinCurveTension; + +/** Controls the tightness of the curve for the rotation path. */ +var() float AngCurveTension; + +/** + * Use a Quaternion linear interpolation between keys. + * This is robust and will find the 'shortest' distance between keys, but does not support ease in/out. + */ +var() bool bUseQuatInterpolation; + +/** In the editor, show a small arrow at each keyframe indicating the rotation at that key. */ +var() bool bShowArrowAtKeys; + +/** Disable previewing of this track - will always position Actor at Time=0.0. Useful when keyframing an object relative to this group. */ +var() bool bDisableMovement; + +/** If false, when this track is displayed on the Curve Editor in Matinee, do not show the Translation tracks. */ +var() bool bShowTranslationOnCurveEd; + +/** If false, when this track is displayed on the Curve Editor in Matinee, do not show the Rotation tracks. */ +var() bool bShowRotationOnCurveEd; + +/** If true, 3D representation of this track in the 3D viewport is disabled. */ +var() bool bHide3DTrack; + +/** Use just the raw Location/Rotation of the base actor instead of calculating the initial offset (makes IMF_RelativeToInitial behave more like you would expect). */ +var() bool bUseRawActorTMforRelativeToInitial; + +enum EInterpTrackMoveFrame +{ + /** Track should be fixed relative to the world. */ + IMF_World, + + /** Track should move relative to the initial position of the actor when the interp sequence was started. */ + IMF_RelativeToInitial +}; + +/** Indicates what the movement track should be relative to. */ +var() editconst EInterpTrackMoveFrame MoveFrame; + + +enum EInterpTrackMoveRotMode +{ + /** Should take orientation from the . */ + IMR_Keyframed, + + /** Point the X-Axis of the controlled Actor at the group specified by LookAtGroupName. */ + IMR_LookAtGroup, + + /** Should look along the direction of the translation path, with Z always up. */ + // IMR_LookAlongPath // TODO! + + /** Do not change rotation. Ignore it. */ + IMR_Ignore +}; + +var() EInterpTrackMoveRotMode RotMode; + +defaultproperties +{ + TrackInstClass=class'Engine.InterpTrackInstMove' + + bOnePerGroup=true + + TrackTitle="Movement" + + LinCurveTension=0.0 + AngCurveTension=0.0 + + MoveFrame=IMF_World + RotMode=IMR_Keyframed + + bShowTranslationOnCurveEd=true + bShowRotationOnCurveEd=false + + SupportedSubTracks.Add( (SupportedClass=class'Engine.InterpTrackMoveAxis', SubTrackName="X", GroupIndex=0) ) + SupportedSubTracks.Add( (SupportedClass=class'Engine.InterpTrackMoveAxis', SubTrackName="Y", GroupIndex=0) ) + SupportedSubTracks.Add( (SupportedClass=class'Engine.InterpTrackMoveAxis', SubTrackName="Z", GroupIndex=0) ) + SupportedSubTracks.Add( (SupportedClass=class'Engine.InterpTrackMoveAxis', SubTrackName="X", GroupIndex=1 ) ) + SupportedSubTracks.Add( (SupportedClass=class'Engine.InterpTrackMoveAxis', SubTrackName="Y", GroupIndex=1 ) ) + SupportedSubTracks.Add( (SupportedClass=class'Engine.InterpTrackMoveAxis', SubTrackName="Z", GroupIndex=1 ) ) + + `if(`isdefined(CHAIR_INTERNAL)) + // The default behavior for UDK is false, but we always want this true for ChAIR games + bUseRawActorTMforRelativeToInitial=true + `endif +} diff --git a/Engine/Classes/InterpTrackMoveAxis.uc b/Engine/Classes/InterpTrackMoveAxis.uc new file mode 100644 index 0000000..d47017e --- /dev/null +++ b/Engine/Classes/InterpTrackMoveAxis.uc @@ -0,0 +1,77 @@ +class InterpTrackMoveAxis extends InterpTrackFloatBase + dependson(InterpTrackMove) + native(Interpolation); + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * Subtrack for InterpTrackMove + * Transforms an interp actor on one axis + */ + +/** List of axies this track can use */ +enum EInterpMoveAxis +{ + AXIS_TranslationX, + AXIS_TranslationY, + AXIS_TranslationZ, + AXIS_RotationX, + AXIS_RotationY, + AXIS_RotationZ, +}; + +/** The axis which this track will use when transforming an actor */ +var EInterpMoveAxis MoveAxis; + +/** Lookup track to use when looking at different groups for transform information*/ +var InterpLookupTrack LookupTrack; + +cpptext +{ + virtual INT GetKeyframeIndex( FLOAT KeyTime ) const; + virtual INT AddKeyframe( FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode ); + virtual void UpdateKeyframe(INT KeyIndex, UInterpTrackInst* TrInst); + virtual INT SetKeyframeTime( INT KeyIndex, FLOAT NewKeyTime, UBOOL bUpdateOrder ); + virtual void RemoveKeyframe( INT KeyIndex ); + virtual INT DuplicateKeyframe( INT KeyIndex, FLOAT NewKeyTime ); + FName GetLookupKeyGroupName( INT KeyIndex ); + void SetLookupKeyGroupName( INT KeyIndex, const FName& NewGroupName ); + void ClearLookupKeyGroupName( INT KeyIndex ); + + // FCurveEdInterface interface + virtual FColor GetSubCurveButtonColor( INT SubCurveIndex, UBOOL bIsSubCurveHidden ) const; + virtual INT CreateNewKey( FLOAT KeyIn ); + virtual void DeleteKey( INT KeyIndex ); + virtual INT SetKeyIn( INT KeyIndex, FLOAT NewInVal ); + + /** + * Provides the color for the given key at the given sub-curve. + * + * @param SubIndex The index of the sub-curve + * @param KeyIndex The index of the key in the sub-curve + * @param[in] CurveColor The color of the curve + * @return The color that is associated the given key at the given sub-curve + */ + virtual FColor GetKeyColor(INT SubIndex, INT KeyIndex, const FColor& CurveColor); + void GetKeyframeValue( UInterpTrackInst* TrInst, INT KeyIndex, FLOAT& OutTime, FLOAT &OutValue, FLOAT* OutArriveTangent, FLOAT* OutLeaveTangent ); + FLOAT EvalValueAtTime( UInterpTrackInst* TrInst, FLOAT Time ); + + virtual class UMaterial* GetTrackIcon() const; + + /** + * Reduce Keys within Tolerance + * + * @param bIntervalStart start of the key to reduce + * @param bIntervalEnd end of the key to reduce + * @param Tolerance tolerance + */ + virtual void ReduceKeys( FLOAT IntervalStart, FLOAT IntervalEnd, FLOAT Tolerance ); +}; + +defaultproperties +{ + CurveTension=0.0 + bSubTrackOnly=true; + TrackTitle="Move Axis Track" +} + diff --git a/Engine/Classes/InterpTrackNotify.uc b/Engine/Classes/InterpTrackNotify.uc new file mode 100644 index 0000000..94f611f --- /dev/null +++ b/Engine/Classes/InterpTrackNotify.uc @@ -0,0 +1,64 @@ +/** + * InterpTrackNotify + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class InterpTrackNotify extends InterpTrack + native(Interpolation); + +cpptext +{ + // UObject interface + //virtual void PostLoad(); + + // InterpTrack interface + virtual INT GetNumKeyframes() const; + virtual void GetTimeRange(FLOAT& StartTime, FLOAT& EndTime) const; + virtual FLOAT GetTrackEndTime() const; + virtual FLOAT GetKeyframeTime(INT KeyIndex) const; + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual INT SetKeyframeTime(INT KeyIndex, FLOAT NewKeyTime, UBOOL bUpdateOrder=true); + virtual void RemoveKeyframe(INT KeyIndex); + virtual INT DuplicateKeyframe(INT KeyIndex, FLOAT NewKeyTime); + virtual UBOOL GetClosestSnapPosition(FLOAT InPosition, TArray &IgnoreKeys, FLOAT& OutPosition); + //virtual FColor GetKeyframeColor(INT KeyIndex) const; + + virtual void PreviewUpdateTrack(FLOAT NewPosition, class UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + + /** Get the name of the class used to help out when adding tracks, keys, etc. in UnrealEd. + * @return String name of the helper class.*/ + virtual const FString GetEdHelperClassName() const; + + virtual class UMaterial* GetTrackIcon() const; + virtual void DrawTrack( FCanvas* Canvas, UInterpGroup* Group, const FInterpTrackDrawParams& Params ); +} + +/** Sequence node to pass into the Notify function */ +var AnimNodeSequence Node; + +/** Name of the parent node - used for the Notify function */ +var name ParentNodeName; + +/** Sequence to be the Outer of the Notifies */ +var AnimSequence OuterSequence; + +/** AnimSet to be the Outer of the OuterSequence */ +var AnimSet OuterSet; + +/** Information for one notify in the track. */ +struct native NotifyTrackKey +{ + var float Time; + var AnimNotify Notify; +}; + +/** Array of notifies to fire off. */ +var array NotifyTrack; + +defaultproperties +{ + TrackInstClass=class'Engine.InterpTrackInstNotify' + TrackTitle="Notify" +} diff --git a/Engine/Classes/InterpTrackParticleReplay.uc b/Engine/Classes/InterpTrackParticleReplay.uc new file mode 100644 index 0000000..9d71b8f --- /dev/null +++ b/Engine/Classes/InterpTrackParticleReplay.uc @@ -0,0 +1,87 @@ +class InterpTrackParticleReplay extends InterpTrack + native(Interpolation); + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * + * This track implements support for creating and playing back captured particle system data + */ + +cpptext +{ + // InterpTrack interface + virtual INT GetNumKeyframes() const; + virtual void GetTimeRange(FLOAT& StartTime, FLOAT& EndTime) const; + virtual FLOAT GetTrackEndTime() const; + virtual FLOAT GetKeyframeTime(INT KeyIndex) const; + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual INT SetKeyframeTime(INT KeyIndex, FLOAT NewKeyTime, UBOOL bUpdateOrder=true); + virtual void RemoveKeyframe(INT KeyIndex); + virtual INT DuplicateKeyframe(INT KeyIndex, FLOAT NewKeyTime); + virtual UBOOL GetClosestSnapPosition(FLOAT InPosition, TArray &IgnoreKeys, FLOAT& OutPosition); + + virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + + /** Get the name of the class used to help out when adding tracks, keys, etc. in UnrealEd. + * @return String name of the helper class.*/ + virtual const FString GetEdHelperClassName() const; + + virtual class UMaterial* GetTrackIcon() const; + + /** Whether or not this track is allowed to be used on static actors. */ + virtual UBOOL AllowStaticActors() { return TRUE; } + + /** + * Lets the interface object know that we are beginning a drag operation. + */ + virtual void BeginDrag(FInterpEdInputData &InputData); + + /** + * Lets the interface object know that we are ending a drag operation. + */ + virtual void EndDrag(FInterpEdInputData &InputData); + + /** + * @return Returns the mouse cursor to display when this input interface is moused over. + */ + EMouseCursor GetMouseCursor(FInterpEdInputData &InputData); + + /** + * Called when an object is dragged. + */ + void ObjectDragged(FInterpEdInputData& InputData); + + virtual void DrawTrack( FCanvas* Canvas, UInterpGroup* Group, const FInterpTrackDrawParams& Params ); +} + + +/** Data for a single key in this track */ +struct native ParticleReplayTrackKey +{ + /** Position along timeline */ + var float Time; + + /** Time length this clip should be captured/played for */ + var() float Duration; + + /** Replay clip ID number that identifies the clip we should capture to or playback from */ + var() int ClipIDNumber; +}; + +/** Array of keys */ +var editinline array TrackKeys; + +/** True in the editor if track should be used to capture replay frames instead of play them back */ +var transient editoronly const bool bIsCapturingReplay; + +/** Current replay fixed time quantum between frames (one over frame rate) */ +var transient editoronly const float FixedTimeStep; + + +defaultproperties +{ + TrackInstClass=class'Engine.InterpTrackInstParticleReplay' + TrackTitle="Particle Replay" +} diff --git a/Engine/Classes/InterpTrackSkelControlScale.uc b/Engine/Classes/InterpTrackSkelControlScale.uc new file mode 100644 index 0000000..865ffcb --- /dev/null +++ b/Engine/Classes/InterpTrackSkelControlScale.uc @@ -0,0 +1,23 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackSkelControlScale extends InterpTrackFloatBase + native(Interpolation); + +cpptext +{ + // InterpTrack interface + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); +} + +/** Name of property in Group Actor which this track mill modify over time. */ +var() name SkelControlName; + +defaultproperties +{ + TrackInstClass=class'Engine.InterpTrackInstSkelControlScale' + TrackTitle="SkelControl Scale" + bIsAnimControlTrack=true +} diff --git a/Engine/Classes/InterpTrackSkelControlStrength.uc b/Engine/Classes/InterpTrackSkelControlStrength.uc new file mode 100644 index 0000000..e15568f --- /dev/null +++ b/Engine/Classes/InterpTrackSkelControlStrength.uc @@ -0,0 +1,23 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackSkelControlStrength extends InterpTrackFloatBase + native(Interpolation); + +cpptext +{ + // InterpTrack interface + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); +} + +/** Name of property in Group Actor which this track mill modify over time. */ +var() name SkelControlName; + +defaultproperties +{ + TrackInstClass=class'Engine.InterpTrackInstSkelControlStrength' + TrackTitle="SkelControl Strength" + bIsAnimControlTrack=true +} diff --git a/Engine/Classes/InterpTrackSlomo.uc b/Engine/Classes/InterpTrackSlomo.uc new file mode 100644 index 0000000..38f0d64 --- /dev/null +++ b/Engine/Classes/InterpTrackSlomo.uc @@ -0,0 +1,28 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackSlomo extends InterpTrackFloatBase + native(Interpolation); + +cpptext +{ + // InterpTrack interface + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual void UpdateKeyframe(INT KeyIndex, UInterpTrackInst* TrInst); + virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + virtual void SetTrackToSensibleDefault(); + + virtual class UMaterial* GetTrackIcon() const; + + // InterpTrackSlomo interface + FLOAT GetSlomoFactorAtTime(FLOAT Time); +} + +defaultproperties +{ + bOnePerGroup=true + bDirGroupOnly=true + TrackInstClass=class'Engine.InterpTrackInstSlomo' + TrackTitle="Slomo" +} diff --git a/Engine/Classes/InterpTrackSound.uc b/Engine/Classes/InterpTrackSound.uc new file mode 100644 index 0000000..f857cb9 --- /dev/null +++ b/Engine/Classes/InterpTrackSound.uc @@ -0,0 +1,80 @@ +class InterpTrackSound extends InterpTrackVectorBase + native(Interpolation); + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * + * A track that plays sounds on the groups Actor. + */ + +cpptext +{ + virtual void PostLoad(); + + // InterpTrack interface + virtual INT GetNumKeyframes() const; + virtual void GetTimeRange(FLOAT& StartTime, FLOAT& EndTime) const; + virtual FLOAT GetTrackEndTime() const; + virtual FLOAT GetKeyframeTime(INT KeyIndex) const; + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual INT SetKeyframeTime(INT KeyIndex, FLOAT NewKeyTime, UBOOL bUpdateOrder=true); + virtual void RemoveKeyframe(INT KeyIndex); + virtual INT DuplicateKeyframe(INT KeyIndex, FLOAT NewKeyTime); + virtual UBOOL GetClosestSnapPosition(FLOAT InPosition, TArray &IgnoreKeys, FLOAT& OutPosition); + + virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + virtual void PreviewStopPlayback(class UInterpTrackInst* TrInst); + + /** Get the name of the class used to help out when adding tracks, keys, etc. in UnrealEd. + * @return String name of the helper class.*/ + virtual const FString GetEdHelperClassName() const; + + virtual class UMaterial* GetTrackIcon() const; + virtual void DrawTrack( FCanvas* Canvas, UInterpGroup* Group, const FInterpTrackDrawParams& Params ); + + /** Whether or not this track is allowed to be used on static actors. */ + virtual UBOOL AllowStaticActors() { return TRUE; } + + // InterpTrackSound interface + /** + * Returns the key at the specified position in the track. + */ + struct FSoundTrackKey& GetSoundTrackKeyAtPosition(FLOAT InPosition); + + virtual void SetTrackToSensibleDefault(); +} + +/** Information for one sound in the track. */ +struct native SoundTrackKey +{ + var float Time; + var float Volume; + var float Pitch; + var() SoundCue Sound; + + structdefaultproperties + { + Volume=1.f + Pitch=1.f + } +}; + +/** Array of sounds to play at specific times. */ +var array Sounds; + +/** if set, sound plays only when playing the matinee in reverse instead of when the matinee plays forward */ +var() bool bPlayOnReverse; +/** If true, sounds on this track will not be forced to finish when the matinee sequence finishes. */ +var() bool bContinueSoundOnMatineeEnd; +/** If TRUE, don't show subtitles for sounds played by this track. */ +var() bool bSuppressSubtitles; +/** If true and track is controlling a pawn, makes the pawn "speak" the given audio. */ +var() bool bTreatAsDialogue; + +defaultproperties +{ + TrackInstClass=class'Engine.InterpTrackInstSound' + TrackTitle="Sound" +} diff --git a/Engine/Classes/InterpTrackToggle.uc b/Engine/Classes/InterpTrackToggle.uc new file mode 100644 index 0000000..c1cc7d0 --- /dev/null +++ b/Engine/Classes/InterpTrackToggle.uc @@ -0,0 +1,88 @@ +class InterpTrackToggle extends InterpTrack + native(Interpolation); + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * + * A track containing toggle actions that are triggered as its played back. + */ + +cpptext +{ + // InterpTrack interface + virtual INT GetNumKeyframes() const; + virtual void GetTimeRange(FLOAT& StartTime, FLOAT& EndTime) const; + virtual FLOAT GetTrackEndTime() const; + virtual FLOAT GetKeyframeTime(INT KeyIndex) const; + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual INT SetKeyframeTime(INT KeyIndex, FLOAT NewKeyTime, UBOOL bUpdateOrder=true); + virtual void RemoveKeyframe(INT KeyIndex); + virtual INT DuplicateKeyframe(INT KeyIndex, FLOAT NewKeyTime); + virtual UBOOL GetClosestSnapPosition(FLOAT InPosition, TArray &IgnoreKeys, FLOAT& OutPosition); + + virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + + /** Get the name of the class used to help out when adding tracks, keys, etc. in UnrealEd. + * @return String name of the helper class.*/ + virtual const FString GetEdHelperClassName() const; + + virtual class UMaterial* GetTrackIcon() const; + + /** Whether or not this track is allowed to be used on static actors. */ + virtual UBOOL AllowStaticActors() { return TRUE; } + + virtual void DrawTrack( FCanvas* Canvas, UInterpGroup* Group, const FInterpTrackDrawParams& Params ); +} + +/** Enumeration indicating toggle action */ +enum ETrackToggleAction +{ + ETTA_Off, + ETTA_On, + ETTA_Toggle, + ETTA_Trigger +}; + +/** Information for one toggle in the track. */ +struct native ToggleTrackKey +{ + var float Time; + var() ETrackToggleAction ToggleAction; +}; + +/** Array of events to fire off. */ +var array ToggleTrack; + +/** + * If true, the track will call ActivateSystem on the emitter each update (the old 'incorrect' behavior). + * If false (the default), the System will only be activated if it was previously inactive. + */ +var() bool bActivateSystemEachUpdate; + +/** + * If true, the track will activate the system w/ the 'Just Attached' flag. + */ +var() bool bActivateWithJustAttachedFlag; + +/** If events should be fired when passed playing the sequence forwards. */ +var() bool bFireEventsWhenForwards; + +/** If events should be fired when passed playing the sequence backwards. */ +var() bool bFireEventsWhenBackwards; + +/** If true, events on this track are fired even when jumping forwads through a sequence - for example, skipping a cinematic. */ +var() bool bFireEventsWhenJumpingForwards; + + +defaultproperties +{ + TrackInstClass=class'Engine.InterpTrackInstToggle' + TrackTitle="Toggle" + bActivateSystemEachUpdate=false + bActivateWithJustAttachedFlag=true + bFireEventsWhenForwards=true + bFireEventsWhenBackwards=true + bFireEventsWhenJumpingForwards=true +} diff --git a/Engine/Classes/InterpTrackVectorBase.uc b/Engine/Classes/InterpTrackVectorBase.uc new file mode 100644 index 0000000..3657d7a --- /dev/null +++ b/Engine/Classes/InterpTrackVectorBase.uc @@ -0,0 +1,82 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackVectorBase extends InterpTrack + native(Interpolation) + abstract; + +cpptext +{ + // UObject interface + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + // InterpTrack interface + virtual INT GetNumKeyframes() const; + virtual void GetTimeRange(FLOAT& StartTime, FLOAT& EndTime) const; + virtual FLOAT GetTrackEndTime() const; + virtual FLOAT GetKeyframeTime(INT KeyIndex) const; + virtual INT SetKeyframeTime(INT KeyIndex, FLOAT NewKeyTime, UBOOL bUpdateOrder=true); + virtual void RemoveKeyframe(INT KeyIndex); + virtual INT DuplicateKeyframe(INT KeyIndex, FLOAT NewKeyTime); + virtual UBOOL GetClosestSnapPosition(FLOAT InPosition, TArray &IgnoreKeys, FLOAT& OutPosition); + + virtual FColor GetKeyframeColor(INT KeyIndex) const; + + // FCurveEdInterface interface + virtual INT GetNumKeys(); + virtual INT GetNumSubCurves() const; + + /** + * Provides the color for the sub-curve button that is present on the curve tab. + * + * @param SubCurveIndex The index of the sub-curve. Cannot be negative nor greater or equal to the number of sub-curves. + * @param bIsSubCurveHidden Is the curve hidden? + * @return The color associated to the given sub-curve index. + */ + virtual FColor GetSubCurveButtonColor(INT SubCurveIndex, UBOOL bIsSubCurveHidden) const; + + virtual FLOAT GetKeyIn(INT KeyIndex); + virtual FLOAT GetKeyOut(INT SubIndex, INT KeyIndex); + virtual void GetInRange(FLOAT& MinIn, FLOAT& MaxIn); + virtual void GetOutRange(FLOAT& MinOut, FLOAT& MaxOut); + + /** + * Provides the color for the given key at the given sub-curve. + * + * @param SubIndex The index of the sub-curve + * @param KeyIndex The index of the key in the sub-curve + * @param[in] CurveColor The color of the curve + * @return The color that is associated the given key at the given sub-curve + */ + virtual FColor GetKeyColor(INT SubIndex, INT KeyIndex, const FColor& CurveColor); + + virtual BYTE GetKeyInterpMode(INT KeyIndex); + virtual void GetTangents(INT SubIndex, INT KeyIndex, FLOAT& ArriveTangent, FLOAT& LeaveTangent); + virtual FLOAT EvalSub(INT SubIndex, FLOAT InVal); + + virtual INT CreateNewKey(FLOAT KeyIn); + virtual void DeleteKey(INT KeyIndex); + + virtual INT SetKeyIn(INT KeyIndex, FLOAT NewInVal); + virtual void SetKeyOut(INT SubIndex, INT KeyIndex, FLOAT NewOutVal); + virtual void SetKeyInterpMode(INT KeyIndex, EInterpCurveMode NewMode); + virtual void SetTangents(INT SubIndex, INT KeyIndex, FLOAT ArriveTangent, FLOAT LeaveTangent); + + /** Returns TRUE if this curve uses legacy tangent/interp algorithms and may be 'upgraded' */ + virtual UBOOL UsingLegacyInterpMethod() const; + + /** 'Upgrades' this curve to use the latest tangent/interp algorithms (usually, will 'bake' key tangents.) */ + virtual void UpgradeInterpMethod(); +} + +/** Actually track data containing keyframes of a vector as it varies over time. */ +var InterpCurveVector VectorTrack; + +/** Tension of curve, used for keypoints using automatic tangents. */ +var() float CurveTension; + +defaultproperties +{ + TrackTitle="Generic Vector Track" + CurveTension=0.0 +} diff --git a/Engine/Classes/InterpTrackVectorMaterialParam.uc b/Engine/Classes/InterpTrackVectorMaterialParam.uc new file mode 100644 index 0000000..09c21d8 --- /dev/null +++ b/Engine/Classes/InterpTrackVectorMaterialParam.uc @@ -0,0 +1,41 @@ +class InterpTrackVectorMaterialParam extends InterpTrackVectorBase + native(Interpolation); + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +cpptext +{ + virtual void PreSave(); + virtual void PostLoad(); + virtual void PreEditChange(UProperty* PropertyThatWillChange); + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual void PostDuplicate(); + + // InterpTrack interface + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + + //virtual class UMaterial* GetTrackIcon() const; +} + +/** materials whose parameters we want to change and the references to those materials + * that need to be given MICs in the same level, compiled at save time + */ +var() const array Materials; +var deprecated const MaterialInterface Material; +/** Name of parameter in the MaterialInstance which this track will modify over time. */ +var() name ParamName; + +/** @compatibility: indicates we need to gather material references on first use + * (can't do in PostLoad() because Actors initialize components array in their own PostLoad() which might not have been called yet) + */ +var transient bool bNeedsMaterialRefsUpdate; + +defaultproperties +{ + TrackInstClass=class'Engine.InterpTrackInstVectorMaterialParam' + TrackTitle="Vector Material Param" +} diff --git a/Engine/Classes/InterpTrackVectorProp.uc b/Engine/Classes/InterpTrackVectorProp.uc new file mode 100644 index 0000000..b33c158 --- /dev/null +++ b/Engine/Classes/InterpTrackVectorProp.uc @@ -0,0 +1,32 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class InterpTrackVectorProp extends InterpTrackVectorBase + native(Interpolation); + +cpptext +{ + /** Returns the property name */ + virtual UBOOL GetPropertyName( FName& PropertyNameOut ) const { PropertyNameOut = PropertyName; return TRUE; } + + // InterpTrack interface + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual void UpdateKeyframe(INT KeyIndex, UInterpTrackInst* TrInst); + virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + + /** Get the name of the class used to help out when adding tracks, keys, etc. in UnrealEd. + * @return String name of the helper class.*/ + virtual const FString GetEdHelperClassName() const; + + virtual class UMaterial* GetTrackIcon() const; +} + +/** Name of property in Group Actor which this track mill modify over time. */ +var() editconst name PropertyName; + +defaultproperties +{ + TrackInstClass=class'Engine.InterpTrackInstVectorProp' + TrackTitle="Vector Property" +} diff --git a/Engine/Classes/InterpTrackVisibility.uc b/Engine/Classes/InterpTrackVisibility.uc new file mode 100644 index 0000000..0711bf3 --- /dev/null +++ b/Engine/Classes/InterpTrackVisibility.uc @@ -0,0 +1,99 @@ +class InterpTrackVisibility extends InterpTrack + native(Interpolation); + +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * + * This track implements support for setting or toggling the visibility of the associated actor + */ + +cpptext +{ + // InterpTrack interface + virtual INT GetNumKeyframes() const; + virtual void GetTimeRange(FLOAT& StartTime, FLOAT& EndTime) const; + virtual FLOAT GetTrackEndTime() const; + virtual FLOAT GetKeyframeTime(INT KeyIndex) const; + virtual INT AddKeyframe(FLOAT Time, UInterpTrackInst* TrInst, EInterpCurveMode InitInterpMode); + virtual INT SetKeyframeTime(INT KeyIndex, FLOAT NewKeyTime, UBOOL bUpdateOrder=true); + virtual void RemoveKeyframe(INT KeyIndex); + virtual INT DuplicateKeyframe(INT KeyIndex, FLOAT NewKeyTime); + virtual UBOOL GetClosestSnapPosition(FLOAT InPosition, TArray &IgnoreKeys, FLOAT& OutPosition); + + virtual void PreviewUpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst); + virtual void UpdateTrack(FLOAT NewPosition, UInterpTrackInst* TrInst, UBOOL bJump); + + /** Get the name of the class used to help out when adding tracks, keys, etc. in UnrealEd. + * @return String name of the helper class.*/ + virtual const FString GetEdHelperClassName() const; + + virtual class UMaterial* GetTrackIcon() const; + + /** Whether or not this track is allowed to be used on static actors. */ + virtual UBOOL AllowStaticActors() { return TRUE; } + + virtual void DrawTrack( FCanvas* Canvas, UInterpGroup* Group, const FInterpTrackDrawParams& Params ); +} + + +/** Visibility track actions */ +enum EVisibilityTrackAction +{ + /** Hides the object */ + EVTA_Hide, + + /** Shows the object */ + EVTA_Show, + + /** Toggles visibility of the object */ + EVTA_Toggle +}; + + + +/** Required condition for firing this event */ +enum EVisibilityTrackCondition +{ + /** Always play this event */ + EVTC_Always, + + /** Only play this event when extreme content (gore) is enabled */ + EVTC_GoreEnabled, + + /** Only play this event when extreme content (gore) is disabled */ + EVTC_GoreDisabled +}; + + + +/** Information for one toggle in the track. */ +struct native VisibilityTrackKey +{ + var float Time; + var() EVisibilityTrackAction Action; + + /** Condition that must be satisfied for this key event to fire */ + var EVisibilityTrackCondition ActiveCondition; +}; + +/** Array of events to fire off. */ +var array VisibilityTrack; + +/** If events should be fired when passed playing the sequence forwards. */ +var() bool bFireEventsWhenForwards; + +/** If events should be fired when passed playing the sequence backwards. */ +var() bool bFireEventsWhenBackwards; + +/** If true, events on this track are fired even when jumping forwads through a sequence - for example, skipping a cinematic. */ +var() bool bFireEventsWhenJumpingForwards; + +defaultproperties +{ + TrackInstClass=class'Engine.InterpTrackInstVisibility' + TrackTitle="Visibility" + bFireEventsWhenForwards=true + bFireEventsWhenBackwards=true + bFireEventsWhenJumpingForwards=true +} diff --git a/Engine/Classes/Inventory.uc b/Engine/Classes/Inventory.uc new file mode 100644 index 0000000..428fb72 --- /dev/null +++ b/Engine/Classes/Inventory.uc @@ -0,0 +1,261 @@ +//============================================================================= +// Inventory +// +// Inventory is the parent class of all actors that can be carried by other actors. +// Inventory items are placed in the holding actor's inventory chain, a linked list +// of inventory actors. Each inventory class knows what pickup can spawn it (its +// PickupClass). When tossed out (using the DropFrom() function), inventory items +// spawn a DroppedPickup actor to hold them. +// +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= + +class Inventory extends Actor + abstract + native + nativereplication; + +//----------------------------------------------------------------------------- + +var Inventory Inventory; // Next Inventory in Linked List +var InventoryManager InvManager; +var localized string ItemName; + +/** if true, this inventory item should be dropped if the owner dies */ +var bool bDropOnDeath; + +//----------------------------------------------------------------------------- +// Pickup related properties +var bool bDelayedSpawn; +var bool bPredictRespawns; // high skill bots may predict respawns for this item +var() float RespawnTime; // Respawn after this time, 0 for instant. +var float MaxDesireability; // Maximum desireability this item will ever have. +var() localized string PickupMessage; // Human readable description when picked up. +var() SoundCue PickupSound; +var() string PickupForce; +var class DroppedPickupClass; +var PrimitiveComponent DroppedPickupMesh; +var PrimitiveComponent PickupFactoryMesh; +var ParticleSystemComponent DroppedPickupParticles; + +cpptext +{ + // AActor interface. + INT* GetOptimizedRepList( BYTE* InDefault, FPropertyRetirement* Retire, INT* Ptr, UPackageMap* Map, UActorChannel* Channel ); +} + +// Network replication. +replication +{ + // Things the server should send to the client. + if ( (Role==ROLE_Authority) && bNetDirty && bNetOwner ) + Inventory, InvManager; +} + +simulated function String GetHumanReadableName() +{ + return Default.ItemName; +} + +event Destroyed() +{ + // Notify Pawn's inventory manager that this item is being destroyed (remove from inventory manager). + if ( Pawn(Owner) != None && Pawn(Owner).InvManager != None ) + { + Pawn(Owner).InvManager.RemoveFromInventory( Self ); + } +} + +/* Inventory has an AI interface to allow AIControllers, such as bots, to assess the + * desireability of acquiring that pickup. The BotDesireability() method returns a + * float typically between 0 and 1 describing how valuable the pickup is to the + * AIController. This method is called when an AIController uses the + * FindPathToBestInventory() navigation intrinsic. + * @param PickupHolder - Actor in the world that holds the inventory item (usually DroppedPickup or PickupFactory) + * @param P - the Pawn the AI is evaluating this item for + * @param C - the Controller that is evaluating this item. Might not be P.Controller - the AI may choose to + * evaluate the usability of the item by the driver Pawn of a vehicle it is currently controlling, for example + */ +static function float BotDesireability(Actor PickupHolder, Pawn P, Controller C) +{ + local Inventory AlreadyHas; + local float desire; + + desire = Default.MaxDesireability; + + if ( Default.RespawnTime < 10 ) + { + AlreadyHas = P.FindInventoryType(Default.class); + if ( AlreadyHas != None ) + { + return -1; + } + } + return desire; +} + +/* DetourWeight() +value of this path to take a quick detour (usually 0, used when on route to distant objective, but want to grab inventory for example) +*/ +static function float DetourWeight(Pawn Other,float PathWeight) +{ + return 0; +} + +/* GiveTo: + Give this Inventory Item to this Pawn. + InvManager.AddInventory implements the correct behavior. +*/ +final function GiveTo( Pawn Other ) +{ + if ( Other != None && Other.InvManager != None ) + { + Other.InvManager.AddInventory( Self ); + } +} + +/* AnnouncePickup + This inventory item was just picked up (from a DroppedPickup or PickupFactory) +*/ +function AnnouncePickup(Pawn Other) +{ + Other.HandlePickup(self); + + if (PickupSound != None) + { + Other.PlaySound( PickupSound ); + } +} + +/** + * This Inventory Item has just been given to this Pawn + * (server only) + * + * @param thisPawn new Inventory owner + * @param bDoNotActivate If true, this item will not try to activate + */ +function GivenTo( Pawn thisPawn, optional bool bDoNotActivate ) +{ + `LogInv(thisPawn @ "Weapon:" @ Self); + Instigator = ThisPawn; + ClientGivenTo(thisPawn, bDoNotActivate); +} + +/** + * This Inventory Item has just been given to this Pawn + * (owning client only) + * + * @param thisPawn new Inventory owner + * @param bDoNotActivate If true, this item will not try to activate + */ +reliable client function ClientGivenTo(Pawn NewOwner, bool bDoNotActivate) +{ + // make sure Owner is set - if Inventory item fluctuates Owners there is a chance this might not get updated normally + SetOwner(NewOwner); + Instigator = NewOwner; + + `LogInv(NewOwner @ "Weapon:" @ Self); + + if( NewOwner != None && NewOwner.Controller != None ) + { + NewOwner.Controller.NotifyAddInventory(Self); + } +} + +/** + * Event called when Item is removed from Inventory Manager. + * Network: Authority + */ +function ItemRemovedFromInvManager(); + + +/** DenyPickupQuery + Function which lets existing items in a pawn's inventory + prevent the pawn from picking something up. + * @param ItemClass Class of Inventory our Owner is trying to pick up + * @param Pickup the Actor containing that item (this may be a PickupFactory or it may be a DroppedPickup) + * @return true to abort pickup or if item handles pickup + */ +function bool DenyPickupQuery(class ItemClass, Actor Pickup) +{ + // By default, you can only carry a single item of a given class. + if ( ItemClass == class ) + { + return true; + } + + return false; +} + + +/** + * Drop this item out in to the world + * + * @param StartLocation - The World Location to drop this item from + * @param StartVelocity - The initial velocity for the item when dropped + */ +function DropFrom(vector StartLocation, vector StartVelocity) +{ + local DroppedPickup P; + + if( Instigator != None && Instigator.InvManager != None ) + { + Instigator.InvManager.RemoveFromInventory(Self); + } + + // if cannot spawn a pickup, then destroy and quit + if( DroppedPickupClass == None || DroppedPickupMesh == None ) + { + Destroy(); + return; + } + + P = Spawn(DroppedPickupClass,,, StartLocation); + if( P == None ) + { + Destroy(); + return; + } + + P.SetPhysics(PHYS_Falling); + P.Inventory = self; + P.InventoryClass = class; + P.Velocity = StartVelocity; + P.Instigator = Instigator; + P.SetPickupMesh(DroppedPickupMesh); + P.SetPickupParticles(DroppedPickupParticles); + + Instigator = None; + GotoState(''); +} + +static function string GetLocalString( + optional int Switch, + optional PlayerReplicationInfo RelatedPRI_1, + optional PlayerReplicationInfo RelatedPRI_2 + ) +{ + return Default.PickupMessage; +} + +defaultproperties +{ + Begin Object Class=SpriteComponent Name=Sprite + Sprite=Texture2D'EditorResources.S_Actor' + HiddenGame=True + AlwaysLoadOnClient=False + AlwaysLoadOnServer=False + SpriteCategoryName="Inventory" + End Object + Components.Add(Sprite) + + bOnlyDirtyReplication=true + bOnlyRelevantToOwner=true + NetPriority=1.4 + bHidden=true + Physics=PHYS_None + bReplicateMovement=false + RemoteRole=ROLE_SimulatedProxy + DroppedPickupClass=class'DroppedPickup' + MaxDesireability=0.1000 +} diff --git a/Engine/Classes/InventoryManager.uc b/Engine/Classes/InventoryManager.uc new file mode 100644 index 0000000..bd0841a --- /dev/null +++ b/Engine/Classes/InventoryManager.uc @@ -0,0 +1,800 @@ +//============================================================================= +// InventoryManager +// Base class to manage Pawn's inventory +// This provides a simple interface to control and interact with the Pawn's inventory, +// such as weapons, items and ammunition. +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= + +class InventoryManager extends Actor + native; + + +/** First inventory item in inventory linked list */ +var Inventory InventoryChain; + +/** + * Player will switch to PendingWeapon, once the current weapon has been put down. + * @fixme laurent -- PendingWeapon should be made protected, because too many bugs result by setting this variable directly. + * It's only safe to read it, but to change it, SetCurrentWeapon() should be used. + */ +var Weapon PendingWeapon; + +var Weapon LastAttemptedSwitchToWeapon; + +/** if true, don't allow player to put down weapon without switching to another one */ +var bool bMustHoldWeapon; + +/** Holds the current "Fire" status for both firing modes */ +var private Array PendingFire; + +// +// Network replication. +// +replication +{ + + if ( (!bSkipActorPropertyReplication || bNetInitial) && (Role==ROLE_Authority) && bNetDirty && bNetOwner ) + InventoryChain; +} + +event PostBeginPlay() +{ + Super.PostBeginPlay(); + Instigator = Pawn(Owner); +} + +simulated function INT GetPendingFireLength(Weapon InWeapon) +{ + return PendingFire.Length; +} + +simulated function SetPendingFire(Weapon InWeapon, int InFiringMode) +{ + if( InFiringMode < PendingFire.Length ) + { + PendingFire[InFiringMode] = 1; + } +} + +simulated function ClearPendingFire(Weapon InWeapon, int InFiringMode) +{ + if( InFiringMode < PendingFire.Length ) + { + PendingFire[InFiringMode] = 0; + } +} + +simulated final function bool IsPendingFire(Weapon InWeapon, INT InFiringMode) +{ + return bool(PendingFire[InFiringMode]); +} + +simulated function ClearAllPendingFire(Weapon InWeapon) +{ + local int i; + for(i=0; i BaseClass, out Inventory Inv ); + +/** + * Setup Inventory for Pawn P. + * Override this to change inventory assignment (from a pawn to another) + * Network: Server only + */ +function SetupFor(Pawn P) +{ + Instigator = P; + SetOwner(P); +} + + +/** Event called when inventory manager is destroyed, called from Pawn.Destroyed() */ +event Destroyed() +{ + DiscardInventory(); +} + + +/** + * Handle Pickup. Can Pawn pickup this item? + * + * @param ItemClass Class of Inventory our Owner is trying to pick up + * @param Pickup the Actor containing that item (this may be a PickupFactory or it may be a DroppedPickup) + * + * @return whether or not the Pickup actor should give its item to Other + */ +function bool HandlePickupQuery(class ItemClass, Actor Pickup) +{ + local Inventory Inv; + + if( InventoryChain == None ) + { + return TRUE; + } + + // Give other Inventory Items a chance to deny this pickup + ForEach InventoryActors(class'Inventory', Inv) + { + if( Inv.DenyPickupQuery(ItemClass, Pickup) ) + { + return FALSE; + } + } + return TRUE; +} + + +/** + * returns the inventory item of the requested class if it exists in this inventory manager. + * @param DesiredClass class of inventory item we're trying to find. + * @param bAllowSubclass whether subclasses of the desired class are acceptable + * @return Inventory actor if found, None otherwise. + */ +simulated event Inventory FindInventoryType(class DesiredClass, optional bool bAllowSubclass) +{ + local Inventory Inv; + + ForEach InventoryActors(DesiredClass, Inv) + { + if (bAllowSubclass || Inv.Class == DesiredClass) + { + return Inv; + } + } + return None; +} + + +/** + * Spawns a new Inventory actor of NewInventoryItemClass type, and adds it to the Inventory Manager. + * @param NewInventoryItemClass Class of inventory item to spawn and add. + * @return Inventory actor, None if couldn't be spawned. + */ +simulated function Inventory CreateInventory(class NewInventoryItemClass, optional bool bDoNotActivate) +{ + local Inventory Inv; + + if( NewInventoryItemClass != None ) + { + inv = Spawn(NewInventoryItemClass, Owner); + if( inv != None ) + { + if( !AddInventory(Inv, bDoNotActivate) ) + { + `warn("InventoryManager::CreateInventory - Couldn't Add newly created inventory" @ Inv); + Inv.Destroy(); + Inv = None; + } + } + else + { + `warn("InventoryManager::CreateInventory - Couldn't spawn inventory" @ NewInventoryItemClass); + } + } + + return Inv; +} + +/** + * Adds an existing inventory item to the list. + * Returns true to indicate it was added, false if it was already in the list. + * + * @param NewItem Item to add to inventory manager. + * @return true if item was added, false otherwise. + */ +simulated function bool AddInventory(Inventory NewItem, optional bool bDoNotActivate) +{ + local Inventory Item, LastItem; + + // The item should not have been destroyed if we get here. + if( (NewItem != None) && !NewItem.bDeleteMe ) + { + // if we don't have an inventory list, start here + if( InventoryChain == None ) + { + InventoryChain = newItem; + } + else + { + // Skip if already in the inventory. + for (Item = InventoryChain; Item != None; Item = Item.Inventory) + { + if( Item == NewItem ) + { + return FALSE; + } + LastItem = Item; + } + LastItem.Inventory = NewItem; + } + + `LogInv("adding" @ NewItem @ "bDoNotActivate:" @ bDoNotActivate); + + NewItem.SetOwner( Instigator ); + NewItem.Instigator = Instigator; + NewItem.InvManager = Self; + NewItem.GivenTo( Instigator, bDoNotActivate); + + // Trigger inventory event + Instigator.TriggerEventClass(class'SeqEvent_GetInventory', NewItem); + return TRUE; + } + + return FALSE; +} + + +/** + * Attempts to remove an item from the inventory list if it exists. + * + * @param Item Item to remove from inventory + */ +simulated function RemoveFromInventory(Inventory ItemToRemove) +{ + local Inventory Item; + local bool bFound; + + if( ItemToRemove != None ) + { + if( InventoryChain == ItemToRemove ) + { + bFound = TRUE; + InventoryChain = ItemToRemove.Inventory; + } + else + { + // If this item is in our inventory chain, unlink it. + for(Item = InventoryChain; Item != None; Item = Item.Inventory) + { + if( Item.Inventory == ItemToRemove ) + { + bFound = TRUE; + Item.Inventory = ItemToRemove.Inventory; + break; + } + } + } + + if( bFound ) + { + ItemToRemove.ItemRemovedFromInvManager(); + ItemToRemove.SetOwner(None); + ItemToRemove.Inventory = None; + } + + // make sure we don't have other references to the item + if( ItemToRemove == Instigator.Weapon ) + { + Instigator.Weapon = None; + } + + if (Instigator.Health > 0 && Instigator.Weapon == None) + { + if (PendingWeapon != None && PendingWeapon != ItemToRemove) + { + `LogInv("Removed current weapon while changing weapons, call ChangedWeapon"); + ChangedWeapon(); + } + else if(Instigator.Controller != None) + { + `LogInv("Calling ClientSwitchToBestWeapon to make sure a weapon is brought up"); + Instigator.Controller.ClientSwitchToBestWeapon(TRUE); + } + } + } +} + +/** + * Discard full inventory, generally because the owner died + */ +simulated event DiscardInventory() +{ + local Inventory Inv; + local vector TossVelocity; + local bool bBelowKillZ; + + `LogInv(""); + + // don't drop any inventory if below KillZ or out of world + bBelowKillZ = (Instigator == None) || (Instigator.Location.Z < WorldInfo.KillZ); + + ForEach InventoryActors(class'Inventory', Inv) + { + if( Inv.bDropOnDeath && !bBelowKillZ ) + { + TossVelocity = vector(Instigator.GetViewRotation()); + TossVelocity = TossVelocity * ((Instigator.Velocity dot TossVelocity) + 500.f) + 250.f * VRand() + vect(0,0,250); + Inv.DropFrom(Instigator.Location, TossVelocity); + } + else + { + Inv.Destroy(); + } + } + + // Clear reference to Weapon + Instigator.Weapon = None; + + // Clear reference to PendingWeapon + PendingWeapon = None; +} + +/** called when our owner is killed */ +function OwnerDied() +{ + Destroy(); + if (Instigator.InvManager == self) + { + Instigator.InvManager = None; + } +} + +/** + * Hook called from HUD actor. Gives access to HUD and Canvas + * + * @param H HUD + */ +simulated function DrawHud( HUD H ); + +/** + * Returns a weight reflecting the desire to use the + * given weapon, used for AI and player best weapon + * selection. + * + * @param Weapon W + * @return Weapon rating (range -1.f to 1.f) + */ +simulated function float GetWeaponRatingFor( Weapon W ) +{ + local float Rating; + + if ( !W.HasAnyAmmo() ) + return -1; + + if (!Instigator.IsHumanControlled()) + { + Rating = W.GetAIRating(); + // tend to stick with same weapon + if (W == Instigator.Weapon && Instigator.Controller != None && Instigator.Controller.Enemy != None) + { + Rating += 0.21; + } + } + else + { + Rating = 1; + } + + return Rating; +} + + +/** + * returns the best weapon for this Pawn in loadout + */ +simulated function Weapon GetBestWeapon( optional bool bForceADifferentWeapon ) +{ + local Weapon W, BestWeapon; + local float Rating, BestRating; + + ForEach InventoryActors( class'Weapon', W ) + { + if( w.HasAnyAmmo() ) + { + if( bForceADifferentWeapon && + W == Instigator.Weapon ) + { + continue; + } + + Rating = W.GetWeaponRating(); + if( BestWeapon == None || + Rating > BestRating ) + { + BestWeapon = W; + BestRating = Rating; + } + } + } + + return BestWeapon; +} + + +/** + * Switch to best weapon available in loadout + * Network: LocalPlayer + */ +simulated function SwitchToBestWeapon( optional bool bForceADifferentWeapon ) +{ + local Weapon BestWeapon; + + `LogInv("bForceADifferentWeapon:" @ bForceADifferentWeapon); + + // if we don't already have a pending weapon, + if( bForceADifferentWeapon || + PendingWeapon == None || + (AIController(Instigator.Controller) != None) ) + { + // figure out the new weapon to bring up + BestWeapon = GetBestWeapon( bForceADifferentWeapon ); + + if( BestWeapon == None ) + { + return; + } + + // if it matches our current weapon then don't bother switching + if( BestWeapon == Instigator.Weapon ) + { + BestWeapon = None; + PendingWeapon = None; + Instigator.Weapon.Activate(); + } + } + + // stop any current weapon fire + Instigator.Controller.StopFiring(); + + // and activate the new pending weapon + SetCurrentWeapon(BestWeapon); +} + + +/** + * Switches to Previous weapon + * Network: Client + */ +simulated function PrevWeapon() +{ + local Weapon CandidateWeapon, StartWeapon, W; + + StartWeapon = Instigator.Weapon; + if ( PendingWeapon != None ) + { + StartWeapon = PendingWeapon; + } + + // Get previous + ForEach InventoryActors( class'Weapon', W ) + { + if ( W == StartWeapon ) + { + break; + } + CandidateWeapon = W; + } + + // if none found, get last + if ( CandidateWeapon == None ) + { + ForEach InventoryActors( class'Weapon', W ) + { + CandidateWeapon = W; + } + } + + // If same weapon, do not change + if ( CandidateWeapon == Instigator.Weapon ) + { + return; + } + + SetCurrentWeapon(CandidateWeapon); +} + + +/** + * Switches to Next weapon + * Network: Client + */ +simulated function NextWeapon() +{ + local Weapon StartWeapon, CandidateWeapon, W; + local bool bBreakNext; + + StartWeapon = Instigator.Weapon; + if( PendingWeapon != None ) + { + StartWeapon = PendingWeapon; + } + + ForEach InventoryActors( class'Weapon', W ) + { + if( bBreakNext || (StartWeapon == None) ) + { + CandidateWeapon = W; + break; + } + if( W == StartWeapon ) + { + bBreakNext = true; + } + } + + if( CandidateWeapon == None ) + { + ForEach InventoryActors( class'Weapon', W ) + { + CandidateWeapon = W; + break; + } + } + // If same weapon, do not change + if( CandidateWeapon == Instigator.Weapon ) + { + return; + } + + SetCurrentWeapon(CandidateWeapon); +} + + +/** + * Set DesiredWeapon as Current (Active) Weapon. + * Network: LocalPlayer + * + * @param DesiredWeapon, Desired weapon to assign to player + */ +reliable client function SetCurrentWeapon(Weapon DesiredWeapon) +{ + // Switch to this weapon + InternalSetCurrentWeapon(DesiredWeapon); + + // Tell the server we have changed the pending weapon + if( Role < Role_Authority ) + { + ServerSetCurrentWeapon(DesiredWeapon); + } +} + +/** + * ServerSetCurrentWeapon begins the Putdown sequence on the server. This function makes + * the assumption that if TryPutDown succeeded on the client, it will succeed on the server. + * This function shouldn't be called from anywhere except SetCurrentWeapon + * + * Network: Dedicated Server + */ +reliable server function ServerSetCurrentWeapon(Weapon DesiredWeapon) +{ + InternalSetCurrentWeapon(DesiredWeapon); +} + +simulated private function InternalSetCurrentWeapon(Weapon DesiredWeapon) +{ + local Weapon PrevWeapon; + + PrevWeapon = Instigator.Weapon; + + `LogInv("PrevWeapon:" @ PrevWeapon @ "DesiredWeapon:" @ DesiredWeapon); + + // Make sure we are switching to a new weapon + // Handle the case where we're selecting again a weapon we've just deselected + if( PrevWeapon != None && DesiredWeapon == PrevWeapon && !PrevWeapon.IsInState('WeaponPuttingDown') ) + { + if(!DesiredWeapon.IsInState('Inactive') && !DesiredWeapon.IsInState('PendingClientWeaponSet')) + { + `LogInv("DesiredWeapon == PrevWeapon - abort"@DesiredWeapon.GetStateName()); + return; + } + } + + // Set the new weapon as pending + SetPendingWeapon(DesiredWeapon); + + // if there is an old weapon handle it first. + if( PrevWeapon != None && PrevWeapon != DesiredWeapon && !PrevWeapon.bDeleteMe && !PrevWeapon.IsInState('Inactive') ) + { + // Try to put the weapon down. + `LogInv("Try to put down previous weapon first."); + PrevWeapon.TryPutdown(); + } + else + { + // We don't have a weapon, force the call to ChangedWeapon + ChangedWeapon(); + } +} + + +/** + * Set the pending weapon for switching. + * This shouldn't be called outside of SetCurrentWeapon() + */ +simulated function SetPendingWeapon(Weapon DesiredWeapon) +{ + `LogInv("SetPendingWeapon to" @ DesiredWeapon); + // set the new weapon as pending + PendingWeapon = DesiredWeapon; +} + + +/** Prevents player from being without a weapon. */ +simulated function bool CancelWeaponChange() +{ + `LogInv(`showvar(PendingWeapon)); + // if PendingWeapon is None, prevent instigator from having no weapon, + // so re-activate current weapon. + if( PendingWeapon == None && bMustHoldWeapon ) + { + PendingWeapon = Instigator.Weapon; + } + + return FALSE; +} + +/** Clear pending weapon, put it in a good state. */ +simulated function ClearPendingWeapon() +{ + `LogInv(`showvar(PendingWeapon)); + + if (PendingWeapon != None) + { + PendingWeapon.GotoState('Inactive'); + PendingWeapon = None; + } +} + + +/** + * ChangedWeapon is called when the current weapon is finished being deactivated + */ +simulated function ChangedWeapon() +{ + local Weapon OldWeapon; + + // Save current weapon as old weapon + OldWeapon = Instigator.Weapon; + + // Make sure we can switch to a null weapon, otherwise, reactivate the current weapon + `LogInv(`showvar(PendingWeapon)@`showvar(bMustHoldWeapon)); + if( PendingWeapon == None && bMustHoldWeapon ) + { + if( OldWeapon != None ) + { + OldWeapon.Activate(); + PendingWeapon = OldWeapon; + } + } + + `LogInv("switch from" @ OldWeapon @ "to" @ PendingWeapon); + + // switch to Pending Weapon + Instigator.Weapon = PendingWeapon; + + // Play any Weapon Switch Animations + Instigator.PlayWeaponSwitch(OldWeapon, PendingWeapon); + + // If we are going to an actual weapon, activate it. + if( PendingWeapon != None ) + { + // Setup the Weapon + PendingWeapon.Instigator = Instigator; + + // Make some noise + if( WorldInfo.Game != None ) + { + Instigator.MakeNoise( 0.1, 'ChangedWeapon' ); + } + + // Activate the Weapon + PendingWeapon.Activate(); + PendingWeapon = None; + } + + // Notify of a weapon change + if( Instigator.Controller != None ) + { + Instigator.Controller.NotifyChangedWeapon(OldWeapon, Instigator.Weapon); + } +} + + +/** + * Weapon just given to a player, check if player should switch to this weapon + * Network: LocalPlayer + * Called from Weapon.ClientWeaponSet() + */ +simulated function ClientWeaponSet(Weapon NewWeapon, bool bOptionalSet, optional bool bDoNotActivate) +{ + local Weapon OldWeapon; + + `LogInv("NewWeapon:" @ NewWeapon @ "bOptionalSet:" @ bOptionalSet @ "bDoNotActivate:" @ bDoNotActivate); + if( !bDoNotActivate ) + { + OldWeapon = Instigator.Weapon; + + // If no current weapon, then set this one + if( OldWeapon == None || OldWeapon.bDeleteMe || OldWeapon.IsInState('Inactive') ) + { + `LogInv("OldWeapon == None or Inactive - Set new weapon right away" @ NewWeapon); + SetCurrentWeapon(NewWeapon); + return; + } + + if( OldWeapon == NewWeapon ) + { + if( NewWeapon.IsInState('PendingClientWeaponSet') ) + { + `LogInv("OldWeapon == NewWeapon - but in PendingClientWeaponSet, so reset." @ NewWeapon); + SetCurrentWeapon(NewWeapon); + } + else + { + `LogInv("OldWeapon == NewWeapon - abort" @ NewWeapon); + } + return; + } + + if( bOptionalSet ) + { + if( OldWeapon.DenyClientWeaponSet() || + (Instigator.IsHumanControlled() && PlayerController(Instigator.Controller).bNeverSwitchOnPickup) ) + { + `LogInv("bOptionalSet && (DenyClientWeaponSet() || bNeverSwitchOnPickup) - abort" @ NewWeapon); + + LastAttemptedSwitchToWeapon = NewWeapon; + return; + } + } + + if( PendingWeapon == None || !PendingWeapon.HasAnyAmmo() || PendingWeapon.GetWeaponRating() < NewWeapon.GetWeaponRating() ) + { + // Compare switch priority and decide if we should switch to new weapon + if( !Instigator.Weapon.HasAnyAmmo() || Instigator.Weapon.GetWeaponRating() < NewWeapon.GetWeaponRating() ) + { + `LogInv("Switch to new weapon:" @ NewWeapon); + SetCurrentWeapon(NewWeapon); + return; + } + } + } + + `LogInv("Send to inactive state" @ NewWeapon); + NewWeapon.GotoState('Inactive'); +} + +simulated function UpdateController() +{ + local Inventory Item; + local Weapon Weap; + + for (Item = InventoryChain; Item != None; Item = Item.Inventory) + { + Weap = Weapon(Item); + if ( Weap != None ) + { + Weap.CacheAIController(); + } + } +} + +defaultproperties +{ + TickGroup=TG_DuringAsyncWork + + bReplicateInstigator=TRUE + RemoteRole=ROLE_SimulatedProxy + bOnlyDirtyReplication=TRUE + bOnlyRelevantToOwner=TRUE + NetPriority=1.4 + bHidden=TRUE + Physics=PHYS_None + bReplicateMovement=FALSE + bStatic=FALSE + bNoDelete=FALSE +} diff --git a/Engine/Classes/JsonObject.uc b/Engine/Classes/JsonObject.uc new file mode 100644 index 0000000..9b403ba --- /dev/null +++ b/Engine/Classes/JsonObject.uc @@ -0,0 +1,117 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * This is a generic JSON object in unrealscript + */ +class JsonObject extends Object + native; + + +/// COMMENT!! + + +var native Map_Mirror ValueMap{TMap}; +var native Map_Mirror ObjectMap{TMap}; + +var native array ValueArray; +var native array ObjectArray; + + +/** + * Looks up an object with the given key in the ObjectMap + * + * @param Key The key to search for + * + * @return A subobject/array inside this object + */ +native function JsonObject GetObject(const string Key); + +/** + * Looks up a value with the given key in the ObjectMap. If it was a number + * in the Json string, this will be prepended with \# (see below helpers) + * + * @param Key The key to search for + * + * @return A string value + */ +native function string GetStringValue(const string Key); + +/** + * @param Key the key to check on this object + * + * @return true if the key exists, false otherwise + */ +native function bool HasKey(const string Key); + +/** + * Helper functions to convert special strings that the decoder will make from numbers + */ +event int GetIntValue(const string Key) +{ + local string Value; + + // look up the key, and skip the \# + Value = Mid(GetStringValue(Key), 2); + return int(Value); +} + +event float GetFloatValue(const string Key) +{ + local string Value; + + // look up the key, and skip the \# + Value = Mid(GetStringValue(Key), 2); + return float(Value); +} + +event bool GetBoolValue(const string Key) +{ + local string Value; + + // look up the key, and skip the \# + Value = Mid(GetStringValue(Key), 2); + return bool(Value); +} + + +/** + * Set an object + */ +native function SetObject(const string Key, JsonObject Object); +native function SetStringValue(const string Key, const string Value); + +/** + * Helper functions to make special strings that the encoder will turn into numbers + */ +event SetIntValue(const string Key, int Value) +{ + SetStringValue(Key, "\\#" $ Value); +} + +event SetFloatValue(const string Key, float Value) +{ + SetStringValue(Key, "\\#" $ Value); +} + +event SetBoolValue(const string Key, bool Value) +{ + SetStringValue(Key, "\\#" $ (Value ? "true" : "false")); +} + +/** + * Encodes an object hierarchy to a string suitable for sending over the web + * + * @param Root The toplevel object in the hierarchy + * + * @return A well-formatted Json string + */ +static native function string EncodeJson(JsonObject Root); + +/** + * Decodes a Json string into an object hierarchy (all needed objects will be created) + * + * @param Str A Json string (probably received from the web) + * + * @return The root object of the resulting hierarchy + */ +static native function JsonObject DecodeJson(const string Str); diff --git a/Engine/Classes/KActor.uc b/Engine/Classes/KActor.uc new file mode 100644 index 0000000..1c7a14b --- /dev/null +++ b/Engine/Classes/KActor.uc @@ -0,0 +1,434 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class KActor extends DynamicSMActor + native(Physics) + nativereplication + placeable + ClassGroup(Physics) + showcategories(Navigation); + +cpptext +{ + // AActor interface + virtual void physRigidBody(FLOAT DeltaTime); + virtual INT* GetOptimizedRepList(BYTE* InDefault, FPropertyRetirement* Retire, INT* Ptr, UPackageMap* Map, UActorChannel* Channel); + virtual void OnRigidBodyCollision(const FRigidBodyCollisionInfo& MyInfo, const FRigidBodyCollisionInfo& OtherInfo, const FCollisionImpactData& RigidCollisionData); + UBOOL ShouldTrace(UPrimitiveComponent* Primitive, AActor *SourceActor, DWORD TraceFlags); + + /** + * Function that gets called from within Map_Check to allow this actor to check itself + * for any potential errors and register them with map check dialog. + */ +#if WITH_EDITOR + virtual void CheckForErrors(); +#endif + + virtual void TickSpecial(FLOAT DeltaSeconds); +} + +var() bool bDamageAppliesImpulse; +var() repnotify bool bWakeOnLevelStart; + +// Impact effects +var ParticleSystemComponent ImpactEffectComponent; +var AudioComponent ImpactSoundComponent; +var AudioComponent ImpactSoundComponent2; // @TODO: This could be turned into a dynamic array; but for the moment just 2 will do. +var float LastImpactTime; +var PhysEffectInfo ImpactEffectInfo; + +// Slide effects +var ParticleSystemComponent SlideEffectComponent; +var AudioComponent SlideSoundComponent; +var bool bCurrentSlide; +var bool bSlideActive; +var float LastSlideTime; +var PhysEffectInfo SlideEffectInfo; + +/** Enable 'Stay upright' torque, that tries to keep Z axis of KActor pointing along world Z */ +var(StayUprightSpring) bool bEnableStayUprightSpring; + +/** Torque applied to try and keep KActor horizontal. */ +var(StayUprightSpring) float StayUprightTorqueFactor; + +/** Max torque that can be applied to try and keep KActor horizontal */ +var(StayUprightSpring) float StayUprightMaxTorque; + +/** If TRUE limit the maximum speed this object can move. */ +var() bool bLimitMaxPhysicsVelocity; +/** If bLimitMaxPhysicsVelocity is TRUE, this is how fast the object can move. */ +var() float MaxPhysicsVelocity; + +var native const RigidBodyState RBState; +var native const float AngErrorAccumulator; +/** replicated version of DrawScale3D */ +var repnotify vector ReplicatedDrawScale3D; + +var transient vector InitialLocation; +var transient rotator InitialRotation; + +/** whether we need to replicate RBState - used to avoid it for bNoDelete KActors that haven't moved or been awakened yet + * as in that case the client should already have the same data + */ +var transient bool bNeedsRBStateReplication; + +/** + * Set TRUE to disable collisions with Pawn rigid bodies on clients. Set this to true if using optimizations that + * could cause the server to miss or ignore contacts that the client might dtect with this KActor, which could cause + * vibration, rubberbanding, and general visual badness. + */ +var bool bDisableClientSidePawnInteractions; + +replication +{ + if (bNeedsRBStateReplication && Role == ROLE_Authority) + RBState; + if (bNetInitial && Role == ROLE_Authority) + bWakeOnLevelStart, ReplicatedDrawScale3D; +} + +/** Util for getting the PhysicalMaterial applied to this KActor's StaticMesh. */ +native final function PhysicalMaterial GetKActorPhysMaterial(); + +/** Forces the resolve the RBState regardless of whether the actor is sleeping */ +native final function ResolveRBState(); + +simulated event PostBeginPlay() +{ + Super.PostBeginPlay(); + + if (bWakeOnLevelStart && (StaticMeshComponent != None) ) + { + StaticMeshComponent.WakeRigidBody(); + } + else + { + bNeedsRBStateReplication = !bNoDelete; + } + ReplicatedDrawScale3D = DrawScale3D * 1000.0f; // avoids effects of vector rounding + + // Initialise impact/slide components (if we are being notified of physics events, and have sounds/effects set up + // in PhysicalMaterial applied to our static mesh. + if((StaticMeshComponent != None) && StaticMeshComponent.bNotifyRigidBodyCollision) + { + SetPhysicalCollisionProperties(); + } + + InitialLocation = Location; + InitialRotation = Rotation; + + if ( bDisableClientSidePawnInteractions && (Role != ROLE_Authority) && (StaticMeshComponent != None) ) + { + // on clients, turn off collision with pawn RBs, Let replication handle collision response + // to avoid server/client disagreement. + StaticMeshComponent.SetRBCollidesWithChannel(RBCC_Pawn, FALSE); + } +} + +/** called when the actor falls out of the world 'safely' (below KillZ and such) */ +simulated event FellOutOfWorld(class dmgType) +{ + ShutDown(); + Super.FellOutOfWorld(dmgType); +} + +simulated event Destroyed() +{ + // Let the components play out normally + if( ImpactEffectInfo.Sound != None ) + { + if( ImpactSoundComponent != none ) + { + ImpactSoundComponent.bAutoDestroy = TRUE; + } + + if( ImpactSoundComponent2 != none ) + { + ImpactSoundComponent2.bAutoDestroy = TRUE; + } + } + + if( SlideEffectInfo.Sound != None ) + { + SlideSoundComponent.bAutoDestroy = TRUE; + } + + Super.Destroyed(); + } + +simulated function SetPhysicalCollisionProperties() +{ + local PhysicalMaterial PhysMat; + PhysMat = GetKActorPhysMaterial(); + // cache effect info + ImpactEffectInfo = PhysMat.FindPhysEffectInfo(EPMET_Impact); + SlideEffectInfo = PhysMat.FindPhysEffectInfo(EPMET_Slide); + + if(ImpactEffectInfo.Effect != None) + { + ImpactEffectComponent = new(self) class'ParticleSystemComponent'; + //AttachComponent(ImpactEffectComponent); + ImpactEffectComponent.bAutoActivate = FALSE; + ImpactEffectComponent.SetTemplate(ImpactEffectInfo.Effect); + } + +`if (`__TW_) + // do nothing +`else + if(ImpactEffectInfo.Sound != None) + { + ImpactSoundComponent = new(self) class'AudioComponent'; + //AttachComponent(ImpactSoundComponent); + ImpactSoundComponent.SoundCue = ImpactEffectInfo.Sound; + + ImpactSoundComponent2 = new(self) class'AudioComponent'; + //AttachComponent(ImpactSoundComponent2); + ImpactSoundComponent2.SoundCue = ImpactEffectInfo.Sound; + } +`endif // __TW_ + + if(SlideEffectInfo.Effect != None) + { + SlideEffectComponent = new(self) class'ParticleSystemComponent'; + //AttachComponent(SlideEffectComponent); + SlideEffectComponent.bAutoActivate = FALSE; + SlideEffectComponent.SetTemplate(SlideEffectInfo.Effect); + } + +`if (`__TW_) + // do nothing +`else + if(SlideEffectInfo.Sound != None) + { + SlideSoundComponent = new(self) class'AudioComponent'; + //AttachComponent(SlideSoundComponent); + SlideSoundComponent.SoundCue = SlideEffectInfo.Sound; + } +`endif // __TW_ +} + + +/** Makes sure these properties get set up on spawned meshes. Factories do not set the mesh before PostBeginPlay is called. */ +simulated event SpawnedByKismet() +{ + if(StaticMeshComponent.bNotifyRigidBodyCollision) + { + SetPhysicalCollisionProperties(); + } + + InitialLocation = Location; + InitialRotation = Rotation; +} + +simulated event ReplicatedEvent(name VarName) +{ + local vector NewDrawScale3D; + + if (VarName == 'bWakeOnLevelStart') + { + if (bWakeOnLevelStart) + { + StaticMeshComponent.WakeRigidBody(); + } + } + else if (VarName == nameof(ReplicatedDrawScale3D)) + { + NewDrawScale3D = ReplicatedDrawScale3D / 1000.0; // needs to match multiply in PostBeginPlay() + SetDrawScale3D(NewDrawScale3D); + } + else + { + Super.ReplicatedEvent(VarName); + } +} + +event ApplyImpulse( Vector ImpulseDir, float ImpulseMag, Vector HitLocation, optional TraceHitInfo HitInfo, optional class DamageType ) +{ + local vector AppliedImpulse; + + AppliedImpulse = Normal(ImpulseDir) * ImpulseMag; + + if( HitInfo.HitComponent != None ) + { + HitInfo.HitComponent.AddImpulse( AppliedImpulse, HitLocation, HitInfo.BoneName ); + } + else + { // if no HitComponent is passed, default to our CollisionComponent + CollisionComponent.AddImpulse( AppliedImpulse, HitLocation ); + } +} + +/** + * Default behaviour when shot is to apply an impulse and kick the KActor. + */ +event TakeDamage(int Damage, Controller EventInstigator, vector HitLocation, vector Momentum, class DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser) +{ + // call Actor's version to handle any SeqEvent_TakeDamage for scripting + Super.TakeDamage(Damage, EventInstigator, HitLocation, Momentum, DamageType, HitInfo, DamageCauser); + + if ( bDamageAppliesImpulse && DamageType.default.KDamageImpulse > 0 ) + { + if ( VSize(momentum) < 0.001 ) + { + `Log("Zero momentum to KActor.TakeDamage"); + return; + } + + ApplyImpulse(Momentum, + DamageType.default.KDamageImpulse, + HitLocation, + HitInfo, + DamageType); + } +} + +/** + * Respond to radial damage as well. + */ +simulated function TakeRadiusDamage +( + Controller InstigatedBy, + float BaseDamage, + float DamageRadius, + class DamageType, + float Momentum, + vector HurtOrigin, + bool bFullDamage, + Actor DamageCauser, + optional float DamageFalloffExponent=1.f +) +{ + local int Idx; + local SeqEvent_TakeDamage DmgEvt; + // search for any damage events + for (Idx = 0; Idx < GeneratedEvents.Length; Idx++) + { + DmgEvt = SeqEvent_TakeDamage(GeneratedEvents[Idx]); + if (DmgEvt != None) + { + // notify the event of the damage received + DmgEvt.HandleDamage(self, InstigatedBy, DamageType, BaseDamage); + } + } + if ( bDamageAppliesImpulse && damageType.default.RadialDamageImpulse > 0 && (Role == ROLE_Authority) ) + { + CollisionComponent.AddRadialImpulse(HurtOrigin, DamageRadius, damageType.default.RadialDamageImpulse, RIF_Linear, damageType.default.bRadialDamageVelChange); + } +} + +/** If this KActor receives a Toggle ON event from Kismet, wake the physics up. */ +simulated function OnToggle(SeqAct_Toggle action) +{ + if(action.InputLinks[0].bHasImpulse) + { + StaticMeshComponent.WakeRigidBody(); + } +} + +/** + * Called upon receiving a SeqAct_Teleport action. Grabs + * the first destination available and attempts to teleport + * this actor. + * + * @param inAction - teleport action that was activated + */ +simulated function OnTeleport(SeqAct_Teleport inAction) +{ + local array objVars; + local int idx; + local Actor destActor; + + // find the first supplied actor + inAction.GetObjectVars(objVars,"Destination"); + for (idx = 0; idx < objVars.Length && destActor == None; idx++) + { + destActor = Actor(objVars[idx]); + } + + // and set to that actor's location + if (destActor != None) + { + StaticMeshComponent.SetRBPosition(destActor.Location); + StaticMeshComponent.SetRBRotation(destActor.Rotation); + PlayTeleportEffect(false, true); + } +} + +simulated function Reset() +{ +`if (`__TW_) + if ( bDeleteMe ) + { + return; + } +`endif + StaticMeshComponent.SetRBLinearVelocity( Vect(0,0,0) ); + StaticMeshComponent.SetRBAngularVelocity( Vect(0,0,0) ); + StaticMeshComponent.SetRBPosition( InitialLocation ); + StaticMeshComponent.SetRBRotation( InitialRotation ); + + if (!bWakeOnLevelStart) + { + StaticMeshComponent.PutRigidBodyToSleep(); + } + else + { + StaticMeshComponent.WakeRigidBody(); + } + + // Resolve the RBState and get all of the needed flags set + ResolveRBState(); + + // Force replication + bForceNetUpdate = TRUE; + + super.Reset(); +} + +defaultproperties +{ + TickGroup=TG_PostAsyncWork + + SupportedEvents.Add(class'SeqEvent_RigidBodyCollision') + + Begin Object Name=StaticMeshComponent0 + WireframeColor=(R=0,G=255,B=128,A=255) + BlockRigidBody=true + RBChannel=RBCC_GameplayPhysics + RBCollideWithChannels=(Default=TRUE,BlockingVolume=TRUE,GameplayPhysics=TRUE,EffectPhysics=TRUE) + bBlockFootPlacement=false + End Object + + bDamageAppliesImpulse=true + bNetInitialRotation=true + Physics=PHYS_RigidBody + bStatic=false + bCollideWorld=false + bProjTarget=true + bBlockActors=true + bWorldGeometry=false + + bNoDelete=true + bAlwaysRelevant=true + bSkipActorPropertyReplication=false + bUpdateSimulatedPosition=true + bReplicateMovement=true + RemoteRole=ROLE_SimulatedProxy + + bCollideActors=true + bNoEncroachCheck=true + bBlocksTeleport=true + bBlocksNavigation=true + bPawnCanBaseOn=false + bSafeBaseIfAsleep=TRUE + bNeedsRBStateReplication=true + + StayUprightTorqueFactor=1000.0 + StayUprightMaxTorque=1500.0 + + MaxPhysicsVelocity=350.0 + + ReplicatedDrawScale3D=(X=1000.0,Y=1000.0,Z=1000.0) // set so that default scale of (1,1,1) doesn't replicate anything + + bDisableClientSidePawnInteractions=TRUE +} diff --git a/Engine/Classes/KActorFromStatic.uc b/Engine/Classes/KActorFromStatic.uc new file mode 100644 index 0000000..2b5e2be --- /dev/null +++ b/Engine/Classes/KActorFromStatic.uc @@ -0,0 +1,221 @@ +/** + * Version of KActor that can be dynamically spawned and destroyed during gameplay + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + **/ +class KActorFromStatic extends KActor + native(Physics) + notplaceable + transient; + +/** Actor from whome this static mesh came */ +var Actor MyStaticMeshActor; + +/** Max speed from an impulse */ +var float MaxImpulseSpeed; + +cpptext +{ + virtual void NotifyBump(AActor *Other, UPrimitiveComponent* OtherComp, const FVector &HitNormal); + virtual UBOOL IgnoreBlockingBy( const AActor *Other ) const; +#if __TW_PHYSICS_ + virtual UBOOL ShouldTrace(UPrimitiveComponent* Primitive,AActor *SourceActor, DWORD TraceFlags); +#endif +} + +/** Disable precomputed lighting when become dynamic */ +final native function DisablePrecomputedLighting(); + +auto state Initializing +{ + /** Delay disabling lightmaps by one tick to avoid lighting pop */ + event Tick(float DeltaTime) + { + DisablePreComputedLighting(); + GotoState(''); + } +} + +/** + * A little while after it goes to sleep, make the static mesh static again + */ +event OnSleepRBPhysics() +{ +`if(`__TW_PERFORMANCE_) + // Skip timer (unnecessary with our lighting) and go straight to sleep + MakeStatic(); + Destroy(); + return; +`endif + BecomeStatic(); +} + +/** + * Cancel becoming static + */ +event OnWakeRBPhysics() +{ + ClearTimer('BecomeStatic'); +} + +/** If still asleep, make static */ +function BecomeStatic() +{ + if ( !WorldInfo.bDropDetail && (WorldInfo.TimeSeconds - LastRenderTime < 0.15) ) + { + // wait till not rendered to avoid having lighting pop be visible + SetTimer(1.0, false, 'BecomeStatic'); + return; + } + + // if woke up again, don't make static + if ( StaticMeshComponent.RigidBodyIsAwake() ) + { + return; + } + + MakeStatic(); + Destroy(); +} + +/** + * Move the StaticMeshComponent back to its original actor owner (MyStaticMeshActor), and fix its position again. + */ +static native function MakeStatic(); + +/** + * @PARAM MovableMesh: Move this StaticMeshComponent to a KActorFromStatic + * @RETURNS a KActorSpawnable actor with MovableMesh as its mesh (removing MovableMesh from its current owner) + */ +static native function KActorFromStatic MakeDynamic(StaticMeshComponent MovableMesh); + +/** + * Figure out velocity change here so we can bound it. + */ +event ApplyImpulse( Vector ImpulseDir, float ImpulseMag, Vector HitLocation, optional TraceHitInfo HitInfo, optional class DamageType ) +{ + local float BodyMass; + + BodyMass = StaticMeshComponent.BodyInstance.GetBodyMass(); + if ( (BodyMass > 0.0) && ((DamageType == None) || !DamageType.default.bRadialDamageVelChange) ) + { + if ( BodyMass < 1.0 ) + { + BodyMass = Sqrt(BodyMass); + } + + ImpulseMag = FMin(ImpulseMag/BodyMass, MaxImpulseSpeed); + } + + CollisionComponent.AddImpulse( Normal(ImpulseDir) * ImpulseMag, HitLocation,, TRUE ); +`if(`__TW_PERFORMANCE_) + // reset the default lifespan everytime a new impulse is applied + LifeSpan = default.LifeSpan; +`endif +} + +/** + * Bumped or touched by pawn, so take impulse from it. + */ +function ReceiveImpulse(Pawn Other, Vector HitLocation, Vector HitNormal) +{ + local vector HitDir; + local float ImpulseMag; + + HitDir = Location - HitLocation; + HitDir.Z = FMax(HitDir.Z, 0.0); + HitDir = Normal(HitDir); + ImpulseMag = FMax( 0.5*Other.GroundSpeed, ((Other.Velocity - Velocity) dot HitDir)); +`if(`__TW_PHYSICS_) + // apply a factor of pawn mass to get momentum + ImpulseMag *= (Other.Mass / 75.f) * 5.0; +`endif + ApplyImpulse(HitDir, ImpulseMag, Location); +} + +/** + * Bump event is only called for KActorFromStatic if Other is a Pawn + */ +event Bump( Actor Other, PrimitiveComponent OtherComp, Vector HitNormal ) +{ + ReceiveImpulse(Pawn(Other), Other.Location, HitNormal); +} + +/** + * Pawns will Touch rather than Bump + */ +event Touch( Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal ) +{ + if ( Pawn(Other) != None ) + { + ReceiveImpulse(Pawn(Other), HitLocation, HitNormal); + } +} + +/** + * Respond to radial damage as well. + */ +simulated function TakeRadiusDamage +( + Controller InstigatedBy, + float BaseDamage, + float DamageRadius, + class DamageType, + float Momentum, + vector HurtOrigin, + bool bFullDamage, + Actor DamageCauser, + optional float DamageFalloffExponent=1.f +) +{ + local int Idx; + local SeqEvent_TakeDamage DmgEvt; + // search for any damage events + for (Idx = 0; Idx < GeneratedEvents.Length; Idx++) + { + DmgEvt = SeqEvent_TakeDamage(GeneratedEvents[Idx]); + if (DmgEvt != None) + { + // notify the event of the damage received + DmgEvt.HandleDamage(self, InstigatedBy, DamageType, BaseDamage); + } + } + if ( bDamageAppliesImpulse && DamageType.default.RadialDamageImpulse > 0 && (Role == ROLE_Authority) ) + { + ApplyImpulse(Location-HurtOrigin, DamageType.default.RadialDamageImpulse, Location,, DamageType); + } +} + +`if(`__TW_PHYSICS_) +simulated function Reset(); +`endif + +`if(`__TW_PERFORMANCE_) +simulated event Destroyed() +{ + Super.Destroyed(); + if ( bRigidBodyWasAwake ) + { + `log(self@"destroyed for not going to sleep. Lost static actor"@MyStaticMeshActor); + } +} +`endif + +defaultproperties +{ + RemoteRole=ROLE_None + bNoDelete=false + bCallRigidBodyWakeEvents=true + MaxImpulseSpeed=900.0 + bCanStepUpOn=false + + CollisionComponent=None + StaticMeshComponent=None + Components.Remove(StaticMeshComponent0) + LightEnvironment=None + Components.Remove(MyLightEnvironment) +`if(`__TW_PERFORMANCE_) + // If this KActor is having trouble going to sleep delete it (static will be lost!) + LifeSpan=15.f +`endif +} diff --git a/Engine/Classes/KActorSpawnable.uc b/Engine/Classes/KActorSpawnable.uc new file mode 100644 index 0000000..dd65935 --- /dev/null +++ b/Engine/Classes/KActorSpawnable.uc @@ -0,0 +1,68 @@ +/** + * Version of KActor that can be dynamically spawned and destroyed during gameplay + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + **/ +class KActorSpawnable extends KActor + native(Physics) + notplaceable; + + +/** If this is true then the KActor will scale to zero before hiding self */ +var bool bRecycleScaleToZero; + +/** Whether or not we are scaling to zero (in C++ TickSpecial()) */ +var protected bool bScalingToZero; + +cpptext +{ + virtual void TickSpecial(FLOAT DeltaSeconds); +} + + +simulated function Initialize() +{ + bScalingToZero = FALSE; + SetDrawScale( default.DrawScale ); + + ClearTimer('Recycle'); + SetHidden(FALSE); + StaticMeshComponent.SetHidden(FALSE); + SetTickIsDisabled(false); + SetPhysics(PHYS_RigidBody); + SetCollision(true, false); +} + +/** This will reset the KActorSpawnable to its default state either first scaling to zero or by just hiding the object. **/ +simulated function Recycle() +{ + if( bRecycleScaleToZero == TRUE ) + { + bScalingToZero = TRUE; + } + else + { + RecycleInternal(); + } +} + +/** This will reset the KActorSpawnable to its default state. This is useful for pooling. **/ +simulated event RecycleInternal() +{ + SetHidden(TRUE); + StaticMeshComponent.SetHidden(TRUE); + SetPhysics(PHYS_None); + SetCollision(false, false); + ClearTimer('Recycle'); + SetTickIsDisabled(true); +} + + + +/** Used when the actor is pulled from a cache for use. */ +native final function ResetComponents(); + +defaultproperties +{ + bNoDelete=FALSE +} diff --git a/Engine/Classes/KAsset.uc b/Engine/Classes/KAsset.uc new file mode 100644 index 0000000..7db73bd --- /dev/null +++ b/Engine/Classes/KAsset.uc @@ -0,0 +1,240 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class KAsset extends Actor + native(Physics) + nativereplication + ClassGroup(Physics) + placeable; + +var() const editconst SkeletalMeshComponent SkeletalMeshComponent; + +var() bool bDamageAppliesImpulse; +var() bool bWakeOnLevelStart; + +/** Whether this KAsset should block Pawns. */ +var() bool bBlockPawns; + +/** Used to replicate mesh to clients */ +var repnotify transient SkeletalMesh ReplicatedMesh; + +/** Used to replicate physics asset to clients */ +var repnotify transient PhysicsAsset ReplicatedPhysAsset; + +replication +{ + if ( Role == ROLE_Authority) + ReplicatedMesh, ReplicatedPhysAsset; +} + +cpptext +{ +public: + // AActor interface. + virtual INT* GetOptimizedRepList(BYTE* InDefault, FPropertyRetirement* Retire, INT* Ptr, UPackageMap* Map, UActorChannel* Channel); + + /** + * Function that gets called from within Map_Check to allow this actor to check itself + * for any potential errors and register them with map check dialog. + */ +#if WITH_EDITOR + virtual void CheckForErrors(); +#endif + + UBOOL ShouldTrace(UPrimitiveComponent* Primitive, AActor *SourceActor, DWORD TraceFlags); + UBOOL IgnoreBlockingBy(const AActor* Other) const; +} + +simulated event PostBeginPlay() +{ + Super.PostBeginPlay(); + + if (bWakeOnLevelStart) + { + SkeletalMeshComponent.WakeRigidBody(); + } + ReplicatedMesh = SkeletalMeshComponent.SkeletalMesh; + ReplicatedPhysAsset = SkeletalMeshComponent.PhysicsAsset; +`if(`__TW_PERFORMANCE_) + // Added forceskel update to allow us to use bUpdateSkelWhenNotRendered + if ( !SkeletalMeshComponent.bUpdateSkelWhenNotRendered ) + { + SkeletalMeshComponent.ForceSkelUpdate(); + } +`endif +} + +/** Sets the new mesh and physics asset, along with the replicated properties for clients. */ +final function SetMeshAndPhysAsset(SkeletalMesh NewMesh, PhysicsAsset NewPhysAsset) +{ + SkeletalMeshComponent.SetSkeletalMesh(NewMesh); + ReplicatedMesh = NewMesh; + SkeletalMeshComponent.SetPhysicsAsset(NewPhysAsset); + ReplicatedPhysAsset = NewPhysAsset; +} + +simulated event ReplicatedEvent( name VarName ) +{ + if (VarName == 'ReplicatedMesh') + { + SkeletalMeshComponent.SetSkeletalMesh(ReplicatedMesh); + } + else if(VarName == 'ReplicatedPhysAsset') + { + SkeletalMeshComponent.SetPhysicsAsset(ReplicatedPhysAsset); + } +} + +/** + * Default behaviour when shot is to apply an impulse and kick the KActor. + */ +simulated event TakeDamage(int Damage, Controller EventInstigator, vector HitLocation, vector Momentum, class DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser) +{ + local vector ApplyImpulse; + + // call Actor's version to handle any SeqEvent_TakeDamage for scripting + Super.TakeDamage(Damage, EventInstigator, HitLocation, Momentum, DamageType, HitInfo, DamageCauser); + + if ( bDamageAppliesImpulse && damageType.default.KDamageImpulse > 0 ) + { + if ( VSize(momentum) < 0.001 ) + { + `Log("Zero momentum to KActor.TakeDamage"); + return; + } + + // Make sure we have a valid TraceHitInfo with our SkeletalMesh + // we need a bone to apply proper impulse + CheckHitInfo( HitInfo, SkeletalMeshComponent, Normal(Momentum), hitlocation ); + + ApplyImpulse = Normal(momentum) * damageType.default.KDamageImpulse; + if ( HitInfo.HitComponent != None ) + { + HitInfo.HitComponent.AddImpulse(ApplyImpulse, HitLocation, HitInfo.BoneName); + } + } +} + +/** + * Take Radius Damage + * + * @param InstigatedBy, instigator of the damage + * @param Base Damage + * @param Damage Radius (from Origin) + * @param DamageType class + * @param Momentum (float) + * @param HurtOrigin, origin of the damage radius. + * @param DamageCauser the Actor that directly caused the damage (i.e. the Projectile that exploded, the Weapon that fired, etc) + */ +simulated function TakeRadiusDamage +( + Controller InstigatedBy, + float BaseDamage, + float DamageRadius, + class DamageType, + float Momentum, + vector HurtOrigin, + bool bFullDamage, + Actor DamageCauser, + optional float DamageFalloffExponent=1.f +) +{ + if ( bDamageAppliesImpulse && damageType.default.RadialDamageImpulse > 0 && (Role == ROLE_Authority) ) + { + CollisionComponent.AddRadialImpulse(HurtOrigin, DamageRadius, damageType.default.RadialDamageImpulse, RIF_Linear, damageType.default.bRadialDamageVelChange); + } +} + +/** If this KAsset receives a Toggle ON event from Kismet, wake the physics up. */ +simulated function OnToggle(SeqAct_Toggle action) +{ + if(action.InputLinks[0].bHasImpulse) + { + SkeletalMeshComponent.WakeRigidBody(); + } +} + +simulated function OnTeleport(SeqAct_Teleport InAction) +{ + local Actor DestActor; + + DestActor = Actor(SeqVar_Object(InAction.VariableLinks[1].LinkedVariables[0]).GetObjectValue()); + if (DestActor != None) + { + SkeletalMeshComponent.SetRBPosition(DestActor.Location); + } + else + { + InAction.ScriptLog("No Destination for" @ InAction @ "on" @ self); + } +} + + +/** Performs actual attachment. Can be subclassed for class specific behaviors. */ +function DoKismetAttachment( Actor Attachment, SeqAct_AttachToActor Action ) +{ + Attachment.SetBase( Self,, SkeletalMeshComponent, Action.BoneName ); +} + + + +defaultproperties +{ + TickGroup=TG_PostAsyncWork + + Begin Object Class=DynamicLightEnvironmentComponent Name=MyLightEnvironment + End Object +`if(`__TW_LIGHTING_MODIFICATIONS_) + // Don't add to components list +`else + Components.Add(MyLightEnvironment) +`endif + + Begin Object Class=SkeletalMeshComponent Name=KAssetSkelMeshComponent + CollideActors=true + BlockActors=true + BlockZeroExtent=true + BlockNonZeroExtent=false + BlockRigidBody=true + bHasPhysicsAssetInstance=true + bUpdateKinematicBonesFromAnimation=false + bUseTickOptimization=false + PhysicsWeight=1.0 + RBChannel=RBCC_GameplayPhysics + RBCollideWithChannels=(Default=TRUE,BlockingVolume=TRUE,GameplayPhysics=TRUE,EffectPhysics=TRUE) + LightEnvironment=MyLightEnvironment + bSkipAllUpdateWhenPhysicsAsleep=TRUE + bBlockFootPlacement=false + End Object + CollisionComponent=KAssetSkelMeshComponent + SkeletalMeshComponent=KAssetSkelMeshComponent + Components.Add(KAssetSkelMeshComponent) + + SupportedEvents.Add(class'SeqEvent_ConstraintBroken') + SupportedEvents.Add(class'SeqEvent_RigidBodyCollision') + + bDamageAppliesImpulse=true + bNetInitialRotation=true + Physics=PHYS_RigidBody + bEdShouldSnap=true + bStatic=false + bCollideActors=true + bBlockActors=true + bWorldGeometry=false + bCollideWorld=false + bProjTarget=true + + bNoDelete=true + bAlwaysRelevant=true + bSkipActorPropertyReplication=false + bUpdateSimulatedPosition=true + bReplicateMovement=true +`if(`__TW_NETWORKING_) + // SimProxy makes sense in KAssetSpawnable, but not in KAsset. TakeDamage is + // marked simulated and only applies local client damage impulses. + RemoteRole=ROLE_None +`else + RemoteRole=ROLE_SimulatedProxy +`endif + bReplicateRigidBodyLocation=FALSE +} diff --git a/Engine/Classes/KAssetSpawnable.uc b/Engine/Classes/KAssetSpawnable.uc new file mode 100644 index 0000000..c8a2e39 --- /dev/null +++ b/Engine/Classes/KAssetSpawnable.uc @@ -0,0 +1,12 @@ +/** + * Version of KAsset that can be dynamically spawned and destroyed during gameplay + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + **/ +class KAssetSpawnable extends KAsset + notplaceable; + +defaultproperties +{ + bNoDelete=false +} diff --git a/Engine/Classes/KMeshProps.uc b/Engine/Classes/KMeshProps.uc new file mode 100644 index 0000000..2b58ab9 --- /dev/null +++ b/Engine/Classes/KMeshProps.uc @@ -0,0 +1,140 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +// It would be nice if you could subclass structs in script.. ah well. Don't want overhead of making these UObjects. + +class KMeshProps extends Object + native + noexport; + +// KAggregateGeom and all Elems are in UNREAL scale. +// InertiaTensor, COMOffset & Volume are in PHYSICS scale. + +struct KSphereElem +{ + var() editconst Matrix TM; + var() editconst float Radius; + + /** Disable rigid body collision for this shape. */ + var() bool bNoRBCollision; + + /** Check against this shape even when per-poly collision is being used. */ + var() bool bPerPolyShape; + +`if(`__TW_HITZONE_DETECTION_) + /** Disable UE's LineCheck collision with this shape and use it only for RBCollision. Note: Opposite of a HitZone */ + var() bool bNoUECollision; + + /** When tracing HitZone collision return this name instead of the default bone name. Allows us to have + * multiple named collision zones assigned to the same bone. + */ + var() name HitZoneName; +`endif + + structdefaultproperties + { + Radius=1 + TM=(XPlane=(X=1,Y=0,Z=0,W=0),YPlane=(X=0,Y=1,Z=0,W=0),ZPlane=(X=0,Y=0,Z=1,W=0),WPlane=(X=0,Y=0,Z=0,W=1)) + } +}; + +struct KBoxElem +{ + var() editconst Matrix TM; + var() editconst float X, Y, Z; // length (not radius) + + /** Disable rigid body collision for this shape. */ + var() bool bNoRBCollision; + + /** Check against this shape even when per-poly collision is being used. */ + var() bool bPerPolyShape; + +`if(`__TW_HITZONE_DETECTION_) + /** Disable UE's LineCheck collision with this shape and use it only for RBCollision. Note: Opposite of a HitZone */ + var() bool bNoUECollision; + + /** When tracing HitZone collision return this name instead of the default bone name. Allows us to have + * multiple named collision zones assigned to the same bone. + */ + var() name HitZoneName; +`endif + + structdefaultproperties + { + X=1 + Y=1 + Z=1 + TM=(XPlane=(X=1,Y=0,Z=0,W=0),YPlane=(X=0,Y=1,Z=0,W=0),ZPlane=(X=0,Y=0,Z=1,W=0),WPlane=(X=0,Y=0,Z=0,W=1)) + } +}; + +struct KSphylElem +{ + var() editconst Matrix TM; // The transform assumes the sphyl axis points down Z. + var() editconst float Radius; + var() editconst float Length; // This is of line-segment ie. add Radius to both ends to find total length. + + /** Disable rigid body collision for this shape. */ + var() bool bNoRBCollision; + + /** Check against this shape even when per-poly collision is being used. */ + var() bool bPerPolyShape; + +`if(`__TW_HITZONE_DETECTION_) + /** Disable UE's LineCheck collision with this shape and use it only for RBCollision. Note: Opposite of a HitZone */ + var() bool bNoUECollision; + + /** When tracing HitZone collision return this name instead of the default bone name. Allows us to have + * multiple named collision zones assigned to the same bone. + */ + var() name HitZoneName; +`endif + + structdefaultproperties + { + Radius=1 + Length=1 + TM=(XPlane=(X=1,Y=0,Z=0,W=0),YPlane=(X=0,Y=1,Z=0,W=0),ZPlane=(X=0,Y=0,Z=1,W=0),WPlane=(X=0,Y=0,Z=0,W=1)) + } +}; + +/** One convex hull, used for simplified collision. */ +struct KConvexElem +{ + /** Array of indices that make up the convex hull. */ + var array VertexData; + + /** Array of planes holding the vertex data in SIMD order */ + var array PermutedVertexData; + + /** Index buffer for triangles making up the faces of this convex hull. */ + var array FaceTriData; + + /** All different directions of edges in this hull. */ + var array EdgeDirections; + + /** All different directions of face normals in this hull. */ + var array FaceNormalDirections; + + /** Array of the planes that make up this convex hull. */ + var array FacePlaneData; + + /** Bounding box of this convex hull. */ + var box ElemBox; +}; + +struct KAggregateGeom +{ + var() editfixedsize array SphereElems; + var() editfixedsize array BoxElems; + var() editfixedsize array SphylElems; + var() editfixedsize array ConvexElems; + var() editfixedsize array BoxMirrorConvexElems; + var native nontransactional noimport pointer RenderInfo; + + /** Collision against this geom will not specially handle the "close and parallel" case. Special-case. */ + var() bool bSkipCloseAndParallelChecks; +}; + +var() vector COMNudge; // User-entered offset. UNREAL UNITS +var() KAggregateGeom AggGeom; diff --git a/Engine/Classes/Keypoint.uc b/Engine/Classes/Keypoint.uc new file mode 100644 index 0000000..c11a5db --- /dev/null +++ b/Engine/Classes/Keypoint.uc @@ -0,0 +1,28 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +//============================================================================= +// Keypoint, the base class of invisible actors which mark things. +//============================================================================= +class Keypoint extends Actor + abstract + placeable + native; + +var() SpriteComponent SpriteComp; + +defaultproperties +{ + Begin Object Class=SpriteComponent Name=Sprite + Sprite=Texture2D'EditorResources.S_Keypoint' + HiddenGame=True + AlwaysLoadOnClient=False + AlwaysLoadOnServer=False + SpriteCategoryName="Keypoints" + End Object + Components.Add(Sprite) + SpriteComp=Sprite; + + bStatic=True + bHidden=True +} diff --git a/Engine/Classes/KillZDamageType.uc b/Engine/Classes/KillZDamageType.uc new file mode 100644 index 0000000..401a879 --- /dev/null +++ b/Engine/Classes/KillZDamageType.uc @@ -0,0 +1,11 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class KillZDamageType extends DamageType + abstract + native; + +defaultproperties +{ + bCausedByWorld=true +} diff --git a/Engine/Classes/KismetBookMark.uc b/Engine/Classes/KismetBookMark.uc new file mode 100644 index 0000000..a9c4ee2 --- /dev/null +++ b/Engine/Classes/KismetBookMark.uc @@ -0,0 +1,19 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * Simple class to represent bookmarks in Kismet. + */ +class KismetBookMark extends BookMark2D + hidecategories(Object) + native; + +/** Name of the sequence the bookmark applies to */ +var string BookMarkSequencePathName; + +cpptext +{ +} + +defaultproperties +{ +} diff --git a/Engine/Classes/Ladder.uc b/Engine/Classes/Ladder.uc new file mode 100644 index 0000000..d13b96f --- /dev/null +++ b/Engine/Classes/Ladder.uc @@ -0,0 +1,58 @@ +/*============================================================================= +// Ladders are associated with the LadderVolume that encompasses them, and provide AI navigation +// support for ladder volumes. Direction should be the direction that climbing pawns +// should face +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +============================================================================= */ + +class Ladder extends NavigationPoint + placeable + native; + +cpptext +{ +#if WITH_EDITOR + virtual UBOOL CanConnectTo(ANavigationPoint* Dest, UBOOL bCheckDistance); + void addReachSpecs(AScout *Scout, UBOOL bOnlyChanged=0); +#endif + void InitForPathFinding(); + void ClearPaths(); + virtual UBOOL ReachedBy(APawn* P, const FVector& TestPosition, const FVector& Dest); +} + +var LadderVolume MyLadder; +var Ladder LadderList; + +/* +Check if ladder is already occupied +*/ +event bool SuggestMovePreparation(Pawn Other) +{ + if ( MyLadder == None ) + return false; + + if ( !MyLadder.InUse(Other) ) + { + MyLadder.PendingClimber = Other; + return false; + } + + Other.Controller.bPreparingMove = true; + Other.Acceleration = vect(0,0,0); + return true; +} + +defaultproperties +{ + Begin Object NAME=CollisionCylinder + CollisionRadius=+00040.000000 + CollisionHeight=+00080.000000 + End Object + + Begin Object NAME=Sprite + Sprite=Texture2D'EditorResources.S_Ladder' + End Object + + bSpecialMove=true + bNotBased=true +} diff --git a/Engine/Classes/LadderReachSpec.uc b/Engine/Classes/LadderReachSpec.uc new file mode 100644 index 0000000..4dadebe --- /dev/null +++ b/Engine/Classes/LadderReachSpec.uc @@ -0,0 +1,25 @@ +//============================================================================= +// LadderReachSpec. +// +// A LadderReachSpec connects Ladder NavigationPoints in a LadderVolume +// +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class LadderReachSpec extends ReachSpec + native; + +cpptext +{ + virtual FPlane PathColor() + { + // light purple = ladder + return FPlane(1.f,0.5f, 1.f,0.f); + } + virtual INT CostFor(APawn* P); +} + +defaultproperties +{ + bCanCutCorners=false +} + diff --git a/Engine/Classes/LadderVolume.uc b/Engine/Classes/LadderVolume.uc new file mode 100644 index 0000000..7b5aa08 --- /dev/null +++ b/Engine/Classes/LadderVolume.uc @@ -0,0 +1,150 @@ +/*============================================================================= +// LadderVolumes, when touched, cause ladder supporting actors to use Phys_Ladder. +// note that underwater ladders won't be waterzones (no breathing problems) +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +============================================================================= */ + +class LadderVolume extends PhysicsVolume + native + placeable; + +var() rotator WallDir; +var vector LookDir; +var vector ClimbDir; // pawn can move in this direction (or reverse) +var const Ladder LadderList; // list of Ladder actors associated with this LadderVolume +var() bool bNoPhysicalLadder; // if true, won't push into/keep player against geometry in lookdir +var() bool bAutoPath; // add top and bottom ladders automatically +var() bool bAllowLadderStrafing; // if true, players on ladder can strafe sideways + +var Pawn PendingClimber; + +/** Editor visual cue for the direction of the wall */ +var ArrowComponent WallDirArrow; + +cpptext +{ + // Editor modification +#if WITH_EDITOR + FVector FindTop(FVector V); + FVector FindCenter(); + virtual INT AddMyMarker(AActor *S); +#endif + virtual void PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent); +} + +simulated event PostBeginPlay() +{ + local Ladder L, M; + local vector Dir; + + Super.PostBeginPlay(); + LookDir = vector(WallDir); + if ( !bAutoPath && (LookDir.Z != 0) ) + { + ClimbDir = vect(0,0,1); + for ( L=LadderList; L!=None; L=L.LadderList ) + for ( M=LadderList; M!=None; M=M.LadderList ) + if ( M != L ) + { + Dir = Normal(M.Location - L.Location); + if ( (Dir dot ClimbDir) < 0 ) + Dir *= -1; + ClimbDir += Dir; + } + + ClimbDir = Normal(ClimbDir); + if ( (ClimbDir Dot vect(0,0,1)) < 0 ) + ClimbDir *= -1; + } +} + +function bool InUse(Pawn Ignored) +{ + local Pawn StillClimbing; + + ForEach TouchingActors(class'Pawn',StillClimbing) + { + if ( (StillClimbing != Ignored) && StillClimbing.bCollideActors && StillClimbing.bBlockActors ) + return true; + } + + if ( PendingClimber != None ) + { + if ( (PendingClimber.Controller == None) + || !PendingClimber.bCollideActors || !PendingClimber.bBlockActors + || (Ladder(PendingClimber.Controller.MoveTarget) == None) + || (Ladder(PendingClimber.Controller.MoveTarget).MyLadder != self) ) + PendingClimber = None; + } + return ( (PendingClimber != None) && (PendingClimber != Ignored) ); +} + +simulated event PawnEnteredVolume(Pawn P) +{ + local rotator PawnRot; + + Super.PawnEnteredVolume(P); + if ( !P.CanGrabLadder() ) + return; + + PawnRot = P.Rotation; + PawnRot.Pitch = 0; + if ( (vector(PawnRot) Dot LookDir > 0.9) + || ((AIController(P.Controller) != None) && (Ladder(P.Controller.MoveTarget) != None)) ) + P.ClimbLadder(self); + else if ( !P.bDeleteMe && (P.Controller != None) ) + spawn(class'PotentialClimbWatcher',P); +} + +simulated event PawnLeavingVolume(Pawn P) +{ + local Controller C; + + if ( P.OnLadder != self ) + return; + Super.PawnLeavingVolume(P); + P.OnLadder = None; + P.EndClimbLadder(self); + if ( P == PendingClimber ) + PendingClimber = None; + + // tell all waiting pawns, if not in use + if ( !InUse(P) ) + { + foreach WorldInfo.AllControllers(class'Controller', C) + { + if (C.bPreparingMove && Ladder(C.MoveTarget) != None && Ladder(C.MoveTarget).MyLadder == self) + { + C.bPreparingMove = false; + PendingClimber = C.Pawn; + return; + } + } + } +} + +simulated event PhysicsChangedFor(Actor Other) +{ + if ( (Other.Physics == PHYS_Falling) || (Other.Physics == PHYS_Ladder) || Other.bDeleteMe || (Pawn(Other) == None) || (Pawn(Other).Controller == None) ) + return; + spawn(class'PotentialClimbWatcher',Other); +} + +defaultproperties +{ + Begin Object Class=ArrowComponent Name=Arrow + ArrowColor=(R=150,G=100,B=150) + ArrowSize=5.0 + End Object + WallDirArrow = Arrow + Components.Add(Arrow) + + Begin Object Name=BrushComponent0 + HiddenEditor=false + End Object + + RemoteRole=ROLE_SimulatedProxy + ClimbDir=(X=+0.0,Y=+0.0,Z=+1.0) + bAutoPath=true + bAllowLadderStrafing=true +} diff --git a/Engine/Classes/Landscape.uc b/Engine/Classes/Landscape.uc new file mode 100644 index 0000000..5c99127 --- /dev/null +++ b/Engine/Classes/Landscape.uc @@ -0,0 +1,140 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class Landscape extends LandscapeProxy + dependson(LightComponent) + native(Terrain) + hidecategories(LandscapeProxy) + showcategories(Display, Movement, Collision, Lighting, LOD); + +enum ELandscapeSetupErrors +{ + LSE_None, + LSE_NoLandscapeInfo, // No Landscape Info available + LSE_CollsionXY, // There was already component with same X,Y + LSE_NoLayerInfo // No Layer Info, need to add proper layers +}; + +/** Layers that can be painted on the landscape */ +var deprecated array LayerNames; + +/** Structure storing Layer Data */ +struct native LandscapeLayerInfo +{ + var() Name LayerName; + // Used to erosion caculation? + var() float Hardness; + var editoronly bool bNoWeightBlend; + var() PhysicalMaterial PhysMaterial; + var editoronly MaterialInstanceConstant ThumbnailMIC; + var editoronly transient bool bSelected; + var editoronly transient int DebugColorChannel; + var editoronly transient string LayerSourceFile; + + structcpptext + { + // tor + FLandscapeLayerInfo(FName InName, FLOAT InHardness=0.5f, UBOOL InNoWeightBlend=FALSE, const TCHAR* SourceFile=NULL) + : LayerName(InName) + , Hardness(InHardness) + , bNoWeightBlend(InNoWeightBlend) + , PhysMaterial(NULL) +#if WITH_EDITORONLY_DATA + , ThumbnailMIC(NULL) + , bSelected(FALSE) + , DebugColorChannel(0) + , LayerSourceFile(E_ForceInit) +#endif // WITH_EDITORONLY_DATA + { +#if WITH_EDITORONLY_DATA + LayerSourceFile = SourceFile; +#endif // WITH_EDITORONLY_DATA + } + + // for TArray::FindItemIndexByKey + UBOOL operator==( const FLandscapeLayerInfo& Other ) const + { + return LayerName == Other.LayerName; + } + } +}; + +var deprecated array LayerInfos; + +cpptext +{ + // Make a key for XYtoComponentMap + static QWORD MakeKey( INT X, INT Y ) { return ((QWORD)(*(DWORD*)(&X)) << 32) | (*(DWORD*)(&Y) & 0xffffffff); } + static void UnpackKey( QWORD Key, INT& OutX, INT& OutY ) { *(DWORD*)(&OutX) = (Key >> 32); *(DWORD*)(&OutY) = Key&0xffffffff; } + + virtual class ALandscape* GetLandscapeActor(); + virtual void ClearComponents(); + + static FName DataWeightmapName; +#if WITH_EDITOR + virtual void PreSave(); + virtual void UpdateComponentsInternal(UBOOL bCollisionUpdate = FALSE); + + // ALandscape interface + UBOOL ImportFromOldTerrain(class ATerrain* OldTerrain); + void Import(INT VertsX, INT VertsY, INT ComponentSizeQuads, INT NumSubsections, INT SubsectionSizeQuads, WORD* HeightData, const TCHAR* HeightmapFileName, TArray ImportLayerInfos, BYTE* AlphaDataPointers[] ); + virtual void UpdateLandscapeActor(class ALandscape* Landscape, UBOOL bSearchForActor = TRUE); + + virtual UMaterialInterface* GetLandscapeMaterial() const; + UBOOL HasAllComponent(); // determine all component is in this actor + + // UObject interface + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual void PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent); + virtual void PostEditMove(UBOOL bFinished); + + // Include Components with overlapped vertices + static void CalcComponentIndicesOverlap(const INT X1, const INT Y1, const INT X2, const INT Y2, const INT ComponentSizeQuads, + INT& ComponentIndexX1, INT& ComponentIndexY1, INT& ComponentIndexX2, INT& ComponentIndexY2); + + // Exclude Components with overlapped vertices + static void CalcComponentIndices(const INT X1, const INT Y1, const INT X2, const INT Y2, const INT ComponentSizeQuads, + INT& ComponentIndexX1, INT& ComponentIndexY1, INT& ComponentIndexX2, INT& ComponentIndexY2); + + static void SplitHeightmap(ULandscapeComponent* Comp, UBOOL bMoveToCurrentLevel = FALSE); + + /** + * Function that gets called from within Map_Check to allow this actor to check itself + * for any potential errors and register them with map check dialog. + */ + virtual void CheckForErrors(); + + void UpdateOldLayerInfo(); +#endif + virtual void Serialize(FArchive& Ar); + virtual void BeginDestroy(); + virtual void PostLoad(); +} + +defaultproperties +{ + Begin Object Name=Sprite + Sprite=Texture2D'EditorResources.S_Terrain' + SpriteCategoryName="Landscape" + End Object + + DrawScale3D=(X=128.0,Y=128.0,Z=256.0) + bEdShouldSnap=True + bCollideActors=True + bBlockActors=True + bWorldGeometry=True + bStatic=True + bNoDelete=True + bHidden=False + bMovable=False + StaticLightingResolution=1.0 + StreamingDistanceMultiplier=1.0 + bIsProxy=False + bLockLocation=False + + +`if(`__TW_PERSISTENT_SPLATTER_SYSTEM_) + SplatterMapResolution=1.0 +`endif +} + \ No newline at end of file diff --git a/Engine/Classes/LandscapeComponent.uc b/Engine/Classes/LandscapeComponent.uc new file mode 100644 index 0000000..f0f1c38 --- /dev/null +++ b/Engine/Classes/LandscapeComponent.uc @@ -0,0 +1,341 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class LandscapeComponent extends PrimitiveComponent + native(Terrain) + hidecategories(Display, Attachment, Physics, Debug, Lighting, Collision, Movement, Rendering, PrimitiveComponent, Object); + +var() const editconst int SectionBaseX, + SectionBaseY; + +var const int ComponentSizeQuads, // Total number of quads for this component + SubsectionSizeQuads, // Number of quads for a subsection of the component. SubsectionSizeQuads+1 must be a power of two. + NumSubsections; // Number of subsections in X or Y axis + +var() MaterialInterface OverrideMaterial; +var MaterialInstanceConstant MaterialInstance; + +/** Stores information about which weightmap texture and channel each layer is stored */ +struct native WeightmapLayerAllocationInfo +{ + var Name LayerName; + var byte WeightmapTextureIndex; + var byte WeightmapTextureChannel; + + structcpptext + { + FWeightmapLayerAllocationInfo(FName InLayerName) + : LayerName(InLayerName) + , WeightmapTextureIndex(255) // Indicates an invalid allocation + , WeightmapTextureChannel(255) + {} + } +}; + +/** List of layers, and the weightmap and channel they are stored */ +var private const array WeightmapLayerAllocations; + +/** Weightmap texture reference */ +var private const array WeightmapTextures; + +/** UV offset to component's weightmap data from component local coordinates*/ +var Vector4 WeightmapScaleBias; + +/** U or V offset into the weightmap for the first subsection, in texture UV space */ +var float WeightmapSubsectionOffset; + +/** UV offset to Heightmap data from component local coordinates */ +var Vector4 HeightmapScaleBias; + +/** Heightmap texture reference */ +var private const Texture2D HeightmapTexture; + +/** Cached bounds, created at heightmap update time */ +var const BoxSphereBounds CachedBoxSphereBounds; + +/** Cached local-space bounding box, created at heightmap update time */ +var const Box CachedLocalBox; + +/** Unique ID for this component, used for caching during distributed lighting */ +var private const editoronly Guid LightingGuid; + +/** Array of shadow maps for this component. */ +var private const array ShadowMaps; +/** INTERNAL: Array of lights that don't apply to the terrain component. */ +var const array IrrelevantLights; + +/** Reference to the texture lightmap resource. */ +var native private const LightMapRef LightMap; + +`if(`__TW_PERSISTENT_SPLATTER_SYSTEM_) +var(PersistentSplats) private const editconst int SplatterMapRes; +var private const TWSplatterMap2D SplatterMap; +`endif + +/** Pointer to data shared with the render therad, used by the editor tools */ +var private native pointer EditToolRenderData{struct FLandscapeEditToolRenderData}; + +/** Heightfield mipmap used to generate collision */ +var int CollisionMipLevel; + +/** Platform-specific data */ +var private native pointer PlatformData{void}; + +/** Platform-specific data size */ +var const native int PlatformDataSize; + +var editoronly transient bool bNeedPostUndo; + +/** Forced LOD level to use when rendering */ +var(LOD) int ForcedLOD; +/** Neighbor LOD data to use when rendering, 255 is unspecified */ +var byte NeighborLOD[8]; +/** LOD level Bias to use when rendering */ +var(LOD) int LODBias; +/** Neighbor LOD bias to use when rendering, 128 is 0 bias, 0 is -128 bias, 255 is 127 bias */ +var byte NeighborLODBias[8]; + +cpptext +{ + // UObject interface + virtual void AddReferencedObjects( TArray& ObjectArray ); + virtual void Serialize(FArchive& Ar); + virtual void BeginDestroy(); +#if WITH_EDITOR + virtual void PostLoad(); + virtual void PostEditImport(); + virtual void PostEditUndo(); + virtual void PostRename(); + + // Register ourselves with the actor. + ELandscapeSetupErrors SetupActor(UBOOL bForce = FALSE); + + virtual void Attach(); +#endif + + // UPrimitiveComponent interface + virtual FPrimitiveSceneProxy* CreateSceneProxy(); + virtual void GetUsedMaterials( TArray& OutMaterials ) const; + virtual void UpdateBounds(); + void SetParentToWorld(const FMatrix& ParentToWorld); + virtual INT GetNumElements() const { return 1; } + virtual UMaterialInterface* GetElementMaterial(INT MaterialIndex) const { return MaterialInstance; } + virtual void SetElementMaterial(INT ElementIndex, UMaterialInterface* InMaterial); + +#if WITH_EDITOR + class ULandscapeInfo* GetLandscapeInfo(UBOOL bSpawnNewActor = TRUE) const; + virtual void GetStaticLightingInfo(FStaticLightingPrimitiveInfo& OutPrimitiveInfo,const TArray& InRelevantLights,const FLightingBuildOptions& Options); + virtual UBOOL GetLightMapResolution( INT& Width, INT& Height ) const; + virtual void GetStaticTriangles(FPrimitiveTriangleDefinitionInterface* PTDI) const; + void DeleteLayer(FName LayerName, struct FLandscapeEditDataInterface* LandscapeEdit); + void GeneratePlatformData( UE3::EPlatformType Platform, void*& NewPlatformData, INT& NewPlatformDataSize, UTexture2D*& NewWeightTexture ) const; + + // Persistent splatter editor support + #if __TW_PERSISTENT_SPLATTER_SYSTEM_ + virtual void InvalidateSplatterMapData(); + virtual void MarkSplatterMapRequiringRebuild(); + virtual UBOOL GetPersistentSplatterInfo(FTWPersistentSplatterPrimitiveInfo& OutPrimitiveInfo); + virtual UBOOL GetSplatterMapResolution( INT& Width, INT& Height ) const; + virtual UBOOL ShouldAllowPersistentSplats() const; + virtual void UpdateDependencies(); + #endif +#endif + +#if __TW_PERSISTENT_SPLATTER_SYSTEM_ + // Persistent splatter support + virtual UTWSplatterMap2D* GetSplattermap(const INT LODIndex = 0); +#endif + + virtual void InvalidateLightingCache(); + /** + * Requests whether the component will use texture, vertex or no lightmaps. + * + * @return ELightMapInteractionType The type of lightmap interaction the component will use. + */ + virtual ELightMapInteractionType GetStaticLightingType() const { return LMIT_Texture; } + virtual void GetStreamingTextureInfo(TArray& OutStreamingTextures) const; + + // Decal + void GenerateDecalRenderData(FDecalState* Decal, TArray< FDecalRenderData* >& OutDecalRenderDatas) const; + + // ULandscapeComponent Interface + + /** Return's the landscape actor associated with this component. */ + class ALandscape* GetLandscapeActor() const; + class ALandscapeProxy* GetLandscapeProxy() const; + TMap< UTexture2D*,struct FLandscapeWeightmapUsage >& GetWeightmapUsageMap(); + + virtual const FGuid& GetLightingGuid() const + { +#if WITH_EDITORONLY_DATA + return LightingGuid; +#else + static const FGuid NullGuid( 0, 0, 0, 0 ); + return NullGuid; +#endif // WITH_EDITORONLY_DATA + } + + virtual void SetLightingGuid() + { +#if WITH_EDITORONLY_DATA + LightingGuid = appCreateGuid(); +#endif // WITH_EDITORONLY_DATA + } + +#if WITH_EDITOR + // UObject interface + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + /** Initialize the landscape component */ + void Init(INT InBaseX,INT InBaseY,INT InComponentSizeQuads, INT InNumSubsections,INT InSubsectionSizeQuads); + + /** + * Recalculate cached bounds using height values. + */ + void UpdateCachedBounds(); + + /** + * Update the MaterialInstance parameters to match the layer and weightmaps for this component + * Creates the MaterialInstance if it doesn't exist. + */ + void UpdateMaterialInstances(); + + /** + * Generate mipmaps for height and tangent data. + * @param HeightmapTextureMipData - array of pointers to the locked mip data. + * This should only include the mips that are generated directly from this component's data + * ie where each subsection has at least 2 vertices. + */ + void GenerateHeightmapMips(TArray& HeightmapTextureMipData, INT ComponentX1=0, INT ComponentY1=0, INT ComponentX2=MAXINT, INT ComponentY2=MAXINT,struct FLandscapeTextureDataInfo* TextureDataInfo=NULL); + + /** + * Generates empty mipmaps for weightmap + */ + static void CreateEmptyTextureMips(UTexture2D* Texture, UBOOL bClear = FALSE); + + /** + * Generate mipmaps for weightmap + * Assumes all weightmaps are unique to this component. + * @param WeightmapTextureBaseMipData: array of pointers to each of the weightmaps' base locked mip data. + */ + template + static void GenerateMipsTempl(INT InNumSubsections, INT InSubsectionSizeQuads, UTexture2D* WeightmapTexture, DataType* BaseMipData); + static void GenerateWeightmapMips(INT InNumSubsections, INT InSubsectionSizeQuads, UTexture2D* WeightmapTexture, FColor* BaseMipData); + static void GenerateDataMips(INT InNumSubsections, INT InSubsectionSizeQuads, UTexture2D* WeightmapTexture, BYTE* BaseMipData); + + /** + * Update mipmaps for existing weightmap texture + */ + template + static void UpdateMipsTempl(INT InNumSubsections, INT InSubsectionSizeQuads, UTexture2D* WeightmapTexture, TArray& WeightmapTextureMipData, INT ComponentX1=0, INT ComponentY1=0, INT ComponentX2=MAXINT, INT ComponentY2=MAXINT, struct FLandscapeTextureDataInfo* TextureDataInfo=NULL); + static void UpdateWeightmapMips(INT InNumSubsections, INT InSubsectionSizeQuads, UTexture2D* WeightmapTexture, TArray& WeightmapTextureMipData, INT ComponentX1=0, INT ComponentY1=0, INT ComponentX2=MAXINT, INT ComponentY2=MAXINT, struct FLandscapeTextureDataInfo* TextureDataInfo=NULL); + static void UpdateDataMips(INT InNumSubsections, INT InSubsectionSizeQuads, UTexture2D* Texture, TArray& TextureMipData, INT ComponentX1=0, INT ComponentY1=0, INT ComponentX2=MAXINT, INT ComponentY2=MAXINT, struct FLandscapeTextureDataInfo* TextureDataInfo=NULL); + + /** + * Creates or updates collision component height data + * @param HeightmapTextureMipData: heightmap data + * @param ComponentX1, ComponentY1, ComponentX2, ComponentY2: region to update + * @param Whether to update bounds from render component. + */ + void UpdateCollisionHeightData(FColor* HeightmapTextureMipData, INT ComponentX1=0, INT ComponentY1=0, INT ComponentX2=MAXINT, INT ComponentY2=MAXINT, UBOOL bUpdateBounds=FALSE, UBOOL bRebuild=FALSE); + + /** + * Updates collision component dominant layer data + * @param WeightmapTextureMipData: weightmap data + * @param ComponentX1, ComponentY1, ComponentX2, ComponentY2: region to update + * @param Whether to update bounds from render component. + */ + void UpdateCollisionLayerData(TArray& WeightmapTextureMipData, INT ComponentX1=0, INT ComponentY1=0, INT ComponentX2=MAXINT, INT ComponentY2=MAXINT); + + /** + * Updates collision component dominant layer data for the whole component, locking and unlocking the weightmap textures. + */ + void UpdateCollisionLayerData(); + + /** + * Creates weightmaps for this component for the layers specified in the WeightmapLayerAllocations array + */ + void ReallocateWeightmaps(struct FLandscapeEditDataInterface* DataInterface=NULL); + + /** + * Generate a key for this component's layer allocations to use with MaterialInstanceConstantMap. + */ + UMaterialInterface* GetLandscapeMaterial() const; + FString GetLayerAllocationKey() const; + void GetLayerDebugColorKey(INT& R, INT& G, INT& B) const; + + void RemoveInvalidWeightmaps(); + + virtual void ExportCustomProperties(FOutputDevice& Out, UINT Indent); + virtual void ImportCustomProperties(const TCHAR* SourceText, FFeedbackContext* Warn); + + void InitHeightmapData(TArray& Heights, UBOOL bUpdateCollision); + void InitWeightmapData(TArray& LayerNames, TArray >& Weights); + + FLOAT GetLayerWeightAtLocation( const FVector& InLocation, FName InLayerName, TArray* LayerCache=NULL ); + + /** Return the LandscapeHeightfieldCollisionComponent matching this component */ + ULandscapeHeightfieldCollisionComponent* GetCollisionComponent() const; +#endif + +#if __TW_PRECOMPUTED_VISIBILITY_ + virtual void InvalidatePrecomputedVisibility() + { + MarkPrecomputedVisibilityRequiringRebuild(); + } +#endif + + friend class FLandscapeComponentSceneProxy; + friend struct FLandscapeComponentDataInterface; + + INT GetLODBias(FLOAT HeightThreshold); // Calculate LOD Bias based on heightmap complexity + void SetLOD(UBOOL bForced, INT InLODValue); +} + +defaultproperties +{ +`if(`__TW_LIGHTING_MODIFICATIONS_) + // Landscape lighting channels are toggled per actor + // Do not assign lighting channesl per component + bOverrideAutoLightingChannels=TRUE +`else + LightingChannels=(Static=TRUE,bInitialized=TRUE) +`endif + CollideActors=TRUE + BlockActors=TRUE + BlockZeroExtent=TRUE + BlockNonZeroExtent=TRUE + BlockRigidBody=TRUE + CastShadow=TRUE + bAcceptsLights=TRUE + bAcceptsDecals=TRUE + bAcceptsStaticDecals=TRUE + bUsePrecomputedShadows=TRUE + bForceDirectLightMap=TRUE + bUseAsOccluder=TRUE + bAllowCullDistanceVolume=FALSE + CollisionMipLevel=0 + bNeedPostUndo=FALSE + LODBias=0 + ForcedLOD=-1 + NeighborLOD[0]=255 + NeighborLOD[1]=255 + NeighborLOD[2]=255 + NeighborLOD[3]=255 + NeighborLOD[4]=255 + NeighborLOD[5]=255 + NeighborLOD[6]=255 + NeighborLOD[7]=255 + NeighborLODBias[0]=128 + NeighborLODBias[1]=128 + NeighborLODBias[2]=128 + NeighborLODBias[3]=128 + NeighborLODBias[4]=128 + NeighborLODBias[5]=128 + NeighborLODBias[6]=128 + NeighborLODBias[7]=128 + +`if(`__TW_PERSISTENT_SPLATTER_SYSTEM_) + bAllowPersistentSplatters=TRUE +`endif +} diff --git a/Engine/Classes/LandscapeGizmoActiveActor.uc b/Engine/Classes/LandscapeGizmoActiveActor.uc new file mode 100644 index 0000000..92295d5 --- /dev/null +++ b/Engine/Classes/LandscapeGizmoActiveActor.uc @@ -0,0 +1,122 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class LandscapeGizmoActiveActor extends LandscapeGizmoActor + notplaceable + native(Terrain); + +enum ELandscapeGizmoType +{ + LGT_None, + LGT_Height, + LGT_Weight +}; + +struct native GizmoSelectData +{ + var editoronly float Ratio; + var editoronly float HeightData; + var editoronly native map{FName, FLOAT} WeightDataMap; + + structcpptext + { + FGizmoSelectData() + #if WITH_EDITORONLY_DATA + : Ratio(0.f), HeightData(0.f) + #endif + { + } + } +}; + +var transient editoronly ELandscapeGizmoType DataType; +var const private native map{QWORD, FGizmoSelectData} SelectedData; + +var editoronly Texture2D GizmoTexture; +var editoronly Vector2D TextureScale; +var editoronly array SampledHeight; +var editoronly array SampledNormal; +var editoronly int SampleSizeX; +var editoronly int SampleSizeY; +var editoronly float CachedWidth; +var editoronly float CachedHeight; +var editoronly float CachedScaleXY; +var editoronly transient vector FrustumVerts[8]; + +var editoronly Material GizmoMaterial; +var editoronly MaterialInstance GizmoDataMaterial; +var editoronly Material GizmoMeshMaterial; +var editoronly Material GizmoMeshMaterial2; + +var() editoronly editconst array LayerNames; // only for showing LayerNames currently contained... + +cpptext +{ +#if WITH_EDITOR + // UObject interface. + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + // AActor interface. + virtual void PostEditMove(UBOOL bFinished); + virtual void PostLoad(); + + ALandscapeGizmoActor* SpawnGizmoActor(); + + virtual void Serialize(FArchive& Ar); + void ClearGizmoData(); + void FitToSelection(); + void FitMinMaxHeight(); + void SetTargetLandscape(ULandscapeInfo* LandscapeInfo); + + void CalcNormal(); + void SampleData(INT SizeX, INT SizeY); + + void ExportToClipboard(); + void ImportFromClipboard(); + void Import(INT VertsX, INT VertsY, WORD* HeightData, TArray ImportLayerNames, BYTE* LayerDataPointers[] ); + void Export(INT Index, TArray& Filenames); + + FLOAT GetNormalizedHeight(WORD LandscapeHeight); + FLOAT GetLandscapeHeight(FLOAT NormalizedHeight); + + FLOAT GetWidth() { return Width * DrawScale * DrawScale3D.X; } + FLOAT GetHeight() { return Height * DrawScale * DrawScale3D.Y; } + FLOAT GetLength() { return LengthZ * DrawScale * DrawScale3D.Z; } + + void SetLength(FLOAT WorldLength) { LengthZ = WorldLength / (DrawScale * DrawScale3D.Z); } + + static const INT DataTexSize; +private: + FORCEINLINE FLOAT GetWorldHeight(FLOAT NormalizedHeight); +#endif +} + +defaultproperties +{ + //TickGroup=TG_DuringAsyncWork + + Components.Remove(Sprite) + + GizmoMaterial = Material'EditorLandscapeResources.LandscapeGizmo_Mat' + GizmoDataMaterial = MaterialInstanceConstant'EditorLandscapeResources.LandscapeGizmo_Mat_Copied' + GizmoMeshMaterial = Material'EditorLandscapeResources.LandscapeGizmoHeight_Mat' + GizmoMeshMaterial2 = Material'EditorLandscapeResources.LandscapeGizmoHeight_UnderMat' + + Begin Object Class=LandscapeGizmoRenderComponent Name=GizmoRenderer + End Object + Components.Add(GizmoRenderer) + + bStatic=true + bMovable=false + Width=1280 + Height=1280 + LengthZ=1280 + MarginZ=512 + DataType=LGT_None + bEditable=true + SampleSizeX=0 + SampleSizeY=0 + CachedWidth=0 + CachedHeight=0 + CachedScaleXY=0 +} diff --git a/Engine/Classes/LandscapeGizmoActor.uc b/Engine/Classes/LandscapeGizmoActor.uc new file mode 100644 index 0000000..9180b65 --- /dev/null +++ b/Engine/Classes/LandscapeGizmoActor.uc @@ -0,0 +1,50 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ + +class LandscapeGizmoActor extends Actor + notplaceable + native(Terrain); + +var(Gizmo) editoronly float Width; +var(Gizmo) editoronly float Height; +var(Gizmo) editoronly float LengthZ; +var(Gizmo) editoronly float MarginZ; + +var(Gizmo) editoronly float MinRelativeZ; +var(Gizmo) editoronly float RelativeScaleZ; + +var(Gizmo) editoronly editconst transient LandscapeInfo TargetLandscapeInfo; + +cpptext +{ +#if WITH_EDITOR + virtual void Duplicate(ALandscapeGizmoActor* Gizmo); + //virtual void EditorApplyTranslation(const FVector& DeltaTranslation, UBOOL bAltDown, UBOOL bShiftDown, UBOOL bCtrlDown); +#endif +} + +defaultproperties +{ + TickGroup=TG_DuringAsyncWork + + Begin Object Class=SpriteComponent Name=Sprite + Sprite=Texture2D'EditorResources.S_DecalActorIcon' + Scale=0.3 + HiddenGame=True + AlwaysLoadOnClient=False + AlwaysLoadOnServer=False + SpriteCategoryName="Misc" + End Object + Components.Add(Sprite) + + bStatic=true + bMovable=false + Width=1280 + Height=1280 + LengthZ=1280 + MarginZ=512 + bEditable=false + MinRelativeZ=0.0 + RelativeScaleZ=1.0 +} diff --git a/Engine/Classes/LandscapeGizmoRenderComponent.uc b/Engine/Classes/LandscapeGizmoRenderComponent.uc new file mode 100644 index 0000000..673650b --- /dev/null +++ b/Engine/Classes/LandscapeGizmoRenderComponent.uc @@ -0,0 +1,23 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class LandscapeGizmoRenderComponent extends PrimitiveComponent + native(Terrain) + hidecategories(Object); + +cpptext +{ + /** + * Creates a new scene proxy for the path rendering component. + * @return Pointer to the FLandscapeGizmoSceneProxy + */ + virtual FPrimitiveSceneProxy* CreateSceneProxy(); +}; + +defaultproperties +{ + HiddenGame=true + AlwaysLoadOnClient=false + AlwaysLoadOnServer=false + bSelectable=false +} diff --git a/Engine/Classes/LandscapeHeightfieldCollisionComponent.uc b/Engine/Classes/LandscapeHeightfieldCollisionComponent.uc new file mode 100644 index 0000000..2700490 --- /dev/null +++ b/Engine/Classes/LandscapeHeightfieldCollisionComponent.uc @@ -0,0 +1,122 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class LandscapeHeightfieldCollisionComponent extends PrimitiveComponent + native(Terrain); + +/** The collision height values. */ +var native const UntypedBulkData_Mirror CollisionHeightData{FWordBulkData}; + +/** List of layers painted on this component. Matches the WeightmapLayerAllocations array in the LandscapeComponent. */ +var const array ComponentLayers; + +/** Indices into the ComponentLayers array for the per-vertex dominant layer. */ +var native const UntypedBulkData_Mirror DominantLayerData{FByteBulkData}; + +/** Offset of component in landscape quads */ +var const int SectionBaseX; +var const int SectionBaseY; + +/** Size of component in collision quads */ +var int CollisionSizeQuads; + +/** Collision scale: (ComponentSizeQuads+1) / (CollisionSizeQuads+1) */ +var float CollisionScale; + +/** The flags for each collision quad. See ECollisionQuadFlags. */ +var const array CollisionQuadFlags; + +var const array PhysicalMaterials; + +/** Physics engine version of heightfield data. */ +/*var const native pointer RBHeightfield{class NxHeightField};*/ +var const native pointer RBHeightfield{class PxHeightField}; + +/** Cached bounds, created at heightmap update time */ +var const BoxSphereBounds CachedBoxSphereBounds; + +var bool bIncludeHoles; +var editoronly transient bool bHeightFieldDataHasHole; + +`if(`__TW_PERSISTENT_SPLATTER_SYSTEM_) +/** Needed to reconstruct hit UVs */ +var Vector4 LandscapeLightmapScaleBias; + +/** Ref to the same splattermap as the LandscapeComponent */ +var private const TWSplatterMap2D SplatterMap; +`endif + +cpptext +{ + enum ECollisionQuadFlags + { + QF_PhysicalMaterialMask = 63, // Mask value for the physical material index, stored in the lower 6 bits. + QF_EdgeTurned = 64, // This quad's diagonal has been turned. + QF_NoCollision = 128, // This quad has no collision. + }; + + // UPrimitiveComponent interface. + virtual void UpdateBounds(); + virtual void SetParentToWorld(const FMatrix& ParentToWorld); + virtual void InitComponentRBPhys(UBOOL bFixed); + virtual UBOOL PointCheck(FCheckResult& Result,const FVector& Location,const FVector& Extent,DWORD TraceFlags); + virtual UBOOL LineCheck(FCheckResult& Result,const FVector& End,const FVector& Start,const FVector& Extent,DWORD TraceFlags); + + // UObject Interface + virtual void Serialize(FArchive& Ar); + virtual void BeginDestroy(); +#if WITH_EDITOR + virtual void ExportCustomProperties(FOutputDevice& Out, UINT Indent); + virtual void ImportCustomProperties(const TCHAR* SourceText, FFeedbackContext* Warn); + virtual void PostEditImport(); + virtual void PostEditUndo(); + virtual void PreSave(); + + // Register ourselves with the actor. + ELandscapeSetupErrors SetupActor(UBOOL bForce = FALSE); + void PostLoad(); + + // Update Collision object for add LandscapeComponent tool + void UpdateAddCollisions(UBOOL bForceUpdate = FALSE); + + /** Return the LandscapeComponent matching this collision component */ + class ULandscapeComponent* GetLandscapeComponent() const; + + class ULandscapeInfo* GetLandscapeInfo(UBOOL bSpawnNewActor = TRUE) const; + + /** Return a list of collision triangles in world space */ + void GetCollisionTriangles( TArray& OutTriangleVerts ); + +#endif + +#if __TW_PERSISTENT_SPLATTER_SYSTEM_ + // Persistent splatter support + virtual UTWSplatterMap2D* GetSplattermap(const INT LODIndex = 0); +#endif + + /** Returns the landscape actor associated with this component. */ + class ALandscape* GetLandscapeActor() const; + class ALandscapeProxy* GetLandscapeProxy() const; + + /** Recreate heightfield and restart physics */ + void RecreateHeightfield(UBOOL bUpdateAddCollision = TRUE); +} + +defaultproperties +{ + CollideActors=TRUE + BlockActors=TRUE + BlockZeroExtent=TRUE + BlockNonZeroExtent=TRUE + BlockRigidBody=TRUE + CastShadow=TRUE + bAcceptsLights=TRUE + bAcceptsDecals=FALSE + bAcceptsStaticDecals=FALSE + bAcceptsDynamicDecals=FALSE + bUsePrecomputedShadows=TRUE + bUseAsOccluder=TRUE + bAllowCullDistanceVolume=FALSE + bIncludeHoles=FALSE + bHeightFieldDataHasHole=TRUE +} diff --git a/Engine/Classes/LandscapeInfo.uc b/Engine/Classes/LandscapeInfo.uc new file mode 100644 index 0000000..6e785b1 --- /dev/null +++ b/Engine/Classes/LandscapeInfo.uc @@ -0,0 +1,103 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class LandscapeInfo extends Object + native(Terrain); + +/** Landscape datas */ +var const Guid LandscapeGuid; + +var const native map{FName, struct FLandscapeLayerStruct*} LayerInfoMap; + +var const native pointer DataInterface{struct FLandscapeDataInterface}; + +/** Map of the SectionBaseX/Y component offets (in heightmap space) to the component. Valid in editor only. */ +var const native map{QWORD,class ULandscapeComponent*} XYtoComponentMap; + +/** Map of the SectionBaseX/Y component offets (in heightmap space) to the collison components. Valid in editor only. */ +var const native map{QWORD,class ULandscapeHeightfieldCollisionComponent*} XYtoCollisionComponentMap; + +var const LandscapeProxy LandscapeProxy; + +/** Structure storing Collision for LandscapeComponent Add */ +struct native LandscapeAddCollision +{ + var editoronly vector Corners[4]; + structcpptext + { + FLandscapeAddCollision() + { +#if WITH_EDITORONLY_DATA + Corners[0] = Corners[1] = Corners[2] = Corners[3] = FVector(0.f, 0.f, 0.f); +#endif // WITH_EDITORONLY_DATA + } + } +}; + +/** Map of the SectionBaseX/Y component offets to the newly added collison components. Only available near valid LandscapeComponents. Valid in editor only. */ +var const native map{QWORD,struct FLandscapeAddCollision} XYtoAddCollisionMap; + +var const private native transient Set_Mirror Proxies{TSet}; + +var const private native Set_Mirror SelectedComponents{TSet}; +var const private native Set_Mirror SelectedCollisionComponents{TSet}; +var const private native Set_Mirror SelectedRegionComponents{TSet}; + +var const private native map{QWORD,FLOAT} SelectedRegion; + +var editoronly string HeightmapFilePath; + +var editoronly transient bool bIsValid; + +cpptext +{ + void GetSharedProperties(ALandscapeProxy* Landscape); +#if WITH_EDITOR + virtual void PreSave(); + virtual void PostEditUndo(); + + struct FLandscapeDataInterface* GetDataInterface(); + + void GetComponentsInRegion(INT X1, INT Y1, INT X2, INT Y2, TSet& OutComponents); + UBOOL GetLandscapeExtent(INT& MinX, INT& MinY, INT& MaxX, INT& MaxY); + void Export(TArray& Layernames, TArray& Filenames); + UBOOL ReimportHeightmap(INT DataSize, const WORD* Data); + UBOOL ReimportLayermap(FName LayerName, TArray& Data); + ALandscape* ChangeComponentSetting(INT VertsX, INT VertsY, INT InNumSubsections, INT InSubsectionSizeQuads); + + UBOOL GetSelectedExtent(INT& MinX, INT& MinY, INT& MaxX, INT& MaxY); + FVector GetLandscapeCenterPos(FLOAT& LengthZ, INT MinX = MAXINT, INT MinY = MAXINT, INT MaxX = MININT, INT MaxY = MININT); + UBOOL IsValidPosition(INT X, INT Y); + void DeleteLayer(FName LayerName); + + void UpdateDebugColorMaterial(); + + // Used by all selection tool... + void UpdateSelectedComponents(TSet& NewComponents, UBOOL bIsComponentwise = TRUE); + // Sort selected components based on location + void SortSelectedComponents(); + void ClearSelectedRegion(UBOOL bIsComponentwise = TRUE); + + // Update Collision object for add LandscapeComponent tool + void UpdateAllAddCollisions(); + void UpdateAddCollision(QWORD LandscapeKey, UBOOL bForceUpdate = FALSE); + + // Update LayerInfoMap + UBOOL UpdateLayerInfoMap(ALandscapeProxy* Proxy = NULL, UBOOL bInvalidate = FALSE); + + void UpdateLODBias(FLOAT Threshold); + + void CheckValidate(); +#endif + + // UObject interface + virtual void Serialize(FArchive& Ar); + virtual void BeginDestroy(); + virtual void PostLoad(); +} + +defaultproperties +{ + bIsValid = FALSE +} + \ No newline at end of file diff --git a/Engine/Classes/LandscapeLayerInfoObject.uc b/Engine/Classes/LandscapeLayerInfoObject.uc new file mode 100644 index 0000000..e7750d5 --- /dev/null +++ b/Engine/Classes/LandscapeLayerInfoObject.uc @@ -0,0 +1,26 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + */ +class LandscapeLayerInfoObject extends Object + native(Terrain); + +var() Name LayerName; +var() PhysicalMaterial PhysMaterial; +var() float Hardness; +var editoronly bool bNoWeightBlend; + +cpptext +{ + UBOOL GetSharedProperties(FLandscapeLayerInfo* Info); +#if WITH_EDITOR + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual void PostLoad(); +#endif +} + +defaultproperties +{ + Hardness=0.5 + bNoWeightBlend=false +} \ No newline at end of file diff --git a/Engine/Classes/LandscapeMaterialInstanceConstant.uc b/Engine/Classes/LandscapeMaterialInstanceConstant.uc new file mode 100644 index 0000000..4a3d5af --- /dev/null +++ b/Engine/Classes/LandscapeMaterialInstanceConstant.uc @@ -0,0 +1,24 @@ +class LandscapeMaterialInstanceConstant extends MaterialInstanceConstant + native(Material); + +var bool bIsLayerThumbnail; +var int DataWeightmapIndex; +var int DataWeightmapSize; + +cpptext +{ + /** + * Custom version of AllocateResource to minimize the shaders we need to generate + * @return The allocated resource + */ + FMaterialResource* AllocateResource(); + + static FString LandscapeVisibilitySwitchName; +} + +defaultproperties +{ + bIsLayerThumbnail=False + DataWeightmapIndex=-1 + DataWeightmapSize=0 +} \ No newline at end of file diff --git a/Engine/Classes/LandscapeProxy.uc b/Engine/Classes/LandscapeProxy.uc new file mode 100644 index 0000000..0240b4c --- /dev/null +++ b/Engine/Classes/LandscapeProxy.uc @@ -0,0 +1,227 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class LandscapeProxy extends Info + native(Terrain) + hidecategories(Display, Attachment, Physics, Debug, Lighting, LOD); + +/** Guid for LandscapeEditorInfo **/ +var const Guid LandscapeGuid; + +/** Max LOD level to use when rendering */ +var(LOD) int MaxLODLevel; + +/** Default physical material, used when no per-layer values physical materials */ +var(Landscape) PhysicalMaterial DefaultPhysMaterial; + +/** + * Allows artists to adjust the distance where textures using UV 0 are streamed in/out. + * 1.0 is the default, whereas a higher value increases the streamed-in resolution. + */ +var(Landscape) const float StreamingDistanceMultiplier; + +/** Combined material used to render the landscape */ +var(Landscape) MaterialInterface LandscapeMaterial; +var(LOD) float LODDistanceFactor; + +/** The array of LandscapeComponent that are used by the landscape */ +var const array LandscapeComponents; + +/** Array of LandscapeHeightfieldCollisionComponent */ +var const array CollisionComponents; + +/** Structure storing channel usage for weightmap textures */ +struct native LandscapeWeightmapUsage +{ + var LandscapeComponent ChannelUsage[4]; + + structcpptext + { + // tor + FLandscapeWeightmapUsage() + { + ChannelUsage[0] = NULL; + ChannelUsage[1] = NULL; + ChannelUsage[2] = NULL; + ChannelUsage[3] = NULL; + } + + // Serializer + friend FArchive& operator<<( FArchive& Ar, FLandscapeWeightmapUsage& U ); + + INT FreeChannelCount() const + { + return ((ChannelUsage[0] == NULL) ? 1 : 0) + + ((ChannelUsage[1] == NULL) ? 1 : 0) + + ((ChannelUsage[2] == NULL) ? 1 : 0) + + ((ChannelUsage[3] == NULL) ? 1 : 0); + } + } +}; + +/** Map of material instance constants used to for the components. Key is generated with ULandscapeComponent::GetLayerAllocationKey() */ +var const native map{FString ,class UMaterialInstanceConstant*} MaterialInstanceConstantMap; + +/** Map of weightmap usage */ +var const native map{UTexture2D*,struct FLandscapeWeightmapUsage} WeightmapUsageMap; + +/** + * The resolution to cache lighting at, in texels/patch. + * A separate shadow-map is used for each terrain component, which is up to + * (MaxComponentSize * StaticLightingResolution + 1) pixels on a side. + * Must be a power of two, 1 <= StaticLightingResolution <= MaxTesselationLevel. + */ +var(Lighting) float StaticLightingResolution; + +`if(`__TW_PERSISTENT_SPLATTER_SYSTEM_) +/** The resolution to use for splattermaps in texels/patch */ +var(PersistentSplats) float SplatterMapResolution; +`endif + +`if(`__TW_LIGHTING_MODIFICATIONS_) +/** + * Lighting channels controlling light/ primitive interaction. Only allows interaction if at least one channel is shared + * + */ +var(Lighting) const LightingChannelContainer LightingChannels; +`endif + +var(LandscapeProxy) transient Landscape LandscapeActor; +var const bool bIsProxy; +var editoronly transient bool bIsSetup; +var editoronly transient bool bResetup; +var editoronly transient bool bIsMovingToLevel; // Check for the Move to Current Level case + +/** The Lightmass settings for this object. */ +var(Lightmass) LightmassPrimitiveSettings LightmassSettings ; + +/** The landscape LOD level to use when generating collision data */ +var(LOD) int CollisionMipLevel; + +/** The first landscape LOD level to use on mobile platforms */ +var(LOD) int MobileLodBias; + +struct native LandscapeLayerStruct +{ + var LandscapeLayerInfoObject LayerInfoObj; + + var editoronly MaterialInstanceConstant ThumbnailMIC; + var editoronly LandscapeProxy Owner; + var editoronly transient int DebugColorChannel; + var editoronly transient bool bSelected; + var editoronly string SourceFilePath; + + structcpptext + { + FLandscapeLayerStruct(ULandscapeLayerInfoObject* InLayerInfo, class ALandscapeProxy* InProxy, const TCHAR* InFilePath) +#if WITH_EDITORONLY_DATA + : SourceFilePath(E_ForceInit) +#endif + { + LayerInfoObj = InLayerInfo; +#if WITH_EDITORONLY_DATA + ThumbnailMIC = NULL; + DebugColorChannel = 0; + bSelected = FALSE; + Owner = InProxy; + SourceFilePath = InFilePath; +#endif + } + } +}; + +var array LayerInfoObjs; + +/** Data set at creation time */ +var const int ComponentSizeQuads; // Total number of quads in each component +var const int SubsectionSizeQuads; // Number of quads for a subsection of a component. SubsectionSizeQuads+1 must be a power of two. +var const int NumSubsections; // Number of subsections in X and Y axis + +cpptext +{ + // AActor interface + virtual UBOOL ShouldTrace(UPrimitiveComponent* Primitive,AActor *SourceActor, DWORD TraceFlags); + virtual void UpdateComponentsInternal(UBOOL bCollisionUpdate = FALSE); + virtual void ClearComponents(); + virtual void InitRBPhys(); + + virtual class ALandscape* GetLandscapeActor(); + + virtual FGuid* GetGuid() { return &LandscapeGuid; } + + // Cross level things... + virtual void ClearCrossLevelReferences(); + +#if WITH_EDITOR + ULandscapeLayerInfoObject* GetLayerInfo(const TCHAR* LayerName, UPackage* Package = NULL, const TCHAR* SourceFilePath = NULL); + ULandscapeInfo* GetLandscapeInfo(UBOOL bSpawnNewActor = TRUE); + + virtual void PostScriptDestroyed(); + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual void PreSave(); + virtual void InitRBPhysEditor(); + + virtual void PreEditUndo(); + virtual void PostEditUndo(); + virtual void PostEditMove(UBOOL bFinished); + virtual void PostEditImport(); + + virtual UMaterialInterface* GetLandscapeMaterial() const; + + // Called before editor copy, TRUE allow export + virtual UBOOL ShouldExport(); + // Called before editor paste, TRUE allow import + virtual UBOOL ShouldImport(FString* ActorPropString, UBOOL IsMovingLevel); + virtual UBOOL GetSelectedComponents(TArray& SelectedObjects); + + void RemoveInvalidWeightmaps(); + void ChangedPhysMaterial(); + + virtual void UpdateLandscapeActor(class ALandscape* Landscape, UBOOL bSearchForActor = TRUE); + UBOOL IsValidLandscapeActor(class ALandscape* Landscape); + void GetSharedProperties(class ALandscape* Landscape); + + static void RestoreLandscapeAfterSave(); +#endif + + // UObject interface + virtual void Serialize(FArchive& Ar); + virtual void BeginDestroy(); + virtual void PostLoad(); + +#if !PS3 + void ChangeLODDistanceFactor(FLOAT InLODDistanceFactor); +#endif +} + +defaultproperties +{ + Begin Object Name=Sprite + Sprite=Texture2D'EditorResources.S_Terrain' + End Object + + DrawScale3D=(X=128.0,Y=128.0,Z=256.0) + StaticLightingResolution=1.0 + StreamingDistanceMultiplier=1.0 + bEdShouldSnap=True + bCollideActors=True + bBlockActors=True + bWorldGeometry=True + bStatic=True + bNoDelete=True + bHidden=False + bMovable=False + bIsProxy=True + bLockLocation=True + MaxLODLevel=-1 + bIsSetup=False + bResetup=False + bIsMovingToLevel=False + LODDistanceFactor=1.f + CollisionMipLevel=0 + +`if(`__TW_LIGHTING_MODIFICATIONS_) + LightingChannels=(Outdoor=TRUE,bInitialized=TRUE) +`endif +} + \ No newline at end of file diff --git a/Engine/Classes/LensFlare.uc b/Engine/Classes/LensFlare.uc new file mode 100644 index 0000000..a97c53d --- /dev/null +++ b/Engine/Classes/LensFlare.uc @@ -0,0 +1,310 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class LensFlare extends Object + native(LensFlare) + dontcollapsecategories + hidecategories(Object); + +/** + * Helper for getting curves from distributions + */ +struct native transient LensFlareElementCurvePair +{ + var string CurveName; + var object CurveObject; +}; + +/** + * LensFlare Element + */ +struct native LensFlareElement +{ + /** + * The name of the element. (Optional) + */ + var() name ElementName; + + /** + * The position along the ray from the source to the viewpoint to render the flare at. + * 0.0 = At the source + * 1.0 = The source point reflected about the view center. + * < 0 = The point along the ray going away from the center past the source. + * > 1 = The point along the ray beyond the 'end point' of the ray reflection. + */ + var() float RayDistance; + + /** + * Whether the element is enabled or not + */ + var() bool bIsEnabled; + + /** + * Whether the element value look ups should use the radial distance + * from the center to the edge of the screen or the ratio of the distance + * from the source element. + */ + var() bool bUseSourceDistance; + + /** + * Whether the radial distance should be normalized to a unit value. + * Without this, the radial distance will be 0..1 in the horizontal and vertical cases. + * It will be 0..1.4 in the corners. + */ + var() bool bNormalizeRadialDistance; + + /** + * Whether the element color value should be scaled by the source color. + */ + var() bool bModulateColorBySource; + + /** + * The 'base' size of the element + */ + var() vector Size; + + /** + * The material(s) to use for the flare element. + */ + var(Material) array LFMaterials; + + /** + * Each of the following properties are accessed based on the radial distance from the + * center of the screen to the edge. + * <1 = Opposite the ray direction + * 0 = Center view + * 1 = Edge of screen + * >1 = Outside of screen edge + */ + + /** Index of the material to use from the LFMaterial array. */ + var(Material) rawdistributionfloat LFMaterialIndex; + + /** Global scaling. */ + var(Scaling) rawdistributionfloat Scaling; + + /** Anamorphic scaling. */ + var(Scaling) rawdistributionvector AxisScaling; + + /** Rotation. */ + var(Rotation) rawdistributionfloat Rotation; + /** If TRUE, always rotate the element to orient towards the source */ + var(Rotation) bool bOrientTowardsSource; + + /** Color (passed to the element material via the VertexColor expression) */ + var(Color) rawdistributionvector Color; + /** Alpha (passed to the element material via the VertexColor expression) */ + var(Color) rawdistributionfloat Alpha; + + /** Offset. */ + var(Offset) rawdistributionvector Offset; + + /** Source to camera distance scaling. */ + /** Value to scale the AxisScaling by. Uses source to camera distance to look up the value (in Unreal units) */ + var(Scaling) rawdistributionvector DistMap_Scale; + /** Value to scale the Color by. Uses source to camera distance to look up the value (in Unreal units) */ + var(Scaling) rawdistributionvector DistMap_Color; + /** Value to scale the Alpha by. Uses source to camera distance to look up the value (in Unreal units) */ + var(Scaling) rawdistributionfloat DistMap_Alpha; + + structcpptext + { + void GetCurveObjects(TArray& OutCurves); + void DuplicateDistribution_Float(const FRawDistributionFloat& SourceDist, UObject* Outer, FRawDistributionFloat& NewDist); + void DuplicateDistribution_Vector(const FRawDistributionVector& SourceDist, UObject* Outer, FRawDistributionVector& NewDist); + UBOOL DuplicateFromSource(const FLensFlareElement& InSource, UObject* Outer); + UObject* GetCurve(FString& CurveName); + } + + structdefaultproperties + { + RayDistance=0.0 + bNormalizeRadialDistance=true + + Begin Object Class=DistributionFloatConstant Name=DistributionLFMaterialIndex + Constant=0.0; + End Object + LFMaterialIndex=(Distribution=DistributionLFMaterialIndex) + + Begin Object Class=DistributionFloatConstant Name=DistributionScaling + Constant=1.0; + End Object + Scaling=(Distribution=DistributionScaling) + + Begin Object Class=DistributionVectorConstant Name=DistributionAxisScaling + Constant=(X=1.0,Y=1.0,Z=0.0) + End Object + AxisScaling=(Distribution=DistributionAxisScaling) + + Begin Object Class=DistributionFloatConstant Name=DistributionRotation + Constant=1.0; + End Object + Rotation=(Distribution=DistributionRotation) + + Begin Object Class=DistributionVectorConstant Name=DistributionColor + Constant=(X=1.0,Y=1.0,Z=1.0) + End Object + Color=(Distribution=DistributionColor) + + Begin Object Class=DistributionFloatConstant Name=DistributionAlpha + Constant=1.0f; + End Object + Alpha=(Distribution=DistributionAlpha) + + Begin Object Class=DistributionVectorConstant Name=DistributionOffset + Constant=(X=0.0,Y=0.0,Z=0.0) + End Object + Offset=(Distribution=DistributionOffset) + + Begin Object Class=DistributionVectorConstant Name=DistributionDistMap_Scale + Constant=(X=1.0,Y=1.0,Z=1.0) + End Object + DistMap_Scale=(Distribution=DistributionDistMap_Scale) + + Begin Object Class=DistributionVectorConstant Name=DistributionDistMap_Color + Constant=(X=1.0,Y=1.0,Z=1.0) + End Object + DistMap_Color=(Distribution=DistributionDistMap_Color) + + Begin Object Class=DistributionFloatConstant Name=DistributionDistMap_Alpha + Constant=1.0f; + End Object + DistMap_Alpha=(Distribution=DistributionDistMap_Alpha) + } +}; + +/** The Source of the lens flare */ +var editinline export LensFlareElement SourceElement; +/** The StaticMesh to use as the source (optional) */ +var(Source) StaticMesh SourceMesh; +/** The scene depth priority group to draw the source primitive in. */ +var const ESceneDepthPriorityGroup SourceDPG; + +/** The individual reflection elements of the lens flare */ +var editinline export array Reflections; +/** The scene depth priority group to draw the reflection primitive(s) in. */ +var(Reflections) const ESceneDepthPriorityGroup ReflectionsDPG; + +/** Viewing cone angles. */ +var(Visibility) float OuterCone; +var(Visibility) float InnerCone; +var(Visibility) float ConeFudgeFactor; +var(Visibility) float Radius; +/** When true the new algorithm is used (NOTE: The new algorithm does not use ConeFudgeFactor). */ +var(Visibility) bool bUseTrueConeCalculation; +/** (New Algorithm only) If this is non-zero the lens flare will always draw with at least the strength specified, even behind or outside outer cone. */ +var(Visibility) float MinStrength; + +/** Occlusion. */ +/** + * The mapping of screen coverage percentage (the result returned by occlusion checks) + * to the value passed into the materials for LensFlareOcclusion. + */ +var(Occlusion) rawdistributionfloat ScreenPercentageMap; + +/** + * If TRUE, use the given bounds. + * If FALSE and a static mesh is set for the source, the static mesh bounds will be used. + * If FALSE and no static mesh is set, it will use the default bounds (likely not a good thing). + */ +var(Bounds) bool bUseFixedRelativeBoundingBox; +/** The fixed bounding box to use when bUseFixedRelativeBoundingBox is TRUE */ +var(Bounds) box FixedRelativeBoundingBox; + +/** Debugging helpers */ +var(Debug) bool bRenderDebugLines; + +/** Used for curve editor to remember curve-editing setup. */ +var export InterpCurveEdSetup CurveEdSetup; + +/** Internal variable used to initialize new entries in the Reflectsions array */ +var transient int ReflectionCount; + +/** The angle to use when rendering the thumbnail image */ +var rotator ThumbnailAngle; + +/** The distance to place the system when rendering the thumbnail image */ +var float ThumbnailDistance; + +/** Internal: Indicates the thumbnail image is out of date */ +var bool ThumbnailImageOutOfDate; +/** Internal: The thumbnail image */ +var Texture2D ThumbnailImage; + +// +cpptext +{ + // UObject interface. + virtual void PreEditChange(UProperty* PropertyAboutToChange); + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual void PostLoad(); + + // CurveEditor helper interface + void AddElementCurvesToEditor(INT ElementIndex, UInterpCurveEdSetup* EdSetup); + void RemoveElementCurvesFromEditor(INT ElementIndex, UInterpCurveEdSetup* EdSetup); + void AddElementCurveToEditor(INT ElementIndex, FString& CurveName, UInterpCurveEdSetup* EdSetup); + UObject* GetElementCurve(INT ElementIndex, FString& CurveName); + + // + const FLensFlareElement* GetElement(INT ElementIndex) const; + + /** Return TRUE if element was found and bIsEnabled set to given value. */ + UBOOL SetElementEnabled(INT ElementIndex, UBOOL bInIsEnabled); + + /** Initialize the element at the given index */ + UBOOL InitializeElement(INT ElementIndex); + + /** Get the curve objects associated with the LensFlare itself */ + void GetCurveObjects(TArray& OutCurves); +} + +// +defaultproperties +{ + Begin Object Class=DistributionFloatConstant Name=DistributionLFMaterialIndex + Constant=0.0; + End Object + Begin Object Class=DistributionFloatConstant Name=DistributionScaling + Constant=1.0; + End Object + Begin Object Class=DistributionVectorConstant Name=DistributionAxisScaling + Constant=(X=1.0,Y=1.0,Z=0.0) + End Object + Begin Object Class=DistributionFloatConstant Name=DistributionRotation + Constant=0.0; + End Object + Begin Object Class=DistributionVectorConstant Name=DistributionColor + Constant=(X=1.0,Y=1.0,Z=1.0) + End Object + Begin Object Class=DistributionFloatConstant Name=DistributionAlpha + Constant=1.0f; + End Object + Begin Object Class=DistributionVectorConstant Name=DistributionOffset + Constant=(X=0.0,Y=0.0,Z=0.0) + End Object + Begin Object Class=DistributionVectorConstant Name=DistributionDistMap_Scale + Constant=(X=1.0,Y=1.0,Z=1.0) + End Object + Begin Object Class=DistributionVectorConstant Name=DistributionDistMap_Color + Constant=(X=1.0,Y=1.0,Z=1.0) + End Object + Begin Object Class=DistributionFloatConstant Name=DistributionDistMap_Alpha + Constant=1.0f; + End Object + + SourceElement=(ElementName="Source",RayDistance=0.0,bIsEnabled=true,Size=(X=75.0f,Y=75.0f,Z=75.0f),LFMaterialIndex=(Distribution=DistributionLFMaterialIndex),Scaling=(Distribution=DistributionScaling),AxisScaling=(Distribution=DistributionAxisScaling),Rotation=(Distribution=DistributionRotation),Color=(Distribution=DistributionColor),Alpha=(Distribution=DistributionAlpha),Offset=(Distribution=DistributionOffset),DistMap_Scale=(Distribution=DistributionDistMap_Scale),DistMap_Color=(Distribution=DistributionDistMap_Color),DistMap_Alpha=(Distribution=DistributionDistMap_Alpha)) + SourceDPG=SDPG_World + ReflectionsDPG=SDPG_Foreground + + OuterCone=0.0 + InnerCone=0.0 + ConeFudgeFactor=0.5 + Radius=0.0 + bUseTrueConeCalculation=false + MinStrength=0.0 + + Begin Object Class=DistributionFloatConstantCurve Name=DistributionScreenPercentageMap + ConstantCurve=(Points=((InVal=0.0,OutVal=0.0),(InVal=1.0,OutVal=1.0))) + End Object + ScreenPercentageMap=(Distribution=DistributionScreenPercentageMap) +} diff --git a/Engine/Classes/LensFlareComponent.uc b/Engine/Classes/LensFlareComponent.uc new file mode 100644 index 0000000..65469fa --- /dev/null +++ b/Engine/Classes/LensFlareComponent.uc @@ -0,0 +1,182 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class LensFlareComponent extends PrimitiveComponent + native(LensFlare) + hidecategories(Object) + hidecategories(Physics) + hidecategories(Collision) + editinlinenew + dependson(LensFlare); + +var() const LensFlare Template; +var const DrawLightConeComponent PreviewInnerCone; +var const DrawLightConeComponent PreviewOuterCone; +var const DrawLightRadiusComponent PreviewRadius; + +struct LensFlareElementInstance +{ + // No UObject reference +}; + +/** If TRUE, automatically enable this flare when it is attached */ +var() bool bAutoActivate; + +/** Internal variables */ +var transient bool bIsActive; +var transient bool bHasTranslucency; +var transient bool bHasUnlitTranslucency; +var transient bool bHasUnlitDistortion; +var transient bool bUsesSceneColor; +var transient bool bHasSeparateTranslucency; + +/** Viewing cone angles. */ +var transient float OuterCone; +var transient float InnerCone; +var transient float ConeFudgeFactor; +var transient float Radius; +/** When true the new algorithm is used (NOTE: The new algorithm does not use ConeFudgeFactor). */ +var transient bool bUseTrueConeCalculation; +/** (New Algorithm only) If this is non-zero the lens flare will always draw with at least the strength specified, even behind or outside outer cone. */ +var transient float MinStrength; + +/** The color of the source */ +var(Rendering) linearcolor SourceColor; + +/** Storage for mobile as to whether this lens flare was visible based on a line check on previous check*/ +var bool bVisibleForMobile; + +struct native LensFlareElementMaterials +{ + var() array ElementMaterials; +}; + +/** Per-element material overrides. These must NOT be set directly or a race condition can occur between GC and the rendering thread. */ +var transient array Materials; + +/** Command fence used to shut down properly */ +var native const pointer ReleaseResourcesFence{class FRenderCommandFence}; + +/** Used to determine when to trace on mobile platforms */ +var float NextTraceTime; + +native final function SetTemplate(LensFlare NewTemplate, bool bForceSet=FALSE); +native function SetSourceColor(linearcolor InSourceColor); +native function SetIsActive(bool bInIsActive); + +cpptext +{ + // UObject interface + virtual void BeginDestroy(); + virtual UBOOL IsReadyForFinishDestroy(); + virtual void FinishDestroy(); + virtual void PreEditChange(UProperty* PropertyThatWillChange); + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + virtual void PostLoad(); + + // UActorComponent interface. + virtual void Attach(); + +public: + // UPrimitiveComponent interface + virtual void UpdateBounds(); + virtual void Tick(FLOAT DeltaTime); + + /** + * Setup the Materials array for the lens flare component. + * + * @param bForceReset If TRUE, reset the array and refill it from the template. + */ + void SetupMaterialsArray(UBOOL bForceReset); + + virtual INT GetNumElements() const; + virtual UMaterialInterface* GetElementMaterial(INT MaterialIndex) const; + virtual void SetElementMaterial(INT ElementIndex, UMaterialInterface* InMaterial); + + /** + * Retrieves the materials used in this component + * + * @param OutMaterials The list of used materials. + */ + virtual void GetUsedMaterials( TArray& OutMaterials ) const; + + /** Returns true if the prim is using a material with unlit distortion */ + virtual UBOOL HasUnlitDistortion() const; + /** Returns true if the prim is using a material with unlit translucency */ + virtual UBOOL HasUnlitTranslucency() const; + /** Returns true if the prim is using a material with lit translucency */ + virtual UBOOL HasLitTranslucency() const; + /** Returns true if the prim is using a material with separate translucency */ + virtual UBOOL HasSeparateTranslucency() const; + + /** + * Returns true if the prim is using a material that samples the scene color texture. + * If true then these primitives are drawn after all other translucency + */ + virtual UBOOL UsesSceneColor() const; + + /** + * Initialize the draw data that gets used when creating the visualization scene proxys. + * + * @param bUseTemplate If true, will initialize with the data found in the lens flare template object. + */ + virtual void InitializeVisualizationData(UBOOL bUseTemplate); + + virtual FPrimitiveSceneProxy* CreateSceneProxy(); + + // InstanceParameters interface + void AutoPopulateInstanceProperties(); +} + +/** + * @param ElementIndex - The element to access the material of. + * @return the material used by the indexed element of this mesh. + */ +native function MaterialInterface GetMaterial(int ElementIndex); + +/** + * Changes the material applied to an element of the mesh. + * @param ElementIndex - The element to access the material of. + * @return the material used by the indexed element of this mesh. + */ +native virtual function SetMaterial(int ElementIndex, MaterialInterface Material); + +`if(`__TW_LIGHTING_MODIFICATIONS_) +/** Returns the number of elements */ +native function int GetNumMaterials(); +`endif + +/** + * Creates a material instance for the specified element index. The parent of the instance is set to the material being replaced. + * @param ElementIndex - The index of the skin to replace the material for. + */ +function MaterialInstanceConstant CreateAndSetMaterialInstanceConstant(int ElementIndex) +{ + local MaterialInstanceConstant Instance; + + // Create the material instance. + Instance = new(self) class'MaterialInstanceConstant'; + Instance.SetParent(GetMaterial(ElementIndex)); + + // Assign it to the given mesh element. + // This MUST be done after setting the parent; otherwise the component will use the default material in place of the invalid material instance. + SetMaterial(ElementIndex,Instance); + + return Instance; +} + + +defaultproperties +{ + NextTraceTime=0.0 + bAutoActivate=true + bTickInEditor=true + TickGroup=TG_PostAsyncWork + bAllowApproximateOcclusion=false + bFirstFrameOcclusion=true + bIgnoreNearPlaneIntersection=true + + SourceColor=(R=1.0,G=1.0,B=1.0,A=1.0) + + bVisibleForMobile=false; +} diff --git a/Engine/Classes/LensFlareSource.uc b/Engine/Classes/LensFlareSource.uc new file mode 100644 index 0000000..e7a24da --- /dev/null +++ b/Engine/Classes/LensFlareSource.uc @@ -0,0 +1,257 @@ +/** + * LensFlare source actor class. + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class LensFlareSource extends Actor + native(LensFlare) + placeable; + +var() editconst const LensFlareComponent LensFlareComp; + +/** used to update status of toggleable level placed lens flares on clients */ +var repnotify bool bCurrentlyActive; + +replication +{ + if (bNoDelete) + bCurrentlyActive; +} + +cpptext +{ + void AutoPopulateInstanceProperties(); + + // AActor interface. + /** + * Function that gets called from within Map_Check to allow this actor to check itself + * for any potential errors and register them with map check dialog. + */ +#if WITH_EDITOR + virtual void CheckForErrors(); +#endif +} + +//native noexport event SetTemplate(LensFlare NewTemplate); +native final function SetTemplate(LensFlare NewTemplate); + +simulated event PostBeginPlay() +{ + bCurrentlyActive = LensFlareComp.bIsActive; +`if(`__TW_PERFORMANCE_) + if (WorldInfo.NetMode == NM_DedicatedServer) + { + SetTickIsDisabled(true); + } +`endif +} + +/** + * Handling Toggle event from Kismet. + */ +simulated function OnToggle(SeqAct_Toggle action) +{ + // Turn ON + if (action.InputLinks[0].bHasImpulse) + { + LensFlareComp.SetIsActive(TRUE); + bCurrentlyActive = TRUE; + } + // Turn OFF + else if (action.InputLinks[1].bHasImpulse) + { + LensFlareComp.SetIsActive(FALSE); + bCurrentlyActive = FALSE; + } + // Toggle + else if (action.InputLinks[2].bHasImpulse) + { + // If spawning is suppressed or we aren't turned on at all, activate. + if (!bCurrentlyActive) + { + LensFlareComp.SetIsActive(TRUE); + bCurrentlyActive = TRUE; + } + else + { + LensFlareComp.SetIsActive(FALSE); + bCurrentlyActive = FALSE; + } + } + LensFlareComp.LastRenderTime = WorldInfo.TimeSeconds; + ForceNetRelevant(); +} + +simulated event ReplicatedEvent(name VarName) +{ + if (VarName == nameof(bCurrentlyActive)) + { + LensFlareComp.SetIsActive(bCurrentlyActive); + LensFlareComp.LastRenderTime = WorldInfo.TimeSeconds; + } +} + +simulated function SetFloatParameter(name ParameterName, float Param) +{ +/*** + if (LensFlareComp != none) + { + LensFlareComp.SetFloatParameter(ParameterName, Param); + } + else + { + `log("Warning: Attempting to set a parameter on "$self$" when the PSC does not exist"); + } +***/ +} + +simulated function SetVectorParameter(name ParameterName, vector Param) +{ +/*** + if (LensFlareComp != none) + { + LensFlareComp.SetVectorParameter(ParameterName, Param); + } + else + { + `log("Warning: Attempting to set a parameter on "$self$" when the PSC does not exist"); + } +***/ +} + +simulated function SetColorParameter(name ParameterName, linearcolor Param) +{ +/*** + if (LensFlareComp != none) + { + LensFlareComp.SetColorParameter(ParameterName, Param); + } + else + { + `log("Warning: Attempting to set a parameter on "$self$" when the PSC does not exist"); + } +***/ +} + +simulated function SetExtColorParameter(name ParameterName, float Red, float Green, float Blue, float Alpha) +{ +/*** + local linearcolor c; + + if (LensFlareComp != none) + { + c.r = Red; + c.g = Green; + c.b = Blue; + c.a = Alpha; + LensFlareComp.SetColorParameter(ParameterName, C); + } + else + { + `log("Warning: Attempting to set a parameter on "$self$" when the PSC does not exist"); + } +***/ +} + + +simulated function SetActorParameter(name ParameterName, actor Param) +{ +/*** + if (LensFlareComp != none) + { + LensFlareComp.SetActorParameter(ParameterName, Param); + } + else + { + `log("Warning: Attempting to set a parameter on "$self$" when the PSC does not exist"); + } +***/ +} + +/** + * Kismet handler for setting particle instance parameters. + */ +/*** +simulated function OnSetLensFlareParam(SeqAct_SetLensFlareParam Action) +{ + local int Idx, ParamIdx; + if ((LensFlareComp != None) && (Action.InstanceParameters.Length > 0)) + { + for (Idx = 0; Idx < Action.InstanceParameters.Length; Idx++) + { + if (Action.InstanceParameters[Idx].ParamType != PSPT_None) + { + // look for an existing entry + ParamIdx = LensFlareComp.InstanceParameters.Find('Name',Action.InstanceParameters[Idx].Name); + // create one if necessary + if (ParamIdx == -1) + { + ParamIdx = LensFlareComp.InstanceParameters.Length; + LensFlareComp.InstanceParameters.Length = ParamIdx + 1; + } + // update the instance parm + LensFlareComp.InstanceParameters[ParamIdx] = Action.InstanceParameters[Idx]; + if (Action.bOverrideScalar) + { + LensFlareComp.InstanceParameters[ParamIdx].Scalar = Action.ScalarValue; + } + } + } + } +} +***/ +defaultproperties +{ + // Visual things should be ticked in parallel with physics + TickGroup=TG_DuringAsyncWork + + Begin Object Class=SpriteComponent Name=Sprite + Sprite=Texture2D'EditorResources.S_Emitter' + HiddenGame=True + AlwaysLoadOnClient=False + AlwaysLoadOnServer=False + bIsScreenSizeScaled=True + ScreenSize=0.0025 + SpriteCategoryName="LensFlares" + End Object + Components.Add(Sprite) + + // Inner cone visualization. + Begin Object Class=DrawLightConeComponent Name=DrawInnerCone0 + ConeColor=(R=150,G=200,B=255) + End Object + Components.Add(DrawInnerCone0) + + // Outer cone visualization. + Begin Object Class=DrawLightConeComponent Name=DrawOuterCone0 + ConeColor=(R=200,G=255,B=255) + End Object + Components.Add(DrawOuterCone0) + + // Light radius visualization. + Begin Object Class=DrawLightRadiusComponent Name=DrawRadius0 + End Object + Components.Add(DrawRadius0) + + Begin Object Class=LensFlareComponent Name=LensFlareComponent0 + PreviewInnerCone=DrawInnerCone0 + PreviewOuterCone=DrawOuterCone0 + PreviewRadius=DrawRadius0 + End Object + LensFlareComp=LensFlareComponent0 + Components.Add(LensFlareComponent0) + + Begin Object Class=ArrowComponent Name=ArrowComponent0 + ArrowColor=(R=0,G=255,B=128) + ArrowSize=1.5 + bTreatAsASprite=True + AlwaysLoadOnClient=False + AlwaysLoadOnServer=False + SpriteCategoryName="LensFlares" + End Object + Components.Add(ArrowComponent0) + + bEdShouldSnap=true + bHardAttach=true + bGameRelevant=true + bNoDelete=true +} diff --git a/Engine/Classes/LevelGridVolume.uc b/Engine/Classes/LevelGridVolume.uc new file mode 100644 index 0000000..396889f --- /dev/null +++ b/Engine/Classes/LevelGridVolume.uc @@ -0,0 +1,299 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class LevelGridVolume extends Volume + native + dependson(KMeshProps) + hidecategories(Advanced,Attachment,Collision,Volume,Physics,Location) + autoexpandcategories(LevelGridVolume) + placeable; + + + +/** Structure contains coordinates for a single grid cell */ +struct native LevelGridCellCoordinate +{ + /** Cell X coordinate */ + var int X; + + /** Cell Y coordinate */ + var int Y; + + /** Cell Z coordinate */ + var int Z; + + structcpptext + { + /** Constructor */ + FLevelGridCellCoordinate() + : X( 0 ), Y( 0 ), Z( 0 ) + { + } + + /** Equality operator */ + UBOOL operator==( const FLevelGridCellCoordinate& RHS ) const + { + return ( RHS.X == X && RHS.Y == Y && RHS.Z == Z ); + } + } +}; + + + +/** Possible shapes for grid cells */ +enum LevelGridCellShape +{ + /** Axis-aligned boxes */ + LGCS_Box, + + /** Hexagonal prism */ + LGCS_Hex +}; + + +/** Name of this level grid volume, which is also the prefix for level names created for volume. If empty, the level grid volume actor's name will be used instead. You should set this name before placing any actors into the level, and never change it afterwards! */ +var() const string LevelGridVolumeName; + +/** Shape of the cells this grid is composed of */ +var() const LevelGridCellShape CellShape; + +/** The number of streaming volumes should the grid be subdivided into along each axis. Be careful when changing this after actors have been added to the level grid volume! */ +var() const int Subdivisions[ 3 ]; + +/* +* Width of each grid cell (X axis size.) Be careful when changing this after actors have been added to the level grid volume! / +var() const int CellWidth; + +* Depth of each grid cell (Y axis size.) Be careful when changing this after actors have been added to the level grid volume! / +var() const int CellDepth; + +* Height of each grid cell (Z axis size.) Be careful when changing this after actors have been added to the level grid volume! / +var() const int CellHeight; + +* Location offset for all grid cells in the map. Be careful when changing this after actors have been added to the level grid volume! / +var() const vector GridOffset; +*/ + + +/** Minimum distance between a grid cell and the viewer before a cell's level will be queued to stream in */ +var() const float LoadingDistance; + +/** Extra distance before the LoadingDistance which levels should stay loaded. This can be used to prevent a level from continuously being loaded and unloaded as the viewer's distance to the cell crosses the LoadingDistance threshold. */ +var() const float KeepLoadedRange; + +/** Grid cell convex shape, used for fast distance tests */ +var const transient KConvexElem CellConvexElem; + + + +cpptext +{ + /** + * Gets the "friendly" name of this grid volume + * + * @return The name of this grid volume + */ + FString GetLevelGridVolumeName() const; + + + /** + * UObject: Performs operations after the object is loaded + */ + virtual void PostLoad(); + + + /** + * UObject: Called when a property value has been changed in the editor. + * + * @param PropertyThatChanged The property that changed, or NULL + */ + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); + + + /** + * Computes the world space bounds of the entire grid + * + * @return Bounds of the grid in world space + */ + FBox GetGridBounds() const; + + + /** + * Computes the size of a grid subdivision (not necessarily the same as a grid cell's bounds!) + * + * @return Size of a grid subdivision + */ + FVector GetGridCellSubdivisionSize() const; + + + /** + * Computes the size of a single grid cell + * + * @return Size of the cell + */ + FVector GetGridCellSize() const; + + + + /** + * Computes the world space bounds of a single grid cell + * + * @param InCoords Coordinate of cell to compute bounds for + * + * @return Bounds of the cell in world space + */ + FBox GetGridCellBounds( const FLevelGridCellCoordinate& InCoords ) const; + + + /** + * Updates the convex volume that represents the shape of a single cell within this volume. + * Important: The convex volume is centered about the origin and not relative to any volume or cell! + */ + void UpdateConvexCellVolume(); + + + /** + * Computes the center point of a grid cell + * + * @param InCoords Coordinate of cell to compute bounds for + * + * @return Center point of the cell in world space + */ + FVector GetGridCellCenterPoint( const FLevelGridCellCoordinate& InCoords ) const; + + + /** + * Computes the 2D shape of a hex cell for this volume + * + * @param OutHexPoints Array that will be filled in with the 6 hexagonal points + */ + void ComputeHexCellShape( FVector2D* OutHexPoints ) const; + + + /** + * Gets all levels associated with this level grid volume (not including the P level) + * + * @param OutLevels List of levels (out) + */ + void GetLevelsForAllCells( TArray< class ULevelStreaming* >& OutLevels ) const; + + + /** + * Finds the level for the specified cell coordinates + * + * @param InCoords Grid cell coordinates + * + * @return Level streaming record for level at the specified coordinates, or NULL if not found + */ + class ULevelStreaming* FindLevelForGridCell( const FLevelGridCellCoordinate& InCoords ) const; + + + /** + * Returns true if the specified actor belongs in this grid network + * + * @param InActor The actor to check + * + * @return True if the actor belongs in this grid network + */ + UBOOL IsActorMemberOfGrid( AActor* InActor ) const; + + + /** + * Returns true if the specified cell is 'usable'. That is, the bounds of the cell overlaps the actual + * level grid volume's brush + * + * @return True if the specified cell is 'usable' + */ + UBOOL IsGridCellUsable( const FLevelGridCellCoordinate& InCellCoord ) const; + + + /** + * Computes the grid cell that a box should be associated with based on the cell that it most + * overlaps. If the box doesn't overlap any cells but bMustOverlap is false, then the function + * will choose the cell that's closest to the box. + * + * @param InBox The box to test + * @param bMustOverlap True if the box must overlap a cell for the function to succeed + * @param OutBestCell (Out) The best cell for the box + * + * @return True if a cell was found for the box. If bMustOverlap is false, the function will always return true. + */ + UBOOL FindBestGridCellForBox( const FBox& InBox, const UBOOL bMustOverlap, FLevelGridCellCoordinate& OutBestCell ) const; + + + /** + * Checks to see if an AABB overlaps the specified grid cell + * + * @param InCellCoord The grid cell coordinate to test against + * @param InBox The world space AABB to test + * + * @return True if the box overlaps the grid cell + */ + UBOOL TestWhetherCellOverlapsBox( const FLevelGridCellCoordinate& InCellCoord, const FBox& InBox ) const; + + + /** + * Computes the minimum distance between the specified point and grid cell in world space + * + * @param InCellCoord The grid cell coordinate to test against + * @param InPoint The world space location to test + * + * @return Squared distance to the cell + */ + FLOAT ComputeSquaredDistanceToCell( const FLevelGridCellCoordinate& InCellCoord, const FVector& InPoint ) const; + + + /** + * Determines whether or not the level associated with the specified grid cell should be loaded based on + * distance to the viewer's position + * + * @param InCellCoord The grid cell coordinate associated with the level we're testing + * @param InViewLocation The viewer's location + * @param bIsAlreadyLoaded Pass true if the associated level is already loaded, otherwise false. This is used to determine whether we should keep an already-loaded level in memory based on a configured distance threshold. + * + * @return True if level should be loaded (or for already-loaded levels, should stay loaded) + */ + UBOOL ShouldLevelBeLoaded( const FLevelGridCellCoordinate& InCellCoord, const FVector& InViewLocation, const UBOOL bIsAlreadyLoaded ) const; + + + /** + * AActor: Checks this actor for errors. Called during the map check phase in the editor. + */ +#if WITH_EDITOR + virtual void CheckForErrors(); +#endif +} + + +defaultproperties +{ + Begin Object Name=BrushComponent0 + CollideActors=False + BlockActors=False + BlockZeroExtent=False + BlockNonZeroExtent=False + BlockRigidBody=False + End Object + + Begin Object Class=LevelGridVolumeRenderingComponent Name=LevelGridVolumeRenderer + End Object + Components.Add(LevelGridVolumeRenderer) + + bColored=true + + // Grey brush + BrushColor=(R=80,G=80,B=80,A=255) + + bCollideActors=False + bBlockActors=False + bProjTarget=False + SupportedEvents.Empty + + CellShape=LGCS_Box + Subdivisions[0]=1 + Subdivisions[1]=1 + Subdivisions[2]=1 + + LoadingDistance=20480 + KeepLoadedRange=2048 +} diff --git a/Engine/Classes/LevelGridVolumeRenderingComponent.uc b/Engine/Classes/LevelGridVolumeRenderingComponent.uc new file mode 100644 index 0000000..5ba5675 --- /dev/null +++ b/Engine/Classes/LevelGridVolumeRenderingComponent.uc @@ -0,0 +1,27 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class LevelGridVolumeRenderingComponent extends PrimitiveComponent + native + hidecategories(Object) + editinlinenew; + +cpptext +{ + /** + * Creates a new scene proxy for the path rendering component. + * @return Pointer to the FPathRenderingSceneProxy + */ + virtual FPrimitiveSceneProxy* CreateSceneProxy(); + + /** Sets the bounds of this primitive */ + virtual void UpdateBounds(); +}; + + +defaultproperties +{ + HiddenGame=true + AlwaysLoadOnClient=false + AlwaysLoadOnServer=false +} diff --git a/Engine/Classes/LevelStreaming.uc b/Engine/Classes/LevelStreaming.uc new file mode 100644 index 0000000..22f4303 --- /dev/null +++ b/Engine/Classes/LevelStreaming.uc @@ -0,0 +1,125 @@ +/** + * LevelStreaming + * + * Abstract base class of container object encapsulating data required for streaming and providing + * interface for when a level should be streamed in and out of memory. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class LevelStreaming extends Object + abstract + editinlinenew + native; + +/** Name of the level package name used for loading. */ +var() editconst const name PackageName; + +/** Pointer to Level object if currently loaded/ streamed in. */ +var transient const level LoadedLevel; + +/** Offset applied to actors after loading. */ +var() const vector Offset; + +/** Transform applied to actors after loading. */ +var() const Matrix LevelTransform; + +/** Current/ old offset required for changing the offset at runtime, e.g. in the Editor. */ +var const vector OldOffset; + +/** Whether the level is currently visible/ associated with the world */ +var const transient bool bIsVisible; + +/** Whether we currently have a load request pending. */ +var const transient bool bHasLoadRequestPending; + +/** Whether we currently have an unload request pending. */ +var const transient bool bHasUnloadRequestPending; + +/** Whether this level should be visible in the Editor */ +var() editoronly const bool bShouldBeVisibleInEditor; + +/** Whether this level's bounding box should be visible in the Editor. */ +var const bool bBoundingBoxVisible; + +/** Whether this level is locked; that is, its actors are read-only. */ +var() const bool bLocked; + +/** Whether this level is fully static - if it is, then assumptions can be made about it, ie it doesn't need to be reloaded since nothing could have changed */ +var() const bool bIsFullyStatic; + +/** Whether the level should be loaded */ +var const transient bool bShouldBeLoaded; + +/** Whether the level should be visible if it is loaded */ +var const transient bool bShouldBeVisible; + +/** Whether we want to force a blocking load */ +var transient bool bShouldBlockOnLoad; + +/** The level's color; used to make the level easily identifiable in the level browser, for actor level visulization, etc. */ +var() const color DrawColor; + +/** The level streaming volumes bound to this level. */ +var() const editconst array EditorStreamingVolumes; + +/** If TRUE, will be drawn on the 'level streaming status' map (STAT LEVELMAP console command) */ +var() bool bDrawOnLevelStatusMap; + +/** Cooldown time in seconds between volume-based unload requests. Used in preventing spurious unload requests. */ +var() float MinTimeBetweenVolumeUnloadRequests; + +/** Time of last volume unload request. Used in preventing spurious unload requests. */ +var const transient float LastVolumeUnloadRequestTime; + +/** Whether this level streaming object's level should be unloaded and the object be removed from the level list. */ +var const transient bool bIsRequestingUnloadAndRemoval; + +/** List of keywords to filter on in the level browser */ +var editoronly array Keywords; + +/** The grid volume bound to this level, if any */ +var() const editconst LevelGridVolume EditorGridVolume; + +/** Row, column and depth of this streaming level in a streaming grid network */ +var() const editconst int GridPosition[ 3 ]; + + +cpptext +{ + /** + * Returns whether this level should be present in memory which in turn tells the + * streaming code to stream it in. Please note that a change in value from FALSE + * to TRUE only tells the streaming code that it needs to START streaming it in + * so the code needs to return TRUE an appropriate amount of time before it is + * needed. + * + * @param ViewLocation Location of the viewer + * @return TRUE if level should be loaded/ streamed in, FALSE otherwise + */ + virtual UBOOL ShouldBeLoaded( const FVector& ViewLocation ); + + /** + * Returns whether this level should be visible/ associated with the world if it is + * loaded. + * + * @param ViewLocation Location of the viewer + * @return TRUE if the level should be visible, FALSE otherwise + */ + virtual UBOOL ShouldBeVisible( const FVector& ViewLocation ); + + /** Get a bounding box around the streaming volumes associated with this LevelStreaming object */ + FBox GetStreamingVolumeBounds(); + + // UObject interface. + virtual void PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent); +} + +defaultproperties +{ + bShouldBeVisibleInEditor=TRUE + DrawColor=(R=255,G=255,B=255,A=255) + + MinTimeBetweenVolumeUnloadRequests=2.0 + + bDrawOnLevelStatusMap=TRUE +} diff --git a/Engine/Classes/LevelStreamingAlwaysLoaded.uc b/Engine/Classes/LevelStreamingAlwaysLoaded.uc new file mode 100644 index 0000000..803c5e0 --- /dev/null +++ b/Engine/Classes/LevelStreamingAlwaysLoaded.uc @@ -0,0 +1,27 @@ +/** + * LevelStreamingAlwaysLoaded + * + * @documentation + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class LevelStreamingAlwaysLoaded extends LevelStreaming + native; + +/** Determines whether or not his Always loaded level is one that was auto created for a Procedural Building LOD level. **/ +var() bool bIsProceduralBuildingLODLevel; + +cpptext +{ + /** + * Returns whether this level should be present in memory which in turn tells the + * streaming code to stream it in. Please note that a change in value from FALSE + * to TRUE only tells the streaming code that it needs to START streaming it in + * so the code needs to return TRUE an appropriate amount of time before it is + * needed. + * + * @param ViewLocation Location of the viewer + * @return TRUE + */ + virtual UBOOL ShouldBeLoaded( const FVector& ViewLocation ); +} \ No newline at end of file diff --git a/Engine/Classes/LevelStreamingDistance.uc b/Engine/Classes/LevelStreamingDistance.uc new file mode 100644 index 0000000..71bf1ea --- /dev/null +++ b/Engine/Classes/LevelStreamingDistance.uc @@ -0,0 +1,30 @@ +/** + * LevelStreamingDistance + * + * Distance based streaming implementation. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class LevelStreamingDistance extends LevelStreaming + native; + + +/** Origin of level used for distance calculation to viewer */ +var() vector Origin; +/** Maximum distance to viewer at which the level still is streamed in */ +var() float MaxDistance; + +cpptext +{ + /** + * Returns whether this level should be present in memory which in turn tells the + * streaming code to stream it in. Please note that a change in value from FALSE + * to TRUE only tells the streaming code that it needs to START streaming it in + * so the code needs to return TRUE an appropriate amount of time before it is + * needed. + * + * @param ViewLocation Location of the viewer + * @return TRUE if level should be loaded/ streamed in, FALSE otherwise + */ + virtual UBOOL ShouldBeLoaded( const FVector& ViewLocation ); +} diff --git a/Engine/Classes/LevelStreamingKismet.uc b/Engine/Classes/LevelStreamingKismet.uc new file mode 100644 index 0000000..558cb2f --- /dev/null +++ b/Engine/Classes/LevelStreamingKismet.uc @@ -0,0 +1,33 @@ +/** + * LevelStreamingKismet + * + * Kismet triggerable streaming implementation. + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class LevelStreamingKismet extends LevelStreaming + native; + +cpptext +{ + /** + * Returns whether this level should be present in memory which in turn tells the + * streaming code to stream it in. Please note that a change in value from FALSE + * to TRUE only tells the streaming code that it needs to START streaming it in + * so the code needs to return TRUE an appropriate amount of time before it is + * needed. + * + * @param ViewLocation Location of the viewer + * @return TRUE if level should be loaded/ streamed in, FALSE otherwise + */ + virtual UBOOL ShouldBeLoaded( const FVector& ViewLocation ); + + /** + * Returns whether this level should be visible/ associated with the world if it is + * loaded. + * + * @param ViewLocation Location of the viewer + * @return TRUE if the level should be visible, FALSE otherwise + */ + virtual UBOOL ShouldBeVisible( const FVector& ViewLocation ); +} diff --git a/Engine/Classes/LevelStreamingPersistent.uc b/Engine/Classes/LevelStreamingPersistent.uc new file mode 100644 index 0000000..bc4af15 --- /dev/null +++ b/Engine/Classes/LevelStreamingPersistent.uc @@ -0,0 +1,40 @@ +/** + * LevelStreamingPersistent + * + * @documentation + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class LevelStreamingPersistent extends LevelStreaming + transient + native; + +cpptext +{ + /** + * Returns whether this level should be present in memory which in turn tells the + * streaming code to stream it in. Please note that a change in value from FALSE + * to TRUE only tells the streaming code that it needs to START streaming it in + * so the code needs to return TRUE an appropriate amount of time before it is + * needed. + * + * @param ViewLocation Location of the viewer + * @return TRUE + */ + virtual UBOOL ShouldBeLoaded( const FVector& ViewLocation ) + { + return TRUE; + } + + /** + * Returns whether this level should be visible/ associated with the world if it is + * loaded. + * + * @param ViewLocation Location of the viewer + * @return TRUE + */ + virtual UBOOL ShouldBeVisible( const FVector& ViewLocation ) + { + return TRUE; + } +} diff --git a/Engine/Classes/LevelStreamingVolume.uc b/Engine/Classes/LevelStreamingVolume.uc new file mode 100644 index 0000000..6e98f59 --- /dev/null +++ b/Engine/Classes/LevelStreamingVolume.uc @@ -0,0 +1,133 @@ +/** + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + * + * Used to affect level streaming in the game and level visibility in the editor. + */ +class LevelStreamingVolume extends Volume + native + hidecategories(Advanced,Attachment,Collision,Volume) + placeable; + +struct CheckpointRecord +{ + var bool bDisabled; +}; + +/** Levels affected by this level streaming volume. */ +var() noimport const editconst array StreamingLevels; + +/** If TRUE, this streaming volume should only be used for editor streaming level previs. */ +var() bool bEditorPreVisOnly; + +/** + * If TRUE, this streaming volume is ignored by the streaming volume code. Used to either + * disable a level streaming volume without disassociating it from the level, or to toggle + * the control of a level's streaming between Kismet and volume streaming. + */ +var() bool bDisabled; + +/** Enum for different usage cases of level streaming volumes. */ +enum EStreamingVolumeUsage +{ + SVB_Loading, + SVB_LoadingAndVisibility, + SVB_VisibilityBlockingOnLoad, + SVB_BlockingOnLoad, + SVB_LoadingNotVisible +}; + +/** Determines what this volume is used for, e.g. whether to control loading, loading and visibility or just visibilty (blocking on load) */ +var() EStreamingVolumeUsage StreamingUsage; + +/** If TRUE, level will stream when closer than TestVolumeDistance to the volume. */ +var() bool bTestDistanceToVolume; + +/** If bTestDistanceToVolume is TRUE, level will stream in if closer than this to volume. */ +var() float TestVolumeDistance; + + + +var deprecated EStreamingVolumeUsage Usage; + + +/** + * Kismet support for toggling bDisabled. + */ +simulated function OnToggle(SeqAct_Toggle action) +{ + if (action.InputLinks[0].bHasImpulse) + { + // "Turn On" -- mapped to enabling of volume streaming for this volume. + bDisabled = FALSE; + } + else if (action.InputLinks[1].bHasImpulse) + { + // "Turn Off" -- mapped to disabling of volume streaming for this volume. + bDisabled = TRUE; + } + else if (action.InputLinks[2].bHasImpulse) + { + // "Toggle" + bDisabled = !bDisabled; + } +} + +function CreateCheckpointRecord(out CheckpointRecord Record) +{ + Record.bDisabled = bDisabled; +} + +function ApplyCheckpointRecord(const out CheckpointRecord Record) +{ + bDisabled = Record.bDisabled; +} + +cpptext +{ + // UObject interace. + /** + * Serialize function. + * + * @param Ar Archive to serialize with. + */ + void Serialize( FArchive& Ar ); + + /** + * Performs operations after the object is loaded. + * Used for fixing up deprecated fields. + */ + virtual void PostLoad(); + + // AActor interface. + /** + * Function that gets called from within Map_Check to allow this actor to check itself + * for any potential errors and register them with map check dialog. + */ +#if WITH_EDITOR + virtual void CheckForErrors(); +#endif +} + +defaultproperties +{ + Begin Object Name=BrushComponent0 + CollideActors=False + BlockActors=False + BlockZeroExtent=False + BlockNonZeroExtent=False + BlockRigidBody=False + End Object + + bColored=true + // Orange Brush + BrushColor=(R=255,G=165,B=0,A=255) + + bCollideActors=False + bBlockActors=False + bProjTarget=False + SupportedEvents.Empty + SupportedEvents(0)=class'SeqEvent_Touch' + // streaming volumes are server side - resultant levels to load or not is what is sent to the client + bForceAllowKismetModification=true + StreamingUsage=SVB_LoadingAndVisibility +} diff --git a/Engine/Classes/LiftCenter.uc b/Engine/Classes/LiftCenter.uc new file mode 100644 index 0000000..2f21d6c --- /dev/null +++ b/Engine/Classes/LiftCenter.uc @@ -0,0 +1,127 @@ +//============================================================================= +// LiftCenter. +// Used to support AI navigation on lifts. +// should be placed in the center of the navigable lift surface. +// Used in conjunction with LiftExits +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class LiftCenter extends NavigationPoint + placeable + native; + +var InterpActor MyLift; +var float MaxDist2D; +var vector LiftOffset; // starting vector between MyLift location and LiftCenter location +var bool bJumpLift; +var float CollisionHeight; +/** if specified, must touch this to start the lift */ +var() Trigger LiftTrigger; + +cpptext +{ + virtual UBOOL ShouldBeBased(); +#if WITH_EDITOR + void addReachSpecs(AScout *Scout, UBOOL bOnlyChanged); + virtual void ReviewPath(APawn* Scout); +#endif + void FindBase(); +} + +event PostBeginPlay() +{ + Super.PostBeginPlay(); + + if (Base == MyLift && MyLift != None) + { + LiftOffset = Location - MyLift.Location; + MyLift.bIsLift = true; + } +} + +/** SpecialHandling is called by the navigation code when the next path has been found. +It gives that path an opportunity to modify the result based on any special considerations +Here, we check if the mover needs to be triggered +*/ +event Actor SpecialHandling(Pawn Other) +{ + // if no lift, no trigger, or trigger already hit, no special handling + if (MyLift == None || LiftTrigger == None || LiftTrigger.bRecentlyTriggered) + { + return self; + } + else + { + return LiftTrigger; + } +} + +/* +Check if mover is positioned to allow Pawn to get on +*/ +event bool SuggestMovePreparation(Pawn Other) +{ + // if already on lift, no problem + if ( Other.base == MyLift ) + return false; + + // make sure LiftCenter is correctly positioned on the lift + if ( (Base != MyLift) || (Location != MyLift.Location + LiftOffset) ) + { + SetLocation(MyLift.Location + LiftOffset); + SetBase(MyLift); + } + + // if mover is moving, wait + if (!IsZero(MyLift.velocity) || !ProceedWithMove(Other)) + { + Other.Controller.WaitForMover(MyLift); + return true; + } + + return false; +} + +function bool ProceedWithMove(Pawn Other) +{ + // see if mover is at appropriate location + if ( Other.Controller == None ) + return false; + else if ( (LiftExit(Other.Controller.MoveTarget) != None) && Other.ReachedDestination(self) ) + return LiftExit(Other.Controller.MoveTarget).CanBeReachedFromLiftBy(Other); + else + { + //check distance directly - make sure close + if ( (Location.Z - CollisionHeight < Other.Location.Z - Other.GetCollisionHeight() + Other.MAXSTEPHEIGHT + 2.0) + && (Location.Z - CollisionHeight > Other.Location.Z - Other.GetCollisionHeight() - 1200) + && (VSize2D(Location - Other.Location) < MaxDist2D || (IsZero(MyLift.Velocity) && Other.ValidAnchor() && LiftExit(Other.Anchor) != None)) ) + { + return true; + } + } + + // if we need to hit the trigger, go do that + if (LiftTrigger != None && !LiftTrigger.bRecentlyTriggered && IsZero(MyLift.Velocity)) + { + Other.SetMoveTarget(LiftTrigger); + return true; + } + + return false; +} + +defaultproperties +{ + Begin Object NAME=Sprite + Sprite=Texture2D'EditorResources.Lift_Center' + End Object + + RemoteRole=ROLE_None + bStatic=false + bSpecialMove=true + ExtraCost=400 + MaxDist2D=+400.000 + bNoAutoConnect=true + bNeverUseStrafing=true + bForceNoStrafing=true + CollisionHeight=50 +} diff --git a/Engine/Classes/LiftExit.uc b/Engine/Classes/LiftExit.uc new file mode 100644 index 0000000..f5f3ce1 --- /dev/null +++ b/Engine/Classes/LiftExit.uc @@ -0,0 +1,80 @@ +//============================================================================= +// LiftExit. +// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. +//============================================================================= +class LiftExit extends NavigationPoint + placeable + native; + +var() LiftCenter MyLiftCenter; +var() bool bExitOnly; // if true, can only get off lift here. + +cpptext +{ + virtual void ReviewPath(APawn* Scout); +} + +function bool CanBeReachedFromLiftBy(Pawn Other) +{ + return ( (Location.Z < Other.Location.Z + Other.GetCollisionHeight()) + && Other.LineOfSightTo(self) ); +} + +function WaitForLift(Pawn Other) +{ + if (MyLiftCenter != None) + { + Other.SetDesiredRotation(rotator(Location - Other.Location)); + Other.Controller.WaitForMover(MyLiftCenter.MyLift); + } +} + +event bool SuggestMovePreparation(Pawn Other) +{ + local Controller C; + + if ( (MyLiftCenter == None) || (Other.Controller == None) ) + return false; + if ( Other.Physics == PHYS_Flying ) + { + if ( Other.AirSpeed > 0 ) + Other.Controller.MoveTimer = 2+ VSize(Location - Other.Location)/Other.AirSpeed; + return false; + } + if ( (Other.Base == MyLiftCenter.Base) || Other.ReachedDestination(MyLiftCenter) ) + { + // if pawn is on the lift, see if it can get off and go to this lift exit + if ( CanBeReachedFromLiftBy(Other) ) + { + return false; + } + + // make pawn wait on the lift + WaitForLift(Other); + return true; + } + else if (MyLiftCenter != None) + { + foreach WorldInfo.AllControllers(class'Controller', C) + { + if ( (C.Pawn != None) && (C.PendingMover == MyLiftCenter.MyLift) && WorldInfo.GRI.OnSameTeam(C,Other.Controller) && C.Pawn.ReachedDestination(self) ) + { + WaitForLift(Other); + return true; + } + } + Other.Controller.ReadyForLift(); + } + return false; +} + +defaultproperties +{ + Begin Object NAME=Sprite + Sprite=Texture2D'EditorResources.Lift_Exit' + End Object + + bSpecialMove=true + bNeverUseStrafing=true + bForceNoStrafing=true +} diff --git a/Engine/Classes/Light.uc b/Engine/Classes/Light.uc new file mode 100644 index 0000000..306045e --- /dev/null +++ b/Engine/Classes/Light.uc @@ -0,0 +1,375 @@ +/** + * Abstract Light + * + * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. + */ +class Light extends Actor + native(Light) + ClassGroup( Lights ); + + +var() editconst const LightComponent LightComponent; + +`if(`__TW_LIGHTING_MODIFICATIONS_) // Light Animation +/** Supported light animation types */ +enum ELightAnimationTechnique +{ + /** No Animation */ + LightAnim_None, + /** Random on/off */ + LightAnim_Flicker, + /** Interpolate smoothly between on/off */ + LightAnim_Pulse, + /** Like flicker, but the pattern is constant and repeating */ + LightAnim_Strobe, + /** Light remains off mostly except when it flickers on */ + LightAnim_ChaoticFlicker, + /** Light remains on mostly except when it flickers off */ + LightAnim_InverseChaoticFlicker +}; + +/** The maximum brightness value for this light. Default is 1.0 */ +var(LightAnimation) const float MaxBrightness; + +/** The minimum brightness override value for this light. If 0, it uses the + global value for the light animation type specified in WorldInfo. */ +var(LightAnimation) const float MinBrightness; + +/** Light animation type used by this light */ +var(LightAnimation) ELightAnimationTechnique AnimationType; + +/** The rate at which the LightAnimation is played. Default is 1.0. Must be greater than 0 */ +var(LightAnimation) float AnimationFrequency; + +/** Time offset into the LightAnimation. This is used to add variation so that +all the animations are not in perfect sync. default is 0.0. +Note: This value will not have any effect it is a multiple of the inverse of the AnimationFrequency. +Eg. If the AnimationFrequency is 0.5, AnimationTimeOffsets of 2, 4, 6 ... will have same effect at 0 */ +var(LightAnimation) float AnimationTimeOffset; + +/** The static mesh represtation of the light fixture */ +var(LightAnimation) StaticMeshComponent LightMesh; + +/** The MICs used by the light fixture that need modification */ +var transient array LightMeshMICs; + +/** The MICs used by the base mesh (actor we're standing on) that need modification */ +var transient array BaseMeshMICs; + +/** Lens flare component for the light */ +var(LightAnimation) LensFlareComponent LensFlareComp; + +/** The MICs used by the lens flare that need modification */ +var transient array LensFlareMICs; + +/** Animation output from previous frame */ +var transient float CurveOutputValue; +`endif // Light Animation + +cpptext +{ +public: + // AActor interface. + /** + * Function that gets called from within Map_Check to allow this actor to check itself + * for any potential errors and register them with map check dialog. + */ +#if WITH_EDITOR + virtual void CheckForErrors(); +#endif + + /** + * This will determine which icon should be displayed for this light. + **/ + virtual void DetermineAndSetEditorIcon(); + + /** + * For this type of light, set the values which would make it affect Dynamic Primitives. + **/ + virtual void SetValuesForLight_DynamicAffecting(); + + /** + * For this type of light, set the values which would make it affect Static Primitives. + **/ + virtual void SetValuesForLight_StaticAffecting(); + + /** + * For this type of light, set the values which would make it affect Dynamic and Static Primitives. + **/ + virtual void SetValuesForLight_DynamicAndStaticAffecting(); + + /** + * Returns true if the light supports being toggled off and on on-the-fly + * + * @return For 'toggleable' lights, returns true + */ + virtual UBOOL IsToggleable() const + { + // By default, lights are not toggleable. You can override this in derived classes. + return FALSE; + } + + /** Invalidates lighting for a lighting rebuild. */ + void InvalidateLightingForRebuild(UBOOL bOnlyVisible = FALSE); + +#if __TW_LIGHTING_MODIFICATIONS_ // Light Animation + /** ticks the light + * @return TRUE if the actor was ticked, FALSE if it was aborted (e.g. because it's in stasis) + */ + virtual UBOOL Tick(FLOAT DeltaTime, enum ELevelTick TickType); + + /** Returns the material parameter value when synching with this light */ + FLOAT GetLightMICParamValue(); + + virtual void PostLoad(); + /** Process change of property value for the light */ + virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); +#endif +} + + +/** replicated copy of LightComponent's bEnabled property */ +var repnotify bool bEnabled; + +replication +{ + if (Role == ROLE_Authority) + bEnabled; +} + +`if(`__TW_LIGHTING_MODIFICATIONS_) +/** @return whether light volumetrics is supported */ +native static final function bool IsVolumetricLightingSupported(); +/** @return whether light functions are supported */ +native static final function bool AreLightFunctionsSupported(); +`endif + +simulated event ReplicatedEvent(name VarName) +{ + if (VarName == 'bEnabled') + { + LightComponent.SetEnabled(bEnabled); + +`if(`__TW_LIGHTING_MODIFICATIONS_) + // Update the state of the lens flare component attached to the light + LensFlareComp.SetIsActive(bEnabled); + LensFlareComp.LastRenderTime = WorldInfo.TimeSeconds; +`endif + } + else + { + Super.ReplicatedEvent(VarName); + } +} + +/* epic =============================================== +* ::OnToggle +* +* Scripted support for toggling a light, checks which +* operation to perform by looking at the action input. +* +* Input 1: turn on +* Input 2: turn off +* Input 3: toggle +* +* ===================================================== +*/ +simulated function OnToggle(SeqAct_Toggle action) +{ + if (!bStatic) + { + if (action.InputLinks[0].bHasImpulse) + { + // turn on + LightComponent.SetEnabled(TRUE); + `if(`__TW_LIGHTING_MODIFICATIONS_) + LensFlareComp.SetIsActive(TRUE); + `endif + } + else if (action.InputLinks[1].bHasImpulse) + { + // turn off + LightComponent.SetEnabled(FALSE); + `if(`__TW_LIGHTING_MODIFICATIONS_) + LensFlareComp.SetIsActive(FALSE); + `endif + } + else if (action.InputLinks[2].bHasImpulse) + { + // toggle + LightComponent.SetEnabled(!LightComponent.bEnabled); + `if(`__TW_LIGHTING_MODIFICATIONS_) + LensFlareComp.SetIsActive(LightComponent.bEnabled); + `endif + } + bEnabled = LightComponent.bEnabled; + ForceNetRelevant(); + SetForcedInitialReplicatedProperty(Property'Engine.Light.bEnabled', (bEnabled == default.bEnabled)); + + `if(`__TW_LIGHTING_MODIFICATIONS_) + LensFlareComp.LastRenderTime = WorldInfo.TimeSeconds; + `endif + } +} + +`if(`__TW_LIGHTING_MODIFICATIONS_) // Light Animation + +/** returns true if the light mesh is a volumetric light cone */ +native function bool HasVolumetricLightMesh(); + +event PostBeginPlay() +{ + local int i; + local MaterialInterface ParentMat; + local MaterialInstanceConstant NewMIC; + local float DummyValue; + local bool bVolumetricLightMesh; + + if (WorldInfo.NetMode == NM_DedicatedServer) + { + SetTickIsDisabled(true); + return; + } + + // Disable and destroy light if the light has a light function + // and light functions are not supported + if( !AreLightFunctionsSupported() && LightComponent.Function != none ) + { + // disable tick must come first to ensure component reattach + SetTickIsDisabled(true); + LightComponent.SetEnabled(false); + return; + } + + // Check to see if the light mesh attached is a volumetric light cone mesh + // All the materials used by the light mesh need to be translucent for it to + // be considered as a volumetric light mesh + if( LightMesh != none ) + { + bVolumetricLightMesh = HasVolumetricLightMesh(); + } + + if( !bVolumetricLightMesh || IsVolumetricLightingSupported() ) + { + // Create and cache the MICs that need modification (for the static mesh attachment) + LightMeshMICs.Remove(0, LightMeshMICs.length); + if( LightMesh != none ) + { + for( i=0; i