*!L<%e"%;OO R?7%%% %!%#%$%%%(%*%+&f&g&p&q&&&&&&&&&&&&&''7'E'M'M'M'M'J.|;z!;!;!;!;!;!;!;!;!;!;!;!F<!F<!F<!F<!J<!J<!L<!NoneEngineCoreSystemColor InternalTimeTrigger DetailScaleDefaultMaterialUSizeVClampLODSetVSizeUBitsUClampVBitsPaletteTextureMipZeroKarma WeaponFire Lighting MaxColor CollisionForce LightColorbMaskedObject MovementMessageMaxMin DamageTypeRangeFluidSurfaceInfoResetColorsPostBeginPlayWeapon BeginStateDisplayI3DL2ListenerKarmaConstraint RemoteRoleHUD TakeDamage GetItemName TriggerEventVectorSoundMoverTouchTimerXBoxPlayerInputClientMessage DrawTypePhysicsVolume ParseOptionCollisionRadius Projector xProcMeshCollisionHeight bNoDelete PclVisualsTick DestroyedFirebStatic Advanced IsPlayerPawnbCollideActors ProcessMove Material OrientationDecorationLayerShader LevelSummary PclEmitterGetbHidden KarmaParamsFormat DisplayDebug LevelInfoPickup EndStateConsoleCommandOpenCount PclMovement BeamNoiseFindInventoryType ContainsServerResponseLinexWeatherEffectAILogfAddPrecacheMaterial GiveWeapon DecorationHeaderChangedWeapon TerrainLayerGameReplicationInfo PlayerMoveBump PreBeginPlayZIsHumanControlledConsoleIsLocallyControlled bDirectional GameProfileUserBegin GameEndedXDiedTexOscillatorGetViewRotation MeshSpawning SoundVolumeGIPropsDisplayText WaitForMoverGetHumanReadableName SetPause SceneManagerAdd UnTriggerY IsRelevant VelocityAltFireHasAmmoReceiveLocalizedMessage LookPresetReplicateMove TerrainInfo TeleporterPutDown ZoneLightClientPlayForceFeedback ServerMoveDeadClose CombinerInitNavigationPointAnimNotify_Effect ShouldCrouch NextWeapon ClientTravelNone SelectNext PrevWeaponKUpdateConstraintParams PawnDied KVehiclePawn KilledByUnTouchHandlePickupQuerybEdShouldSnap RotationPossess Powerups ZoneInfoUpdateRotationDescFindTriggerActor ChangeTeamGRIPropsDisplayTextServerReStartPlayer FindByNamePlayerControllerError TexRotatorRemoveIconClientReStart InventoryDecorationType NetPriority Activate StopFire RangeVectorbBlockPlayersSize bBlockActorsSpecialHandlingLocal WeaponChangeBeamRestartPlayerxMaterialController DeathStringParticleSoundFemaleSuicidebUnlit ViewShake LadderInfoUpdatePrecacheMaterialsLongClientAdjustPositionGiveTo BeginEvent GameInfoRenderOverlays PlayWaiting PlayerStart LocationStopForceFeedback RateSelfSetHandDoClosePhysics MaleSuicideDoOpenShadowProjector Interpolator FinalBlendDying StopFiring LadderVolumeScale PlayFiringParseChatPercVar ShakeViewbAlwaysRelevantFinishedOpening CheckScorePlayTeleportEffect RevolutionFindPlayerStartVolumebCollideWorldUntriggerEvent FadeColorDoJump Broadcast CanSplashbCollideWhenPlacingTime ChangeNameBecomeViewTarget GetStringSuggestMovePreparationBeamBranching AddMutatorBroadcastLocalizedFadingFluidSurfaceOscillatorTyping FragmentNoneEventbLocationalHit WarpZoneInfoGlobalLanded ServerTravel bProjTarget TeamBeacon FillPlayInfo MoverSoundsPlayerResponseLineClientSetRotationMutatorPathKActor DetourWeightSwitchToBestWeaponNotifyPhysicsVolumeChangeClientVoiceMessage DrawScaleSubActionCameraEffect CanTrigger HandlePickuppclBeamClearDeleteInventory AdjustAim AdminReply KillEvent AdminLoginbGameRelevantConstantColorDoorOpenNextLadderAtRungbOnlyDirtyReplicationDetachFromPawn AdminLogout TexScalerBrush PostTouchMaterialSequence Rendering ScoreKillLineOfSightTriggerRecommendWeapon CheckEndGamePlayerWalkingKickBan CheckShakeCorona ProcessTouchKick PreventDeathProceedWithMove ViewFlashGibPerterbationKeyFrameReachedBotDesireability MusicTrigger MoverEventsSayFixFOV EndEventEndZoom ladderrung UnPossessedReadyToPickupVScaleIMaster UnPossess bBlockKarma VExponentHitWall HExponent AskForPawnChangeAnimationCleanOutSavedMovesPrioritizeArmorEffectIsRelevantFinishedClosing PositionNameDisableTriggerEnableTrigger IsFiring StartFire SameTeamAs bArmorStopsSetDefaultDisplayProperties MoverLoopedRotator bHiddenEd HitFXDataRunningNetUpdateFrequencyForceFeedbackArmorPriority EndLogging AdjustViewKarmaParamsCollision GetFireStart PlayerInputbWorldGeometryKarmaParamsSkelbNetTemporary BaseChangeAttach ActorEnteredBringUp AmbientGlowsignAnimEndEncroachingOnSetOwnerDisplay StartBerserkReachedDestination StopBerserk OwnerEventDrawHUD LookPresets PresetName PlayIdle bSpecialMove NotifyLandedHScaleClientOpenMenu RotationRate TypingClose DropFrom PickUpBase TypingOpenStartSleepingAnnouncePickup InitializeInitDroppedPickupForTriggerControl PointOfViewTriggerToggle LoopMove LiftCenterStandOpenTimedGetLocalStringRestartStartInterpolation KeyEvent LiftExit Settings SoundEmitterStyleTeamSayMesh ProcessDriveAttachProjector LogEntryGetConsoleFontEndClimbLadderMaterialSequenceItemCompressAccel AddGroupHandleWalking VolumeFogUpdateAnimNotify_Sound MaxRange UseLowGore FailMessage VClampModeCalcDrawOffset UClampModePickupFunctionGetServerDetailsArmor CheckBobCheckIPPolicy OpenMenuAdminPlayerCalcView SkeletalMeshNone Animation SetGameSpeedIsAdminPostNetBeginPlay SwitchWeapon GetMatchInfo GetIntOption AtCapacityBlockingVolumeSetViewRotationParticleBeamEndPointSuicide NotifyKilledUpdateShakeRotComponentTrail ShootSpecial LimitPitchBroadcastTeamClientSetLocationEndGame ClientDying PclSoftBodySetFallScoreObjective LieStill IsSpectating ModifierChunkUpTexCoordSourceRecommendComboGetDefaultWeaponColorModifierGeneral FindGoodView InvertLookSetMesh EyePosition ReportAdmin ColorNamesParticleVelocityScaleParticleColorScaleNoneParticleRevolutionScaleTouchingWaterVolume TeamMessageThirdPersonEffectsPlayerChangedClassTravelPostAcceptTravelPreAcceptParticleTimeScalePlayerWaitingUsedBy AlwaysKeep AddInventoryMyDefaultWeaponUpdateLaddersTeamSymbolNotifyTexPannerTriggeredGetInventoryClassOverrideKInertiaTensorAddPRI TexPannerTexOscillatorTriggered SpectatingW ModifyPlayer ModifyLogin LoadPlayers KillBotsSetPlayerNameReviewJumpSpots TexModifierSetWaitingPlayer NextItemMaterialSwitch TossWeapon SheerRate SheerAxisTickConstantColorPlayWeaponSwitch PlayTakeHitCameraOverlay LinkToSkyboxRatePlayerStart PlayerFlying RemoveUserInCurrentCombo FaceRotationPlayerSwimming MakeURLFor SpawningCannotJumpNowPlayerDriving CreateGroup MatActionGetCurrentMatchInfoJumpPad TimeZoneSessionKickBanCalcBehindViewEnterStartStateKilled ScoreEventSparkLineOfSightToSetMoveTargetGetMatchDescriptionParticleBeamScale VehicleFire PreLoginVehicleCeaseFire AdminEnteredClientKDriverLeave AdminExited KDriverLeave Security PostRender KickPlayer BanPlayerCheckOptionsAdmin ValidLoginAnimNotify_DestroyEffect PlayDyingGetServerPlayersAllowsBroadcastBroadcastText DrawColorInitGameReplicationInfo ClimbLadder AllowFire AddGameRules EncompassesHandleRestartGameOverridePickupQuery ThrowWeaponPrecacheGameStaticMeshesJumpPrecacheGameTextures NetDamageServerRestartGame CausePainToDestroyEffectsSurfaceKVehicleFactoryInitGRIExplode bAlwaysGibs AIControllerDetachProjectorRocketServerMoveDisplayMessages ScoreBoardServerSetHandedness KeyValuePairInUseServerSetAutoTaunt UpdateShadow WeaponPickupClientPlaySound LinkActorsPlayBeepSoundRedoMergedPrivs MergePrivsCanGrabLadder Generate GivePawnClientSetViewTarget AddCheats FinishNotify PlayerLineupForceGenerateKeyTypeMakeGroupStopMakeGroupReturnAudioFinishedInterpolationAllowRepeatPickup SleepingShouldReTriggerSetDisplayPropertiesFellOutOfWorldBumpOpenTimedGetRespawnTimeUpdatePrecacheStaticMeshesFadeOut PossessedByCreate SetRespawn DefaultPens TriggerPound BumpButton BaseStarted BaseFinished bEnabled SpawnCopyPickupMessage DoLogoutCheckTouchList BeginPlay SmoothMouseMaxDesireabilityHiddenServerGivePawnbFixedRotationDir ProjectilePendingClientWeaponSetbUseCylinderCollisionReceiveWarningAdjustDesireFordamageAttitudeTo MoverOpened PlayerTick MoverClosed DamageShakeTransientSoundVolume UnderLiftSpecialCalcViewBroadcastLocalizedMessage EncroachedBy SoundRadiusbDisturbFluidSurface bOwnerNoSeebShouldBaseAtStartup bMovablebTravelPlaneMoverFinished ReadyToFireRemap GetPathIndexGetComponentAccelCheckOutOfAmmo FilterOutputAcceptClientWeaponSetEvents KillAllPawns LifeSpan ViewSelfbNetInitialRotation HolderDiedViewBotGetEffectStartAddAmmobAcceptsProjectorsPhysicsVolumeChange GetViewAxesFallingCreatedGetFacingDirectionWantsSmoothedView Reselect ActivatedInitPlayerReplicationInfoKarmaParamsRBFullCheckReplacementPlayEntrySplash TimerPop GibModifier FlashScaleGetPawnDamageEffectGetPawnDamageEmitterGetPawnDamageSoundbActive FovAnglebCanOpenDoorsAssociatedTouchbCanDoSpecial MinHitWallInitForPendingStasisAwardAdrenalineAvoidCertainDeath WasKilledByOrderNotifyAddInventoryNotifyTakeHit PawnIsInPain Stopping GameHasEndedClientGameEndedSendVoiceMessageBotVoiceMessage ActorLeavingLightBrightness LightRadius FearThisSpotPawnEnteredVolumePawnLeavingVolume FireWeaponAt RateWeaponWeaponPreferenceClientSwitchToBestWeaponbForceNoStrafing SetPawnClassbNeverUseStrafingNotifyHitWallPostNetReceivePhysicsChangedFor ExtraCostNormalTriggerPrepareForMoveTeamBeaconTeamColors righthandLeadInOutLoopingLeadInOutLooper ConstantLoopTriggerOpenTimedLog InitialStateConnectFailure MakeAdminSpawnDefaultHUDNoneClientGotoState ClientSetHUDClientStopForceFeedbackClientSetMusic StartZoomRemoveManagedGroupAddManagedGroupIsDeadClientSetBehindViewForceDeathUpdateCubemapShortServerMove ServerDrive ReturnGroupShortClientAdjustPositionClientAdjustPositionClientUpdatePosition RemoveGroupStaticMeshActorClientDamageShakeAnimNotify_MatSubAction RestartLevelServerThrowWeaponAnimNotify_ScriptUse KDriverEnterClientKDriverEnter ServerUseSetNameClearProgressMessagesCalcFirstPersonViewTurnTowardNearestEnemy TurnAroundPlayerClimbing HasPrivilege PlayLanded PlayMovingEmitter LandThumpReduceCylinderbLightingVisibilityPlayerRocketing ValidName ScriptingServerViewNextPlayerServerViewSelf TexEnvMapPlayHitPlayDyingSoundPlayMoverHitSound AttractModeUpdateRocketAccelerationCanDoubleJumpWaitingForPawn DoDoubleJumpCheckWaterJumpTakeDrowningDamageCanRestartPlayerbStasisGetKillerControllerNone ShieldAbsorb HasUDamageSetMovementPhysicsbOrientOnSlopeGasp FreeObject JumpOffPawn AllWeapons gibbedByServerChangedWeaponGetWeaponBoneFor ViewClassNonebReplicateInstigatorbReplicateMovementbSkipActorPropertyReplicationAllocateObjectNoneNoneWeaponFireAgainCanThrowWeapon RefireRateTriggerScript MotionBlurLengthOfLadderTakeFallingDamage AddVelocityPriorityObjectiveStartle FirstPerson ManifestAttachmentClass AttachToPawn TeamInfoIsFirstPersonWasPlayerPawn WeaponBobModifiedPlayerViewOffset AIScript ControllerAmmoAllAmmo DropToGround VignetteNote MyDamageTypeUseAmmoNoneGetDamageRadiusArmorAbsorbDamageArmorImpactEffect BestModeBotFireIncrementFlashCountZeroFlashCount CanThrowClientWeaponThrown GiveAmmo OutOfAmmo DoAutoSwitchServerStopFireAddCameraEffect ConsumeAmmoAdjustPlayerDamage DrawScale3D BreathTimer RespawnTime AccelRateClientStopFire MaxLightsStaticPrecacheRespawnEffect CloseAll CloseMenuDesireability DetailChangeFallingPickup ValidTouchCheckTouching EST_Default EST_Rock EST_Dirt EST_Metal EST_Wood EST_Plant EST_FleshEST_Ice EST_Snow EST_Water EST_GlassFillPrecacheMaterialsArraySetWeaponStay ScaleGlowFillPrecacheStaticMeshesArrayGetBeaconTextCreateKeyMenusCheckCountdownDrawInstructionGfx DrawRouteDisplayProgressMessagesDrawSpectatingHudDrawLevelActionDisplayBadConnectionAlertLocalizedMessageDrawTypingPrompt bShadowCastbStaticLightingSetScoreBoardClass InitializedAddTextMessage DetachActor AttachActorAbandonProjectorbDynamicAttachKImpactbProjectActorFOV RandSpinGetMessageIndex PlayerSpeechClientInitialize SortPRIArrayInOrderUpdateScoreBoard UpdateGRIDrawScoreboard KUpdateState InitEffects GetNextMap DoFireEffectDrawMuzzleFlashCriticalPlayerFlashMuzzleFlash GetRulesStartMuzzleSmoke ModeDoFireServerPlayFiringGetFailSwitch PlayPreFirePlayStartHold PlayFireEndGetConsoleColorClientReceiveNotify bIsSpecialAllowBroadcastLocalizedUpdateSentText AllowPrivKProportionalGap OnAdminReplyPlayLandingAnimation GetAdminNameRequiresPasswordSetGamePasswordSetAdminPasswordSetAdminFromURLbBlockZeroExtentTracesPreClientTravel KStiffness PreTeleport InitPrivs GameEvent bNetNotify SpecialEventProcess_MessageDisconnectEvent ConnectEvent StartGameNewGameMass FullTimeDate ShutdownGetLocalPlayerControllerCheckForDoubleClickMoveGetAddressURLUpdateSmoothingUpdateSensitivityAddPrecacheStaticMeshTurnOn SpawnPickupRemoveCameraEffect mLifeRange mRegenRange mSpeedRange mSizeRange mColorRange SinglePlayer DelayedWarp CalcVelocityZoneVisibilityPulseServerStartFire ShaderActionCombinerAction TimeStamp SetFocusToUpdatePlayerLocation RemovePRISetProgressMessageSetProgressTime SetWalkingRemoveFromTeam SpecialCostStopPlayFiringPlayExitSplashCheckRelevanceStopRollingDemoMutatorIsAllowedParseMessageString ConsoleClose ConsoleOpenZTestStartSizeRangeType GetMapList RestartGame SendPlayer PickTeamDiscardInventoryWarmupbPathColliding PickupQueryShouldRespawn ReduceDamage* CanSpectate IsOnTeamBroadcastDeathMessageEnumPositionDescription PreRenderSetPlayerDefaultsAddDefaultInventoryLogoutSpriteTextPositionDescriptionGetDefaultPlayerClass StartMatchContinueSinglePlayerGameFindFirstUnfinishedLadderStartNewMatchCheatJumpMatchWorldToScreenProcessServerTravelCheatSkipMatch GetKeyValue GrabOptionGetServerPortAnimNotify_Trigger InitLoggingEffectsGIPropsExtrasQuality DrawText TextSize DrawTile DrawPortal GameSpeedMaterialTrigger ServerInfoUOscillationRateVOscillationRateUOscillationAmplitudeGetTotalSceneTimeVOscillationAmplitude CameraShake UseTriggerRetriggerActionStopAfterPeriodFade BadClient ProbationClientPerformNativePerform TakeOverGetMoveTargetSpawnControllerForControllerClass IsInPain GetDebugNameSetGRIMatchStartingMapName SetOwnerIK_MouseWheelDown GetMeshName PlayAnimIK_MouseWheelUpIK_JoySlider2 TweenTime LoopAnim TweenAnim IsAnimating FinishAnimHasAnimStopAnimatingIK_JoySlider1 FreezeAnimAt SetAnimFrameIK_JoyV IsTweeningAnimStopLoopingEnableChannelNotifyGetNotifyChannel LinkSkelAnimIK_JoyU IK_MouseW LinkMesh IK_MouseZ BoneRefreshAnimBlendParams IK_MouseY IK_MouseX IK_UnknownE3 IK_UnknownE2 IK_UnknownE1 IK_UnknownE0AnimBlendToAlpha IK_UnknownDFIK_SingleQuoteGetBoneCoordsGetBoneRotationIK_RightBracketGetRootLocationGetRootRotationGetRootLocationDeltaGetRootRotationDelta AttachToBone IK_BackslashDetachFromBoneLockRootMotionIK_LeftBracket SetBoneScale IK_UnknownDA IK_UnknownD9SetBoneDirection IK_UnknownD8 IK_Joy16SetBoneLocationSetBoneRotationGetAnimParams IK_Joy15 IK_Joy14 IK_Joy13AnimIsInGroup IK_Joy12GetClosestBone IK_Joy11 IK_Joy10IK_Joy9IK_Joy8IK_Joy7 UpdateURLIK_Joy6IK_Joy5IK_Joy4 GetUrlOptionIK_Joy3GetRenderBoundingSphereDrawDebugLineIK_Joy2IK_Joy1 DebugClock DebugUnclockFinishInterpolation SetPhysics IK_UnknownC7OnlyAffectPawnsKGetRBQuaternionKGetRigidBodyState IK_UnknownC6KDrawRigidBodyStateNoneKRBVecToVectorNoneKRBVecFromVector KSetMass KGetMassKSetInertiaTensorNoneNoneKGetInertiaTensorKSetDampingPropsNone IK_TildeKGetDampingProps KSetFriction IK_Slash KGetFrictionKSetRestitutionrestKGetRestitutionKSetCOMOffset IK_PeriodKGetCOMOffsetKGetCOMPosition IK_MinusKSetImpactThreshold IK_CommaKGetImpactThresholdKWake KIsAwake KAddImpulse IK_EqualsKSetStayUpright IK_SemicolonNoneKSetBlockKarma IK_UnknownB8KSetActorGravScale IK_UnknownB7KGetActorGravScaleKDisableCollision IK_UnknownB6KEnableCollision KSetSkelVel IK_UnknownB5 IK_UnknownB4 KGetSkelMassKFreezeRagdollKAddBoneLifter IK_UnknownB3LateralFriction SoftnessKRemoveLifterFromBoneKRemoveAllBoneLiftersKMakeRagdollAvailableKIsRagdollAvailable IK_UnknownB2 IK_UnknownB1 IK_UnknownB0ClockUnClock PlayMusic IK_UnknownAF IK_UnknownAE StopMusic IK_UnknownAD IK_UnknownAC StopAllMusic IK_UnknownAB IK_UnknownAA IK_UnknownA9 IK_UnknownA8 IK_UnknownA7 IK_UnknownA6 IK_UnknownA5 IK_UnknownA4 IK_RControlTrace IK_LControl IK_RShift IK_LShift IK_Unknown9F FastTrace IK_Unknown9E IK_Unknown9D IK_Unknown9C IK_Unknown9B IK_Unknown9ADestroy SetTimer IK_Unknown99 IK_Unknown98 PlaySound IK_Unknown97 IK_Unknown96 IK_Unknown95PlayOwnedSoundGetSoundDurationPlayFeedbackEffect IK_Unknown94StopFeedbackEffectForceFeedbackSupported MakeNoise IK_Unknown93PlayerCanSeeMeSuggestFallVelocity IK_Unknown92IK_ScrollLock IK_NumLock IK_Unknown8F IK_Unknown8E IK_Unknown8D GetMapName IK_Unknown8CIK_Unknown10E IK_Unknown8B GetNextSkin IK_Unknown8A IK_Unknown89 IK_Unknown88IK_F24 GetURLMap GetNextIntIK_F23GetNextIntDescEntryGetCacheEntryIK_F22MoveCacheEntryIK_F21 AllActorsIK_F20DynamicActors ChildActors BasedActorsTouchingActors TraceActorsIK_F19IK_F18IK_F17 RadiusActorsVisibleActorsVisibleCollidingActorsIK_F16CollidingActorsIK_F15IK_F14IK_F13IK_F12 LFReferenceIK_F11IK_F10IK_F9IK_F8bDecayTimeScalebReflectionsScale HurtRadiusIK_F7 DamageRadiusIK_F6IK_F5IK_F4bReflectionsDelayScale bReverbScaleIK_F3bReverbDelayScale ReplaceTextIK_F2IK_F1 IK_GreySlashbEchoTimeScaleIK_NumPadPeriod IK_GreyMinus IK_SeparatorbDecayHFLimit BaseRadiusUK_Unknown10FSetBase IK_GreyPlusIK_JoyX POS_Auto IK_GreyStar IK_NumPad9 IK_NumPad8 IK_NumPad7 NearSpot IK_NumPad6TouchingActor POS_Defense POS_Offense IK_NumPad5 POS_Roam IsInVolume IK_NumPad4AutonomousPhysicsPOS_Supporting IK_NumPad3 IK_NumPad2 ZoneTriggerGetCollisionExtentSetOverlayMaterial IK_NumPad1 IK_NumPad0xPrivilegeBase IK_Unknown5F IK_Unknown5E IK_Unknown5D IK_Unknown5C IK_Unknown5BIK_ZxMaterialTriggerIK_YIK_XIK_WIK_VIK_UIK_TIK_SIK_RIK_Q MoveSmoothIK_PIK_OIK_NSetRelativeLocationSetRelativeRotationIK_JoyYIK_MIK_LWindIK_KIK_JxAdminUserListIK_IIK_HIK_GIK_FIK_EAmbientVolumeIK_DIK_CIK_BIK_A IK_Unknown40 xAdminUser IK_Unknown3F IK_Unknown3E IK_Unknown3D IK_Unknown3C IK_Unknown3B IK_Unknown3AIK_9IK_8 NormalPairIK_7IK_6IK_5TEXMAPAXIS_XYTEXMAPAXIS_XZTEXMAPAXIS_YZIK_4 SORT_NoSortSORT_BackToFrontSORT_FrontToBackxAdminGroupListIK_3UScale xAdminGroupIK_2IK_1IK_0IK_Help IK_Delete IK_Insert IK_PrintScrn IK_Execute IK_PrintxAdminConfigBase IK_SelectIK_Down IK_RightIK_UpIK_LeftIK_HomeIK_End IK_PageDown IK_PageUp IK_Space IK_Unknown1F IK_Unknown1E IK_Unknown1D IK_Unknown1C IK_Escape DecoInfo TempScale IK_Unknown1ADecoSectorInfoDecorationLayerData IK_Unknown19TerrainSectorSize IK_Unknown18 IK_Unknown17 TerrainScale IK_Unknown16 IK_Unknown15 IK_CapsLock IK_PauseIK_AltIK_Ctrl IK_Shift IK_Unknown0F IK_Unknown0E IK_Enter IK_Unknown0C IK_Unknown0B IK_Unknown0AIK_Tab IK_Backspace IK_Unknown07 IK_Unknown06 IK_Unknown05IK_MiddleMouse IK_CancelIK_RightMouse IK_LeftMouseIK_None IST_Axis IST_Release IST_Hold IST_Press SetRotation IST_NoneSplitStringToArray FindIndexIK_JoyZ StoreSettingPerform SaveSettings SetLocationIK_JoyR AddSetting PopClass AddClass PlayInfoDataMSM_ForcedRigidMSM_SinglePiece MSM_MixedMSM_RigidOnlyMSM_SmoothOnly ILM_UniformILM_PseudoShaded ILM_Unlit IDM_Fading IDM_NormalISM_PivotHorizontalISM_PivotVertical ISM_Fixed XAdminBase ISM_SpritePATHSTYLE_BezierPATHSTYLE_LinearEndControlPointStartControlPointbSmoothCornerSub EndAlpha bFadeOutMove VolumeTimerSASTATUS_Expired VoicePackSASTATUS_EndingSASTATUS_RunningSASTATUS_WaitingbExpireParticlesAO_Use_Alpha_From_Material2AO_Use_Alpha_From_Material1AO_Add AO_MultiplyAFFECT_ViewportCamera AFFECT_Actor AO_Use_MaskCO_Use_Color_From_MaskCO_Add_With_Mask_ModulationCO_AlphaBlend_With_Mask CO_SubtractCO_Add CO_MultiplyCO_Use_Color_From_Material2 bHideHUDCO_Use_Color_From_Material1 AlphaBlend SceneSpeedPanRateTR_OscillatingRotationTR_ConstantlyRotatingTR_FixedRotation IK_UnknownF4 SetDrawType IK_UnknownF5 RTA_Ignore RTA_Reset RTA_ReverseSetStaticMeshIK_AttnSetDrawScale3D IK_CrSelVOscillationPhase SetDrawScale FGT_SquareFGT_HexagonalFluidGridTypeFluidGridSpacing FluidXSize FluidYSizeFluidHeightScale FluidSpeed FluidDampingFluidNoiseFrequencyFluidNoiseStrength IK_ExSelTestRippleSpeedTestRippleStrengthTestRippleRadiusUTiles OT_JitterVTilesOT_StretchRepeat OT_StretchAlphaHeightScale AlphaMaxShootStrengthOT_PanRippleVelocityFactorTouchStrength EnvMapTypeEM_CameraSpaceEM_WorldSpaceTexCoordCount TCN_4DCoords TCN_3DCoords TCN_2DCoords TCS_NoChangeTCS_ProjectorCoords WarmUpTime UpdateRateTCS_CameraEnvMapCoordsTCS_WorldEnvMapCoordsTCS_CameraCoordsTCS_WorldCoords TCS_Stream7 TCS_Stream6 TCS_Stream5 TCS_Stream4 TCS_Stream3 TCS_Stream2 TCS_Stream1Pling Strength TCS_Stream0 FB_Invisible Suicided FB_Brighten FB_Darken ResourceFB_Translucent PlayerName&FB_AlphaModulate_MightNotFogCorrectlyFB_AlphaBlend FB_Modulate ObjectPool FB_OverwriteLoop MSTA_Stop ServerName MSTA_Pause MSTA_Reset MaxPlayers IK_ErEof MSTA_IgnorebRestartLevel bPauseable bWeaponStaybCanChangeSkinSetCollisionSizeMSA_FadeToMaterialMSA_ShowMaterialModulateStaticLighting2XbCanViewOthersbDelayedStart OB_DarkenbChangeLevels OB_Brighten OB_InvisibleOB_TranslucentGameDifficulty OB_ModulateAutoAimIK_Play OB_Masked OB_NormalFC_Sinusoidal FC_LinearParticleProjectorInfoTerrainMaterialLayerIK_Zoom IK_NoName SetCollisionHUDTypeIK_PA1SetSize BlobShadowMaxSpectatorsShadowDarknessDirty MatchInfoLODSET_LightmapDefaultPlayerName GameNameFearCostFallOff GoalScoreLODSET_RenderMapLODSET_InterfaceDeathMessageClassGameMessageClassLODSET_Terrain MutatorClassLODSET_WeaponSkinAccessControlClassLODSET_PlayerSkinBroadcastHandlerClass LODSET_WorldPlayerControllerClassNameGameReplicationInfoClass LODSET_NoneGameStatsClassNoneSleepbAlphaTextureMapListSecurityClassGibbedEMTT_LightSpaceAcronymEMTT_WorldSpaceEMTT_ViewSpace GameRules IK_OEMClearGetSavedGames GameMessage FellLavaDeleteDataObjectAllDataObjects SavePackageDeletePackage LoadMapListMapsfell LocalMessageFailedConnectFindPlayerByID HFReference ChangeMapDynamicProjectorMessagingSpectatorNoneDecalDamTypeTelefraggedbRequiresTickCrushedBroadcastHandlerGetNetworkNumberGetServerInfoBitmap ArmorPickup TC_ClampbNativeEventsTC_WrapAirAbsorptionHFAccessControlLoadDataObjectCreateDataObjectBaseDifficultyTEXF_RRRGGGBBBPlayerCharacter TEXF_G16 FLAG_DownTEXF_L8FLAG_HeldEnemy TEXF_DXT5GameLadderName TEXF_DXT3 TEXF_NODATA TEXF_RGBA8 TEXF_RGB8 TEXF_DXT1 TEXF_RGB16FLAG_HeldFriendly TEXF_RGBA7TEXF_P8TextureFormatMaterialVSize FLAG_HomeMaterialUSizeKILLZ_SuicideBranchEmitter RegisterGameHighFrequencyPoints KILLZ_LavaLowFrequencyPoints PackageName LocalizeBeamTextureVScaleBeamTextureUScale KILLZ_NoneScreenToWorldGetNumPositionsParticleBeamDataPTEP_OffsetAsAbsolutePTEP_TraceOffset PTEP_Actor PTEP_OffsetPTEP_Distance DCLICK_DoneGetNumTeammatesForMatchPTEP_VelocityRenderTwoSidedUseMeshBlendModeDCLICK_ActiveLineSegmentsRange DCLICK_BackParticleSparkData HudClassProjectionNormalDCLICK_Forward DCLICK_Right PTDU_ScalePTDU_RightAndNormalPTDU_UpAndNormalAddGameSpecificInventory PTDU_Normal PTDU_Forward PTDU_Right DCLICK_Left DCLICK_NoneTRAVEL_RelativePTDU_UpGetPositionDescription PTDU_NoneAlphaTRAVEL_PartialParseKillMessageMaxTrailTwistAngleDistanceThreshold DeathMessage SetPosition SetLineup+TRAVEL_Absolute SetFocusMaxPointsPerTrail MessageClassModulationTimeParticleTrailInfoParticleTrailDataSpawnParticleSetControllerStatus HistoryBot TimePerDemoAddVelocityMultiplierRange TimeTooIdle-AddVelocityFromOtherEmitter AddTeammateTriggerDisabledTimeBeforeRebootLifetimeRange EchoTimeTalkSecondsBeforeInactive UseSound DrawStyleAutomaticInitialSpawningReleaseTeammate TeamTalkClearTeammates DateTimeRelativeBoneIndexRangeSkeletalScaleDeleteInitSplinePathInitSplineRotUseStaticMeshBatchingUseRegularSizeScale SpinCCWorCWNextSplinePosZWrite bNoRepMeshNextSplineRotKScale AlphaTest KScale3DKImpactThreshold TooManyBotsKMassFindTeamDesignationKLinearDamping MeshNormalConsoleToggleKAngularDampingUniformVelocityScaleKActorGravScaleUniformMeshScale OtherTeamMeshScaleRangeKVelDropBelowThresholdVelocityScaleRangebHighDetailOnlyStartMassRangeIconMaterialNameAddLocationFromOtherEmitter FriendlyNameStartRollingDemo bClientOnlybDestroyOnSimErrorKConvulseSpacingGetInventoryClassRespawnDeadParticles CTFMatchesWorldSpaceOverlays ReplaceWith MaxParticles WeaponTickVehicleStateReceivedUpdateCharacter FadeInFactorDelayedConsoleCommand ReverbDelayTornOff TeamName C_WorldBoxFadeOutFactor TeamColor AltTeamColor StartCrouch ForceNoiseBelongsOnTeam AddToTeamColorMultiplierRangeC_GroundPlaneSpawnFromOtherEmitterbStopCountDownDampingFactorRangeExtentMultiplier SoakStop ParticleC_GroundHighlightSetupSpecialPathAbilitiesSetRequiredGameResolution ShortName C_BrushWirePTSU_LocationPTSU_SpawnOffset PTSU_None PTMS_Random PTMS_Linear PTMS_None PTSC_RandomPTSC_LinearLocalC_PivotPTSC_LinearGlobal PTSC_NonePTEA_PositiveZSetInitialState SetHeadScale FT_Constant GetPRIArrayPTEA_NegativeX PTLS_All PTLS_Polar PTLS_Sphere PTLS_BoxPTVD_AddRadialPTVD_OwnerAndStartPositionPTVD_StartPositionAndOwner PTVD_None PTRS_Normal PTRS_Offset PTRS_Actor PTRS_NonePTCS_AbsolutePTCS_RelativePTCS_IndependentPTDS_Brighten PTDS_Darken(PTDS_AlphaModulate_MightNotFogCorrectlyStringSpectatingStringUnknownPTDS_TranslucentPTDS_ModulatedSetCharacterNameGetLocationName GetPortrait FT_DragAlongPTDS_AlphaBlendFT_NoneSetAnimAction PTDS_RegularBM_HACKBM_MODULATEINVCOLOR_ADDALPHAGetBeaconCountGetBeaconAddressBM_MODULATEINVALPHA_ADDCOLORDoLoginBM_MODULATEALPHA_ADDCOLORBM_PREMODULATEBM_BLENDCURRENTALPHABM_BLENDTEXTUREALPHAPMBM_BLENDFACTORALPHABM_BLENDTEXTUREALPHABM_BLENDDIFFUSEALPHA BM_ADDSMOOTHServerValidationResponse PostUpdate SetMoveFor BM_SUBTRACTBM_ADDSIGNED2X BM_ADDSIGNEDBM_ADDBM_MODULATE4X LocationNameKillZBM_MODULATE2X BM_MODULATE PlayerList RestartMapbAdjustSamplingMouseSmoothingMode MatTickValueNone MTF_NoActionMTF_FadeConstantColorAmbientSaturationDistanceFogColorDistanceFogStartDistanceFogEndDistanceFogBlendTimeMTF_PulseConstantColor TexUPanSpeed TexVPanSpeed ZoneSoundMatTriggerActionMouseSmoothingStrength MTA_NoActionMTA_SwapCombinerMat2 ZoneActorsNoneMTA_SwapCombinerMat1MTA_SwapShaderSpecularMTA_SwapShaderSelfIllumMTA_SwapShaderDiffuseFlyingMouseSensitivity bFirstHitPrecacheContentClampToMaxParticlesbCallPreSpawnWarpServerCallbackUnWarpmColElasticityAnimRepWireframeTextureWhiteSquareTexture LargeVertex TimeDilation ReplaceMenu mNumTileRowsmNumTileColumns ATF_None ATF_Random ATF_PulseATF_SmoothStep ATF_ExpInOutATF_LerpInOut mAttenKb mAttenKaIdealPlayerCountMinIdealPlayerCountMaxMouseSamplingTime mAttenuateDoubleClickTimePDL_Low PDL_Medium PDL_HighPhysicsDetailLevelKarmaTimeScaleRagdollTimeScale MaxRagdollsKarmaGravScalebKStaticFriction C_SelectmAirResistanceDecalStayScalebEnableDodging mSpawnVecBRenderTextureRemoveInteractionVisibleGroupsbSuspendWhenNotVisibleSetSmoothingModeSetSmoothingStrengthmMaxParticles DetailModemStartParticlesmRegenST_TestST_OwnerSkeletonST_ExplodeRing ST_ExplodeST_StaticMeshST_AimedSphere ST_CylinderST_DiscST_Line ST_SpherePT_BeamMusicVolumeOverrideDefaultTexture PT_BranchPT_Mesh LEVACT_NoneLEVACT_LoadingLEVACT_SavingLEVACT_ConnectingLEVACT_PrecachingPT_DiscPT_LineNM_StandaloneNM_DedicatedServerNM_ListenServer NM_Client PT_Stream PT_Sprite PositionKRigidBodyStateKRBVec PreCacheGame SpawnHeightDefaultGravity ProcPling MT_Deform MT_Water NoiseTimer NoiseForceNoiseCheckCollision RestTensionTensionIsEntry GetGameClassProgressCommand C_CurrentForceAttenuation GetLocalURL IsDemoBuildChangeSnapViewThisIsNeverExecutedDesiredRotation ForceClampMovementClampGetStatsIdentifierGetMapFileName C_AddWire Process_TickDampeningRangeProcess_PreRenderC_SubtractWireProcess_PostRenderbJustTeleported DampeningProcMeshVertex spawnVel C_GreyWirebRotateToDesiredC_BrushVertexbBounceProcess_KeyTypeTeamScoreEventProcess_KeyEventnumRows HLookRateMax C_BrushSnapnumColsmaxPclEyeDist deviationOpenLog numParticles CloseLog AdminPlayer WeatherTypeWT_DustWT_SnowWT_RainLife WeatherPcl IPPolicies IPBannedWrongPassword NeedPasswordSessionBanned KickedMsg AdminClassControlDesiredToggleDesired ControlMotor ToggleMotorHT_Controlled HT_Motor HT_Springy SaveAdmins C_Invalid C_ActorWire HT_Normal VLookRateMax PreSpawnedbBlockNonZeroExtentTraces PostTeleport PostLoginC_ActorHiWire KHalfAngleC_BlackC_WhiteC_Mask GetAdminC_SemiSolidWire KSuspDampingC_NonSolidWire PlayJumpKSuspStiffnessKickBanPlayer PlayFalling PlayerSeesMeGetLoggedAdminGetUserKSuspHighLimitC_WireBackgroundKSuspLowLimit KMaxSpeedbKSteeringLockedKMaxSteerSpeedKMaxSteerTorqueTransientSoundRadius CanPerformKGetConstraintTorqueC_WireGridAxisKGetConstraintForceNotifyMissedJump KSecAxis2MTRAN_SlowFadeNotifyJumpApex KPriAxis2NotifyHitMover KSecAxis1 KPriAxis1MTRAN_FastFadebKDisableCollision MTRAN_Fade bIsUnique MTRAN_SeguebIsConsoleMessage bFadeMessage Restitution Lifetime SlipRateMinSlipSM_NoneSM_UpSM_DownNeedsMenuResolution DrawPivot LateralSlipPosXPosY FontSizeRenderComplexMessage RollSlipGetRelatedStringNativeConsoleOpenAssembleString RollFrictionMTRAN_Instant MTRAN_None GetColorGetPos bKTakeShotMaxCoronaSizeMonitoredPawnAlert bInvertVLook GetFontSizeSLOT_Interface SLOT_Talk GetLifeTime ModeTick SLOT_AmbientSLOT_InteractSwitchLevelMessage LeftMessageFailedTeamMessageFailedPlaceMessageFailedSpawnMessageEnteredMessageMaxedOutMessageOvertimeMessageGlobalNameChangeNewTeamMessage ModeHoldFire NoNameChange VoteStarted VotePassedMustHaveStatsNewPlayerMessage StartFiring SLOT_Pain SLOT_Misc SLOT_None C_ActorArrow LongFallLogin C_ScaleBoxKVelDropBelowSoundOcclusionNoneOCCLUSION_StaticMeshesNoneOCCLUSION_BSPOCCLUSION_NoneKVehicleUpdateParamsGetSmallerFontFor HaveHalfFontGetSmallFontFor DamageAttenOCCLUSION_Default InitTitle C_ScaleBoxHi SoundPitch FormatTimeSS_RingSS_Line C_ZoneWireC_Mover SS_RandomSS_NoneSelectedPresetNameC_OrthoBackgroundBotRefireRatebModeExclusive FireRate bClientAnimReloadAnimRateFireEndAnimRate bCanTeleportFireLoopAnimRatePickRandomTauntFor FireAnimRatePreFireAnimRatebExactProjectileCollision ReloadAnim FireEndAnim FireLoopAnim FireAnim PreFireAnimPB_None PB_ModulatePB_AlphaBlendPB_AddDropFrameBufferBlendingOp C_StaticMesh VelScaleMaxTraceDistance bProjectBSPbProjectTerrainbProjectStaticMeshbProjectParticles AccelScaleKSkelConvulse bClipBSPBlowUpC_VolumeBrush bGradientTossZbProjectOnAlphabProjectOnParallelBSP MaxSpeedbDestroyInPainVolumeSpeedDrawTargetingLargerFontThanGradientTextureGetMediumFontFor KForceExceed KApplyForceInitInputSystemC_ConstraintLine C_AnimMeshC_TerrainWire SetCroppingDrawCrosshair SetTargeting ShrinkHUDGrowHUDbShadowActiveURL InitShadowDampeningFactorInitializeControllerDisplayPortrait InitGameShowHudbUseLightingFromBaseReverb STY_AlphaZ STY_ParticleSTY_Subtractive STY_Additive STY_AlphaSTY_ModulatedSetInstructionKeyTextSetInstructionTextSTY_Translucent bJumpCapable bCanJump bCanWalk STY_Masked ShowDebug ShowScores STY_NormalbCanDoubleJump Draw3DLine STY_NoneConsoleMessagePosYConsoleMessageCrosshairOpacityCrosshairScaleHudCanvasScale HudScale MOTDColorProgressFadeTimebCanBeBaseForPawnsNone ConsoleColorbCrosshairShowbShowWeaponBar bShowPointsbShowPersonalInfobShowWeaponInfo bMessageBeep GrayColor GameEnding bLOSHearing TurqColor PurpleColor GoldColor BlueColor CyanColor GreenColor RedColor WhiteColorMinAccelComponentbUseCompressedPosition bWeaponBob CullDistanceReflectionsDelaybSpecialCalcView EndCrouch DrawVignette VelToAccel Visibility DesiredSpeedMaxDesiredSpeed ReflectionsHearingThreshold DecayLFRatio SightRadius UVM_Skin UVM_LightMapAvgPhysicsTimeDemoPlaySoundCollisionSoundUVM_MacroTexture DecayHFRatio Transmogrify DecayTimeListDynamicActorsRemoveFromNavigationAddToNavigationClientValidateRoomHFRespawnEffectTime GroundSpeed WaterSpeed AirSpeed LadderSpeed FreezeFrameJumpZ AirControl WalkingPct CrouchedPct MaxFallSpeedSkinsbPredictRespawns bAmbientGlowbOnlyReplicateHiddenBaseEyeHeight EyeHeightClientStartFire ShootHoop CrouchHeight CrouchRadiusDoReflectEffect CheckReflect HealthMaxHealthClientNameChangeClientHearSoundClientCloseMenu WriteToLogAllowDetourTo HeadScaleRoom noise1timeload SetFlash IsRapidFire noise2timeAddInteraction!StaticMeshProjectorRenderInfoPtrAcceptPlayInfoPropertyBobProjectorRenderInfoPtrSetFogRSetFogGAcceptInventorySoundDampeningDamageScalingFileLog GameStatsAttachmentBoneSetFogBKillViewedActorLandMovementStateWaterMovementState xEmitterLogScriptedSequences Teleport xPickUpBase KBSJointKHinge CanAttack SplashJumpSuggestDefenseStyleSuggestAttackStyle GetAIRating AmmoStatus KConeLimit ChangeSize LockCamera SetAITargetRecommendSplashDamage SplashDamage FireHackFocusOnLeaderRecommendRangedAttackNoneRangedAttackTimeDrawWeaponInfo GetAmmoCount AnimTweaksBlendChangeTime ChargeBarWS_ReadyToFire WS_PutDown WS_BringUp WS_HiddenWS_None DisplayFOVMessageNoAmmo bCanThrowCurrentRating AIRatingPutDownAnimRateSelectAnimRate RunAnimRate AimAnimRate RestAnimRate IdleAnimRate PutDownAnim SelectAnimRunAnimAimAnim RestAnim IdleAnimSetCameraDist KConstraint AccelerationKCarWheelJointUsedUp FireEffect UseChargeEndPathKTireNoneShieldNone FreeCameraSplineLight ClipMarker CauseEvent PolyMarkerWarnTargetPct AmphibiousInitialAmount SetTwistLookStaticItemNameFlyGet4WayDirectionWalk AmbientSound SkyZoneInfo ReachSpec PathNodeScout ViewActorInterpolationPointInventorySpot AIMarkerWarpZoneMarker SavedMoveGhostPlayerReplicationInfo InternetInfo Invisible AmmunitionGodVehicle VehiclePartLODBiasSloMo SetJumpZ BobDampingDefaultPhysicsVolumePotentialClimbWatcherSmallNavigationPointLadder SetGravity AutoLadder AutoDoor SetSpeedReplicationInfoEnvironmentDiffusion InGodModeNearMoveTarget PressingFirePressingAltFireInventoryAttachmentupdaterelativeWeaponAttachmentAntiPortalActorKillAllEnvironmentSize aimerror JumpDestAdjustedStrength KillPawnsAvatar TriggersCreateInventory AvoidMarkerInventoryGroupJumpOutOfWater PointRegion BeamEmitterSummon GetOrders PlayersOnlyGetOrderObject BlurAlphaShake SetOrders CheatView Brightness LevelNameEnemyTeamName RememberSpot DoComboName OverlayColor CameraEffectEnableUDamage ViewPlayerDisableUDamageGetShieldStrengthMaxGetShieldStrengthAddShieldStrengthDrawScreenTextCanvas ViewFlag URLString CheatManagerWaitToSeeEnemy AdminBasebAdjustFromWallsMainMenuClassMenuDescriptionConnectingMenuClassbUpdateSimulatedPositionDrawBoxbOnlyRelevantToOwner DrawBracketLoadedbIgnoreEncroachers NotPlaying AdminGUINone SkipMatchShrinkFont GameEngine JumpMatch DrawLine GiveHealth AdminCommandNoneDrawHorizontalLT_None FontScaleX PrecacheHackGetTeam FontScaleY InteractionbOnlyDrawIfAttachedBaseGUIController InteractionsColorModulate bHighDetailChangeAlwaysMouseLookChangeStairLookInteractionMasterbOnlyOwnerSee bRenderLevel TinyFontNameSmallFontNameSave MedFontNameDodgeConstantMaterial LT_Steady LT_Pulse LT_BlinkNone TexMatrixNoneNone VertexColorStrLenBaseSpectatingOpacityModifier MeshEmitter SetPrivs DrawActor UnlinkUsersPlayNextAnimationbUseDynamicLightsDrawTileClippedDrawTextClippedbActorShadowsParticleMaterial PlayInfoPlayerGetCameraLocationProjectorMaterialSetScreenLightPlayVictoryAnimationPlayerSpideringSetScreenProjectorDrawScreenActor MeshObject SetDodgingDodgingIsEnabledClearDoubleClickActionMoveCameraNone ActionPauseWrapStringToArrayBatchReference MatDemoActorExitPositionsSubActionFadeSubActionTriggerCreateCameraEffect WrapText SubActionFOVSubActionCameraShake BehindViewSubActionOrientationFS_No SwitchLevel SwitchTeambHistoryWarmup GraphDataFS_YesSubActionGameSpeed MatObject FS_Maybe MatSubAction TryToDriveDrawTileStretchedDrawTileJustifiedSubActionSceneSpeed LookTargetDrawTileScaledScriptedTexture ActivateItem PrevItem GetWeaponShadowBitmapMaterialDrawTextJustifiedAnimNotify_ScriptedLightRenderDataPtr AnimNotifyActivateInventoryItem ShowMenuPause QuickLoad QuickSave LocalTravelSetPosSpeechActorRenderDataPtr SparkEmitter SetOriginKillClientAdjustGlowME_StopWhenEncroachME_ReturnWhenEncroachME_CrushWhenEncroachME_IgnoreWhenEncroachMoverEncroachType ClientFlashMV_MoveByTimeMV_GlideByTimeMoverGlideType SetFOVAngleBT_PlayerBump BT_PawnBump BT_AnyBumpSpriteEmitterFindMasterGroupSetClipNumKeysROLE_Authority GetFreeMove MoveTime StayOpenTimeROLE_AutonomousProxyInfobToggleDirectionROLE_SimulatedProxyROLE_DumbProxyVeryShortClientAdjustPositionMoveAutonomousTerrainMaterialRenderedMaterial ROLE_None DrawPatternBitmapMaterial LT_FlickerDT_FluidSurfaceDT_AntiPortal DT_ParticleClientSetFixedCameraShowGun DT_DrawTypeParticleEmitterSetWeaponHand TrailEmitterDT_StaticMesh SetAutoTauntDT_SpriteAnimOnce KeypointDecorationListActor ForceReloadSetMouseSmoothingSetSensitivity ResetFOVSetFOVDecoVolumeObjectList StopZoom DT_Terraform ToggleZoomDT_VerticalSpriteClientReliablePlaySoundAddGroupsByNamePlayAnnouncementAuthorUpdateFlashComponentDT_RopeSpriteAddManagedGroupsByNameCacheSizeMegsbClosed DT_Brush ViewNextBotCanManageGroup DescriptionCanManageUserDT_Mesh DT_Sprite ValidPassDT_None SoundGroup DrawIconStepDirectionProceduralSoundNoneInterpolateToFindStairRotation SetKeyframePasteFromClipboardInsert LT_StrobeNotifyLevelChangePHYS_CinMotion MaxSecLevelTitleWarningOpenTimedMover GetGroupPHYS_HoveringRoleGetManagedGroupGetManagedUsersPHYS_KarmaRagDollSpawn UnlinkGroupsAutoMPStartJumpedTravel PHYS_KarmaPHYS_RootMotion PHYS_Ladder PHYS_TrailerDefaultRotatingMoverCopyToClipboardGetDefaultURLSetViewTargetResetKeyboard FrequencyGetEntryLevelGetServerNetworkAddress StartleBots MaxViewDistGetPlayerNetworkAddressSwitchbForceFeedbackSupportedbEnableGUIForceFeedbackbEnableDamageForceFeedback MaxViewAnglebEnableWeaponForceFeedbackbEnablePickupForceFeedback SceneEndedTT_PlayerProximityTT_PawnProximityTT_ClassProximityTT_AnyProximity TT_ShootTT_HumanPlayerProximityPitchDownLimitbInitiallyActive PitchUpLimitTeamBeaconCustomColor PHYS_SpiderTeamBeaconPlayerInfoMaxDistTeamBeaconMaxDist SceneStartedPlayerNameInfo InputClassPHYS_MovingBrushActorLeavingVolumePHYS_InterpolatingOtherTriggerTogglesOtherTriggerTurnsOn CheatClassOtherTriggerTurnsOffEnemyTurnSpeedLocalMessageClass OwnCamera ViewingFromNoPauseMessageQuickSaveStringProgressTimeOutMaxTimeMargin DefaultFOV DesiredFOV CameraDist OrthoZoomMaxResponseTime bAutoTauntAnnouncerLevel bZeroRollbAlwaysMouseLookActorEnteredVolumePHYS_ProjectilePHYS_RotatingDontReuseTaunt AutoTauntStartMonitoring PHYS_FlyingPHYS_SwimmingbPropagatesSoundCheckFutureSight PHYS_Falling PHYS_Walking PHYS_NoneClientSetWeaponNotifyHeadVolumeChangebNoAutoConnect bNotBased DrawRectbDestinationOnly AIHearSoundbSpecialForced NotifyBumpLT_BackdropLight LightCone SeeMonster SetDrawColorUpdateEyeHeight HearNoiseEnemyNotVisible SeePlayer LightPeriodMayFallLightSaturation MakeColorHeadVolumeChangeEndedRotation ZoneChange JumpVelocityLT_SubtlePulseJumpZModifier AdjustTossWouldReactToSeeingWouldReactToNoise LightEffectDetachLE_QuadraticNonIncidence SendMessagebInitiallyClosed LostChild LE_Sunlight LE_Negative GainedChildCamera LE_RotorGib LE_Cylinder1LE_InterferenceLE_OmniBumpMapGetMoveTargetFor0 LE_ShellLE_NonIncidencebSinglePlayerStart bCoopStartbPrimaryStart Transloc LE_SpotlightNeedsAdrenalineLE_Warp bChangesYaw LE_DiscoReload StopWaitingInLatentExecutionPickAnyTarget Finished PickTargetRemoveControllerAddControllerFindBestInventoryPathWaitForLandingPickWallAdjustactorReachableSuggestedKeyFramepointReachable EAdjustJumpFindRandomDest MaxDist2DFindPathTowardNearestbFastAttachmentReplication LE_ShockFindPathToIntercept FiringSpeedFindPathToward UpdateHit FindPathTo CSG_ActiveCSG_Add CSG_SubtractCSG_IntersectCSG_DeintersectCanSeeFinishRotation MoveToward MainScale PostScaleMoveToAdrenalineMaxPlayerReplicationInfoClassAcquisitionYawRateLE_StaticSpotbAdrenalineEnabled LE_CloudCastCombo LE_FastWave bClampFluid LE_SlowWave bIsPlayer HandednessLE_SearchlightGravityGroundFrictionTerminalVelocityLE_WateryShimmerNameFinishedJumpingGetWeaponClassGetHitEffects IsOfTypeFluidFrictionLowGrav LE_FireWaverLE_TorchWaverLE_NoneSuicideMessageIncrementKillsKDamageImpulseFinishedComboJumping DamageDescIdle FlashFog DrawVertical KBuoyancy LightType LT_FadeOutLT_TexturePaletteLoop bCausesBlood bSkeletizeLT_TexturePaletteOnceAimRunSelect bInstantHitDownPreFire ClimbDir FireLoop bAutoPathFireEndRTA_RetriggerIgnoredStillClimbingPendingClimberbNoPhysicalLadderLookDir DamageEffectDamageWeaponNameWallDir TopAnimationbFastInstantHitClimbingAnimationdepthbAlwaysSevers bSpecialbDetonatesGoopNonebCauseConvulsions bSuperWeaponNonebKUseOwnDeathVelNextPhysicsVolumePawnDamageEffectPawnDamageEmitterPawnDamageSoundsLowGoreDamageEffectLowGoreDamageEmitterLowGoreDamageSoundsLowDetailEffectLowDetailEmitterKExtraAngularDampingKExtraLinearDamping PainTimer DamageKickDamageOverlayMaterialDamageOverlayTime bWaterVolume bNeutralZone KDeathVel KDeathUpKickbBounceVelocitybMoveProjectiles bNoInventory bLowDetail bDestructiveViewFog ExitActor EntryActor HitEffects VictemHealth ExitSound EntrySound Priority DamagePerSec SightCounter ZoneVelocity bPainCausingBlockedClasses bGodMode bLOSflagbAdvancedTacticsbClassBlocker DecoList bAdjustingbPreparingMovebControlAnimationsbEnemyInfoValid bNotifyApexbUsePlayerHearingbJumpOverWallbEnemyAcquired bSoaking bHuntPlayerbAllowedToTranslocatebAllowedToImpactJumpLocationPrioritybFire bAltFire AdjustLocnextController Stimulus MoveTimer MoveTarget FocalPointFocus PendingMover GoalListhomeAssociatedActorTagRespawnPredictionTimeAssociatedActorEnemyTarget LastSeenPosLastSeeingPos LastSeenTimeOldMessageTime RouteCache CurrentPathCurrentPathDir RouteGoal RouteDistLastRouteFind bColoredPreviousPawnClassGroundPitchTimeViewXViewYViewZMonitorStartLocMonitoredPawnMonitorMaxDistSq FearSpotsLastFailedReachFailedReachTimeFailedReachLocation Adrenaline PolyFlagsLATENT_MOVETOWARD BrushColorNewDestination ViewFocus bShouldWalk PostPivot bUseStrafingUnusedLightMeshCsgOper ECsgOperaPoint mHitLocationanActorbWeightDetoursSpawnHitCount LiftOffset GoalClass LiftTrigger S_LiftCenterBaseZXYSpeed KeyFrameMyLiftLiftTag S_LiftExitDist2D MinWeightDestoldDirmagbestAim BestDistFireDirnewRot LastFiredTargetVelocityLatentActionNumber bReversesZ bReversesXbChangesVelocityProductRequired S_TeleportIdSoundLocation ParametersproblemNoneaPawn TeamNumber S_PlayerMaxWait myPickupBase markedItem markedScriptmarkedWarpZone PainVolume LadderList MyLadderNone S_LadderbTempNoCollide bDoorOpenbBlockedWhenClosedRecommendedTrigger MessageIDWaitBroadcastType DoorTriggerNoneMyDoorDoorTagNone NoiseMakerS_DoorSeen JumpSoundTSpeed bNormalizeDest2DVel2D JumpTargetCalculatedGravityZ NeededJumpUpstreamPathsaSpotNumUpstreamPathsbOptionalJumpDest shRotMag shRotRate shRotTime shOffsetMag shOffsetRate shOffsetTime PathWeightSource IncomingSeekerInventoryDistInventoryCachebMustBeReachableshooter projSpeed bSourceOnlyratingbPathsChanged bAutoBuiltbAlwaysUseStrafingpClass bOneWayPath bBlockedtakenbTransientEndPointMaxDist bEndPoint FearCostTransientCostcostbLookUpStairs bSnapToLevel previousPathbKeyboardLook bCenterView bBehindViewbFrozenbUpdatePosition bIsTyping bFixedCamera bJumpStatusbNeverSwitchOnPickup bZooming bAlwaysLevel bSetTurnRot bCheatFlying bFreeCamera prevOrderedbCameraPositionLocked bViewBot nextOrderedUseFixedVisibility bFreeCam bFreeCamZoombFreeCamSwivelbBlockCloseCamerabValidBehindCamerabForcePrecachebNoVoiceMessagesbNoVoiceTauntsbNoAutoTauntsnextNavigationPointbNoMatureLanguageNonebestPathWeight WaitDelayaBaseXaBaseYaBaseZaMouseXaMouseY aForwardaTurnaStrafeaUpaLookUpbStrafe bSnapLevelbLook bFreeLook bTurn180bTurnToNearestbXAxisbYAxisDoubleClickDir ShowFlagsMisc1Misc2RendMapvisitedWeight ForcedPaths OldCameraLoc OldCameraRotCameraEffectsProscribedPaths PathList ZoomLevelFixedLocationFixedRotationRenderWorldToCameraConstantGlowScaleConstantGlowFogLastDistanceFogColorLastDistanceFogStartLastDistanceFogEndCurrentDistanceFogEndTimeSinceLastFogChange LastZoneTargetViewRotationTargetEyeHeightTargetWeaponViewOffsetLastPlaySoundLastPlaySpeech Transition SavedMoves FreeMoves PendingMoveCurrentTimeStampLastUpdateTimeServerTimeStamp TimeMarginClientUpdateTimeS_AlarmOldClientWeapon WeaponUpdateProgressMessageProgressColorS_NavP S_Pickup TriggeredFadeOutAllSongsMaterialsToTriggerStatsUsernameStatsPasswordS_MaterialTriggerNoneNoneNoneShakeOffsetRate ShakeOffsetNoneShakeOffsetTimeShakeOffsetMax ShakeRotRate ShakeRotMax ShakeRot ShakeRotTime TurnTarget bKeepTiming GroundPitch TurnRot180 OldFloor bWasActivebSavedInitialActive AdminManagerCameraDeltaRotationCameraDeltaRad CameraSwivelbSavedInitialCollisionmInfomColormXPosmYPosTriggerActor2 TriggerActor TriggerTimeTeamBeaconTextureLinkBeaconTextureReTriggerDelayRepeatTriggerTimePlayerNameArrayDemoViewPitch DemoViewYawPlayerSecurityClassProximityType TriggerTypeForcePrecacheTime ETriggerType S_TriggerRequiredViewDir SeenActor SeenActorTag bTriggered OldTickTimeOscTimePhase FluidInfo Palette65NewViewTarget TravelTypeS_FluidSurfOscOldBase OldKeyNum NewKeyNumAntiPortalTag AntiPortals ClientUpdate RealRotation RealPositionSimInterpolateNextSimOldRotRollNoneNoneNoneNoneNone SimOldRotYaw NewLabelSimOldRotPitch SimOldPosNewPawnbNoAIRelevance bAutoDoor bPlayerOnly newHUDClassnewScoringClass bClientPause bDelaying bOpening PhysRateStepgoalFog goalscale PhysAlpha SavedRotASoundAnnouncementLevelbForceOldRotbVolumeControlinAttenAttenBaseRotDrivenVehicle SavedPosNewSongNewTransition OldPrePivotOldPosBasePosKeyRotKeyPosbOscillatingLoopNewFOV LoopEvent ClosedEvent ClosingEventMode OpenedEvent OpeningEvent LoopSoundMoveAmbientSound ClosedSound ClosingSoundhand OpenedSound IntValue OpeningSound DelayTime FollowerLeadernumTriggerEventsDamageThreshold SavedTriggerInAccel ClientLoc ClientRollView BumpEventNewbRun NewbDuckNewbJumpStatusPlayerBumpEventNewbDoubleJump OldTimeDelta OldAccel clientErr OldTimeStamp DeltaRotViewRotAccelLocDiffNoneNone maxPitchViewYawNewbPressedJumpOldbRunOldbDoubleJumpOldDoubleClickMoveNoneNone bIsLeader InForward InStrafeInJumpbUseShortestRotationbDynamicLightMoverbDamageTriggeredbUseTriggeredNewLocXNewLocYNewLocZbSlavebTriggerOnceOnlyNewVelXNewVelYNewVelZEncroachDamage NewFloorX NewFloorY NewFloorZ MoveActor CurrentMove OtherTime realbRun realbDuck bRealJumpBrushRaytraceKeyfirstWorldRaytraceKey PrevKeyNumNewMoveOldMove LastMove NetMoveDelta BuildAccel AccelNormMoveLocKeyNum BumpType EBumpTypeEMoverGlideTypefogEMoverEncroachTypeDeleteParticleEmittersUseParticleProjectorsbTypingTimeTillReset GlobalOffsetActorForcesEnabledEmitterHeightEmitterRadius BoundingBoxTimeTillResetRangeGlobalOffsetRangeDisableFoggingInvItem AutoReset AutoDestroy Emitters S_EmitterNone averageOverNewWeaponClass CamLookAt LastItem tryPlace havePlaced bForceLeave bWasAltFire DataValue DataNameNextHistorySlotOldTeamCameraHistoryMsg1Msg2 FilterFramesbVehicleIsAltFiringbVehicleIsFiringParentFactoryAimSpotOldAim AimOffset BestTarget bNoZAdjust bLeadingAimRotNone ViewDist RealDistglobalXglobalYglobalZlocalXlocalYlocalZ bAutoDrive NewEffectRemoveExisting ExEffect EffectIndexDestroyEffectClass EffectClassPTarget DriveRot MaxOffsetdt DrivePos fCurrentDriver Throttle SteeringMaxLandingVelocityNone ViewRotationNoneNone bActivatedEnabledNone OldCrouch OldRotation bSaveJumpNoneNoneNoneMyFloor CrossDirFwdDir OldFwdDirOldX RealFloor DesiredSound NewAction finalRot FiringModeChunkPerterbation HitRotationDesiredEmitter bRealSpecDesiredEffectMo BloodOffset PitchChange YawChange bUpdating checkNorm cameraLoc cameraRottriesbesttrynewdist startYaw checkpoint WallNormalMenu bDisconnect bCloseAllbCancelnewHeadVolumeWallNone actualDamageHealMax CommandLineCmdLine HealAmount HitActor OldEyeHeightReply MaxEyeHeightNonesmooth S_Camera decorMassNoneNone OldWeaponLinkLast bHuntingNewItem MyScriptSkill DesiredClassTossVelAmountbFinishedFireComboClassName strafeMagFocus2DLoc2D TargetYaw TargetPitchOldViewRotationEffectiveSpeed NewOrders OrderGiver NewVelocity HeightAdjustCrouchjumpDir S_Inventory WeaponClass GroupOffsetbDisplayableInv bTossedOut PickupClassChargepickPlayerViewOffsetPlayerViewPivotbDrawingFirstPersonThirdPersonActor projStart IconMaterial IconCoords ItemNameFiredAmmunition NewTargetSpeed2DWBob shakevect DrawOffset OldLadderbNewIsWalkingCameraRotationStartLocationCameraLocationCurrentChoiceCurrentWeaponFGoallooktwistMaxAmmo AmmoAmount PawnPosition PickupAmmobRecommendSplashDamagebTossed bTrySplash bLeadTargetbSplashDamageProjectileClass HitFxTickerHitFx FireSound bTryHeadShotrotDirbSever AmountNeededbAmountNeededIsMaxdamtypeBoneNoneNoneShieldStrengthNone SpineBone2 AmmoToAdd SpineBone1 NumCopiesbCanHaveMultipleCopies bActivatableExpireMessageActivateSoundDeActivateSound HeadBone RootBoneTurnDirFootRotProtectionTypeArmorAbsorptionAbsorptionPriority NextArmorTauntAnimNames ArmorDamage TauntAnims IdleRestAnim InsertAfter S_WeaponNUM_FIRE_MODESFireModeClass FireModeIdleWeaponAnim IdleSwimAnimIdleCrouchAnimCrouchTurnLeftAnimCrouchTurnRightAnimTakeoffStillAnim AirStillAnim DodgeAnimsDoubleJumpAnims LandAnims TakeoffAnims AirAnims SelectSound SelectForceBotMode WalkAnims CrouchAnims bMeleeWeapon bSnipingbShowChargingBarbMatchWeapons SwimAnims bForceSwitchbNotInPriorityList bNotInDemoDemoReplacementbPendingSwitch EffectOffset IdleTime OldVelocityEWeaponClientState OldAnimDir DodgeSpeedZDodgeSpeedFactorBackwardStrafeBiasForwardStrafeBias ClientStateExchangeFireModesDefaultPriorityMovementBlendStartTimeTurnRightAnimMaxAmmoPrimaryCurAmmoPrimary TurnLeftAnimMovementAnimsOldAcceleration OldRotYawbLeaderFiring FootStill FootTurningbDoTorsoTwist Recommended oldRating bReverseRun bWaitForAnimbIsIdle bFinishednewmode bPlayedDeathbInitializeAnimation bWasOnGround bWasWalking bWasCrouchedbPhysicsAnimUpdate OldPhysics CheckDistTearOffMomentumInHandHitDamageTypeTakeHitLocation AnimActionLastStartTimeLastStartSpot OnLadder LowGoreBloodbPossiblySwitch bJustSpawned BloodEffectWPbJustSpawnedAmmo addAmountShadow MenuNameWalkBobbobtime AppliedBobLandBobLastPainSoundaltnoise2loudness noise2other noise2spotnoise1loudness noise1other noise1spot ViewPitchReducedDamageType LastPainTimeUnderWaterTime BreathTime HeadVolume RefNormal AmmoDrainOldZDrainwpu SplashTime ShootLocFloor PickupCacheInventoryTypebInstantRespawn SelectedItemPendingWeapon bDropped OwnerNameConstantAcceleration SpawnTime UncrouchTime PickupSound PickupForceSerpentineTimeSerpentineDistSerpentineDirNextPathRadiusDestinationOffsetLastValidAnchorTime NewClass NewPickupBot AlreadyHasdesireFindAnchorFailedTimeCopy LastAnchorAnchor MeleeRangeSkillModifierPeripheralVision Alertness AIScriptTag FlashCountbNoWeaponFiringbNoTeamBeacon bSpecialHUDS_AmmoAlreadyHasArmor bCheckedbThrownbHideRegularHUDbCachedRelevant PlayerOwner PawnOwner PawnOwnerPRIPlayerConsole VoteMenubShowVoteMenubIgnorePlayFiringbRollToDesired bAutoFire bDontPossessbAroundCornerHearingbMuffledHearingbAdjacentZoneHearingbSameZoneHearingbAmbientCreaturebShowScoreBoardbShowDebugInfobShowBadConnectionAlertbUpdatingDisplaybCanPickupInventorybAutoActivatebInvulnerableBody bThumpedbDirectHitWallbSimGravityDisabledbClientCollisionbSteadyFiringbCanWalkOffLedgesbNoVelocityUpdatebIgnoreForcesCrosshairStylebUpdateEyeheightbSimulateGravity ResScaleX ResScaleYConsoleMessageCount bCountJumps TextColor MessageLife TextMessagesConsoleMessagePosXbNoJumpAdjustNonebStopAtLedgesFontScreenWidthMediumFontScreenWidthSmall bAvoidLedges LineColor bCanStrafebCanClimbLaddersbCanFly bCanSwimXPosbReducedSpeed bCrawler bCanCrouchbTryToUncrouch RealStart bIsCrouched LineCountFontDXFontDY TimeLeftbWantsToCrouch bWarping bIsWalking bUpAndOutCriticalString bJustLanded LastViewerLastRealViewerNetRelevancyTimeMsgTypeS_PawnBoundingSphere MessageCountShadowTexture bBlobShadow RootMotionLightDistancebShowTargetLocationLightDirection ShadowActorActive OldLocationGradientMatrix RenderInfoaFontFrustumVerticesFrustumPlanes ProjectTagbProjectOnBackfacesbSwitchToZeroCollisionMomentumTransfer SpawnSound ImpactSoundExplosionDecal ExploWallOutNoneNoneNoneNonebProjectOnUnlitbClipStaticMesh bLevelStatic ProjTexture spinRateEffectWhenDestroyed bPushable bDamageablebPushSoundPlayingbSplash PushSound EndPushSound numLandings Contents NumFrags FragSkin FragType FragMomentumMaterialBlendingOpNewVelNDamagedropped BaseSizeS_Note ThisModeNumEProjectorBlendingGRADIENT_ClipGRADIENT_FadeNone Proj_Icon bNoHumanOnly bNoMature PhraseName PackOwner Callsign ReloadSound NoAmmoSound FireForceNone PreFireTime messageIndex MaxHoldTime HoldTimeServerStartFireTime NextFireTimebFireOnReleasebWaitForRelease messagetype bIsFiring bNowWaitingbServerDelayStopFirebServerDelayStartFire AmmoClass AmmoPerFire AmmoClipSize ShakeRotMagShakeOffsetMag Recipient bSplashJumpbPawnRapidFireAnim bReflectivebAttachSmokeEmitterbAttachFlashEmitterFlashEmitterClass FlashEmitterSmokeEmitterClass SmokeEmitterSpread ESpreadStyleP2P1HoursMinutes SpreadStyle FireCount ScreenWidthbDisplayMessages CurrentMapNoneMapNum ResultSetGRNextGameRulesNewTeamMessageTrailer FailString RelatedPRI2 RelatedPRI1OutPosY InAimErrorS_LightNoneOutPosXMinCoronaSize OutStackModeCoronaRotationCoronaRotationOffsetUseOwnFinalBlend OutDrawPivot ImpactSounds ImpactVolume ImpactEffectbOrientImpactEffectImpactIntervalLastImpactTime ApplyImpulse numSounds SoundNum WheelJointmyHUDMessageString StackMode EStackMode ChildMessage AdhesionbBeepbTireOnGroundGroundSlipVelGroundSlipVec SpinSpeedGroundMaterialGroundSurfaceType ReceiveStatebReceiveStateNewS_KConstraintNoneKConstraintDatabIsPartiallyUniqueKConstraintActor1KConstraintActor2KConstraintBone1KConstraintBone2bComplexStringKPos1 Receiver SenderPRIKPos2 broadcasterbMuteSpectatorsbKForceFrameUpdateKForceThreshold SentTextprivAction forceMag KSteerAnglebAcceptPolicybAcceptAddressMaskPolicy KMotorTorqueLastMatchingPolicy KBrakingbSilentuname bSessionNextC KSuspRef KWheelHeight S_KConeLimit NewGroup Password KDamping S_KHinge EHingeType UsernameNewUserSessionIPPolicies GamePassword KHingeTypeKDesiredAngVel KMaxTorqueKDesiredAngleKAltDesiredAngleKUseAltDesiredKCurrentAngleAdminPasswordbDontAddDefaultAdmin bReplyToGUINone S_KBSJointS_Wind AllPrivs PrivManagersHitTime InvLifeSpan DistAtten EWeatherType PrivClasses LoggedAdminsGroupsUsersFName numActiveeyePoseyeDir spawnOrigin eyeMoveVeceyeVel LogFileNameLogArGEventVictim numFramestexUtexV noReference spawnVecU spawnVecVMyRules EyeSizeClampbForceAffectedpcl pclBlockersMyMutieUSectionOffsetstmp LogString bShowBotsTempLogstatNewDetailModePrecacheStaticMeshesPrecacheMaterialsNextSwitchCountdown bNextItemsNextURL NoiseCounterEProcMeshTypeLocalPlayerControllerControllerList ProcType bRigidEdges pProcData HitEffect BigHitEffectBigMomentumThresholdBigTouchThresholdInfluenceRadiusNavigationPointListEffectLocation EffectNormal touchValuePowerUpGameSpiralEmitterExtraPathCost myPickUp myEmitterDefaultGameTypeMinNetVersionEngineVersionExParticleTypes ComputerNameNetMode ENetMode LevelAction ELevelActionHubStackLevelPlayerDopplermParticleTypeExSpawningTypesCameraRotationDynamicCameraLocationSideCameraLocationFrontCameraLocationTopCameraLocationDynamicbNeverPrecachebHasPathNodesbPathsRebuiltbLowSoundDetail bStartupmSpawningTypebAggressiveLOD mRegenPause mRegenOnTimemRegenOffTime bDropDetail bPlayersOnly mDelayRange bBegunPlay bLonePlayer mRegenDist mSourceActor mChildNamemChildEmitterSourceStaticMeshHideFromMenusSummarymDistanceAttenPausermDirDevmPosDev mSpawnVecA LocalizedPkgLevelEnterText mPosRelative mMassRange LastTaunt mCollisionmOwnerVelocityFactor mRandOrient mSpinRange bKNoInit mGrowthRateEPhysicsDetailLevelSinglePlayerTeamSize Screenshot PauseDelay EAttenFunc MillisecondSecondMinuteHour DayOfWeekDay mAttenFunc mpAttenFuncmRandTexturesmTileAnimationMonthYearmUseMeshNodes mRandMeshes mMeshNodesmPosColorMapXYmPosColorMapXZmLifeColorMap TimeSecondsspringKspringDspringMaxStretchspringMaxCompress nextPick mAttractionmColMakeSoundVelmWaveFrequencymWaveAmplitude mWaveShiftmBendStrength mWaveLockEnd SystemHandleExpire mpParticlesmNumActivePcl mpIteratormbSpinningNodes mLastPos mLastVectormTimemT mRegenBias mRegenTimer mPauseTimermBoundsmSpheremDir mNumUpdatesmAtLeastOneFramemRenderableVertsmTexUmTexV mTotalTiles mInvTileCols mpSprings mNumSprings mWavePhaseA mWavePhaseB blockOnNetnumDestinations mHeadIndex DestinationsInPartOtherSideLevel FragmentsnumFragmentTypesOtherSideActorAltImpactSound WarpCoordsExplosionSize iWarpZoneDam S_KVehFactNone VehicleClassMaxVehicleCount VehicleCountCreatedVehicleSwapMaterialASwapMaterialB EMatAction bNoTeleFragThisTag OtherSideURL TempSkyZoneManualExcludes bLonelyZone ZoneEffect EMatTickFuncEnvironmentMap AmbientHueAmbientBrightness MatTickFuncAmbientVector tickAccumtickPtAtickPtB triggerOn TerrainsbClearToFogColorcc bDistanceFogsh bTerrainZonecb EBlendModeNone KillZTypeZoneTagSkyZone S_ZoneInfoInDoubleClick NewAccelSavedVelocitySavedLocation SavedPhysicsDoubleClickMove bDoubleJump bPressedJumpbDuckbRun NextMovebFoundLEParticleDrawStylePawnRotBestKills GoalsScored bWelcomedbBot bOutOfLivesEParticleCoordinateSystem bReadyToPlaybWaitingPlayer bIsSpectatorEParticleRotationSource bIsFemale VoiceTypeTeamID PreviousNameEParticleVelocityDirectionOldNameOldCharacterNameCharacterName NumLivesEParticleStartLocationShape PlayerZone PlayerVolumeHasFlagDeathsEParticleEffectAxisprisMatchIDEParticleCollisionSound FlagStateFlagPos PRIArray TeamSymbolsEParticleMeshSpawning MOTDLine4 MOTDLine3 MOTDLine2ESkelLocationUpdate MOTDLine1 ServerRegion AdminEmail AdminName RelativeTime RelativeSizeTeamsRelativeRevolution SecondCountRemainingMinuteRelativeVelocity ElapsedTime StartSizeSpinsPerSecond StartSpinRevolutionCenterRevolutionsPerSecondRevolutionsMultiplierColorMultiplierVelocityMultiplierOldMeshLocation MaxLifetime HitCountFlags Subdivision BoneIndexRemainingTimeWeight Probability UseCollisionbTeamSymbolsUpdatedbMatchHasBegunUseCollisionPlanesCollisionPlanesUseMaxCollisionsMaxCollisions GameClass SpawnAmountSpawnedVelocityScaleRangeUseSpawnedVelocityScaleUseColorScale ColorScaleColorScaleRepeats bSuccess HomeBase TeamIndexFadeOutStartTimebSuperRelevantFadeInEndTimeFadeInUseActorForcesaClassCoordinateSystem aClassNameResetAfterChange EffectAxisInventoryClassName DisabledAutoResetTimeRangeStartLocationOffsetStartLocationRangeConfigMenuClassNameStartLocationShapeSphereRadiusRangeStartLocationPolarRangeDefaultWeaponNameDefaultWeaponMeshSpawningStaticMeshVelocityFromMesh NextMutator Requester ComboName TestLabelUseColorFromMeshSpawnOnlyInDirectionOfNormalWhoMeshNormalThresholdRange botToRemove AlphaRefScorerAcceptsProjectorsTeam NewRating BestRatingUseRevolutionRevolutionCenterOffsetRangeRevolutionsPerSecondRangeUseRevolutionScaleRevolutionScaleRevolutionScaleRepeatsUseRotationFromSpinParticlesRotationOffsetTelSpinsPerSecondRangeStartSpinRange DampRotationRotationDampingFactorRangeRotationNormal UseSizeScale BestStart SizeScaleSizeScaleRepeats incomingName UniformSizeUseSkeletalLocationAsSkeletalMeshActorReasonWinnerSoundsSpawningSoundSpawningSoundIndexSpawningSoundProbabilityCollisionSoundIndexCollisionSoundProbabilityMsgParticlesPerSecondInitialParticlesPerSecondSender MapListClassTextureUSubdivisionsTextureVSubdivisionsBlendBetweenSubdivisionsUseSubdivisionScaleSubdivisionScaleSubdivisionStartSubdivisionEndUseRandomSubdivisionNextMapMinSquaredVelocityInitialTimeRangeCurrentInitialDelayRange bNewTeamResetOnTriggerSpawnOnTriggerRangeSpawnOnTriggerPPSStartVelocityRangeStartVelocityRadialRangeMaxAbsVelocityVelocityLossRange bNameChange bAllowPickupGetVelocityDirectionFromUseVelocityScaleVelocityScaleVelocityScaleRepeatsItemWarmupTicksPerSecondRelativeWarmupTime Inactive InactiveTime ParticlesParticleIndexActiveParticles PPSFractionRealExtentMultiplierRealDisableFoggingAllParticlesDead WarmedUp OtherIndex InitialDelayPS2DataMaxActiveParticlesCurrentCollisionSoundIndexCurrentSpawningSoundIndexCurrentMeshSpawningIndex MaxSizeScale KillPendingDeferredParticlesRealMeshNormalMeshVertsAndNormalsCurrentSpawnOnTrigger FirstArmorOriginalDamage DoubleDummy1 DoubleDummy2injured TrailIndex NumPoints LastLocation ViewTargetbOnlySpectator VictimNameUseCrossedSheets KillerName TrailData TrailInfoVerticesPerParticleIndicesPerParticlePrimitivesPerParticleEParticleDirectionUsage KilledPawnKillerInv WeapClass newWeapon PlayerPawn bMessageExitingNoneUseDirectionAsScoreboardClassRealProjectionNormal PawnClassTimeBeforeVisibleTimeBetweenSegmentsStartVelocityPawnClassNamePCTimeBeforeVisibleRangeTimeBetweenSegmentsRange SparkData NumSegmentsDefaultPlayerClassTeamNumUseParticleColor MeshExtentEBeamEndPointTypeaPlayerbAdminInTeam InCharacterinClass InChecksum InPassword InAdminName ActorTagInNameFrequencyScaleRelativeLengthNoneBeamDistanceRangeBeamEndPointsDetermineEndPointBy NewPlayer StartSpotRotatingSheetsTriggerEndpoint CurrentValueLowFrequencyNoiseRange ParseStringHighFrequencyNoiseRange bSpectatorLFScaleFactorsHFScaleFactorsLFScaleRepeatsHFScaleRepeatsUseHighFrequencyScaleUseLowFrequencyScaleNoiseDeterminesEndPointDynamicHFNoiseRangeDynamicHFNoisePointsRangeDynamicTimeBetweenNoiseRange FailCode UseBranchingBranchProbabilityBranchHFPointsRangeAddressBranchSpawnAmountRangeLinkupLifetime SheetsUsed BeamValueSum HFPoints LFPoints HitActorsTimeSinceLastDynamicNoiseNoneFallbackMaterial LocalPlayer UseFallback ValidatedbItemsmut mutClassETextureFormat bUserAddedmutnameNoneGRClassACClassLeftOptInOptInKeyPairResult OldSpeedIndexbPauseETexClampModePRIM ServerStateN MapStringMLMyList ContextIDDetail PlayerIDmyLevelobjName objClassDetailTextureEEnvMapTransformTypeSaveGameManifestCurrentGameProfile DecoTextNameEnvMapTransformType SpecularScreenShotNameNoneHandle bTwoSidedNonebHighColorQualitybHighTextureQuality bRealtime bParametricbRealtimeChanged bHasCompELODSetbWelcomePendingPlayerControllerClassGameRulesModifiers BaseMutatorOtherMesgGroup TimeLimit MaxLives CurrentIDNumBots NormalLODMinLODMaxLOD AnimNext AnimCurrent PrimeCount PrimeCurrent MinFrameRate MaxFrameRate AccumulatorMips CompFormatRenderInterface__LastUpdateTimeFacesCubemapRenderInterface BlobTextureTextureInterfaces LightFOV NumPlayersInvalidNumSpectators BeaconName RenderTargetRenderViewport Revision OldRevision MapPrefixWidth MapListTypeStartXStartYGameOptionsMenuTypeMultiplayerUMenuTypeULVLGameUMenuType CamActor CamLocation CamRotationClearZSettingsMenuType AlphaWeightTextureMatrix RenderMethod FirstPass Gradient Projected BaseMaterialBaseMaterialBlendingFrameBufferBlending bProjectedbStaticProjectorRulesMenuType BlendModeParticleBlending UseTFactor WireframeNumProjectorsEColorFadeType BotMenuTypeScoreBoardTypeColor1Color2 FadePeriod FadePhaseColorFadeTypeDiffuseOpacitySpecularityMaskSelfIlluminationSelfIlluminationMaskEOutputBlendingDefaultPlayerClassName StartTime GoreLevelbEnableStatLogging bLoggingGamebAlreadyChangedbWaitingToStartMatchOutputBlending TwoSidedbAlternateModePerformLightingOnSpecularPassModulateSpecular2XbOverrideTexModifierEMaterialSequenceAction bOverTime bGameEnded bTeamGameEMaterialSequenceTriggerActon PlayerInfoCurrentPlayers GameType QueryPortSequenceItemsTriggerActionIPPaused LastTime TotalTimeEFrameBufferBlending ServerIDStatsIDScorePing PlayerNumValueKeytouchLocation ETexCoordSrc instigatedBy bHasWarmedUp OscillatorsTestRippleAng TimeRollover FluidOriginFluidBoundingBox LatestVerts VertAlphaVerts1Verts0 FluidColor NoRenderZbUseNoRenderZETexCoordCountbShowBoundingBox ClampTerrain ClampBitmapOrientTouchEffectTexCoordProjectedSourceChannelETexEnvMapType TouchEffectOrientShootEffect ShootEffectETexOscillationType ShootRadiusAlphaCurveScaleVOffsetUOffset TestRippleEFluidGridTypeUOscillationPhase Palette53 S_FluidSurf DollyOffsetUOscillationTypeVOscillationTypeLastSuLastSvCurrentUJitterCurrentVJitterERetriggerActionRotInterpolatorPrevOrientation SubActionsSampleLocations CurrentTimebIsSceneStartedTriggeredTimeReverseETexRotationType bIsRunningOldPawnViewerTexRotationTypeConstantRotationOscillationRateOscillationAmplitudeOscillationPhase PanDirectionTotalSceneTimeCurrentActionEColorOperationPctSceneComplete EventEnd EventStart NextSceneTagPlayerScriptTagbCinematicView bLoopingAffectedActorEAlphaOperationAffectEAffectActions_acceleration_speedCombineOperationAlphaOperation Material1 Material2 InvertMask Modulate2X Modulate4X SubAction NotifyName DestroyTag _totalTimeOffsetLocationOffsetRotationLastSpawnedEffect Palette111 Palette113 Palette115 Palette117 Palette119 Palette121 ESAStatus_remainingTime_valuebDoneStartingRotationDelay DurationPctInDurationStatus PctStarting PctEnding PctDuration PctInEnd PctInStart StartAlphaMADisableAfterDuration IntPointComment bReverseRoll bReverseYawbReversePitch EaseIntimebConstantPathVelocity PathVelocity PathLength EPathStyle DollyWithLookAt PathStyleEImpSpaceModeCamOrientation Palette51SubActionIndicatorS_BezierHandle EImpDrawMode S_PathBezier S_PathLinearEImpLightMode Palette43S_ActionCamPause Palette41EMeshSectionMethodS_ActionCamMove Palette39S_MatineeTimeMarkerS_MatineeIPSel Palette35vfOutvfExecbWindowsMouseAvailablebShowWindowsMouseWindowsMouseXWindowsMouseYCurrentNetSpeedConfiguredInternetSpeedConfiguredLanSpeedSelectedCursorLocalInteractionsGUIController IDC_ARROW IDC_SIZEALL IDC_SIZENESW IDC_SIZENS IDC_SIZENWSE IDC_SIZEWE IDC_WAIT S_MatineeIP ThisProp ClassFrom SettingName DisplayName RenderType Grouping ExtraPriv SecLevelbGlobal InfoClasses ClassStack LastError Palette33S_SceneManagerCodeExtras ExtraPrivsTimeOutDataNewVal RangeDataParam2Param1Nonestr EInputActionSecType LastParams LastType OldHeightmapOldTerrainMap EInputKey PaintedColor VertexColorsVertexStreamsRenderCombinationsQuadDomMaterialBitmapEdgeTurnBitmapQuadVisibilityBitmap ShowGridSelectedVertices ToHeightmapToWorld FaceNormals SectorsY SectorsX HeightmapY HeightmapX VerticesDecoLayerData JustLoadedbKCollisionHalfRes InvertedDecoLayerOffsetLayersVertexLightMap TerrainMapSectors Distance RandomYawDisregardTerrainLightingLitDirectionalShowOnInvisibleTerrain DrawOrderAlignToTerrainSeed MaxPerQuadDensityMultiplierFadeoutRadiusScaleMultiplier ColorMap DensityMap ScaleMapShowOnTerrainLayerWeightMap KRestitution KFrictionTerrainMatrixLayerRotationTextureRotationTextureMapAxisVPanUPan AlphaMap ESortOrder ETexMapAxisNormal2Normal1 Palette31 DecoPaint Palette29 TerrainBadS_WhiteCircle Palette25S_TerrainInfo PropertyNameS_ClipMarker3S_ClipMarker2S_ClipMarker1 S_ClipMarker S_PolyMarkerSoundEmitters EmitSound EmitTime EmitVariance EmitInterval Palette13 S_Ambient Palette11 S_Interp myMarkerbLoggingEnabled bNavigate Palette9 S_AIScript Palette7 S_LookTarget Decorations bRandomRoll bRandomYaw bRandomPitchbAlignS_DecorationList Palette3 S_KeypointbResultPbForceDedicated bOverridematbSoundbOutaVolume EventNameSpotframeXLYPosYLGRI bLighting NewTexture NewStyleNoneNoneTextNonedist damageScaleVictims DamageAmountOptionalObject RelatedPRI_2 RelatedPRI_1TexMultiply_ColorFloatAdd_ColorColorMultiply_FloatColorSubtract_ColorColorbIgnoreHiddenEndHitNormHitLoc MatchTag NewFilename FilenameNum SkinDesc SkinName CurrentSkinPrefixDir NameEndingOutTeleporter InTeleporter MaxXYSpeedMaxZStart Destination Loudness EffectName AttenuateRadius bNoOverridebLoop NewTimerRateSpawnRotationSpawnLocation SpawnTag SpawnOwner SpawnClassExtent bTraceActors TraceStart TraceEnd Momentum HitLocationDamage KillType NewVolumeNewZone HitNormalEventInstigator DeltaTime FadeOutTime SongHandle FadeInTimeSongTorque impactNorm impactVelLiftVel AddToCurrent AngVelocityOtherActorGravScale newBlock allowRotate stayUprightImpulsethreshposoffset frictionangdamplindampit2it1RBvec AltColourRBstate newPhysicsLineEnd LineStartOption bSaveDefault NewValue NewOption BiasDistance BiasBone boneDistrayloc GroupName OutAnimRate OutAnimFrame OutSeqName BoneTrans BoneTurn BoneScaleSlotLock AttachmentSpace TimeInterval TargetAlpha bGlobalPose BoneNameOutTimeInTime BlendAlphaStage bKeepAnimNewMeshAnim UnitFlagClearAllButBaseRate Sequence NewOwner NewFloorNewBase DeltaSeconds NewRotation NewLocationDelta NewDrawTypeNewStaticMesh NewScale3D NewScale NewHeight NewRadiusNewBlockPlayersNewBlockActors NewColActorsSecondsCommand BaseMenuGlobalInteractionsInteractionName AttachToNewInteractionNewInteractionClass RemoveMeInterViewportOwnerInteractionArrayTempiIndexUnicodeMsgLife bVisibleClientOverlayCounterClientOverlayTimerMaster OverlayTimer EFlagState eKillZTypeEDoubleClickDir ETravelType MenuWhite MenuBlack MenuGraybLockLocation__OnAdminReply__Delegate NewMenuName bCanceledbScriptInitializedOnGameResConsoleHotKey HistoryTop bPathTemp HistoryCur TypedStrHistory bIgnoreKeys bRunningDemobHoldingStart bHoldingBack TimeIdleTimeHoldingReboot TimePerTitle bObsolete bTempEditorbEdSnap TimePerSoak DemoLevelsBufferedConsoleCommands bSelectedbHiddenEdGroupbClientDemoNetFuncbClientDemoRecordingbDemoRecording bNetRelevant tryCount bNetOwner bNetInitial ForceScale ForceRadius ForceType EForceTypeSimAnim TweenRate bInvertMouse bWasForward bWasBack bWasLeft bWasRight bEdgeForward bEdgeBack bEdgeLeft bEdgeRight AnimFrame AnimRate bAnimLoop AnimSequence KStepTagSmoothedMouse ZeroTime SamplingTime MaybeTime OldSamples MouseSamplesDoubleClickTimerKParamsAngVel FOVScale MouseScaleLinVel Quaternion MINFLOORZaMouse SampleCountsumMAXSTEPHEIGHT ExcludeTag ColLocation PendingTouchOldDoubleClick InputMax BuoyancybInterpolatingbIgnoreOutOfWorldbAlwaysFaceCamerabAutoAlignToTerrainEMusicTransition bLookSpringHLookVLookabxabzwforwstrwaforwastr ESoundSlot bFullVolume NumPresetsESoundOcclusion bAlwaysTick bAnimByOwnerbPendingDelete bHurtEntry ERenderStyleMaxFilterEntriesForwardFilter StrafeFilter SurfaceTypeinratemaxbNegESurfaceTypesUV2Modefilterblogoutput EUV2Mode UV2TexturetotalLockedRotation AntiPortalRepSkin PrePivotStaticMeshProjectorsHardRelMatrix bHardAttachRelativeRotationRelativeLocation Attached AttachTagCachedLocalToWorldCachedRotationLockedLocation LockedRot LockedActorCachedLocation JoinedTag CollisionTag LatentFloatDeletedOctreeBoxRadiiOctreeBoxCenter OctreeBox OctreeNodes TouchingGroup TimerCounter InstigatorLeavesRegionLastRenderTime ZoneNumberiLeafZoneNetTag SpawnLocOverlayMaterial TimerRatebQuietXLevelbAlwaysZeroBoneOffsetbCompressedPosition ActorNamebReplicateAnimations bTearOff bNetDirtybCheatbWasSNFilteredbShowOctreeNodesbDisableSortingbOnlyAffectPawnsbTrailerPrePivot WhiteTexture BlackTexture GrayTexture DefaultFontNone Texture0bTrailerSameRotationbTrailerAllowRotationSpaceXSpaceYOrgXOrgYClipXClipYCurXCurYCurYLbCenter bNoSmoothSizeXSizeYbSuperHighDetail bTimerLoop TinyFont SmallFontMedFontbDynamicLightbTicked bDeleteMe pCanvasUtil EDetailModeCRbLightChanged bAttenByLifebCorona bCheckHotKey WorldLoc bSpecialLitForcedVisibilityZoneTagStaticSectionBatches ElementIndex ClearRGB BatchIndex OutArraydxEOLStaticFilterStateLine EFilterStateRenderRevisionJustificationLightRenderDataXScaleYScaleActorRenderDataPtrBaseOwner ENetRole EDrawType EPhysicsRectXRectY LightPhase LightHue ELightEffect ELightType Palette1 directionS_Actor bracket_sizeDisconnectMenuClass DummyArrayPivotTextScreenWidthTextScreenHeight FinalEffectServerPackages ServerActorsRenderTargetsLastFrameTimeLastURLGPendingLevelGEntryGLevelRoomLFValidPortalOpPortHostReflectionsPan ProtocolCurrentTickRate ReverbPan ClientCycles EchoDepth GameCyclesModulationDepthRoomRolloffFactor TickCyclesbShowLightStatsbShowAudioStatsbShowMatineeStatsbShowXboxMemStatsbShowHistographbShowNetStatsbShowAnimStatsbShowGameStatsbModulationTimeScalebShowHardwareStats EnvironmentUpdated FileType OriginalSize LikelihoodbShowRenderStatsTotalLikelihoodRenderedSound BaseSoundPitchModificationVolumeModificationPitchVarianceVolumeVarianceRenderedPitchModificationRenderedVolumeModificationManifestIndex EPlayerPosbShowFrameRateGRenDev CylinderNoneNoneNUM_POSITIONSNonePlayerPositions TEAM_SIZE PlayerTeamNone LINEUP_SIZE EnemyTeamTeamSymbolNameobj Difficulty SalaryCap baseClassGoalsWinsMatches NUM_LADDERS IsSoaking GameLadderCurrentLadderCurrentMenuRungNextMatchObjectChampBorderObjectbInLadderGame bWonMatch currentGamepn IsOnConsoleStaticSaveConfigParam newladdernewrung ObjectClassrungDynamicLoadObject NewState PickedLadder CurrentLevelNonej bReplaceitSLenposnvalretval NormalizeOrthoRotationExp lineupnumposnV lineupposteampos oldlineuppos oldteammate ReturnValuebotname EDrawPivotPointsManifestEntries InterpCurvenewLEcurMatrixdelLEheadPrevle reachFlagsbPrunedbForced mMaxTimesSplineASplineBSplineCSplineDSplineESplineFSplineGSplineHmStartTmEndTmbInit maDeltaTimesmIndex mTotalTimembRotatorSplinemCntY2t0d0v0t1d1v1X2Y1outdt bSmoothDt bAccumDeltasX1 KarmaDataIntBoxBoxRKAng3 KTriList KLastVelGECamOrientationQuatKStartEnabled KStartLinVel KStartAngVelbKNonSphericalInertiaZAxisYAxisXAxisOriginbKDoubleTickRatebKStayUprightbKAllowRotateCoords KSkeletonbKDoConvulsionsD KShotStart KShotEndKShotStrengthbKImportantRagdollC KCOMOffset DMMatches TDMMatches DOMMatchesB BRMatchesChampionshipMatchesDMLadderIndexTDMLadderIndexDOMLadderIndexCTFLadderIndexBRLadderIndexChampionshipLadderIndexA ScriptText matcharrayAudioSubsystem Projectors DecoLayersNormal ViewportDifficultyModifierChannel ConvexVolume ThumbNameObjectsNetConnection ObjectIndex RenderDeviceFluidSurfacePrimitiveLevel Privileges GameSecLevel Managers bMasterAdmin sGroupName sPrivilegesnGameSecLevelModelprivsClientNone PendingLevel VertexBuffer IndexBufferMeshAnimation Materials StaticMeshStaticMeshInstance MergedPrivsManagedGroupsPassTerrainSectorTerrainPrimitive Primitive MeshInstanceHeightlGroups aGroupNames ClassNameYawRoll newprivsPitchNoneOptionsupass ProgressCmdTagMap uAllGroupsretListuListuGroupsOuterClassLoadMsg MainPrivs SubPrivsTagsGuidPackageInputOutConstRot Property Subsystem TextBufferEnum FunctionbPathStateCompressedPositionStructString StrPropertyStructPropertyArrayPropertyClassPropertyDelegateProperty NamePropertyObjectPropertyFloatProperty BoolProperty IntProperty ByteProperty bReversesYCTFMatchInfo1NoneAllowVoiceMessageGetLastWeaponNone HudOpacitybShowPortraitAnnouncerVolumeConsoleFontSizeCrossHairColorgeDesc ngAuthorNoneNewPingngTitleMessageFontOffset siAdminNameOM siServerName DummyObjectbRequireRawJoystick siAdminEmailngGameGameNameTab OldModulate bSoftKillZLastPawnWeaponNoneLoadFontStaticFontArrayNamesAccelerateMouseGetNumPlayersLoadProgressFontProgressFontName AdminSay HudOverlay StringDead UpdateAccelRender IK_Unicode LoadFontFontArrayFontsProgressFontFontNetUpdateTimeMouseAccelThresholdNoneNone NoProjectionNoneNoneNoneOverrideConsoleFontNameOverrideConsoleFontNoneFailedPathStartNoneNoneMutate NextStats BuildMOTDGetDemoRecordingWeaponGetLocalStatsScreenWeaponCenteredChatSynchronizeWeaponServerUpdatePingCustomizeAnnouncerServerVerifyViewTargetCenteredEffectStart HasOption ForceCrouchCheckIDSetMouseAccel ShowStatsTAUNTGetPlayerIDHashGetFontSizeIndexRecommendLongRangedAttackMutatorFillPlayInfo HudColorPipedSwitchWeaponModifyVelocitybAllowWeaponThrowingClientReplaceMenubShowLocalStats MOTDStateCDHashrenderedmaterial_dummyMySecurityClassinventoryattachment_dummy bBanByIDbReceivedPing PS2FirstMipPointerPropertycameraeffect_dummy ClientWeaponAnnouncementSoundLastPingUpdate bBuiltMOTD DemoViewerMyGameStatsClassbNoEnemyNames MutateStringcombiner_dummyRealViewTarget BannedIDsMOTD bDemoOwnerLocalStatsScreenbContactingLeveltexmodifier_dummybAllowBehindViewNone PS2NumMipsSessionBannedIDsNoneNoneDemoClientSetHUDClientSetInitialMusic SetMusicSetInitialMusicNotifyMusicChangeViewportInitializedStartClientDemoRecAutoLoadMenusNoneNone CamouflagebCanBeDamagedClientWriteStatsClientUpdateFlagHolderbDynamicNetSpeedbAdminCanPause IK_Mouse6 IK_Mouse7 IK_Mouse8 SetNetSpeedSwitchToLastWeaponIndoorMeshDrawscaleOutdoorMeshDrawscale IK_Mouse4 IK_Mouse5GetWeaponStatsbAltbMatch ZeroCollider NewSpeedbNoVoluntarySwitch RenderedHand FlagHolder bAllowFire bFoundPawnIndoorCamouflageMeshbDelay ExactPingOutdoorCamouflageMesh OldHolderbGameRestartedNone BlendRotBlendCBlendedTargetViewRotationNewCNone bInstantStopNoneFindSpecGoalForNone bAttractCamNoneNoneNoneServerSpectateSpeedSpectateSpeedSetSpectateSpeedbHideSpectatorBeacons bWasSpecNoneServerSetClientDemobRepClientDemo bSpectated bClientDemoNoneNoneNoneNoneNoneNoneClientWriteFireClientCapBandwidthDelayedHurtRadiusNotReachableBy KSimParams CenteredRollKSetSimParamsCenteredOffsetY MoveRepSizeKGetSimParamsDynamicPingThresholdGetInventoryGroupbForceDoubleJumpNoneInstigatorControllerPenetrationOffset"DelayedDamageInstigatorControllerSmallEffectOffsetContactSoftnessCenteredRotation CenteredYaw SimParamsPenetrationScale bLevelChangeSmallViewOffsetbSmallWeapons GammaPerSecMaxPenetrationbDelayedDamage bDebuggingbShouldPreloadNoneCapbCheatProtectionOldPingbDelayedSpawnEpsilon MaxTimestepNone PreventSeverCustomCrossHairColorCustomCrosshair RealTeambPartitionSpectatorsNextSpeedChange bNeverSeversNoneSetWeaponViewShakeWeaponShakeViewClientSetWeaponViewShakeClientSetClassicViewClientSideTouch CanMultiJump PokeTerrainbWeaponShouldViewShakebWeaponViewShake LoadingClassEnableWorldLocation bClassicView MaxDepthbModViewShakebAllActorsRelevantNonebForceClassicViewNoneOverrideDownloadCustomCrossHairScale RedirectURLNonebPendingDestroyReplicationViewerCustomCrossHairTextureReplicationViewTargetbShortConnectTimeOutCustomCrossHairTextureName PlayerIP PlayerURLNoneServerTravelingScreenFlashScalingSetFlashScaling ClientCapCollapsedLayersNoneNoneNoneNone MaterialTypeSVehicleWheel ReportCheat CallSignsChatRoomStringGetDisplayTextNoneGIPropDescTextSelfTriggered MapRecord GameRecord GetTeamNumChatRoomMessage VoiceChatValidGameIndexMutatorRecord WeaponRecordNone CacheManagerGRIPropDescTextGetDescriptionText KRepulsorAssembleMessage GetChannelAtNone IsMemberNoneCallServerMoveStopWeaponFiringTurnOff SVehicleClientSetActiveRoomGetVehiclePositionStringVoiceChatRoomTriggerAdvanceAcknowledgePossessionFindCacheGameIndex SetTeamNumNeedNetNotifyCreateDefaultList GetChannelDualTurretServerMoveNoneChangeVoiceChannel InvertMouseAddVoiceChannel ACDescTextRemoveVoiceChatterServerJoinVoiceChannelCheckSuperBerserkNoneNoneDualRocketServerMoveStartSuperBerserk StopDrivingVoiceChatReplicationInfo JoinChannelInitVoiceReplicationInfoChangeVoiceChatModeACDisplayTextCheckTauntValidDualServerMove FadeZoomGetPublicChannelCountTurretServerMoveServerSetChatPassword LeaveChannel NotifyLogoutCrosshairRecord StandardSVehicleFactoryCrosshairItemNoneNone UpdateHUDNoneNotifyTeamChangeNoneGetCameraLocationStartbNotOnDedServerNoneProcessQueueItemParseVoiceCommandSetChannelPasswordAddVoiceChatterClassesAutoJoinVoiceChatAddItemToQueueRanIntoVehiclePossessed SetViewPitchSpecialCalcFirstPersonViewInitPrivateChatRoomWasTriggerAdvanceVehicleLocked SaveMapList GetGameIndexAdjustDriverDamage GetChannelsAddListNoneSetCharacterVoiceUpdateAnnouncementsNoneWaitingForMatchServerLeaveVoiceChannelCheckChannelsPlayerCanRestartWasTriggerControlNone PenScaleServerAcknowledgePossessionServerVoiceCommandLoadSRGrammarNone AttachDriver DriverDiedAnnouncementPlayed InitChannelsbExtraMomentumZPlayerToucherDiedWasTriggerPoundServerChangeVoiceChatMode GetMembersShowMidGameMenu DriverLeftSetActiveListServerGetWeaponStats IsBannedVehicleUnPossessedBHDisplayTextIndependentVehicleInitializeVoiceChatServerToggleBehindView TeamChangedGetCacheMapListDualSpaceFighterServerMove DetachDriverRespawn DelayedSpawnSVehicleTriggerNoneSpecialCalcBehindView TransEffectsFindChannelPasswordSpaceFighterServerMoveCrosshairPack StartDrivingVehicle_DrivingValidGameTypeServerSpectateChangeVoiceTypeVehicleDestroyedCanJoinChannelIsTeamChannel SaveGamePreDrawFPWeapon BHDescTextGetVehicleBase AddMember ServerSpeakDeactivateSpawnProtectionPlaceExitingDriverPrecacheAnnouncementsWasBumpButtonReceiveProjectileWarningServerShortTimeoutSVehicleUpdateParamsPlayerPawnDiedInVolumeIsPublicChannelNoneNoneNoneNoneNoneNoneNoneBecomeSpectatorMidGameMenuClassClientAdjustmentFlyingPathNode VST_FixedNone GameRecordsNotifyFallingHitWallScaleSizeByVelocityMultiplierRanOverDamageTypeChatRoomClass AutoJoinMaskNoneStalledNoneWeaponBerserkPlayerTurreting RadarMapNoneNoneGetPublicChannelsToggleBehindViewIs2004ContentNoneDisableVoiceChatNoneNoneQuestionMenuClassNoneNone RemoveClassIs2003ContentDefaultContentIsQueueingSwitchGetDefenderNumGetAllIntDescEFFECT_WaterVolumeStallZNonebAllowLocalBroadcastIsFullbForceSkelUpdate SetVoiceShadowMaxTraceDistNoneGetQueueWaitTime VST_InvertedbKUseTearOffMomentum WheelInertiaNone UnStalledPTTL_AttachedToParticleNone ChooseFireAtNoneCantBeSpectatorGetPlayerChannelsWasOpenTimedMoverDumpGetOffhandBoneFor MomentumMultJoinGetMemberChannels VoiceCommand UnrealPawnPublicChannelNamesNoneBecameSpectatorClientIsBannedQueueAnnouncementVehicleNameString RemoveMember PTTST_NoneNoneWantsZoomFadeEnableVoiceChat TeamLink DriveAnim RemoveChildbLandingShakeUpdateVehicle PrevTeam InitCacheGetPlayerControllerList AddChildStayUprightStiffnessDestroyVoiceChannelNewDrawWeaponInfoNoneNonebRelativeExitPosNoneGetURLProtocolVoiceIDPlayerSpaceFlying PTTST_LinearNoneVoiceReplicationInfoClassPTTL_FollowEmitterNoneAllowClassRemoval IsQueueing ChannelIndexStoredChatPasswordNone CheckDirGetChannelMembers OccupiedbEnableRepulsionGetDamageType GetBestEntry IsSuperItemGetWeaponList ApplyMapList AnonText GetAllIntbServerMoveSetPawnRotFindBestSuperPickupNoneCrashHandbrakeSlipFactorGetGameTypeListGetMapListTitleAP_InstantOrQueueSwitchAnnouncerQueueManagerbVoiceChatEnabledGetPlayerChannelCount QueueItemGetChannelCountNoneNoneSuspensionTravelTPCamDistanceNoneDriverDamageMult OrderToIndex AP_NormalPawnUnpossessedNoneSendClientAdjustmentNoneDefaultListName WheelRadiusDrawCanvasLineMayDodgeToMoveTargetHandbrakeFrictionFactor RoadPathNodeAP_NoDuplicatesAP_InstantPlayPTTST_PointLifeCopyObjectToClipboard VST_SteeredReallyInvalidGameTypeInvalidGameType CantBePlayer ValidMaskGetChannelIndexSortTT_LivePlayerProximity RenameListVehiclePositionStringVehicleDamageScalingOpenPositionFor RemoveMapGetNameCallSignCanMakePathToNoneNoneNoneGetMutatorList DamRanOverNoneAddMap MaxViewYawbSlowerZAcquireSuperDesireabilityDefaultListExistsNoneGetMapListNamesSetInitialPositionAdminMenuClassNoneVehicleMomentumScalingbZeroPCRotOnEntryCanFindSoundInQueue ClearList IsBPContent MapRecordsNone GetCallSignCrushedDamageTypeGapTimePTTST_RandomDynamicGetActiveListSetChatPasswordGetCrosshairListLeave MaxViewPitchSpeak VehicleMassOldCenteredOffsetYBecomeActivePlayerDelayedWarningDefaultActiveChannelbDrawVehicleShadow IsInLoadoutNone GetSettingsOldCenteredRollNoneNone SetGrammar OldDrawScale TPCamLookatShouldBeHiddenKSetStayUprightParams ShiftMapPTTST_RandomStaticNone CanUseShieldFluidSurfaceShootStrengthModRemoveVoiceChannel ResetListNone RemoveListToggleScreenShotModeGetChannelMembersAtCurrentRotationInventoryClassBackup_InitialStateParentVoiceTypeName StartBase NewbDuck0VehicleStringH StartFloor ChatRoomName WaitTimeSmoothViewPitch bVoiceTalk VoiceInfoPointLifeTimeScreenshotRef stiffnessbForceNoPlayerLightsLastTimerCheckChassisTorque&DetermineVelocityByLocationDifferenceNonebNotifyFallingHitWall NewVoiceIDLastWeaponPickupTime bPlannedJump FlagTarget NewActive VoiceCodecColorSlowCollisionMeshes TextNameidxGameTypeGroupBACKUP_bEnabledkPrivateChatRoom bSingleTeamVoiceChatManager TireLoadAnnouncerSoundChannelPasswordNoneNoneNoneMapListClassName PropName ThrottleTimeNewName ChatPassword ResultQuatVoiceChangeLimit CachedGames Palette123 AttachPos LastTouched bPrivateChatNonePROPNUM ShotTargetNoneStoredChatPasswords ActiveRoomNewPRI NewTeamIndexNoneNone CachedMapsNewLoc PacketLossPendingAdjustmentSteer NewbRun0ServerReadsStdin QuatProduct FileManagerCacheCrosshairsCarQuat bRefresh ExtraInfo CacheWeapons VehicleListMaplistHandlerClass CacheMaps MapListNameLastPickupTimeNewController bNoCascadebWeaponisFiringNonebPendingJumpStatusCrosshairTextureOldChannelIndex bTurnInPlace ViewPitch0PlayerCountMinLastPlayerIDTalkingTime Palette126TeamBeaconBorderMaterialLastDetourWeightbCanWallDodgeSortingMethod GameAcronymcheat ResetConfigbEnableNone GameIndexCurrentVehicleNone ViewRollWheelsbAlreadyPrecachedMaterialsbNewAutoTauntQuatFromRotatorOldControllerbForceTeamSkins bNoTeamSkins Palette75ImpactVelocityTestPRI bLowGoreKAcceleration MetaClass RelatedPRIVCR GIPROPNUM IdleChatAnimStolenAnnouncementGetEnum FilterTypeLastEmitterLocationNoneOldPlayerViewPivot ViewRoll0ChatRoomPasswordInvertSuspensionPositionNewbJumpStatus0TrailShadeType PlayerHash MapHandler bCombine StartKeyNumStayUprightDamping Repulsors RecordIndex LookQuatNoneDoubleClickMove0RenderableParticlesVRIOldCenteredYawNoneLastArmorPickupTimeAlmostLastMoveChanPwd EAPriorityGrammarNoneNewHand S_FlyingPathSmoothViewYawNoneAttachmentClassName BackupViewInUpCacheMutators NewPitch MapListIndexNoneSlipVelColorNoCollisionMeshes NextVehicle TimeStamp0bRagdollBullet NewRecordNoneChatRoomMessageClass ChanNameSupportBoneNameLastAmmoPickupTimeAnimSeqLastPlayerIDTalkingCacheGameTypesbLocal Children MaxChattersRecognizedStringOldMeshNoneNonebDrawDriverInTPNoneKVehicleClassNoneScaleSizeZByVelocityScaleSizeYByVelocityPlayerCountMaxprojChild NewVoiceTypebUseOldWeaponMesh DriveForce LongFriction LatFriction Crosshair bCurrentColorHighDetailMeshesNone ListClassEVehicleSteerTypeNoneNoneNoneNone BoneOffsetNoneNonebLandRecoverySuspensionOffsetNoneWarningProjectileDodgeToGoalPctVehicleShadowLongFrictionFunc LatSlipFuncWheelPositionSupportPivotDistanceNoneControllerArray WheelDir WheelAxleSpinVel SlipAngle RanOverSoundbSmallWeaponBarNoneNoneVoicePackNameEAxisRisebDesireSkinPreloadbHandbrakeWheelLastVehicleCheckNoneNone ChannelName ClientRoll0NewListGroupSettings bStationary WarningDelayNewbDoubleJump0 bAutoTurret NewChildETrailShadeTypeAutoTurretControllerClass FPCamPos bBlockableCurrentVoiceBandwidth InAccel0BACKUP_JumpVelocitybRemoteControlledNone ChannelsHighDetailOverlaybFollowLookDirDummy1bDrawMeshInFPPickupClassName TypedStrPosbPoweredWheelLatSlipNoneLastActiveChannelLastVoiceGainTimeBACKUP_Gravity bSuperPickup LeavingPRI SteerTypeTrackerLastVoiceGainETrailLocationBackup_DisabledWeaponRecordsNone ListName TeamFlagQueueMutatorRecords ViewYaw0BACKUP_bPainCausingOldSmallViewOffsetCrosshairRecordsOldPlayerViewOffset MapIndex bDefensivebNonHumanControlView0 OldPickup VolumeEffect S_RoadPathbThrowRagdoll bFlamingQuatToRotator HurtWallbWeaponisAltFiringbEnterringUnlocksNonebNoInstagibReplaceNoneNoneNoneAcknowledgedPawnScaleSizeXByVelocitybSkinsPreloaded StuckTime NewPassword NewTitlebAlreadyPrecachedMeshesSupportBoneAxis LastLocTimeNewbPendingJumpStatusTrailLocationDummy2 bWasPlayer bStalledbMPOnly bAdvancedRadarMapImagebWheelOnGround TeamOwner ChannelTitlebMultiPlayerOnly FocusLeadNoneBroadcastClassNonebLeaveBodyEffect KContactNone Palette61NewChannelIndex TransEffectNone bInitOldMesh LongSlipVoicePackDescriptionLastHealthPickupTimeArrVoiceReplicationInfodamping OffsetVectorNone Palette73PendingCompressVoiceNonebStrictNoneEntries bTeamLockedNoneVisibleNonePrecacheSoundValidRecordIndex ValidIndex GetTitleareCheatsEnabledSetResetStatus MatchWords ReplaceWordStreamInteractionValidStreamIndex MusicPlayer RoundEndedStreamPlaylistManagerActivatePlaylist HasPlayerGetPlaylistLength GetMapIndex StreamTagMaplistManagerCodedPlainCreateMapItemAddServerDetailGetPathStreamPlaylistOldFirstPerson PlayStream NextSongGetBaseMapNameCacheCalcViewClientVehicleCeaseFireStreamHandleDebugExecAnnouncerRecordSendComplexMsgVCDisplayText SetCurrent PrevSong VCDescTextOnPlaylistChangedDriverLeftVehicleActivateOverlay%SetDelayedDamageInstigatorControllerGetCacheIndexClientNetworkMessageCanEnterVehicle ChatManagerGetCacheGameIndex GetValue GetFileName ParseLines SetActiveMapDriverRadiusDamageFindIndexByNameBeyondViewDistanceGetMapItemIndexSetStoppedPositionGetRandomSong POVChangedUnPressButtons GetCurrentMapItemResetRandomPoolDriverEnteredVehicleCanLeaveVehicle GetGameType GetRepeatCreateMapOption AmmoMaxed GetActiveMapIsConsoleMessage CreateStreamCheckMaxEffectDistanceGetCurrentDirectoryServerChangeTeamGetRecordIndexClearSongInfo GetRepeatAllCreatePlaylistDumpScriptTagAddSong SetMaplistAcceptBroadcastSpeech GetMapURLGetStoredGameIndex GetSound SplitParamsGetShuffleAllNewRecommendComboGetCurrentPlaylist SetTitleCreateMapItemList AddGameType ValidRoomVehicleRecordStreamFinished GetRecords GetShuffleGetCurrentStreamDrivingStatusChanged GetSpree RemoveRecordMakeColorCodeDisableNextObjectiveCanBeReachedFromLiftByCreateDefaultPlaylist GetAllMapURLGetMaps AddStreamWeakObjectives RelevantTo UpdateMapNumFireOnReleaseGoreLevelTextAcceptBroadcastLocalizedItemHasOption CheatFlyGameRecordGroupGetActiveMapIndexValidCacheGameIndexQueueNextSongFindInstigatorSpectatorSpecialCalcView CheatGhostUpdateTiltForceFeedbackChangedActivePlaylist MapHasOption EjectDriver DoSwitch GoToNextMapAllowGameSpeedChangeSetStreamAttachmentPrecacheFallbackPackageVariableTexPanner AddDirectoryGetMaskGetCurrentMapRotation CreateRecordInsertInPlaylistPlayerChangedTeam GetStreamAtStartZoomWithMax InsertSong ParserClassClientClearControllerHandlerAllowsBroadcastAppendPlaylistFindMaplistContainingPlaylistParser AddPlaylistStartDebuggingImportedPlaylistCanvasDrawActorsCheckForErrorsGetActiveMapName RevInStr InsertMap GetPathTo MapChange ChatDebugImport CheatWalkAllowTextMessageGetType DesireAmmoAcceptBroadcastTextHasInvalidMapsIncrementSpreeSetBaseEyeheightClearPlaylistInitializePlaylistCancelChangesChangeDirectory LoadPlaylistAddMaplistRecordFindCacheIndexParseLoadingHint EST_Custom27IsVehicleMutator ResetGame GetExtensionGetStreamDuration AllowMutatorRefreshMapItemSetMapItemListValidOptionIndex ServerSayGetTag EST_Custom03 EST_Custom00 EST_Custom02FindIndexByPathSetType EST_Custom08AddOptionItem EST_Custom10 UPlaylists EST_Custom22RemovePlaylistAtRemoveOptionItemToggleZoomWithMax SetRepeatchartUnTrackPlayerPlayRewardAnnouncementPlayStatusAnnouncementAcceptBroadcastVoice EST_Custom12 EST_Custom04CodecRemoveHudOverlayGetMapSuperMaxOutAmmo EST_Custom14AllowTextToSpeechPrecacheGameAnnouncementsSetPawnFemale PauseSong EST_Custom16SetShuffleAll EST_Custom17 EST_Custom18SubActionSubTitle EST_Custom19 EST_Custom20InitializeMaplistRecordsCodecDescriptionSetDoubleJump RemoveGameStaticGetMapsCreatePlaylistManager ServerSpeech PlayerJoinGetDefaultActiveChannel CodecNameOnStreamingStoppedSceneSubtitlesInstantWarnTarget SeekStream EST_Custom21StaticHasInvalidMapsGetInstigator RemoveSongAt CompareNames EST_Custom23NotifyTeamChangedGetCurrentIndex EST_Custom24VoiceChatCodec EST_Custom25GetRandomPlaylistSetRestrictionID EST_Custom26 RawInputAmmoPickupClass HoldFlag EST_Custom28ServerChatDebug EST_Custom06ServerRequestBanInfo DropFlagServerChatRestrictionStopViewShakingFindPlaylistIndexGetDefaultChannelCreateFileManager IsPlaying EST_Custom11 NotifyLoginGenerateGroupMaplist EST_Custom31InitializeActiveLists EST_Custom01 IsNumericPrecacheAnnouncer Headlights LiftJumpMaskedCompare SceneAbort DumpTagsServerTeamSay EST_Custom30NotifyLocalPlayerTeamReceived BaseDist EST_Custom29JoinChannelAt HealDamageInitMaplistHandlerAllowBecomeActivePlayer HtmlDecode ServerMutateRestartCurrentMap IsStationary ServerIdleGetOptionIndexPlayerCanRestartGameMaplistCommand ServerPauseShowCurrentMapListNotifyLocalPlayerDeadFindEntryVehicleClientForceAmmoUpdateFindIndexByFileNameFixPCRotationGetLogFilenameFindNameIndex GetSongTitle MatchPathGetDefaultMapsGetPlaylistTypeOnAdjustVolumeSetRestriction VerifyMapsNoTranslocatorKeyPressed PlayerExitImmediateStopFireFlipGetStartLocationGetBindWeightInitializePlaylists KillMusic SetGameType SetCacheMapsInitializeParsersCompareItemsSlow GetFullName CompareItems TextToSpeechServerAdminLogin SetRepeatAllDrawCustomBeacon EST_Custom13ProcessCommand RemoveSongRegisterBroadcastHandlerSeekIsInitialized TeamSayQuietRegisterVehicleFindIndexByFullNameDrawCinematicHUD KickWarningbVehicleDestination PawnBaseDied TestLevel EST_Custom15 GetSongsOnStreamChanged== EST_Custom09ClientBecameSpectatorServerNoTranslocator SetShuffle AttachFlag EST_Custom07ImportPlaylistIsDirtyGetNextLoadHintClientBecameActivePlayerDestroyed_HandleDriverGetKeyBindName EST_Custom05RemovePowerupsProcessResponsefourthreeDrawDebugCircletwoonefiveMapVoteMapList WhickedSickSPT_B4SGodLikesix Unstoppable DominatingsevenAdjustBotInterfaceRampageKilling_SpreeeightTimerFrequency HolyShit_F LinkHealMult AcceptTextLudicrousKill_FMonsterKill_Fnine UltraKill GetMapRecord MegaKillGetStreamVolume LocalPerformDumpTagtenTranslauncherVotingHandler MultiKill Double_Kill BringUpTimeValidDirectory MissedDodge adrenalin first_blood ValidMap PIT_Check PIT_Select PIT_Text PIT_Custom Camouflaged Combowhore FlackMonkeyAddOptionStringBoosterNumPassengersBerzerkRemoveOptionString HeadhunterAddRestriction Headshot SendCommandAddConfigArrayItemStronglyRecommendedGetGameRecordSetMapOptionsKickVoteScoreFadeInSecondsGetCustomRewardAnnouncerClassScaleSizeByVelocityMax SPT_None*=AccessControlIniRemoveFromCurrentPlaylistSetBaseDistanceObjectiveGetOutDist FILE_MusicFillToInitialAmmo MaxRoadDistPlaylistParserBaseIsSoftwareRenderingCameraDistRangePlayerChatTypeGetWeaponRecordAddRestrictionIDGetVehicleList GetGameInfoNoBlood CameraSpeedSuspensionMaxRenderTravelLinkedReplicationInfo GetAmmoClassTraceThisActor HasExtensionCenterSpringRangeRollNotifyEnemyLostLock MDL_UltraLowDetailFactorAliasesHasOccupiedTurretBoneSteerAxisbShowRadarMapKickVoteEnabled FlipTorqueClientTriggerMeshLODDetailLevelClearCurrentPlaylistGetMaxChattersbNoAmmoInstancesTimeMarginSlackDeleteConfigArrayItemRemoveDirectoryKScaleJointLimitsMsg_PlayerListMsg_AllGameMapsMsg_AllMapListsMsg_MapRotationListMsg_NoMapsAddedMsg_AddedMapToListMsg_NoMapsRemovedMsg_RemovedFromListMsg_PlayerBannedMsg_SessionBannedMsg_PlayerKickedMsg_NextMapNotFoundMsg_ChangingMapToMsg_NoMapInRotationMsg_NoMapsFoundMsg_MapIsInRotationMsg_MapNotInRotationMsg_UnknownParamMsg_NoParamsFoundMsg_ParamModifiedMsg_ParamNotModifiedMsg_MapListAddedMsg_MapListRemovedSetMusicVolumeMsg_EditingMapListValidStreamNameGetSecurityLevelHackPlayFireSoundAnimMeshGlobalLODFormatTimeDisplayGetAllCharactersbDeferRenderingSPT_M3U B4SParserGetInstalledCodecs FILE_Map SendResponse FILE_None FindGameTypeMaplistRecordMatchSetupLocked ClientMover GetTurrets MinReloadPct PlaySong IsPaused PutDownTimeDeathOverlayTime AdminDebugGetAnnouncerListIsNewGameTypeClientRoundEndedbSetPCRotOnPossessbCanCarryFlag PauseStreambNoTextToSpeechVoiceMessagesClearRestrictionIDbDriverHoldsFlag MapVoteScore ResetInputMDL_LowChatPasswordMenuClass ResetTrailTextToSpeechVoiceVolume MDL_MediumFILE_DirectoryStaticDrawCanvasLineGetMutatorRecordCheckSpeedHackGetTeamSymbolListNone MDL_HighAnnouncerVoiceGetConfigArrayDataBotDifficultySetCharactersbCausedByWorldKickVoteGroupVoiceChatLANCodecDrawDebugSphereAddToPlaylistGetPlaylistCount StreamBase DisplayHit JCR_Banned ParserTypeAddHudOverlayUpdateDistanceFogLODbDramaticLightingChatBanTrackNewPlayerGetAllLoadHintsIsVehicleEmpty IsReadOnlyAccumulationData FILE_LogSTREAMFINISH_ErrorUpdateConfigArrayItem ClientReset LoadID3Tag ParsePath GetPasswordHeadlightScalingbUseHeadlights bNeedSave GetRange ID3FieldKMaxAngularSpeed FILE_DivX ChatGroup FILE_DemoMapVoteGameConfig BlackColorDrivingHeightSetMaskSetMemberMask FILE_TextureGetAvailableMapsCreateNewVoiceChannelJCR_WrongPasswordbAllowViewChangeGetDriveLettersShadowCullDistanceCheckForHeadShotbShowPortraitVCGetRandomTeamSymbol MaplistDirtyGetCurrentTitleSetCustomRewardAnnouncerClassSpecEnteredMessage IsJoinedToSetCustomStatusAnnouncerClassCalcContactRegionNotifyEnemyLockedOn SaveID3Tag NeedsFlipGetPathSeparatorCreateDirectoryServerPlayHorn GetFireModeCustomRadarRange MapVoteGroupShakeViewEvent RulesGroup SpecialChars BotsGroup M3UParser SpeakLast HtmlCharLockOnClassStringbDesiredBehindView ReloadAll NeedAmmo SVehicleIconIsDefaultContentVotingHandlerType FILE_HTMLForceLoadTexturePhilIsPrivateChannelGetBaseDirectory AcceptSpeechSetVoiceMemberMaskGetLoadingHintGetFriendlyName SpokenFor bNoCoronasCanHealSetReservation FreezeAllClearAllDebugLines streamdebugGetMapRotationMainJCR_NeedPassword IsHeadShot FILE_Static MaxOutAmmoGetBotPassenger ViewTurret DeployedMapHistoryInfo UnDeployed PerformDodgeDrivingRadius FILE_Stream WinMatch EnableCheatsSuperHealthMax HeadHeight BeaconColorbCanUseGetVehicleRecordSPT_PLSDefaultPlaylistNameGetDirectoryContents GetCodecInfoFILE_AnimationInitWeaponFires JCR_SuccessNewSpecMessageTooCloseToAttackDramaticLightingScale GetDirectory EntryRadiusFluidTimeScaleFILE_Playlist StopStreamIsInCinematic GetHandleGetMediumFontChangeBaseParamsFeedbackEffectbUseTerrainForRadarRange StopSong NeedToTurnPlayerChatManagerAllowMusicPlaybackAddGameModifierShouldFireWithoutTarget GetAimTarget DustColorResetStaticFilterStateGetPlaylistAtMatchSetupEnabledKAddAngularImpulse JCR_InvalidReservationCostMultiplierIsMouseInvertedSpecialDrawCrosshair NoBindString ModifyThreat FILE_SoundVehicleCheckRadiusbVehicleShadowsTextToSpeechAlias AbortScene GetTaggedGetActiveMapURLDrawTilePartialStretched ServerGroupParseExtensionESST_SkipToNextLineDrawStayingDebugLine CurrentIndex ProcessEvent bVehicleHitDrawActorClippedRemoveCharactersbEnableInitialChatRoom GameGroupGetConfigArrayColumnTitle FilePathGetAnnouncerRecordSpeechReplacement KickIdlerIsCaseSensitive BindColorInstalledCodec ValidFileVoIPLANCodecs AcceptVoice GetPathRoot SpeakDefaultFireProperties OnRefreshGetConfigArrayItemCount JCR_MemberMaplistRecordGroupMapVoteEnabledSTREAMFINISH_EOFConvertToFileExtension FILE_XMLCanChangeTeamChangeSpringFeedbackEffectReceiveBanInfo GetMapTitleVotingReplicationInfoBaseDefaultBroadcastRadiusParseDirectoriesbEnableVoiceChatVoIPInternetCodecsDefaultExtensionTPCamDistRangebAdjustDriversHead PostRender2DAcceptLocalizedFOVBiasEjectMomentumCurrentHandle bRepeatAll GetStreamCenterSpringRangePitchMaplistManagerBasebClientAuthoritativeRoundHasEndedGetCustomStatusAnnouncerClassVehicleTriggerMarker HasWeapon AdjustVolume SetSongs SetHandlebPCRelativeFPRotationLocalBroadcastRangeMapVoteGameConfigLiteSetTeamStreamInterfaceIsPendingConnectionRemovePlaylistRenamePlaylistSetBaseVisibility HeadRadius PLSParser JCR_FullAlternateFallbackSoundPackage GetSubTitlesStreamCommandlet FlipTimeDefaultKickReason CachedSoundGetStreamPositionRecoverFromBadStateCodeSetWheelsScaleClearStayingDebugLinesCenterSpringForceJCR_NotAllowed FILE_IniFadeOutSecondsClearRestrictionAmbientSoundScalingConvertToFileTypebMayCausePainGetPlayerRestrictionbFlyingPreferredbIgnoreVehicles DebugInfoPTEP_DynamicDistance Performance Pint_sizedSetAmbientShake bInvalidbTeamNotifiedUseMusicVolumeAmbShakeOffset AmbShakeRotFileNameWithExtension NewSongsGenre OldRecordcposbHasHandbrakeoposInitialSeekTime SymbolNamesbMenuBeforeRespawnbWasBehindView ScreenLocX MapItemsFieldsAmbientShakeRotMagbRewardSoundsiKeyEStreamFinishReason DebugString bForceStrafeNewPlaylistName SubTitles OverlaysAllow InitialTime__OnRefresh__DelegateLastActiveTime bNewStatusbIncludeOptionsPlaylistNames VehicleIcon LastHitBy NumDivisions OldColorDetectedVideoMemorybOnlySpeakTeamTextStatusAnnouncerRotFreq PublicMask Response TempFileNamebViewingMatineeCinematicbUseCollisionStaticMeshCheater DesiredName LoginDelay OptionName bFreezeKarma LastHornTimeLastSongHandleRecords DefaultTitlebClientTrigger Directory bLocalLogVehicleLostTimeSavedRelativeLocationMaxEffectDistanceTopbCloseHUDScreenbThisClassOnly RawString NewColorThreatCurrentSongDuration SentTextNumbMustJoinBeforeStartdiff OptionStringFullURLNoEntryTexture__ProcessResponse__DelegateTimerInterval NextTimerPopAimDirMutatorClassNameListenerLocationtarg ForcedAlphaMaplistHandlerType bForceAlphaAName Commandlet OptionIndex RandomStream bCanFlipgravUp NewComboName ColumnIndexMultiply_StrStrbPrecachedGameSoundsDesiredZoomLevel ReloadForce NoAmmoForceMaplistRecordNames FlipTimeLeft FlagActorAnnouncerRecordsAddVelocityFromOwner DummyStringFalloffStartTime CacheNameAmbientShakeOffsetFreq RecordNameCurrentStreamAttachmentRecCalcViewActorLocationCurrentSongHandlebBehindViewChangedbAllowPlayerLights Bindings TeamUseTimebNoProjectOnOwner__ProcessCommand__DelegateSavedFireProperties LocalMaskAmbientShakeFalloffTimeActiveChannelLinesbNoTeam HornIndexbHideVehicleNoEntryIndicatorbFastWeaponSwitching SpawnOverlay NumSkips bEnglishOnlyHeadLocMinNetPlayersbRepulsorInContact FalloffTime ParseClassFPCamViewOffsetLastLockWarningTimeCodecssTagContactRegionCenterContactRegionNormalContactRegionRadiusContactRegionNormalForcebCheatsEnabledSpeakingBeaconTextureNewAnnouncerClassLevelTextureLODBiasbHideRemoteDriverOtherLocationNewTeamRandomSphereLoc ASoundNameCacheAnnouncersbFPNoZFromCameraPitch PlaylistNamebSave AntiPortalARotMagbIsSpaceFighter__OnPlaylistChanged__DelegatePlaylistManagerType FlipScaleLastBroadcastStringbDestroyOnWorldPenetrate bDoSafetimeIDTag bInitialized SoundPackageCurrentSongPositionbNewViewTargetLastBroadcastTime bInDodgeMovebShowDamageOverlayNewMask NumSides bAimingHelpLetters bIsGreyScale StreamHandleOptionValueStringCurrentDirectory SeekSecondsPlayerChatClassAcosbNoSinglePlayerInPath DirectionYParmsNextBroadcastHandlerNextBroadcastHandlerClassInsertPositionPlaylistManagerAnnouncerName RandomPool VoIPAllowVADcntCalcViewActorbDetour SplittedbPositiveOnlyNameAMaskLen bMaskRight bMaskLeft FlagOffsetSuffix EFileTypeBorder bCancelledLongestAllPRIParamsrootValues PlayCountExtrabEnableStatsTrackingMsg_MapIsNotInRotationManager bMayRepeatNewMapsbSinglePlayer NewGameType Palette101bPrecachedBaseSoundsColorPlayerAndWeaponTexturescurrListenerRotation EntryVehicle DodgeLandZ MatchedB NewStreamHUDMenuDemoMenuClass MatchedAEqualEqual_MapItemMapItem OldActor$EqualEqual_KeyValuePairKeyValuePairDelim SeekTimebAcuteHearingNewBHbShouldStopKarma CachedSoundsArItemRotateVelocityLossRangePCArrayRemovingClassbHideEditorPaths AddingClassbAlreadyVisited ArrayDimNameBbStruct CacheIndex BeaconTex ClientStop NewAmountFoundbResetNextLoginTime ReportTextEPlayInfoTypeInType bOldDrivingNextRoutePathbSpawnProtected RulesMenuServerSkillLevelAmbientShakeRotFreq KeyNumberLeft BestWeight IsActivebAllowWeaponToss Objective CurrentHintbVehicleTransition SubTitleModeEndBaseAttemptHintViewDirParamA bDrivingPlayerAddressHitDir TrackNumber Palette103 SkillLevelNewRulebSkipNotificationbSeparateTurretFocusAPath NewAmmoClassMatch BulletSoundsNewPos TrackVelbTrackWaitingEntryPositionHUDOverlayFOV MaxZoomLevel FullPrecacheDirectoryPath StuckCount bShuffleAll bKeyVehicleLastPlayerCalcView SongArrayCenterX OffsetMag bHasRadar BoneRollAxis FieldValue bLeftTrack NewPlaylist bTrackWheel bResetting DemoCommand bJumpLiftBACKUP_bHiddenAbsoluteVelocity SongFileNameHearerDummyRotationCamViewOffsetZAmount Palette89 bDrawCorona OffsetFreq VehicleZ PathName InManagerEJoinChatResultINVALIDSONGHANDLECenterYbDisplayTrackChanges bAutoStart LastPlayTime GroupIndexRealSkillLevelArtistAlbumTagID NewMapNumNextReplicationInfobHUDTrackVehicleMessageOfTheDayAmbientShakeFalloffStartTime PanOffset VoteCount MaxIdleTimeDeathOverlayMaterial__OnStreamChanged__DelegateArSM SongName DaSoundNameGameClassNameRefVehicleRecords CacheSound EjectVelVoteReplicationInfoHealerPathsKickVoteCountEMeshLODDetailLevelGravMagCurrentPlaylistCacheVehicles LockOnClass Extension bBulletHitbDirectDamage bOverwrite PlaylistTestAdditionalScale bRubberyPartsPlayerEnterredRotationDirectoryName HornSoundsRealDistanceFogEnd DirectionXVehicleDescriptionbDriverCollideActors AngImpulseRecsCrossCharsbRepeatMapListClassTypeUseAbsoluteTimeForSizeScale CurrentNumColorInterfaceTexturesColorWorldTexturesMinRunOverSpeedCalcViewRotation OldDownDelayHUDSettingsMenuCamViewOffsetWorldbRegisteredChatRoomStartRelativeLocation WheelsScale FlagBoneFExtAllMapsbDetailAttachmentCustomReplicationInfoNumServerDrivesParsersSinglePlayerMenuClass DownDelayLoginDelaySecondsbNoTeamChangesAmbientShakeOffsetMag__OnStreamingStopped__DelegateBindStr bNoDecalsNewMapConfigArrayNamebVehicleDestroyedbBadStateCode AmmoCharge torqueAxisbAbortCinematicMaplistHandlerbSkippedLastUpdate ScreenLocY NewPlayerIDFalloffScaling bWriteToLogStoppedPositionbDirtybNoFail RuleName bFoundErrors"__ChangedActivePlaylist__Delegate SpringCenter NUMPROPSInSexBroadcastRadiusbEnableAmbientShakeOverlayVotingHandlerClass FullMapURL bReceivePlayerToucherDiedNotifybSuccessfulUseNewStreamFileNamebNotifyLocalPlayerTeamReceivedDefaultChannelInMOTDAIMoveCheckTime bEndOfRoundDistanceFogEndMin PortraitPRIInstGameConfigIndexResetCountDown bTestMode NewPrePivotbSpecialCrosshairResultsbValueCalcViewLocation LastActivebRecurseDirectories bReadOnly OldDriver bSameTeam DirectoriesNonebHighScoreKillbAllowMPGameSpeedbAllowVehicles bEjectDriverSongsEStreamPlaylistType MaxRotationbMarkWithPathDotMM RuleValueDesiredTPCamDistanceTPCamWorldOffset StolenSoundHUDOverlayClass TimeStringRealVelocityLossRange RealJumpZ bAllowSpacesbNoDoubleJumpResetTimeDelaybLastPressedJump ListIndex aLastStrafebAddToServerPackagesbScriptPostRenderbRestartTrack HintColor ESST_ModeFallbackPackage PlaylistsaLastUpMapURLs StreamNameFieldIDActiveMaplist bShuffle NewDrawScale RowIndexGainbLiftJumpExitbNoFriendlyFirePlaylistManagerClass aLastForward StreamObjDriverViewPitchDriverViewYawworldUpbAddedInOrderbClearedZBufferMultiplyEqual_StrStrVoiceMemberMaskRewardAnnouncerVehicleMovingTime ParsedPathPlayerStartTime FlagRotation torqueScale OldSteering ReferenceZOffsetMapOptionStringGetPerObjectNamesParamB PenOffsetbVehicleOnGround bCanReach FullPath bIsTutorial FlipAxisDirectoryPartsbDisableNotificationNetworkMsgMenu TempRecordsBestIdxbNoFX NewHandle Mutators DefaultMaps NativeID3Tag MinFlySpeedbParamExtPlaylistIndexBaseNum MaxPathSize NewMapNameGames BaseVisibleLODbBlocksTeleport__OnAdjustVolume__DelegatebDirectionalCoronaHUDOverlayOffsetInFileManagerbEnemyLockedOnbCustomListener NewSound CurrentSongNothingSrcFallbackSoundPackagebScriptedRisebMakeSourceOnly FieldNameLastCameraCalcTimeDefaultActiveNoneAnimNotify_LIPSincFindValidTauntIdleKickReasonPlayLIPSincAnimMinTimeMarginLIPSincAnimEndIsPlayingLIPSincAnimCurrentLIPSincAnim ShowVoteMenuStopLIPSincAnimHasLIPSincAnimAddToPackageMapCriticalEventLIPSincAnimNameIconFlashMaterialbShowLIPSincStatsGetPropertyTextbWasSpeedHack bRealDesirebKickLiveIdlersNoneNoneResetTimeMarginLastSpeedHackLogNoneNone StripColorGetPhysicsVolume IsEnabledHoverPathNodeCheckForSplashbSmoothKarmaStateUpdates IsJumpMovePawnEntryActor MutatorName bTraceWater bFlyingKarma CompareAccel WaterDamagebRepulseWater bCanHoverVehicleDrowningDamType ViewVolumebAllowLadderStrafing SplashEffect NumMutatorsNoneDeadUse StartLocbReadyToSplashNoneNoneInitSavedLevelPostLoadSavedGame SaveGames PreSaveGamebSupportSaveGames TestPawn bIsSaveGame TestPlayerPlayerOwnerNameNoneNone OnBuildMOTD OnPostRenderTakeWaterDamageLockWarningIntervalMaxClientFrameRateLockOnWarning bIgnoreTerminalVelocitycY__OnBuildMOTD__Delegate__OnPostRender__DelegatecXbWasSaturatedNone VerifyLock AggressorNone ShootMissile BlocksShotAt JustStartedNewReservationCostMultiplierChangedReservationGetTargetLocationShouldTargetMissileIncomingMissileNotifyPostLandedbDamagesVehiclesrulerAlternateTarget bForcedOnlyImportantVehicle ONSPowerCore IsArtilleryWaterDustColorbLiberalVehiclePaths bNoSuperSizeDirectionHintbCanDoTrickJumpsLastBlockingVehiclebOrientToVelocitySpawnedEntryActor bSuperSizebNotifyPostLandedBestDirbRepulsorOnWaterbBlockProjectilesAccumKarmaAngleErrorNewDirNavigationPointRangeNoneNoneNoneNoneMultiMinPlayers bBerserkbSlowRefCheckingNoneNonebLargeGameVOIPMinSuicideIntervaldP^=1=-Z9:9:$-l-Z9:9:$-Z -m9:9:$-Z-m9:9:$-Z9:9:$-Z-K9:9:$-m9:9:$9:9:$9:9:$GB Y7Jvhʁ) qY,e p3},e,e,eʁ) p p(bQ 3},e,e,e,e p p3}3} p3}3}(bQ (bQ (bQ 3} ph u u3}3}3}Zs3}Zs@qʁ)ʁ)3}(bQ (bQ (bQ (bQ 3}(bQ (bQ ,e(bQ  u,e3}3} p3}Zse}L,e qY qYe}Le}L,e3}Zs3}Zs,e(bQ p&ɢ&ɢ u p p3}ZszVGBe}Le}LzVGB,ee}Le}L,ezVGBzVGBMJhh p,e p qYe}Lh3}Zs p ph p,eh3}3},e,e u uzVGBzVGBzVGB3} uzVGB3}3}pa,eg _T צ9,e3}@q3},e,ehʁ)ʁ)m?4ʁ),ehʁ)ʁ) qY,e3},e qY qY qY qY qY qY qY@q,e qYʁ)ʁ)ʁ)@q@qʁ)3}@q3}3}ʁ)@q@q@q3}@q@q@q qY qY qY@q@q@qʁ)ʁ)ʁ)3}@q@q@qʁ)ʁ)3},e@q@q@q@q@q@q@qzFzF@q@q@q3}3}Zs3} qY qY@q@q qY qY qY3},e qY@q@q qY3},e qY@q@q qY qY qY qY qY qY qY qY qY3}Zs,er*ъ,e,e,eh3},e qY@q qY@q qY,e u u,e,eʁ),e,e,e,e,e,e,e,e,e,e,e,e,e u u3} u,ee}L3}3}e}Le}L qYe}Le}Le}L(bQ qY3}e}Le}Le}Le}Le}Le}Le}Le}Le}L@q u u u u@q qY@q ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ,e ҽ ҽ,ezVGB ҽ,e ҽ ҽ ҽ qYr*ъ,e,e3}3},e3}3},e,ezVGB,e,e3}zVGB qY qY qY qY qY qY qY qY qY qY,e,e u@q@q qY@q3} u u@u)qi%j%k%p%W@lhHzK@F&P&Q&azX&Y&$?Z&$?\&$/E^&$@Ea&$=n&$Co&$Cp&$Cq&$HCj $Es&$Ct&$L=u&$?v&$?w&$DQ."PFO."|&$B}&$XB@'$ BA'$BSy$AZz$AD'$B^z$GCE'"dX|$A_z$@K'$?VxM'$ Q'$ U'$;Z'$?['$?j|$L?{ga'lb'H}'$>7*d F*+v$@HoP saN M c$L yK $ C:$B=$BFj|Dr!{:W N Sosusv, oE-I-K-i9:t9:$-KE9:t9:$-K-Jr3*3-l /9:t9:$r3*3-l -I-K-i 9:r9:$9:r9:$9:t9:$-KE9:t9:$-K-Jr3*3-l /9:t9:$r3*3-l -I-K-i9:t9:$-I-K-i9:t9:$ w3*3-l -I-K-iH9:t9:$-K-J 9:t9:$9:!9:$-I-K-i+9:t9:$-K9:t9:$-I-K-i9:t9:$9:!9:$-I-K9:9:$-m -Z$-I-K9:9:$-m -Z$ wU*-I-K9:9:$9:r9:$-b2-I-K9:9:$-I-K9:9:$-Z-I-K9:9:$-Z-r -Y-I-K9:9:$-I-K9:9:$-Z-m-I-K9:9:$-Z-a2-Z9:9:$-I-K9:9:$-Z9:r9:$-I-K9:9:$-Z -Y39:r9:$-I-K9:9:$-Z9:r9:$-I-K9:9:$-Z9:^19:$-OGeʁ)@Eʁ)ʁ)ʁ)ʁ)ʁ)3}3}h3}3}h3} u u u uʁ) uʁ) u3}(bQ (bQ ʁ)3}&ɢ&ɢ&ɢ&ɢ&ɢʁ)3}&ɢ&ɢ&ɢ&ɢ&ɢʁ)ʁ)ʁ) ҽ ҽ ҽ ҽ ҽ ҽ ҽ3} ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)e}Le}Lh3}3}3}Zs3}3}Zs*jW3}7R d u Ax+g-[$Bv$?B)$?HuQ$?g :0???l C$?QO Tj$?yS$@K $BF $>v"$C:$A=$AC\"Zm!P$BC$?oVssw sRSN -Z9:9:$-Z9:9:$-m9:t9:$-O-W-X9:9:$9:9:$9:9:$Gj,eʁ)hh qYhhhhh qYhhh3}3}Zs3}hh3}hh qYh@q@qhhhhhh qY@qhhhh@qhhhhhhhhh qYZȵZȵZȵhhʁ)ʁ)ʁ)h,e qYh##h]Tqh]Tq3},e,e,e3}Zs3}Zsr,e3}3}ZszVGB,ezVGB3}Zs3}Zsr,e,e,e,e3}3}hhhhh3},e,e u,ehhh3}3}ZszVGBzVGBzVGBMJzVGB##h#3}ZszVGBzVGBMJzVGBzVGBZszVGB3}Zs3}hhhhh qYhhe}LzVGBe}LhzVGBhhhhhhhhzVGB ҽ ҽ ҽ ҽh ҽ ҽhʁ) ҽ ҽ ҽzVGB ҽhqx $Ba0fi| $_0" N^0]0$BOH*+{:W 0uXsm[zS_91-Z9:9:$-K9:9:$G63}mZe3} uZs3}3}- =1- =1Zsʁ)ʁ)ʁ)Zs- =1- =1ZsZsʁ)ʁ)ʁ)3}3}Zs- =1- =1E $̌?b-] UntitledE-] AnonymousQ "R " ny$@FY ZwZ $fff?[ $?\ "] $?^ a $?f ]Nonek Vwvz~w$?y $n)$?z g0B AC AD UAM!]xGame.xDeathMatchO!$m]g$@FIyHy$?}a$?~a$?[*wb$(B~$Bg.$?^w$̬?$cc+Xssi2sQ]n_4-Z-m9:9:$-m9:9:$ w#w.#*-O9:9:$9:9:$9:9:$9:9:$ -O9:9:$ -O9:9:$-O-W-X9:9:$-W9:9:$9:9:$9:9:$9:9:$9:9:$9:9:$9:9:$9:9:$9:9:$G 6H\ u,e3}U,)7u*FL#{7u*FL#{- =1- =1zVGB- =1- =1zVGB- =1zVGBzVGBWL- =1zVGB uzVGBzVGBO_zVGBO_WLO_SzהSzהSzהSzהzVGBSzהSzהO_zVGBO_zVGBO_O_O_zVGBSzהSzהO_zVGB3}ZsSzהSzהSzהSzהO_O_3}ZsSzה3}3}3}WL3}3}SzהSzהSzהO_O_SzהzVGBzVGBMJSzהy/^O_O_y/^SzהzVGBzVGBMJSzהy/^O_SzהzVGBzVGBzVGBzVGBMJSzהO_O_y/^3}Zs3}Zs@u)@u)DY!UA_UA_7u*F7u*FL#{UA_3}Zs3}ZsY±3}ZsY±3}Zs3}ZsY±3}ZsY±UA_UA_3}3}3}Zs3}ZsY±3}Zs3}ZsY±3}ZsY±zVGBP=t,ct,cP=P=7u*FL#{7u*FL#{7u*FL#{7u*FL#{7u*FL#{7u*FL#{7u*F7u*Fn h:7u*FL#{7u*F7u*Fn h:zVGB@u)hhhʁ)ʁ)ʁ)h3}3}Zs3}Zs@u)ʁ)ʁ)ʁ)hhhhhh qYh qYh qYhhhʁ)ʁ)hʁ)hhhhhhh qYh qYh qYhhhʁ)ʁ)hʁ)3}Zs3}ZshhhzVGBhzVGB3}3}3}3}ZszVGB3}ZszVGBh3}ZszVGB3}Zs3}ZszVGB3}Zs3}Zs3}Zs3}Zs3}Zs3}Zs3}Zs3}Zs3}Zs3}Zs3}Zs3}ZshhzVGBzVGBMJzVGBzVGBzVGBzVGBzVGB3}Zs- =1- =1zVGBʁ)ʁ)zVGBzVGBzVGB3},e,ezVGB,ezVGB3}Zs,ezVGBzVGB3}hhhhhhhe}Le}Le}Le}Lh3}:H:H:H:H:Hhhhhhhh3}zVGB3}h3}:H:H:H:H:H:Hhhhhhhhhhhhhhhh3}h:H:H:H:H:H:Hhhhhhhhhhh(bQ hhhhhhhhhh(bQ h(bQ hhhhhhhhhhhhhhhhh(bQ hhhhhhhhhhhhhhhhhhhhhhhh(bQ hhhhhhhhhzVGB3}3}zVGBzVGB7u*F3}3}e}Le}Le}Le}Le}Le}Le}Le}Le}Le}Lhhhhr*ъhr*ъhhhhh(bQ hhhhhhhhhhP=3}hhhhhhhhhhhhhhhh(bQ hP=P=P=P=P=P=P=hhhhhhhh3}ʁ)hhʁ)i L\hʁ)hi L\ʁ)ZȵZȵʁ)ʁ)3}3}hhhhhhhʁ)ʁ)ʁ)ʁ)3}h3}3}3}3}hhʁ)ʁ)ʁ)ʁ)h3}h3}hZȵʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)3}3}3}hhP=hhhhhh qYh qY3}3}ZszVGBzVGBe}L3}3}ZszVGBzVGBe}Lhhhhhh(bQ h(bQ hhhhh3} ҽ3}3}3}zVGB3}Zs3}ZszVGBzVGBzVGBMJMJhzVGBzVGBMJ3}Zs3}3}zVGB3}zVGB3}3}hh3}he}Lhe}Le}Lhʁ)hhʁ)3}h3}3}Zs3}h3}hhzF3}hhh@qhzFhzF@q@qzF@qhh@q@qzF@qhhhh qYhh qYhh qYh@q@qhh qYh qYh qYhh qY@qhh3}h3}hhhhhhzF3}@u)@u)@u)@u)@u)@u)3}3}3}3}3}Zs3}h3}3}3}zVGBzVGBmp^3}hhhmZe:H:H:H:H:H:H:Hh:H:H:H:H:H:H:H:H:H:H3}:H:H:H:H:H:H:H:H:H:H:H:H:H:H:H:Hh:H:H:H:H:H:H:H:H:H:H:H:H:H:H3}h:Hh:H:Hhh:Hh:H:H:H:H:H:H:H:Hh:H:H:H7u*F- =13}7u*F3}3}3}3}:H:H:H:H:H:H:H:Hh:H:H:H:H:H:H:H:H:H:H:H:H:H:H:H:Hhh:H:H:H:H:H:H:H:H:H:H:H:H:Hh:Hh:Hh:H:Hʁ):Hh:Hʁ):HzVGBzVGB3}zVGBzVGB3}3}3}7u*F7u*F3}hh:H:H:H:H:H:Hʁ)ʁ):H:H:H:Hʁ)ʁ):Hʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)hhʁ)ʁ)ʁ)hʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)hhhhhhhhh3}3}3}3}hhhhh3}3}3}7u*Fhhhhhhhhʁ)hh3}hhh3}zVGB7u*FzVGBmp^ʁ)e}Lhhh qYhh qYԋ u u3}3}Zs- =13}Zs3}Zs3}Zs3}ZszVGB3},e,e u u u ҽ,e3}Zs3}zVGB3}3}3}3}hP=P=P=3}3}Zs*jW3}zVGB@u)@u)7u*F7u*Fn h:7u*F7u*Fn h:UA_e}Le}Lhhhhhh@u)|:H:H:H:HT⁀WLʁ)3}3}3}3}3}3}3}||3}3}3}3}3}3}3}e_ .3}3}3}3}e_ .e_ .e_ .3}@u)7u*FzVGB- =1zVGBMJzVGBMJzVGB7u*Fn h:zVGB- =13}SzהO_y/^3}VF݋VF7u*F7u*Fn h:VF3}h(bQ (bQ @u)@u)3}3}3}- =1hi L\hhhhzVGBhhe}LzVGBe}LhzVGBhhhh:H:H:HzVGBe}L3}zVGBʁ)##3}3}Zs3}ZsY±3}ZsY±3}7u*F3}@u)@u)@u)@u)@u)3}Zs3}Zshhhh,ehi L\3},e u,e3}Zs3}Zsʁ)ʁ)7u*F7u*F7u*F-\ h3}ʁ)ʁ)hʁ)ʁ)ʁ)3}Zsʁ)ʁ)ʁ)ʁ)3}ʁ)ʁ)ʁ)ʁ)3}3}ʁ)mZemZe3}3}3}3}3}3}3}3}3}3}ZshzVGBzVGBh qYh qYqp.o.YxvaHcfcGhG.F.D.C.B.uhZ{@|$?Cgn.z_ax$?l.$>J{$/Dk.$@Gj.$ABwZ!$@@$ Bsi.$Bh.$Bs :0???c$?f.$Ae.] Quick Savingd.]Game is not pauseablec.]Now viewing fromb.]Now viewing from own cameraa.VMmUy`."ȯ^.i X.PCw]Engine.PlayerChatManagerU.$ET.$D^ *^ PPR.*`b$Dyb$Cyf]"!GUI2K4.UT2K4DisconnectOptionPageli]GUI2K4.RemoteAdmin_x]GUI2K4.UT2K4ChatPasswordAt= CODEC_48NBpx= CODEC_96WBR$h0$?g0y { v$@@P sH N{{(A -Z9:9:$-Z9:9:$-m r^*-Z9:9:$-m-O-Z9:9:$-KG2GzVGBH ,]΋ZsZsO_ u,e u ҽMJMJ ҽ ҽ ҽ,ehhhKKKK,e,e,ee}L3}e}Le}L3}3}e}Le}L3}3}KKKKKmZemZemZemZe3}3}3}3}3}3}- =1- =1Szה3}hh uʁ) uʁ)Szה3}3}- =1- =13}Zs- =1W`]Deadv= Spectatingw] UnknownUh[$?IssTo s`aJ|)2 ҽ@EډډډډډډQ*_Z*$?]*$?k$?Qn*b*ZQ p$?t$?A$?k$?sh*i*]UT2003Fonts.FontMonoj*]UT2003Fonts.FontMonol*]UT2003Fonts.FontMono800x600sj\& (9:9:$9:9:$9:9:$G7w qY@q##v'cZD##wO#@qKiKiKiKiKiKiKiKiKiKi3}3}- =1KiKi3}3}- =1KiKi3}- =1KiKiKiKiKi3}3}KiKiKiKiKihhhKiKi3}KiKiKiKiKiKiKiKihKiKiKiKiKiKiKi3}KiKiKiKiKihKiKiKiKiKiKiKiKi3}KiKiKi3}Kih'\"hhhh qYKi3}KiKi3}KiKiKih,eh,eh,ehhh qYKiKiKi3}KiKi3}KihKi3}- =1KiKihhKiKiKiKiKi qY qYh u uh u uKiKiKiKi3}hhhhhhh qYhhhh qYhh uhh qYhh qYh qYhh qYKihKiKiKiKiKi'\"wO#wO#wO#'\"'\"KiKihKiKiwO#wO#wO#wO#'\"'\"'\"h qY qYKi qYh qYh3}hhhKi##hwO#KiKiKi3}3}3}KiKiKi qY qY qY qY qY qY qY qY qY qY qY qY qY@q qY qY qY qY qY qY qY qY qY qY qY qY qY@q@qhh@qY},Y},ʁ)3}Y},Y},Y},Y},ʁ)3}Y},Y},h uhhhhhhhhhhh,ehh,eKi uhhhh ҽKi'\"KiKiKiKiKiKiKiKiKiKiKi3}3}3}hhʁ)KiKih,eKiKiZȵʁ)h,eʁ)ʁ)ʁ)ʁ)ʁ)hh,ehKihh,eKih,e,e,e,eKih,eh,ehh,e@q ҽh ҽhzVGB ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽhhhhh ҽ ҽ ҽ ҽKi ҽ ҽKiKiKiKiZȵKiKiKiKih'\"'\"'\"'\"'\"'\"KiKiKi'\"Ki'\"Ki3}- =13}'\"3}3}3}'\"'\"'\"'\"'\"'\"Ki'\"'\"'\"'\"'\"'\"'\"'\"'\"'\"'\"'\"'\"'\"'\"'\"'\"T(}0S(lR(G1Q(H1P(I1O(K1N($?M($?L($?K($?J($r?I($r?Px$>Yv$>H($?G($?F(]wLj$?@j$ Hj"E(] has no ammoD($BBa*vb$ tb"Wc*rc$?zc]! Crosshairs.Hud.Crosshair_Cross1Mx$?b)F Y7[$@v$@@jl C$?yIss#sU ssN  ss#s+!Poct0$-m-Z9:9:$G3#@qʁ)@q@q@q@q@q@qh##@q#@qhhʁ)@qhhhh ҽʁ)ʁ)ʁ)ʁ)M xʁ)3}hʁ)hʁ)hE)$u?F M 7Og*H*u S`+v$33?P `$s0vA'y(2:H0׿e] u u u u u u3}hhhhhʁ)hʁ)ʁ) u u uh uh uhʁ) uhʁ) us0^XM6fZs0׿e]3}3} u u u3},e u u uzVGB uzVGB u,ee}L3},e,e u u u ҽ,e*jW*jW*jW*jW*jW[в[в[в[в[в[в[в[в[в[в[в[в[в- =1[вSzה[вrr[вZsZsaf> [в*jW,e,e,ezVGB,ezVGB3},e,e,ezVGB,ezVGB3},ezVGB,eIo>+,effIo>+zVGBIo>+v q}oBv q}oB,e3},e,ezVGB,eIo>+|j6,e,ezVGB,ezVGBMJ3}&ɢ&ɢ,effIo>+3},e,e,e,errrV!#Io>+af> EcHEcH3}3} u,ezVGB3},e u u,e,ehhhh@qIo>+hh@q3}#h(bQ hhh@qffIo>+,eY±Y±Y±,e,e,eIo>+Io>+,e,ezVGB,ezVGB,ezVGB3},e,e,e,e,ezVGB,ezVGB,e,e,e,e3}e}L,ee}Le}Le}Lf3},e,e,ehhhhhhhhhhhh*jW*jWhh qY qY*jWhh qY qY*jW,e3},e u uWL,ezVGB,e uY±Y± uzVGB3}3},eaf> f,e uf uf uzVGB u u u uh uhaf>  uY± u u7u*F uzVGB uzVGB u u3}3},e,ezVGB,ezVGBMJ,e,e,e*jW,e,e,e&ɢ&ɢ,e,e&ɢ&ɢ,e,e,e u u,eh,eh,eh3},e,eh,e,e,e,eh,eh,e,eh,e&ɢ,e3},ehe}Le}L,ee}Le}L,ehe}L,ehe}Le}L3}fʁ)3},e,e,e u,e3},e,e,e3},e,e- =1ʁ)ʁ)*jW u u uhh,e uzVGBY±a=0a=0&ɢ&ɢa=0 u u u u u u3} uzVGB uzVGB u u uzVGB uzVGB uzVGB uzVGB uzVGB uY±Y± u3}3}3}3}3}3} u- =1 u u u u- =1 u u u uzVGBY±*jW u u u3}3}3} u u u u3}3}3}3}3}Io>+*jW*jW*jW*jW*jW*jW*jW*jW*jW*jW444ʋY±3}3}Y±Io>+Y±Zs3}af> 3}ʁ)ʁ)ʁ)ʁ)3}ʁ)ʁ)ʁ)mZe3}3}Zs3}3} u uzVGB3}3} u3}3}3},e,ezVGB,ezVGBzVGBzVGBzVGBzVGBMJ,e*jW*jW*jW*jW3}- =1- =13}Y±af> *jW*jW*jWIo>+Io>+Io>+*jW*jW*jW*jW- =1- =1- =1- =1- =1 uzVGBY±Y±Y±Y±Y±3}- =1- =1- =1zVGB- =1zVGB- =1zVGB- =1- =1r3}&ɢ&ɢ&ɢ3}3}ffEcHEcH3}- =1zVGB3}z{}BCEEaeclcOO"I$?K${n?g$?V= Engine.HUDzq] No Gorezq Reduced Gorezq  Full GoreZ"w"BN"_]Playera$33s?eVfahMEngine.Mutatorj]Engine.AccessControll]Engine.BroadcastHandlern]Engine.PlayerControlleroYhUSmkUh`]Gamey]???}y]xVoting.xVotingHandlerz] Bot Skillz Weapons StayzReduce Gore Levelz Game SpeedzMax Spectatorsz  Max Playersz Goal Scorez  Max Livesz Time Limitz World Stats Loggingz Allow Weapon Throwingz Allow Behind Viewz Allow Admin Pausingz Kick Idlers TimezWeapons shake viewNd]&%Set the skill of your bot opponents.Nd<;When enabled, weapons will always be available for pickup.NdECEnable this option to reduce the amount of blood and guts you see.Nd,+Controls how fast time passes in the game.Nd@?Sets the maximum number of spectators that can watch the game.Nd?>Sets the maximum number of players that can join this server.Nd0/The game ends when someone reaches this score.Nd87Limits how many times players can respawn after dying.Nd0/The game ends after this many minutes of play.NdO MEnable this option to send game statistics to the UT2004 global stats serverNd; :When enabled, players can throw their current weapon out.Nd= ~0:0aD|0"Qx$@u$u=z0$EYi$?ni$?sst#`sT(ssSss3"sOL2g9:9:$G@i%Afʁ)3}hʁ)h,eʁ)ʁ)ʁ)3}ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)hʁ)h,ehʁ)hh,eh,e%Afhh,eh,ehhh,ehhhhʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)hhhhh,eh,e%Af%Afʁ)hʁ)3}%Af3}%Af3}%Af%Af%Af%Af%Af%Af%Af%Af3}3}%Af%Af&ɢʁ)&ɢ%Af%Af%Af3},e,e,e,e,e3}3}%Af%Af3}3}&ɢJ,N,V,Y,$?Z,$@],J-V-"*>c`V+[$?v$,@e e PyF $?:$ C=$ CF|bCsH`S&ɢʁ)ʁ)ʁ)ʁ)ʁ)3}&ɢ&ɢ&ɢ&ɢ&ɢ&ɢ&ɢUnwwgUnwwgy.l|dt$$tIdt$tICO>yKpy:$ B=$,Bsgdd~(,l$-m-Z9:9:$G3'\"@q3}- =13}##v'cZD#@q ҽ ҽ3}3}3}h qYi(" T  g($?| $?[$?sK\BH88-Z9:9:$G@` 2>(bQ KmZeʁ)ʁ)hh,ehhhhhʁ)ʁ)3}ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)3}ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)h0׿e]ʁ)0׿e]ʁ)ʁ)0׿e]h3}h3}3}hhhhhh3}3}j0:0mk0$Al0$@Es0$>T@1$?c`[$=ssP]*+dw]*{\* G0JTJ25*jW0׿e]*jW*jW*jW*jW*jW*jW*jW*jW*jW*jW*jWʁ)ʁ)ʁ)ʁ)ʁ)##z {##ʁ)ʁ)ʁ)ʁ)#ʁ)#ʁ)ʁ)ʁ)ʁ)*jW*jW*jW*jW*jW*jW*jW*jW3}Zs3}Zs3}Zs*jW*jW*jW*jW3}i]MutatorArt.nosymssEossos DVG^*-\ D'Bkw s[A1.VD@EI$Dssu5!&'Wv\,30׿e]ʁ)[вqy]Rules[{]GameQ{]ServerOy]Chatsy]Botsoy= Map Votingox] Kick VotingOv `+[$ AssW@svXqb2 vCk;*j;*j;*jssBr"s\Ap2,4ʃ@EWCSMDm`UDm`UDm`UWCSM3}ZsWCSM3}Zs3},e uWCSM,e4zVGBzVGBzVGBWCSMWCSMZs3},e uWCSM,eWCSMZsZs3},eZs,e|] DefaultN] AUTO-ASSIGNN DEFENSEN OFFENSENROAMN SUPPORTY Y Y `$?l]Nameb]Roc~~~~~h]Engine.LadderInfoss2sr #0YbE+7u*F@EqLR"%MR" Nssns sw,vVrFB:MKhvCke֧Oe֧Osv\Qe;*jvCk:MKh:MKh:MKh:MKh:MKh:MKhe֧O:MKh:MKhe֧O:MKh:MKhe֧OsskssIR%u Gsts7sY  sZ[,>@w@u)ʁ)lW˅lW˅h u u p p ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽVF u3}VF݋VF3} ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ uzVGB u u7u*F u uh u u uhh uDY! ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ u3} u u u ҽ ҽ ҽ ҽ ҽ ҽ ҽ u u ҽ u ҽ ҽ u ҽ ҽ u3} ҽ ҽ ҽ ҽ ҽ uh,e,eUnwwg&ɢ uʁ),e,eh,e ҽ,e,e,e,e,e,e,e,eh,e ҽ,e,e,e,eʁ) ҽ,eʁ),e ҽ uʁ),e ҽ,e,eʁ),e uʁ) uh ҽ uh ҽh qYlW˅ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ u u u3} uhhh ҽ ҽ ҽ uʁ) u u uh ҽ ҽ ҽ u ҽ ҽDY! ҽ ҽ ҽDY!DY! ҽ u uhlW˅ u3}ʁ) u un h:n h:n h: ҽ ҽ u\5? uDY!DY!ʁ) u u u- =1 uhhzVGB ҽ uhzVGBMJ ҽ u ҽhzVGB ҽډ ҽhzVGB ҽډډ ҽډډډډqN&*M&*L&*K&*J&*I&*H&*G&*D&*Ry*C&B&A&@&%~%y_^y}%*ؙT`]UT2003Fonts.FontEurostile12z%$?y%*x%$?x_$Cw%$33s?v%$?u%$?|_*Z@"{_"s%$?P`]Engine.DefaultFontP`Engine.DefaultFontP`Engine.DefaultFontP`Engine.DefaultFontP`Engine.DefaultFontP`Engine.DefaultFontP`Engine.DefaultFontP`Engine.DefaultFontP`Engine.DefaultFontO+ss6#0s\sssv{(]2Dm`U@Es@oEfT@EsefHV]B Y7=F>e}Lh uhhhhh u u uhhhhhh u u u@u) u@u) u@u) u@u) u@u) u@u)hhhhhhhh,eh,e u u u@u) u@u) u@u) u u uhhh,ehh,eqc+T&c_ V jSDbssossu, @s0`K~|2Io>+0׿e]Io>+Io>+Io>+Io>+Io>+Io>+Io>+Io>+Io>+Io>+Io>+Io>+Io>+ssNssmsses*s~@g}s]!sd @]NTsS ss[ sh6 ssOJss] ses0uH2VF0׿e] u u@u) u u u@u) u u7u*F u7u*FBk u7u*Fʁ)wH#K#"n*R#T#$?U#$zT?ssX>ssxsY0}I]6xY±0׿e]3}[в[в[в[в uzVGB3}Zs3}3}Zs:MKh3}Zs3}Zs u u uzVGB u uzVGB u3}Zs- =1 u u uh u u u uzVGB u uzVGB u3}Zs- =1 u uzVGB u uzVGB u3}Zs- =1 u uh u u u u uh u uzVGB u uzVGB u3},e,e,ezVGB,ezVGB,e,eh,e2 ;*j2 :MKhe֧O:MKh uzVGB uzVGB3}Zs uzVGB uzVGB3}Zs uzVGB uzVGB uzVGB uzVGB:MKhe֧O3}3}2 2 :MKhe֧O2 :MKhH"Y  ACCEPT;*I"]10Your IP address has been banned on this server.J"]('The password you entered is incorrect.K"]10You need to enter a password to join this game.L"]@?Your IP address has been banned from the current game session.M"]/.You have been forcibly removed from the game._|MNone specified}]Kicked for idling.N"j)Be]Game PasswordBeAccess PoliciesBeAdmin PasswordBe  Login Delayud]NLIf this password is set, players will have to enter it to join this server.udCASpecifies IP addresses or address ranges which have been banned.udKIPassword required to login with administrator privileges on this server.udcaNumber of seconds user must wait after an unsuccessful login attempt before able to login again.ssS sLPD+[в@E0׿e]0׿e]ss}ssossgTZ- GsussU  sMsps s|ssMsfvWzN8e֧OvCk2 2 ;*j2 2 ;*j2 2 ;*j:MKh:MKh:MKh2 2 2 2 ;*j2 ;*j2 2 ;*j:MKh2 2 2 ;*j2 2 ;*j2 2 2 ;*j:MKh2 2 2 ;*j:MKh;*j:MKh2 ;*j:MKh2 2 2 ;*j:MKh;*j:MKh;*j;*jszIZeh3fzF@qfffffffhhh p p psnebC B"g _,eʁ)3}&ɢ&ɢk ͝%Af&ɢ%Af&ɢ3}hhh ҽh ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽ ҽpahh qY qY3}3}ZsqB*y { | $ss]sssIs{!A# GsQ7 ss^3^]UTPNI0]n)f2mZe0׿e]3}RO>RO>3}RO>3}Y$@de*f$;Eg$Eh$?j$?k$?lz$?C>Uosshs@s_ s`zsAssW@ss^sshs svm%sl@sr sIn@y-D)n@ GswAslsm>sIsL sDI6e%$-m-Z9:9:$G3zF@qhhhhhhhzFʁ)###@q#@q##@q@qhhhssH3s sJssi!tspiTsOssg'ss]ssts%s@sUsk ssi&r.n5 4)r.)q.)p.)o.)n.)i.)h.)c.)S)P GsHTssstsJssrs4`o|Fi2K`8Kʁ)ʁ) ҽ ҽX] unspecifiedv Fss~ssv8s`ssH ssPYssdssgssw sq\Ui+3TVqh]N/Asszn!1.sTssp>s*sjsM haFV)ET-Z-m-O-N9:9:$-Z9:9:$G Y},M x3}3}h(bQ h(bQ hhN0$?`z*R&$zEB+t [$AsGczDI)Z]|Gn6r*ъr*ъh,ehwA/~DossAssqssH !s^A# GsNsse@ssX4:[ GsM ss}s skssl@s0_]'6Xf0׿e]3}Zs3}Zs- =13}3}3}3}3}3}3}zVGBzVGBzVGB,ezVGBzVGBzVGB,ezVGBzVGBzVGBzVGB,ezVGB,ezVGB,ezVGBzVGB uzVGBzVGBzVGBzVGBzVGB,ezVGBzVGBzVGB,ezVGBzVGBzVGB,ezVGB- =1- =1zVGBzVGBzVGBzVGBzVGBzVGBzVGBzVGBzVGB,e- =1- =1- =13}Zs3}3}3}Zs3}Zs3}Zs*jW*jWIo>+Io>+3}3}3}3}3}3}3}kwkwkwdD]Stats_%P_%Y_%M_%D_%H_%I_%SssFf&j5sDssxssW ssX@ss s(sCssSssD$@sS3sS sszq#(o%sPs~mBt+@ t ?~\[YI~Qec  " "" "s~DV u1σ@Eu1σu1σu1σu1σu1σu1σu1σH]No Date/Time specified.W] No Data.ssF}Hsh,snisz ss$ssKssSs s^s|@wc' 9:9:$G@ }Bʁ)3}3}3}3}3}3}3}3}3}m l "j "2\$@\@]$?]?g c :0L=^$ B^ B` $>_$ A_ A`*`T P $L>O $?H "G "@ $?|\/7 d Se+`x&Y`F\:$=$VeossvEsss[s^2ssp!yY3@> GsH,ssF3ssNs sQs s@s}sp&s7sssa ssHslss2s\sH _oH =1-Z9:9:$-K9:9:$G2"MJH ,],ezVGB,ezVGB3},e,ezVGB,ezVGB3},e,e,ezVGB,ezVGB,ezVGB,ezVGB,e,ezVGB,ezVGB3}Zs3}ZsSzה,e}]Team@*A*V]RedVBlueVGreenVGold[$@ssgssrsPXb P=@EhP=P=P=P= u uq^_n$>x$@@S $#b ssE szmc,@!RS'|;ssssqssSU M4ssHYI/w@ W7zHHHL Gd"ss52B>s| ssvstt,[Kʁ)CO+`Py:$ A=$ Ass`@ssz=ssss@{  1 )   )) 1  9 ) 1 ) )1 9 J9 ))1))))Z9)1)1) 9)A)9))1 11J)91J)11)9111191)J119)J199s b)99)J9Z1999J9A9)Z1J9 A99b19A1JAs1AAAJA)ZAJAAbAZA1JJZA)bAJJ1bA)sAJJAbJ1JJJsARJAJRAAbRsJRRRbR)ZRA1AsRbRAsR jR9RZZJAZZZRRsZ)R)bb9sb RbbRbbbbsb9jbRAZb)bsj9b9jjZZjjjjZsjjjAj1jsssZZssjj1s1ssssJ{sjsZsJsjssZj {{js1ssJ{{{sAZjs1s1jZss)9A{RŃs̓Js)sRŔ sՔRŔRŜZJs՜Jͬ)ZAެ)ͬb Zʹ޴j)9Žsb9JŬjŔ)ՃsՋսJwEn,`W=@Eqb`VzOD|Rw$ff&?K:0???JZy?tZ!$?$?sAZ!$?$?skZ!$?$?ssH"FZy?tZ!$?$?sAZ!$?$?skZ!$?$?ssHO$?ZQ p$?t$?A$?k$?syZQ p$?t$?A$?k$?su" j"hZ!$?$?sfZy?tZ!$?$?sAZ!$?$?skZ!$?$?ssdZy?tZ!$?$?sAZ!$?$?skZ!$?$?ss]:0?P:0???{Zy?tZ!$B$BsAZ!$B$BskZ!$B$Bss@g:0???vv$KJ:0???IZ!$$?sC`A$?~Z!$@$@sz"wZy?tZ!$?$?sAZ!$?$?skZ!$?$?sssss%sWhssm2sFssx @ssG&ss]BssRnzK@0iHRS'|;|;|;|;|;|;|;|;|;|;|;|;|;|;$AAGd"ss} ss@ssssLl"svsj @pXss[jCPM  pa[Khhhhhhg _g _HPQ$?ssW s(^]H^@` 2*r*ъ(bQ ʁ)ʁ)ʁ)hhhh3},e,e,e,eZ]|,e,e,ehhhh,ehhhhhhhhh,eh,eZ]|Z]|Z]|Z]|Z]|Z]|Z]|M1:0?O1+ssy&ssy ssmssJssto[ s`TnY-J/a2 %H Ho 10n9=9:n%,&9:n9:9:59:c ?c J\9:5vBa<V9:5wJ Bc -TM? ף;o$-C'55nN?M? ף;F}>J>6B~>6B@?6B6@Bc 6@B #<N6@C9<9<5f"9?& Gsv" s`s~ s%sb sUsd ss\Jssss2sepsF_)A؂uʁ)O+:$ B=$ BFss{ssb sPsZRjcU-r9:9:$%Wta9:W9:$ b$b$b$L? Gs]s:}`Fvʁ)e_ +F\:$=$s&eH)Gn6&ɢsUlJ@0H|;|;|;|;|;HGd"ss]ssZsIs s_ssBs%sx @@FP}sJfqx+0PX @Ess~ssC ssLsDsV ssY G s}ssH@ssQl@,s#ss~Y@ssYssT7ssLs&sAssssfssVusO ss@ssEs sl&@smsnss,Ds{hss_sswDss@& sxsCs&sO ssRssD3s sEsssscsWs@sis@sMsass]n@(`nszgssmp}G^nJ7s&9:9:$-K9:9:$G@ @B|j6Gn6UnwwgUnwwgh,eh,eʁ)hhhhʁ)hʁ)hh3}Zsh|j6ʁ)ʁ)|j6ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)3},e,e,e,eh3}hhh3}hh,ehhʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)UnwwgUnwwgUnwwgUnwwgw/q E/+IEyFoss`ZsRrP&f,@!~RS'Gd"@ssf@ssa%}ssRsxssmssIs0y_u7EcH0׿e]DڋL܋L3}Zs3}ZsV!#؋L܋L܋L܋L܋Dssissrss[ \Y-]  GsK@susH ss~ss@ssRs QS3N? pC]%o was crushed by %k.E]%o was crushed.W]%o was crushed.TSB Su$?ssS;LYh9 GsjssfNssss@I sssIsse'@sbZH/WCSM@E44Dm`U44Dm`UDm`U444Dm`UDm`UDm`UDm`UDm`UDm`UDm`U44444Dm`U4Dm`U4Dm`U4Dm`U4Dm`U4Dm`U444444444444r)H_"____ssk2s_ZWZ@&M G~@| "HZȵʁ)ʁ)ʁ)hʁ)ʁ)e}Le}L3}T צ93} uT צ9h uT צ9ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)hʁ)ʁ)ʁ)ʁ)ʁ)e}Le}Lʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)hʁ)ʁ)ʁ)ʁ)ʁ)e}Le}L uhh,eh,ehh,eh,eh3}3} u uʁ)D%$DA%$Bx$\CT  7d Set _ V+v$ @] $`AG8F\saL y:$=$Fj~ ssp~ssTs sxss@$+29@GNU\cjqx     $ + 2 9 @ G N U \ c j q x               $+29@GNU\cjqx\%%j.%7%+%c%G%.@%c77x777j7+777777j%U%N%79%%%%2.cj.q......x.$%777$7N7@7G7\7277$%.+x2G9@\%UNq.%%77%U797Ls~1}.|.{.x.w.s.r.[.Y.S.t-s-r-q-j-f-`-sg&sssR@ssnssqss^Q8R 8X $8aTESTMAnCCn8)@C8I9=,$$}-@p DELETED (bDeleteMe == true)8 a(Cn8)@C8I9=,9=,9=,9:9:$ROLE  I$pNone i$pDumbProxy $pSimulatedProxy $pAutonomousProxy $pAuthority p REMOTE ROLE t $pNone 5$pDumbProxy Z$pSimulatedProxy $pAutonomousProxy $pAuthority -lp Tear Off8 a(Cn8)@CPhysics ! -$pNone K$pWalking i$pFalling $pSwimming $pFlying $pRotating $pProjectile $pInterpolating +$pMovingBrush H$ pSpider f$ pTrailer $ pLadder $ pKarma pppp in physicsvolume .9Vm on base .9V3-M$p - will bounce8 a(Cn8)@C80apppLocation: 9X  Rotation 9Y(Cn8)@C8bapppppVelocity: 9X Speed 9U Speed2D 9U6#?(Cn8)@C8apAcceleration: 9X+(Cn8)@C68B$84apppCollision Radius 9UA Height 9U6Cn8)@C8WapppppCollides with Actors 9T-r , world 9T-Y, proj. target 9T-lCn8)@C8apBlocks Actors 9T-|Cn8)@CTouching /a3 l pp.9Vl 10;zTouching Touching nothing8 a(Cn8)@C68B$Rendered: @ $O $pNormalO $pMaskedO  $pTranslucentO 0 $pModulatedO L $pAlphaO r r $p None $p Sprite  $p Mesh  $p Brush  $p RopeSprite   $p VerticalSprite  8 $p Terraform  _ $p SpriteAnimOnce  $p StaticMesh   9:r9:$p.9V|0 7y%p skins: k %0 k 7y rk y*0 & pp.9Vk y, k  8 a(Cn8)@C~%kjipppppAnimSequence 9Wk Frame 9Uj Rate 9Ui -[$p Anim by OwnerH $ 9:r9:$9:r9:$p9VJH H 9:r9:$p9Vq$8 a(Cn8)@C68B9=,8<apppppTag: 9Ww Event: 9WQ STATE: 9Wa(Cn8)@C89apppInstigator .9V  Owner .9V$Cn8)@C8\apppppppTimer: 9Uo LifeSpan 9UE  AmbientSound 9VU volume 9RXCn8)@C GsU&ss*s\AssyAssd@ssssssss[s sj+@DsGsK@ss sLsxsdvCk@Ese\M 30wO##ʁ)ʁ) qY qY3}3}Zs3}Zsh,ehh,e qY qY qY qYԋ# qY qYh,eh qYhh qYh qYhg _h qYԋ qY@u)@u)3}@u)@u)3}Zs qY|x $?z&y&i $As ]You got a weaponR&$ EVcej:$B=$A{:Wssvssssa#Tsrssc ss@ss_tB/|?atV*U*9?tF9?tY GsssX aAWB$*   " " " " Gd"sp@ @Ѓ@ss%ssIs0sGG 2*DY!0׿e]- =1- =1- =1- =1- =1- =1- =1- =1zVGBzVGBzVGBzVGBzVGBzVGBzVGBzVGBzVGBzVGBzVGBzVGBzVGB u- =1 u@u)@u)@u)@u) ҽ@u) ҽ@u)@u)R@sjSt)E77Ã@Ec$?ssVss@ss~s`sMEssCss ssKssbssssss_@sssmjp(2RO>mZe+ssmEssJs{Qq(Unwwg@Essssrsp ssMssc#YswKsNs*p1sRssLssKssK,sssfV]s~2 a=0VFzVGBzVGBzVGBzVGBMJzVGBzVGBzVGBzVGBl#]Switching Levelsm#] left the game.n#] Could not find team for playero#] Could not find a starting spotp#]Could not spawn playerq#] entered the game.r#] Server is already at capacity.s#]?>Score tied at the end of regulation. Sudden Death Overtime!!!t#]changed name tou#] is now onw#]Name is already in use.x#]started a vote.y#] Vote passed.z#].-Must have stats enabled to join this server.og]43Sorry, you cannot become a spectator at this time.Ri]98Sorry, you cannot become an active player at this time.{g]became a spectator.{#] A new player entered the game.^u]('You are about to be kicked for idling!jz]A spectator entered the game/cy] joined as a spectator.wSssVssbss^ ssQss@Ussfss]s[sssrssts%sss]sst @sZszssFssss\@sr smss] sshCsszs%sssZ%@ssOss|!ssZ ss=YKJ%O\\%J%J7|K6N6N9?J|KT6N6N9?J|KUJ6N6N= GsMgssFsmlZ@9:9:$G@`2%CtW_dmZe3},e,eh,eh,eʁ)hʁ)ʁ)ʁ)ʁ)hʁ)CtW_dʁ)ʁ)hʁ)3},e,e,e,ehhhh,eʁ)ʁ)ʁ)ʁ)CtW_dssvs-skssGssyssC @s]s~T*J/e6iT*6iR*6iQ*G9:s%s9=,6isBi Gsgn!(sjssA$@syoIA)M+ʁ)ssxgs sWssIO*R/R`6@O*6@M*6@J*G9:n%n9=,6@n@ G s|gs sssZssssk@ssvs|ZO @Wʁ)`W=`W=`W=`W=3}`W=7 >+`QFVessZ'ssCssnjs&s]T@ssssLssM s:sssv ssTssVwssossOssr[ssNsIssc ssssFp svss sssrssGsBvwrV(@q$B7KD#B#:0?A#:0?":0?|":0?7OdrFS|SDSDSssssPssvssfssS@I s{ss<sss sCssI,ssL%#(ksX ssa@sskssq!(hss&ssskussj8sgs xR`]@0F)UxxssJsspssQssC*ssJ's-{X`*L#{-\ l Ul @l Aw SZssX"sssssNssjssHFssUPssssspUA*3EUA_@EDY±3}Zs- =1zVGBzVGB3},e,e,ezVGB,ezVGB,ezVGBY±,ezVGBY±Y±,ezVGBzVGBzVGB3}V!#3}ZsV!#3}ZsV!#V!#V!#V!#V!#V!#V!#V!#V!#V!#V!#V!#V!#V!#V!#V!#3}ZsV!#V!#3}ZsV!#3}Zs3}Zs3}Zs3}3}Zs3}Zsbw] Player List:cw]'&Maps that are valid (can be added) todw]$#Available maplists for %gametype%.ew]$#Active maps for maplist %maplist%.fw])(No maps added to the maplist %maplist%.gw]$#Maps successfully added to maplisthw]21No maps were removed from the maplist %maplist%.iw]('Maps successfully removed from maplistjw]+*%Player% has been banned from this serverkw])(%Player% has been banned for this matchlw]%Player% has been kickedmw])(Next map not found; Restarting same mapnw]Changing Map to %NextMap%ow]#"No maps configured for %maplist%.pw]32No matching maps in maplist %maplist% were found.qw]Matching %maplist% mapsrw]32Matching maps which are not members of %maplist%.sw]Unknown Parameter : %Value%tw]No Parameters found!uw]Modification Successfulvw]Could not Modify Parameterww]43Maplist %listname% successfully added for gametypexw]76Maplist %listname% successfully removed from gametypezw]Now editing maplistssQssFEssssBssXssT ssj s:svE*T*&kwf{E* @%{P swP  W&swP  {,wP v{P  ,v{P  wk{f GsgssMssssVVgTJJ$+#R#-H (-F (-x(-v( Gs`ssOssssHss@_vZ Gsl ssLssY1sst  ssxwssz@ si sssHsYsIn!()0nmT6Jr0׿e]rrrrrr3},e,e3}Zs,ezVGB,ezVGB,ezVGB3},e uzVGB,ezVGB uzVGB uzVGB,e,e3},e uzVGB,ezVGB,e,eh,e3}ZszVGBzVGBzVGB3},e uzVGB uzVGB,e3},e,er ur ur uzVGB uzVGB uzVGBr3}[в[вr[вIf]Mute SpectatorsIfPartition Spectatorsdf]IGCheck this option to prevent spectators from chatting during the game.df@?Check this option to separate spectator chat from player chat.ss~ssss\ssB^sC @sxs@ssz ss@ssx@ss}ssssNssD ssyssw, smsxss@!essssQssJUsasA  sKsussK sfsVsssfs|=ssQs2sC ss\ssI ssh ssH?@ssts}n;`T צ9ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)3}s$v$"w$x$y$z$ZI%WrCO+crossRsssse@sr sq_^]\[ZYXWVUTSRQPONMLKJIGFDA~}|{zyxwvutsrqpnmlkjihgfc^ZYXVUTSRQPOMLKJIGFEDCA@~}yxwutsrqponmkjihgfdc_^[XTRQPOLGFECBA~{zywsrqpnmlkiedc][YURQPOMKIHGFEDA}yxwutqponmkjihfedcba`_^\[YXTSRKGFC@~Z`{ytroifa@bxayazaXTONKIHGEDCBA}|{wvtsqnhedba`_^]ZXWQNFEBLJM|hmginp~xLSTW}sr0G @s^U2sSs4sys-sYssL2!DsK#ssv$ @s=sdCssfssp ss@]RTss;sN(sss[sssssH's]2ssq ssy@,sssI@,sS%skssssO sGM@EPv q}oBGn6p/q/q r/BEossssssOskGN|Dv(z {Gn6###g _pSXss]Xg;BC v<9:9:$-m_t]rQ}( u-s r*  Bg; GsZssR%s{ e;DV wP!rQ}( 9-s r*  De; GsQ4ss]ss\ss@snsasshDssshkssF ssD ssLssssyU @O AVsv#ssVko3r4)o3 GsR ssR-@ssz@ssa'ss@ss` @sBQsnsswssK@ss@srssRsK;]Y_\ GsssKssN!ssI_ssyosh!ss]ssssh2sssg ssE!ssssA*s&OtEN?k ͝&ɢhhhh,ehhhhhfI! hhhhh,e3},e,e,e,eh,ehhhh,e,e%Af%Afhhhh%Afhh,eh,ehhhhhhhh,ehhh,ehhh3}Zs%AfE0W U wqEssu!ss^QZ@.> GsC!ssssy(@ssU@ssPAyS]s`ssssQWss@hSMsq ssAssc=IVGu<9w* +a= +a= GsssssslsXw sEssC"ssa@sse ssess@ssfr*sk,sss0yN)3H ,]0׿e]c+ssE@ssSssGssDsOXFT)M xʁ)@qK07_*`+[$ A^'_ ^%sse$sshs&skssl@\sbssEssy@ssW ssz'@SsoEssY'ssMss~ ssX9ssssssss]$ssssNssssI@ssnsss_E)fi L\@E&ɢ&ɢ3}Zs3}Zs3}Zs3}Zs43}ZszVGBzVGBMJ3}ZszVGB3}Zs3}Zs3}3}Zs3}Zs43}3}3}Zs3}Zs43}3}hhhhhhhhhhhhhhhhh3}h@q qY@q3}3}Zsʁ)ʁ)3},e,e,e,e,e,e,eʁ)3},e,e,e,eʁ)3},e,e,e,ezVGB,e,eʁ)3},e,e,ezVGB,e,e,ezVGB,eʁ)hʁ)3}3}3}3}3}3}hhhh,ehhhh(bQ h3}Zs3}Zs3}Zs- =1hhhhh@q qY@qh uhh uh uhhhhhhʁ)ʁ)ʁ)ʁ)ʁ)papahh,eʁ)3}Zs3}3}3}Zsss[ssHE!@JsOssjs-TRmn h:-\ 7u*F u7u*F7u*F u7u*F7u*F u7u*F u7u*F u7u*F u7u*F7u*F7u*F7u*Fu"v$Cx$pB}$@Rsss;sassS@ssY#s@ss@tsnss@  1 )   )) 1  9 ) 1 ) )1 9 J9 ))1))))Z9)1)1) 9)A)9))1 11J)91J)11)9111191)J119)J199s b)99)J9Z1999J9A9)Z1J9 A99b19A1JAs1AAAJA)ZAJAAbAZA1JJZA)bAJJ1bA)sAJJAbJ1JJJsARJAJRAAbRsJRRRbR)ZRA1AsRbRAsR jR9RZZJAZZZRRsZ)R)bb9sb RbbRbbbbsb9jbRAZb)bsj9b9jjZZjjjjZsjjjAj1jsssZZssjj1s1ssssJ{sjsZsJsjssZj {{js1ssJ{{{sAZjs1s1jZss)9A{RŃs̓Js)sRŔ sՔRŔRŜZJs՜Jͬ)ZAެ)ͬb Zʹ޴j)9Žsb9JŬjŔ)ՃsՋսJssABFABb G s@sszcss^D!Js|csZsB ssk)!@@spslsydssz!sssQssssKssOssssJmssJ ssIsssusc ssX s`sc ssssU'ssP sn s}e&sWssssPssssO ssS3M3q%` )M3)L3)J3 GsRssy@ssJ @ssD#@ss\3sscs7shssBssssss@ss}ss@sqxvNg 8SNqED:0HDHDC:0HHssssssss`ssD sCsssssssssssM,so&ssssn&ssjssMsZsh,n sy sZs]'ss ssss\ssnsss*s^ssv&sX sm#ssljssxssM sP8sw#ssssrEs%sGssu ssgsshssussCsspi@x-aE)i@ GsCssFkz3h7`)z3 GsGssBssW ssyxQ|.9V Gss sY ssss@ssissssss ssh ssd sse ssmTiso'ssg sssslssssKZssS?ssMs&sis*s]ssxk,sssi sst @,sD-sssessss`%@ss} sss%sP(ssssssssvssHUs pG3C,q pC]%k pushed %o over the edge.E]%o left a small craterW]%o left a small craterSnxr $@u$?sst4sws|ssSssZ#ssTps}ss`ssssfssssssssOss[ssssssssQsss sRPssss" ssB!s s@sse ssJ!@ssss_X@ss]ssvosms]@ssssrsssssP#ssZKsD sk2ssus{@s0jY+\'2kw0׿e]ssQ@psss^sssAIXBa@2*pA؂uʁ)3}3}hhhh,eh,e3}3}ʁ)hh,eh,eʁ)ʁ)he}Le}Lhhhhhʁ)hZȵhhʁ)hʁ)hhhʁ)P.e \ Pssssqsstssqss`-@ gsssWk@ssRBssssV&fsssssn@@s~ss@sKsE sKsN zsqYoY}GN GsHJsseCXIu ( GsR &su@ gsJBmK!sssXGssGmFmL!sE8ssBssy*ss@zXsVssz5s sosfsssF@ gsssT@ gsMh s} s`sssssfss]& ssA%ss~&ssZCs&scdssxsrsssass ssP s*swissr@sqsP>2sssxIsss;sSs*HhocBm?4ʁ)ʁ)ʁ)ʁ)3}@q3}(bQ wHwHwHʁ)ʁ)ʁ)ʁ)(bQ (bQ (bQ 3}3}7Cd j [$ AsaN ssdsssse@5sMssesTs|ssGssJ"ssw sFaXw|wHFv3}(bQ 3}3}y7V] $AE%y:$A=$@jt!{ ssss`s&sG @ssssl!0sss^(@Lssss~ssJns sW"ssssssbssYssyssLssssxssPssu8sshssHss[ss@ssGss\F ssFssmm!1MsssssU!1Ms@ssT$!1MsQssss@ss\@sr sGis($*011 Q  " " " " Gd"s@@---------------------------------NNN------kkk------------Nb'N------------------k'k------------NNN=NNN------kkk=kkk------Nb'==b'N------k'=='k------NNN=NNN------kkk=kkk------------Nb'N------------------k'k------------NNN------kkk---------------------------------------------------fff------------f'f------------fff=fff------f'=='f------fff=fff------------f'f------------fff------------------------------------------------------------FFF-------------'8-------------------FX'F---------------=X---------FFF=FFF-------'8=X=X'8-------FX'==X'F---------=X---------FFF=FFF-------------'8-------------------FX'F---------------------FFF--------------------------------- sCsk saU2~=sssW @sssssF@isessd"ss[ss]s|s{ssB3#~#}#k#j#g#f#sS=ssssmssos]~.g+q@Essx@ssp8sss`$ @sshs s@sse@HysA@ss}ssdGs0sy@HwsR ssssC @@Dms}@HuF@rL@B7Kʁ)3}3} p pa#7>V +:$?=$?F|DDbssjss@ssussssYssTsgsssA@Hssks&sssssE ssHssu ssusssssrAuPUrC۩Z$?\$L>_$L>a$?e$$tIr"$@EMy$ AgmnMh$HBssssSn(shH sM.@sLsssN.@sGsO.@sBssEsS.@szsssssK@Hqssss;sZ.@ssssush2sgm!00pxtL3mp^0׿e]] $ Asss;sx,5secba`s@sssv P}a5>t,cP=h3}hqG$?y!$DE$?Z"$;Dd#tZG+u]Lineary$G$?A$E$?stG0u] Exponentialy$G$@A$E$@stG+u]Hybridy$?G$@A$?E$@stG+u]Customy$?G$@A$?E$@s[$]Hybridu$$[<{$$@Y%$AO&$=ssj&srskDsCstss~$ssa6ssd ssz ssmDss[U2szsCqpԵ@E@Essy:ss|s]sss\ ssaJZF; GsC ssssss^qB#70^~*u_*a-fC(-a (-BJ(-CJ(-x(-N(Z R*m*f*^C*YC*i* Gs@'ssssssssC6hssslLnLO= Gs@6s sssj!wY`B Gss0oIGcI9:9:$9:9:$G2T⁀0׿e]ʁ)ssssssLssss@ssVssssjsRsssgD sF;ss\8ssssJ%swsmss@ ssmfssk@Dssssms]sP@DssL&mT&OK$wO*OT&U&Hwv*vT&U& GsK&O# 7wO*O#4wv*v# GspKskosssDsssjssl>ssu@ssj@ss]ssnKsb ssvsO%sssgKs]lss|KsJssgsdAssT#ssBssQ%sz@ssYssssDssUslssszsOssWsssss sss\Xp;z%)p;)q;)r;)s;)t;)A<)C< GsZ sssks2sOssssETssf9ss])@ssaP@ssLh@5MVv)@5 GsJssBssesss sr ssgssgssEsscs sK@sr sEssnsshssp sssss;ss sps sdssX%Zsg@ss\pDsUssY?sRPn*@0xxRS'Gd"ssa@,sjss|Vv } GsmAsssssssssssDTvf*$BkD'-\ -\ -\ -\ -\ -\ -\ -\ -\ -\ -\ -\ -\ -\ -\ -\ -\ 7u*F-\ -\ -\ -\ 7u*F-\ 7u*F-\ 7u*F7u*F7u*F7u*F7u*F-\ -\ -\ ssz sa,!w*-sn 5-Z=a $=a $Q-X=B$YB$-_-V=-u-U=\GsQ=R=P=w*osos-u( GSza*D'@Essssss[sIsn @,ssszsskss[3,sss ssssssssswhsssssssVJaN 7Xbt uzVGBzVGBzVGBzVGBzVGBqssI1BJ1shs sssPss\Tmv#Rm5c Fd9:5%9:59:mx9=9:5&cO9:59:Z &9:59:mx9=9:5&cOU*f"9?&-f 9:5&X OF%"9:9:$-Cu  O/a2 %MNMp 10 G sO@ssi>ss@ssssss^|1~q7> h Gsssl@zvsi ssz ,sj ss~ss[ seskssQ1ssM?ssH@ssssLv?sG ssq?ssess?se#sswssjssEssss\ ssxssG@sdTsvS|F-{=&}||R }:|R } Gs}ss{ssp#ssss|ss@ssQssD:@ssssLssjsz sT+bss}ss\uMX1srss] ssxMsq_ GsssN sscuMsss?s@sFssR ss|Sssi ssT ssU sVs$#(sX ssssp@ssKAss}ssGssssUs&sss] ssssOssssk%ssOwssy1ssK@sssscs@s}% sssmsCL Nu`WNL  Fwyc $|=#U 9:c %B L 9<c 9?o:NB o:6s9?N ,6s9?,6s6s9?,6s9?9D9?N ,,+6s9?,6s6s9?,6s9?9D9?N ,,~6s9?,6s6s9?,s9?,-P(N ,@%-f N , %-| N ,%-| --aN , %} $4 &} $4 ,} $4 !,} $4 1,} $4 B B NVCB N-P(9:B&-| -f } s"NB Eb k,b EE9?,s|==-| --a--aC VL N8r*QzJC -}'C  #-}g ?EE9?%C L?NL i "6RE6Rk6R%G-| |=#x"nr*-ma+Rwy w*-m6U 9:u=6U k9:!9:$9:!9:$ ,  %E 6N E 6NzE6U  6N6U  6N6U Ee a=U a+U )rQ* C 9?%CC -z=-x=-| -w=v=se E]# r"g>e@F"g4C9?>h&r*P ]P  ]ePPTe9?,<r*6yP!6jP 6}P"6yP!6}P 6TP3w.%3*w.e3*6jP  3   6jP  6WP `g"6lPL 6OPa GBVry~I3\5?VFb]&%FAILED TO JOIN GAME. NEED PASSWORD.b'&FAILED TO JOIN GAME. WRONG PASSWORD.b)(FAILED TO JOIN GAME. GAME HAS STARTED.bFAILED TO JOIN GAME.F#I#n*V#"ssA&BsV smsm,smfFd`8Kʁ)Z0Z__:0???|$}s[0Z__:0???|$}s@Z__:0???|$}s7*CO>{ bssw=ssJQsssDsB2LsB ssE2s sssKss ssrpss| sssesssT ssssv @s`sgssu@ssZ=sssps{ss]sss(sm<s`sg<ssHssoAlPo!]( Gsqsss;sUpDsss\2sm sstssIssosesGsFss ss}sWsssssLss^ssssB<ssLssNssszsVPssD~ t m"w* t~  Gsa2ssn s sUsXsscXK{ |y'9:9:$K?2K Avw*&"G"K{ G@sH!ss^}ss~os^XssPssusssesT0ss]s|!(sessY;ssM!g=&XFFH@fI! &ɢhhk ͝h%Afk ͝h,ehh,ek ͝hhhhh%Afhh%Af%Afh,e%Af%Af%AfhI0$CW U w@/[ "CS+zEssssssY ssbssa-ssJsshO@ssqsss.sAl4m/9:9:$ ,w*z  GsssV ssK%ssioszssssxss\ ssssssdssU!ssBlYmHx Gss sVBssAs sl7ssWssqbs sVMZM_GHD UkwD *TD a/!nr.D # D D S-e (N_ Gs[ossssssFMssl!ssssAeB\;weB Yw*9Faa   *m*-Xa!s a!Tpq!Oa GsQ@ssc ssG%cs|:FZB=ô Gsh@ssh!@Dg=s\&ssX!@Dg=slNVWY]sDxj^^ DB Gs^ss@ssC%csq!@Dg=sesssslJsp\bM`a@2 dK.pmZemZeʁ)mZemZeʁ)ʁ)hssssIsUsk@sshssssgssissussk ssqssbcss|$ss{$ s=sw$ssissV*ss_ @sss-s@ssFJssfs7sM+s0nnsJ2|IS0׿e]ʁ)Gv$?ssl:ss@sls[ssss!ssjCssD"sssEsnC FsF@ |HsG"sv sfn#(sj@ xHs)@ssLssssOssJ ssm$ssssK"ssPssssssWnssV@ssssQ"ss]ssP"@ssF^sc msssf ms}9ssR"ssUssf$ r%o%l%h%e%d%c%b%a%`%sx\ss@ss^sEsssT"V]x*dGsssU"ssrssVss{mDsssDsqs_$sVsz~@ssF9ss^$ss~ssn!8s{8sssAssY=ssss["ssKssMs sgss{~@ssq8ssc/@sIssJss\"ssZ$Ds_ss`"ssssVspsW$@ssUssEFssVDspsXssVssWssS-ssNss_ssssA sss ssw s|se"ssli@ssw) ss@ssssb ss@~YDsB@H{scssfssssobssssQs|sFssK>2sssZssslsl"n"a?rn"~''r*( an" G@t`rC۩@EU$?W:0???X$$tIsssfsKE ssbD!J ssDssssdsssjssEj s`sEeT6z)T6)X6)Y6)[6 GsP6 ssA !sW ^sPssMssTes s&sspsb@ssssssK susTGssssq @spsQssssV ssFssf@ssZsswess^ssRssp3ssssQKSsZssZKSsiKs&sB#D siG.sossKsus ssb sskB"sasshB"sgBsOXuf'i"&ʁ)##z {z {#3}####z {3}#3}N!$HB7R&$EC+j@:$ B=$ BDssI'fssmsksssmswssuMssssqssN @sqsssspswss\sszs sYssssss_ ssssJ#sspMs~ssYssys} ssQs:s`s sMnssssLUssLssRssssMjglp GsssWs:sssVssUsssgssassNsssss^Hd-nH-kv!-g(O;X9?%-b'aXXa-damg-kq!qg!sUa-MP-TNp(qK!samb W*q!I!W PgWsGsC ss\ssW@ssp,sGs sz@,scssssjss\#s sssssm@ss|o@JsY4ssassfissMssu>@ssIswsl)ssosssss sssIse2Ysd#F4w?e#uz9?, vF4 [~wv*sw*p}v}~}v}e# Gsts*s{q;s\ sskT@sss sdkssu@ssO su  ssB@ssy>@ssdssssI@ssz@ssT2ss%sv>ssN?ssn ssA@Mss%so ssCU@ssU?ssF sVsYT@ssf!JTh?icEBDV.h?-P> wV*VlVE -b -MVVV {9:X9:$ rV* 9:X9:$VE 9:X9:$V-\3 /uVAwV*VE/vV GswSssBssssssXAisCsLGjAc` )jA)iA)hA GsJssU s_ssaAsssssssssslBxs@psrB"s@2se>yshG.sss_>G.s] sesDAIs' Gspssx@ssssGsUs|CssP.st^sW2su2svw ssZstDsst ssM>2sssZEss[E~s]E~sssYssSHsNssS ss`Ug=Cx')g= GsoFsesIisfis=tF%KM=/G!s/a0 RG..10JwR*q!z ua GsyF@ss]=ss@ssssGGIsNG8 sR8.ss8.ss8sHD@ssB ssT@ssVssDD8sjG[O h X -M&"[M> wp*-p 9:W9:$L[  ( Ru{[  [6#?[  [6#?Map[ u"@U9:9:$[E/Q[ G suss@ ssZ_P v&#_EkQ_ GsjsEsss`ssEssss^sszV]sLHsZsUHssi FsJ Wsk FsG Wsm sHIseIssssssSssWJss`Jss@s{~w\ݙv,RI-"BN~*kG*?N*R*??[*_ *\!*g!*k!*?q!*s!*z!*W"*X"*?_"*a"*b"*c"*e"*g"* ?p"*y"*www@$*C$* CR$*W$*X$*\$*t$*$*N%*O%*P%*ssfGLqRg*"r*fq[f qI9=,$$qQapppppCONTROLLER .9V Pawn .9V viewpitch 9S6f[q)@fw~*qJappppp STATE: 9Wa Timer: 9Uo Enemy ~|(^q<apppp STATE: 9Wa Timer: 9Uo NO Enemy (f[q)@fwYC*aBO MonitoredPawn: YC|aBO MonitoredPawn: Nonew\J*aBO Target: \J|7aBO Target: NoneqaOf[q)@fr*q#a NO PLAYERREPLICATIONINFO(Rq[ff[q)@f GsssRK< ~* GsDKMjUA&bD-@ hCL> Gs=|%Aj=g-@-X9:9:$a[C #"m  GsiWss}m B_2zHu n-H-q  GsRMssjaBA& F9:9:$j bS-Xw*Ow*-jw`*`paj G s`McMi xL% Gs@   WVT   MZYcff#%%JVV*22M\]JWYiCRUXz|:CF,i~th*CLBsAV_~k'c|b}GX`*;C|uYyKerpzrgjbWNk TxOt?Vc 09un_`M4-\C Lu MzFt"*1C@t#8q   778sssssKsssss ssssmsplOl/q79:9:$ A Gss~(sNss^ssKPM gsT@ss@sssfsWssyssrAssZ@ss[@ss@sspAssiss_ss|sssKsLssnssbAssTss_Assx s#sQAssssissjsskssg:@ssjssLAgQJ G s\@ssT`} Gse:@ssess~Qssmssss@AssassY:@sss(ss(sY[RNX GsVssQ @\sc@ssS@\s{cR@.OC Gsss}bi%LJs}jEVVYT9:9:$h }{H(6H({vx"9:9:$W -N9:9:$"?w*bRp{i9:9:$iWi pwi*Kai G sssssM@ssD@ssss@ss@ss}ssss_ ssV ssW ssY sssssssossssG?@ssN@ssssss@ssssc ssN ssHs\O-<2mrm*bwO*pppNo damagetype for damage by 9VO with weapon 9VOm 9:9:$pppp9V client damage type 9Vm by 9VO ?% rO*rO *m-^ wc*Oc<9:!9:$ r[*i 9:!9:$m-n6u6u>urOu?uusw*f OOH umw[*[heOOH um>wO*Oh O9?, FOOH umm-X %g ?H #H  Y 9?OH mu?%Gm-QrO* rO wz*D zggwO*D Oe rD *m-^D c-zE"uuD mH 'A uw * D OH mu'wO* wOzO b? GsU ss} ssfVi Jow* -s]?"i ^Yo;Y>]]9?,Y]]@@YYp}?p}?Yo<]V9=9D9?,Y,-T'"V9?,-pYdo:Ydo:kb9?,@b9?,>h&pm>h&YYYV"t`9D9?Yw*9-l*7a!s a!Tp a!Oq!O Uw#6r#)w.#*.#?%-<(v.U.aBB!s B!TpqB.a!OB!l B!HqB ..B!OqB?Ni  Ni 6x m<6x l<6x k<6Aj<6Ai<6Ah<IcwI*ITNcIVIV||IITN|bLw.%y*w.ey*ryIwIaB a!l29:U!9:$9:U!9:$I ax 9?,I* IIw.ey*9?,A9?,I ax 9?,I* I |&x 9?,I }&A9?, aB a!l29:U!9:$9:U!9:$I* I* |bIcI*U-snrU3*\wy*Ua*yrU3*U-sn(  6vg<6vf<6ve<w.%y*w.ey*x y  -sU-K(Ua x w.U*$U6.U`".U-T#9:x9:$9:U!9:$ 9:U!9:$Uox.Uy`Ua x U-K'9:U!9:x9:U!9:$ 9:U!9:$9:x9:$ 9:x9:$UoxwUU a*yvU AaBqB-\' GBsE]ssBss=m9t%c=M}""N_P59?6-v ?% -b3@#!s/a0 pt@#10wt*tzw * wI* r * aIw * d.g Vw3 Gsl ssn ssLWa)t: Gs}ss^j:W )j:)k: GsssB"ssogss@"ss_:ssDsls[:ssBh ss4ssI"ssLssRslsUssH:ssXssC:ssw4sFsO"sT sessS"ssz9ssFM]Ib_( GsV"ssl9ssY"sswssGssX^ss8ssn8ssssss@ssUiss@ss@ss^ssssR7tszb@ca]n !wk*kak* GsCcFcfz GsIcssqE7`qK.$ GsjKcAJ?%w.$*.$W<wk*ka Gsk"m"K<. m"(m"eq!s+a GsOcssRcssu6s ss6s s@sse6ss~css^ss|i s`sZ6s sssC es' -@' Gsz"U& -@( Gs"&sM ssUjsss5&sCk_s^ ss^@&sns*sE#ssH#ssl ssi3@ssssZ3ssI#ssL#ssM#ssN#ssO#ssxssss_gU5Yv )U5)V5 GsK3ssU#ssQn"ssV#ssssssY#ssl ssssTssq2@ssssssss\4ssO4ss^a#V Ow*aL?wx*x-tq!a !RfFq!T^ GsuYsBjGjM}V  Gsssp;svh#r ` w*z*Bza~h# "z Kh#z GsQjssx;sg#@d- aq!a  Gsn$o$p$q$sssWj}3CXo$q!s }3-S(-R4(-J'- 'E A-`2(MlA Gsn#_j@I( Gsssssr3ssLkssFw@ssTkssssG M s`3sVss*su ,sNx@ssMxssq @,sVx@ssW3,sB$ssP3ssYxssF$,s\l sN3sM,sH$ssf{ss`lssK$ sst ssQ|ssAsh0ssP$ssC3ssssPss]0sskm1ssIsl^#]#G#E#C#}"sssGssn~ssX$sssmss_/@sKssDssSssFssssCq(sa$ssc$ssd$ss{2+v w x y z { | } ~  @FsYtGsEsYsruKtkuJsfuLsTtXsTu^sbucsesfshsisxsNs}s@tBtEtzrItetbtWtsBssEj.tC :4wg$*g$Jj.k.l. G sU.s]N#O#P#s|sCsn$ss^ns sz2sT sdnssI ssy2ss`  @s=sx$ss}- s=s~-@ssss_ssk2eV'sm s=sBssv2cst2ssu2@snsBoc.sw-@ss_csD%csE%cwsUsse-ssJocsQss}ssssssw sszs_-s[s` sB@ssAp.sk ssU%sss@sssuDsQ2sN2sHss\%sfps@}s{ ssH-@ss{}ss sssE-@ss@ssC2@Lpqs ssi%ssj%s sssssss`d,_,^,[,W,se%@ss_1 S-Q-P-K-G-A-,s,q,m,j,i,h,sy@ssSs*sD@ssp1ss` sxsk1f1P!8)f1)e1)d1)c1)b1 Gscssss_uMsfuMs|sPss~% ssm sssFsTssB&BsZBK1sss~0]\ZYstss`zsssRssi0Y|[sssf0#G-wv*v# GsK&e0M'$wv*ve0d0 GsD@ssM&@ss qpnmlkjigecasV}[Ysmss\0ssQ~ssU&ssssW& ssQ ssY&ssssJFECss sWsslkjQ1sssYsUsssn]&sEssZi]&sss`sNXNe3g&(ͥ߃@EssUssL[o4 Gsssys-s|s-sV@sSs}s stsssBs*ss@s `g3s&7)6 pC]%o had an aneurysm.E]%o had an aneurysm.W]%o had an aneurysm.TSSssu&sX sM@ssQsqs@ss` ssss{&5s@-5s}&ssassq,ssr&ssssBL RK9 JD4M9? M9? M\wL *BL +MJy*-H 9:L a %-F 9:L B%-xL -_-vL -uT" GsC'ssD'ssn,ssh,ssPsstssK'ssr@fsssmssM'ss^,ssssssssb@s{efw@R'i Y{(TF>ssM,ssssV'ssW'ssX'ssPssBssoss\'ssssssG@ssss_'@ssc'ssgsssshssns[s`psx)@ssossk'sssssB @ssF ssT ssOssl ssq@ssisus@susPs4ssssw(shNkO 3v'cZD#'\"h,eh@q qY@qh'\"'\"h qYh@q qY@q@u)@u)3}@u)@u)x $L>i $As ]You picked up some ammo.R&$zEEkjs0E[G)2 w'Fڞ0׿e]ʁ)hʁ)ʁ)r*ъr*ъhssls&ALE^@y'v[&ɢ%Af%Afh,e%Afh%Afh,e%Afh,eh,e%Afh%Afh,e%Afh%Af%Afʁ)ʁ)ʁ)ʁ)`/w[ "d+zFss@SzvE {'Cx5@EssS@ssm(@sUrQ@0~'x|;Gd"sWVVm@0'W7zHHc$=ssNs;WXnv@0A(TW7zHHj$?k$?l$=n$=sspssD(@ssE(@sss@ss@ssJ@sIsN@SsssH(@ssu@sNsR@sPZ@/v+0M(tPX sss0]pI2O(Mz0׿e]E"H:0BBB*CcFNQssf sssslD@ssR(@ssU( ssV( ss{ s[GOPu,W(\[K\PssY( ssZ( ssv sKKs| [(e ʁ)h$7*CcPQ:$?=$?F|Dbss~ssts2sy@Lsq@ssn@s~pq~p+@ a(Oo~~ss^ses[s;sYV W X sK(s2sG(s2sF(@ssg(@sRgVC+@ i("RS'Gd"ssls;sh@ss\ssl(@sbtQzn(ʁ){-$?d$ AOlQs0cTQ" 2 o([RG0׿e]ʁ)ʁ)ʁ)ʁ)ʁ) p puv$Aw"0x"0y$?z$*Coz$?{$?|$pB}Z!$$Bs$;E@$A$@BB$?D$?G$ AHI$HK$LL$HV$@W$HB7 OS>RGFFbsse@ssssq(@ssr(@sYZ)t(-M@EY)$@O)$?L'"l&"g&$R?e&$zT?]&$?[&"S&$B`;_%"{$X94<$>p$>\$K$@Eo$zCtu|}DHsss(E_HF)B` 2v(Lć(bQ CS>Sssd@sZHL2x(ր%@Essu'ssp @ss^@ss\ssXs4GluDw(~(kAxGn6pSXs[Qu((#[KOQ$33>ossBssMssA)ssB)ssI@^ sC)ssE)ssF)ssG)ssDssI)ssJ)ssK)sss} ~  @!A!sL)ssN)ssM)D!E!F!G!sO)ssz@ss{ssS)ssssU)ssV)ssT)ssX)ssssZ)ss[)sst'ssY)ss^)sssss`)ssr@sa)ssc)ssssd)ssf)ssSs&qyyrX(@i)waq${$ Fu"$zDt"$"Es"r"$`Iq"$o"$?i"$HBf"$@>SsUr_l2j)<UA_3}ZsY±3}ZsY±3}ZsY±3}ZsY±ssb)!@s@ssm'ssq)GK hd GsBsso)ss\@he Gsl'ssssssF sst)ssu) ssu@ss@pskf_!3 G%sy)ps{)ps|)ps})ps~)@ssf'ps\@sssv(sO s LQ3D*rn pC]%o was telefragged by %kE]%o was telefragged by %kW]%o was telefragged by %kTSB S^1u$?ssP sshssF*ssjssH*ssnssy L*e!)L* GsnssJ*ssK*mf!* GsM*sCk@3P*$6C,qC] %k made %o take a deadly swim.E]%o crashed and burnedW]%o crashed and burnedE1sssssQ*ss@ssR*ssssU*ss['ssssX*ssssZ*ssss\*ssss^*ss_*ss`*ssa*ssb*@ssssd*sse*ssssg*ssh*ssi*ssssk*ssl*ssE@sssso*ssp*ssq*@ssr*@ss@sst*ssu*@sssv*@ssssslsx*ssbNQ$-vN-u-vwN*|&N  }&N wN3ww*w-l aN  w  a+N  Gsss|*ss}*ss@+ss@ss~*ssC+ssD+ss@ssssv@ssE+ssG+ssH+ssI+ssssK+ssw@ssL+ssN+ssQ+@ssj@ssssR+ssYssssUW+~! )W+)W)V GsW@ssV+@"! GsX+Z+`")Z+ Gs@ssU+ssTA"s[+ss]+ss^+ss@ss_+ssa+ssb+ssc+sssse+ssf+@ssssh+@ssE@ssssk+ssl+ssx@ssm+sso+ssp+ssq+sssss+sst+ssu+ssssw+ssx+ssy+ssz+ss{+ss~+ss+@ssr@ss|+ssssA,@ssssC,ssD,@s [w3F,w pC]'&%o exploded in a shower of body partsE]'&%o exploded in a shower of body partsW]'&%o exploded in a shower of body partsTSB Su$?ssZssG,ssX ssUsswssHssqssS'ss@ssgssz@ssn@ssssss@ssT,ssS@ssssssssssssssf@ssssssss}@ssssssG@ssE&ssTssg,@ssE'ssj,ssi,@ssMssssQ ssFssp,ss]5sr,5ss,5s| @sst,5sHssv,5sI-oGsu5sl@ssz,5s|,5s},5s~,5s,5sp@5sA-@5sB-@5sssb@ssC-@5sF-@5srssG-@5sYssssssssssssQ-x&b1*-s-s -Q-I`9?%-U-L`9?%-V-PA9?%-W-[A9?%-I`9?%-L`9?%-PA9?%-[A9?%` `6<hd` gw ghx&gA%Ew Ehx&fA&gQ`gEQ`Ei` ^` 9:^%AJ@g^J` gJW9:^%(-j9:|%6-T-iETiEu|E9:_%-x'-{(5i9?%-x(-{'55-u-j-x'-{(9:mA%-{'i?`` |``\ GsT-AR) Gsd@ssP ssI@ssX-ssa@ss@ssXt 0/ GstsX su-~\-M}9:t9:$(?9:\-9:g-9:t9:$y'x9:t9:$dx-] u'( Gs@ssssd ssG@ssK|EeqV% Gs@@msi@msgssd-@msc@ssi-ssj-ssk-@ssss@sm-s}B|  Gso-ssp-sVsq-ssr-sss-ssssz|@t Gsv-rMT=( Gsy-n[ N ( Gscssd s=sqkAq  GsdS8C  Gshssy$ ss|- ssnss{-ss-sscssC.ssD.sVsE.ssF.ssG.ssqssA.ssH.ss^@ssm&ssK.@ssq sso s sk s sk$s~ssQ.sqsR.sX sv@ssV.sW.j$sX.sY.ssT.sX s@ssO@ssL@ss`.@ssa.ssS@sse.ssf.ssg.ssDssc.@ssh.@ssk.ssl.ssg$ss@ssi.ssn.sso.@ssp.@ssq.@ssyAp2)A Gs|@ssj@ssg@ssidq sp sBsBAU_$*jm^*   " " " " Gd"sB@˷KK߸KǸ{xxzKƸkiUTIG3+1cMƸrUʬi6+/{NŸsѬii^3(>yPĸu) ,8IH6+1RĸhT%*&-'% "-42!aSd6# "Xж' "H2#),&$p[;# "! %X^6"&#e]=liV X) <_F,ji 'ɢjI!{`dJJ*'i% 3Ȑ8%0{~J4j6.)GZl&&Hb7I."!#,,#(5g|mY3*&+0Eft||lvv}nnnnnnnnnnnnnnnnnnnnnnnnn9:?Doqnn9:?Doqnn9:BDoqnn9:ADoqnn9:CDoqnn9:@DoqnnnnnnnnnnnnnnnnnnnnnnnnnẺLLLKLOQRW\]_ s@OXGRZIT]MV_NYaNYbQ\cQYcT^eS[eVafS]fW`gU^hZbhWciXbjZdkZak]el[cl^fm\en^in\go_eoajp^hp`gpbjq`iqckrans^msakscjsemtcktfhtjnudqvaluhnvfrwbjvjmvhqweowgnwiqxgtydkxmoxjqyitygpyktzgmyorzjqzls{ju{ir{mp{ou|kw}ir|ot}mw}kp}rt}ox~lv~ns~qwnupymtrvpxots{mwrzoypvt|nxrzq|owuyt|q{rwv~pzt}r|s~qyw|t~syxr|vt~uzys}wuv{zt~xwu|{x~zwuy~|wz}ywz{~zx{z}y|~{}|~}|~|}~ìǰεsONMKsHIs^stv` GsB/WTSRQs`^]\[ZYXsfedsONsF/ssG/sj$sH/sssseSRQseba`_^]\[ZYXUTsqonmkihfsMfM/sN/yvussO/FYs@s~NMJHGFDsPOs@ssRQs|~RsssU/ssx~ssV/ssX/ssY/ssZ/ss]/@s\$@sEss`/@sa/@sG@s[/ssd/@se/@sf/@sg/@sh/@si/@sj/@sF@s]@ssb/ss[ssl/sssso/ssp/ssq/ssr/sssss/ssw/ssx/ssj~@ssu/ssy/ssz/ss{/ssss}/ss~/ssA0ssb~@ss/@ssss_~ssC0ssE0@ssH0ssI0ss]~ssF0ssJ0ssM0ssN0ssO0s sZ~ssssP0ssS0ssssS&ssV0ssss_ssL~ssW0ssY0ssS$ssZ0ss^0ss_0ss`0ssa0sst}s sc0pmkigdc^s`}{zxsssd0ssv+v w x y z { | } ~  @FsYtGsEsYsruKtkuJsfuLsTtXsTu^sbucsesfshsisxsNs}s@tBtEtzrItetbtWt|.$*z*   " "" "Gd"s2@\uԮe{}oSbûȥ||ddddv||:n>fmR{غhƏz¡>SG@LܳtOTőѸ՛ȷ|dPZglx|?*hOǶrXSp_Vn.D'Vگn7> cʶ`4׉-LGٽk11@ ײw;":Nn{ŲĴڠ|vd`vzzze :mϺ{K# `(V8m_oG@! ƵeC:51{w{ɣڹĻׯ|xiq|xx`WxرrrjoaN":fSAž`;  ΍:'LAV†A.LVYmaJ@beTtƳ|nixx|x|Ӻ}umhar}f\j_r޺uN- ֫iGLQզy.DS\2_mSL6So{eƸyͣIJȻxǶwkmhcLSoO6Զӱb7  *yS@LБiSyX1LG8h_hptԸէ̯įvq¬{TJaa_XrS6͡e< L{t]TC:|FO.6.X=_mzbūT\ƮŸȻĻܖg^㱋}W:1S\aSQňƼyS15}kJC;40ܯd7H@V_tƀk\yͮIJ|~~x}a@*1OXa<ūʦj:1@wu\@5/-*%ȊI5LDּmp}ȻûְtJ/"5SXf.ѧmʼt0%"Sh+rÉK0:*\tutɼ~~~x~ş{XJL¶t@}\J<5/%"mzդxF>O${oo}Ƹ~~~~X'ɿS\yuYO@5*"8Ͼ͸iNOXcưx~~~~~w{]<5@߿ɿoXjLaaTH5*±Ӧyoj*hƿͿ~~~~~eba{}ƵyoS.>[}mVSy{D8}{ssst{wXOTb]a`C@<@5{eNC;;;;;;!$'VY¼~{pi``n~{taafj:00074Gʾ{we>%"0[}ujjGc}bC**5@HvkbTH]rYA#0""FH<:CB>Mlx{n``RKB7-0-00  ¡}zof*QtC>JG:**/4`~si[RFB;440-) 'ضytL{wN  z_LA=A-7>4iO{]::1>n~ʺ];774*=_¬}f${ws`Su_LGDL@>R4ie/%wʞuB4(ƅ.!Qʺh.$!wsie;{aSJLLL;%[]T5ew{ݼfL.֮}mž}y_=$$11ow~~~s[N>*teXLLQQJeaHnְ}X1'z}Y':fw`Rd~i>-weXXQVQ #1ƿƿt:"Ѣ}u8aƪyof]]mrSVt@<:1">ֽkOƼRLzӾW- *Ƽk1"ټwyhضzh_YSSG(((t XҟiCѼyʿ_.= =¨zmbOJD@AAucVGAAAGLYcopiniЯ|? 0*Gɜf.Ѱ\:$5'Xt]<""CxHͼmYcʼfL >yoh_Y\TJHKR[> BC ϼ}LƌT$_ڳ`>HT@A}J${xxէbDjƢ{yӺk\hmr'wfa][d`RW}ztpe]]TRW[[i 8m϶ot@p].YřsI0CJDV}zua@Cܽ]$<=ؼyrh_ؾ\SYmr}taXTT[[T`{wpe``[`i&; YVǪwa\X.߭XJ:6ƫR7>JSzzzzhmu\ˤt]:{H¢r_.@ӾyVS_mayo\SOOR[W"C{snnnnsn*Mltw4*OoƢeTSe$eO<<m{[FR\z}rcct@ղ{e~~pb:/XhL$ϼ}rYVhr1tj\TOHWW[t~{xwss{]CF7ZdIpo\ajmѵ`NOOaŔ}ytb@T@'$:C@Ӫ<GrcahG}pb]XORRWT K[H@'Ot{{{ta<5xwK)tRMtS@'L¸iCCOXSwTN'4C{ӵD:'jtoe=OtpaXTTT[W5ZsF"C* p߸|;={]NTab6fO'$D=6hzA( _zzrmhmmhcY_atkJa}Ӱo'R]o}mL {wkbXW[[W nK-:H'@ƿ׃>fy0Ӻytf\fjOTT/'=͵S8}rzrm____YYYYokpJyaYӦp]D/p5t]$4;4C{wki``W[!-dF-5*5`?*h.ǶrTOojjSѝbHba_¦ɗoLzrzzzr__VV_YYYSoOb5=Ǚ]@O *>`[B"'wtniie]1"xiK;%>spWN>pR 6r϶a@/Hf@=ѝj1yaQٽbSrhzzzm_VVVVYYYSj<{t]5ص{C5J CB%4R5k{iieS4;4WF5*'n{peWNHs# LǪ{K/!=zy{rAͧw;:hhrzrh___VVVYSYX*epT/*Cjʗ`/>HFxBZW7FX{sb:5'B~{niW<>~potj\mƺ> cʶ`4T]YɸcԼR%*S_crrm___Y_YYYc1:b*mhӵ}H>W ~`|x^Nst`4K{pe]TN7zzze TO'L\SL1__VVVVVQV_f= yhuzhmi`^FUdMU|`nC%%[wttiNC;7-ǶwkmhcLSoL6Զӵb7  5}uQխx-;H@$!6AYY\YSYcV. Ӿr_SLDen`FBIqPxWW`7Wtkt~`C>;7¨{TJaccXrS6͡e< {}uj.ѻRBFH<a5JftjG$GSSSXXL5$ߡӾmQA@5XiBIMBl[ddFHtN%CtkkwpW>;70$㱋}W:5SaaSQňƼyS15wwtSGnM[O@ Gͧ{XLY6fa1 oӾmS@1/';3I^vPld`Cs{e>"wnee`K;70%}a@*1OXa@ūʦj:t{t\r~n\= $jܽR@16wbO"Ӿ¬}bH5*'$%9MgMP^lĻi0 >{{n4epbXNC>70#ְuJ/"5SXf.ѫmʼt"De\HTpe1A}yW' \ׯxB%:.t{iXTjN5*""",3?BllФW`e{w]$1kbNC>>7) neC'$@\jX@ܗyjµT"`{@ū<Sjˤ~R<ЛZ)*5=ttnWJ@±}]>###UUķdZvv[5t]@SLTepbT:;/ lso@'1Xjѹ֧t¶e:b˽b'uܲs`O$Sմ|?5H[NCCiweC-% UP|PM^ȩF>bƸbN@_csXJ>7- ZUFRXS=DҳyjǺt"eƪ{NHB~ţ{XJLǿt5@oí{nbd#-JJ@ȥq9%/)#Bd4lΘ}eC-&EE^vqqgZqĤn;7kbCC@mS<1/**%:K4?^x]CUKɿS5:Sn]Xs7%H:̩|I4KlxړzrfW>-##93EEE^q|Яdv{iTNtNC:s]O@ͭM)#;K'DZ, 0-#>зe}rhYO<0%%%%,E,9E?Pdi[i|d{{k@fkO<5.Jy\HC40)">IMq|qlN\syƵuoS]~snt`T@.dMFFF%kqU?BB44I7ZjXOC:/4- 99&3EEi{H*gvtJ$TjS@>0%""7II^v|vqliƵoY~kJ=1'C"Jxi[WC%R~~~i`R>[sZ|~вˌ[WKCB3&&&339d{b<0p]$O\J<50%"BI?gvqlZgʰ}oo@sMěЖ[:i{sFFZ>#)iiKC0%#wÉx[xZ,,&&E?9&&3?EwXC'{`H$*wy}yYJ<5/%"Pg^vvql^¦p\fFF0`nč̉iEEqvv^EEEPvpJ:1kR1yjm\TC5*4|gUvqӿwbS\J.WMqЍvdgȻqUKUЕxensp|xȖPZ^lld^{X<1}kJ:$`XHaXLjaOO:/!^qElvͧ{WNJXXMIlש||ĴqUUlЉ``~`wȐפwkqvUI|Fowb@1i}uaJ1' R~O**OYGH:*!9UqvqPvvƳ`CCTXfZMIx̷̍|`xxe֤`>Hb`x^v߫v^ƶ@:MM͢~v~ndiix~˳ōB)%FvIvMUs-SuӶ}jsȯdPbouo\S<:J<1":fn`Z^?^|^^vltaafj@RIRHyʬ}ȻZZxx^^WЩw׭q,)nZ?dP܉0'hǶmOD^Urm\SSO<{a1{|n`[RE^q^^vg}ujjLiaLӾfOgdP^˻ФpI #B;?ldC 8zϵ]:'@|ĒzzrYSDH@Tafxi`RMIZlE^l|lqy}}yaX܃- hz¦uO:/wdlȻПw˟i)&&P` V¦sF*xȚjXGDD'Da{`WKF>>BP|lgd^`iZMF ӵ`;$;>>^vqg^`ttnei 8m¢wK%$|xsлs>*zzr}[ GmrϱtC# C~T:<<<50)-40>g^|v¨zrrjjuw4'Oo!ӬtK% qț~pw`H7ӺyumhXuofjY޺oH) grX>*/5 >̴˭xWW`ws±pbmhcSDoD'ԱǪX0 K{}rYJ5'1:C|~{wbXNC:/)#%)0-v|^ۺkjmcf@Ɯa@GǜtH) ˹sR4On:t徨tH@\c_S_ѪtDɡm}\1 %ttkXH51170-%)0,4ZvPUӱkHXa_h.+Ѫy1Լ}O* DϪ˹nF)Ti:}{㬆yN41S\aSVəƵa:"/`{wk{nXH<7:Wqsnn]JC;/0)%)4,FgEvʞpC/D\\f"צͼh@*"Q͔Wò`75tp{ez\:'1OXa5ūǪN~pWWCC:Ksie]KC>7*--04#^|ZvяmO4'@X\f.׸ӼOHfy~7"H~N'1{wHHӪtC*"5S\aA͙rª{Onnxx~~ni`RKB;440--#qqgvn͏\<''DXa@߸hµWri:{ţiHTwbOO{eOe>$'H\otoׅytfµ]`xȴxi`WKF>;7404B|PUlnN/!1Ofj@f࿅ya¢wZlUvCD˸R-*OeL@S\@a{OJSƼtHw|qgddgv|vddgB,%^|ι||ZwºTcӵutAR05jyaL{oƼLڕĩ|vqlgvqll#Ļx^ZlvBiUZ3ZƼ}=tLsX@Jy{kwpwXf{ư}tв̯|qU^|x||ZU^Zq>#FM&XƸySρ_һ{eJX]ytҧoѳyƵ{ЭĴ|vl^qvUqglg|gqK^Zͼ}tfS}rέŮsR@șƵӼorIJȠvqv||ld;U|ddvUvԲXԪ֐fѿ~`CҳǬ}oa\ĴлȴȻ|v||vvqdZPIBl||qvI{ϺyySys#1f˹ɿ~`>Ký¢kaXLjܴĻĠ|v|gvv|qZ^Zd`ZIlqMZ|g?Pʱ}fSk'W@G`B/Ըp]XSXt܉xĊvZ||d>FMgqq^U^dZvPUP^ͪkXOp$}ߕ0 = Ųt˽K>eýɣwNHJXpĻдvKvxdUZZlvq||^dqlZlvgvԼiNOJfyn=ѽtbo˹iF{չnH˻W>KXX{ĄnZZddZdZdlvlgdgl[Zd^¿wKCJXTݢH!@!ųpbO\iK;˭inλãt]X]fXnĻȻĻȯ|lRBZvZRd|vg^^gqqqldqleOO]b<Ƙ“cVVA8Sy\ajhϿ{tnW@]ä˹ufcjf@̷ȕ|׉3ZNBURdI?Zlv|~d^t}jaaj\YhAAr_Q_rrfczo}jep˻˻}tjfGû̻̩xvMdRIUdq| E߸tK`t\GrݧmB$@@\k˸̻vZq|{1]بprK@=F/˽ŽIJĩBg~ϗC1|=m50'RɽŽȒxq{zN @nC6V:6t@5w{Ľķsq|s~ݬzhfODaӆC ҙ=_yTDAraSuuսx~۪wb_@@b \@n6DYuu}ezûvz<@\$߮a$5trι~~|{Tɵ{fhC/m{]IJ~~~~{e{ֿyG\fJ1$޶<58˽Ť~~xyذ}\.DJ$uJCئ'Ž~~~{nj]OLTCCfbs[Ӻru~~{{wǫ]JX]D:TeNBehp1Ž~niw}XbbC:BPvn`H7--) _嬁r5G~<mL1*NT14swB4*QϡYVs[jLG!4Ce:~Ӂ:=wYS('StiwHLkTL2Tpbe]$ӈ=¿~K~7TfY}}jXQ=kp]4GψOuͼƿ;>s5aArrm_LGG}fHb cϿۺͿ/NwOOT{G @aVLA(A}OؘH!zˆHGɿCɦDH@!@GYYVLmhrk@ arVSAֵ`""ɣƼ/bٗSupkapL@" }SB hˆ;Ϳr:bֿyz؞mXO88~X5h'L] /˿ĹS]@Cb}Y؋oTG=hY_httH JM5ufVy/e{H]KƋ'ӿ686}aJ@LcG==Laei<0$Ѫɗu'7:{:]ïTԸ}cʵ}85}aG=V}V=222G]e"9 $AїǰJ/JJ$JÔpQ+zG.Vu_A+a}V=2++@T`5~^F>}ԂǵbD]bjƜ׽`JzALhrhh_{pjcA2++@JW-.yaӵj֫tLp]|ҫ{༏czmū{TyV=8=GHW-'ST/k8eT}XJXݜuʓrmGƸtniKuaQOJKR;rϙ}k@i>GG}O*<ήDʋyr¶tYm]{\T['O{p]T[ ~ '޺fSJ1HJu}zhkk˂t*JL±cYXJoXJT/W}{snnC Zwe s||lCsk$BweJwzmN Dnb!]njO16_h_YYY1mcyT[d^`5teJ;ݬymfOCaӆC uc7H.1LVVQY6zaheIZ^eN5p{sC7۪wbc@@b *}Q{H5\JVOup.¾uG5C?Zx~5w4pk[;-z<@\'߮aJ{pSi] a`1QwT{f5$9I"`{1XXC;/X$G\G͌zӵX1]:A{e!0*`R:~}BPUvCC}HVteC49`T8t΢}ʺJЩtu7Jd %K-]#EvqZĒHCW@L1-40B|}Ktɵ{:~bF#><# %e|УzcH%9EIqsx{btp<{*/X:)BPvgذ}\{~ki7e>)]~s9EP99^b5e/ NrS:%#vllqnj\OCd̉ggKwixUtw@~}f5KCJ}S@$?xZvǫ[JX[Zvvess-HxdnuuO^SX8T*OfbCIM^x}XbHntɶsvg}9KPLݿ{<|srYJ5{S~eNPg^v}pux_رhJxi Fn% ӦK5tG@'sNB;Ig^i[ϔBWvȐ{ Hrug|}uy[Gk FĩxntK޿tmY}aaʗJ NmC*:{]J1%)-|嶜rh]SrӋ@ ;]Tt:YX.ٵƜr'Ct}b@1`x{nTB0%-0qgkC\Dcш]QOŹ/OXϏ@*S7FqqqH*G}ʽ}}%@ս>D]@m\tpҳj]ƪXt|dZdv^3d{է{n£]؜TřR5u}{{wѿ|qd|qdl^xTKBͿyΣwJ}ќ{x||vqRqllɎƫNض}a_Ȼxv||ldZIvlgwӦyaufŧIӔXTtĻĻddKdqdddv^ʌXXyK'ѩt\ѹi[`kJXĻĠZUdZddgdl]JOӶA=.}tkpîtfaȲMIUv#dw[zfmmzy@@R(@TνĩZXym5h1tý||}14`~m'S}u÷xtSkk@ԑ1W{@uth*:k:Ų~~tѢaS%V±8y~wʸbXC]wHƶGɽwswXpsi4"'c8n:yL!X]Jy¼]iWVupLV]Lئ}Կ]{T*G.aQLc}/rhO֔}-Oɵ:\Q{5}kw{w{buLuGkcLa`"d}y/JDX}Gtm={G+8]"0:ưfbruy{{Y2=Je@OJzk/JrYbJ~fO> oDek}rc]JVLa5uO::XTWJNi@s]{ShuhYYOb/{4}wWW5/SyG=]tHVcVLtf:FvsC1k:z14/m<GLQc!cOZqw-Hi7tXhbY]=|/pb:9|kOO]T{C`;C,n~CT7~Nik@kP{stb}Rw]N>\ek{qqx~tvqgtu)@}}tɮ~teeXVufzycW}uf}be]twTbC|TWtpeTi{q){pataeX{i)pwp){sssj0U|zsk0R|CsKHGFEDq|s|{Qsb`\[ZXWVso0g{qsa{rsss^{sssst0wxDsv0`xMsC$s sw0]xWsx0ZxXsy0WxZs|0Txas{0s sRxss}0UTSsD&XWVs@1c^s|#ssA1gfedsB1kjihsC1onmlsD1rqpsIxA~yxutsssisz ssF1sFss siBsK1icbsgvutsposs(sPwW%sMwh \Eu]a@6N9Dh 9?,h 6N9Dh 9?,h 6N9Dh 9?,h  Gsz%|.sP1|.smssR1 |s{vssW1N M L K J I sluMsp w v u t s r q p o n sI!H!C!B!| { x sMsWsk~sZ1~Ws[1~s Y*o*p*q*g,^-G/W/F1C1B1s{t!v]1s^1w0v0u0m0i0f0d0b0`0L0x/v/t/o/n/k/j/h/f/c/b/^/sFuss`1ssssb1ssc1ssd1sse1sszti-tA'6a9DA}^6a9DA}i6`9DB}^6`9DB}i'^w*9:!9:$6 ]26^6 ]6^%6^%6 ]%66^6 ]6^6^%]^9:kA%I +9:lA%J t*-A (-N(6^9DB}^6^9DB}iw*6^@6^a+^G}t}y!^'-A  w*-W -<Gy!} GsYY 'f Gsx!ssl ssssm L/S Gsz:|0f GsDg < Gsp ss}:@sssEsYsEsssg!ssvY@ssC;@ssc!rYgE GsX!ss_sshYJ I Gsw_ M: -C( GsfY`YcQ GsJ;^Yd U' o$a G sM;ssN;ssO;ssP;ssQ;ssR;ssKYssHYO!C }OL-NI"-N(A(D(ee-}-}'mfwy9:9:$wy*ry y *jdC bO!-\z AI w*=FtO!J`fgE|^A]ihO! GsssBYzs1#zAw*-l **jd`r*q!_  s-Hw#v-<E^+-<-HCq(JT GvsZ;ssssssX;@sszXss\;ss];ss^;ss_;ssoXss@sssslXa;j rSqa; Gsssssh;ssssssj;s.sk;slsl;ssm;ssn;sso;ssssq;s.sr;slss;sst;ssA<ssPssHXss@ssv = -_/,9:9:$W?restart$( Gs@ss{;ssos sIssy;ss};ssssyW|Wx( \-"rQ}(*-_' GsC<ssssssssD<ssv ssssF<ssJ<s.sS<slsssssL<ss~ssssO<ssssaW{ N G@sT<ssU<ssV<ssW<ssssYWs.s@ss]ss@ssssEWKWX, .r|*CcwC*p p ,dmcccVmbmV*wc*CcccVCbCV||CrmCCVa +C|||VCV*C Gsb<ssc<ssd<ssCWssx sse<ssf<ssyssh<ssi<ssj<ssk<ssl<ssp<@sskssq<@sseVsssst<@ssssr<ssnVssu<ssw<ssx<ssy<ssz<ss{<s`s}<ss~<ss@ssA=ssqVssC=ssE=ssF=s`sG=ssH=ssAssJ=ssK=ssL=ssWVssM=ssssP=ssQ=slsT=ss}ssR=ssU=ssssV=ssOVssX=ss@sPVs[=@ssDss_=@ssb=@ssMV@ssKVssh=ss@VEVTpj a!r Gszss|sse=ssBV@ssi=@ss@ssk=@ssxUssm=@ssn=sso=@ss@ssq=ssr=@ssnU@sst=@ssjU@ssb ssu=slsv=ssass@ssx=ssA>ss]ssy=ssF,G,H,I,s}=ssbL,M,sC>ss@>P,Q,R,sssss_U@ssE>@ssD>ssG>ssF>ssYUI>^&)I>)F>)E> Gs{2sH>ssk2s\U@ssN>@ss}2sO>ssL>ssR>ssS>ssssWU@ssV>@ss^2sW>ssU>ssHss[>ss\>ssQU]>E -N]>\>[>(-H(($Z>U> GBs`>G.sa>G.s_G.sXssb>ssf>ysg>ysh>ysvysc>ss@ss~@Mst>ssUBIU`P#9r`*r`W*r>Q * Xa`WwX*X_`i>c>b> GsX@DMs\ssssAUDUq _( Gsz>ssBUssnssy@ssv@ssx>@ssssssss~> ss> ss@? ss@ ssB?ssssssssF?ssssbsV$sFssJ?ssssss\@ssHss_ssK?s.sQ?ssR?ssssJ@ssKssT?ss_?ssJslsW?ssRssX?ssZ?s.smss\?ss]?s.s`?ssa?ssb?sse?ssD@ssDc?6BZ(9:9:$ r\* BD!sD!~\c?D Gsj?ssIT]sf?]sVssg?@]sssZssi?@]sn?ssq?ss}SAF&(9:9:$ r\* AuU V W Y A OqU  w>*w>Q *>Q .AtU V W Y  G sl?@]st?ssBT]sATb G( Gsssw?ss^ ssy?ssr?@]sz?ssss|?ss@@ss@sssssDsA@ssB@ssssuSHsDssF@ssG@ssL@ssI@ssssssJ@ssssP@ssO@ssssUSssR@ssssqssV@ssrRssX@ssssssY@ss\@ssssZ@ss_@ssss]@s.s`@ssa@ssd@ssssRss@ss@ss@sstR@ssssC@Hsj@s^3sl@@ssssC@ssq@ss`Rsss@ss\RssdKRW.sv@sVsw@ssx@ssy@ssssCsi sYg ^A>9:r9:$ -K2 -L2 XB GsX@v -p -p'/a8 ewswe9:e9:$ea/!"] e  sr?] ] ] rq?reAwem-9Dq@ e  ի?e6eA] իqBA] @Aw *w.ee*.ee?%.ee-}p@w  @ABAs10-p( GsERo }h~ Gs}@p ~~ GswssBAs sk@@HssssAAHsusJ GsZ HAc &@HAJIA-q-JA GsIAshsJAssssjQ@ssGAU&@@JJ-q-q Gsk sscsV$sNA@ssRACAHsOAssvI sVQssnssVAisYssTA s#sYAssZAisssFss[AssssSQL$ $q!sa'(-Y(-C'o$ Gs`AssessI.J.K.L.M.N.ViscAssass@QsswPsKswssfAsssshAssiAssgAsskAsslAss~PpP|uD/a3 (w>=w-DwH 9?%0'10( GsnAnPf/ GsqAssssdPssbPusXsstAssuAssu@ssN@ssK@ss@PPsxO'Trrw*7w*` 6I$ E$$dd*-Xa Gs}A{As5sGsfOMOqGspz m GsWOel41w*@ GsUO@sss[sps sssQCBN]cf #r*r* r,* w.g*, jCBr,,*r,* ]r*ew,K GsPIO Md Gs@OOX7b  GsHBwN@ W_ GsoNtNA ,_ GsssKBiNbz^ GseNgNE ] GsAqV3wzwBVVBrVay9?%M"vy v"/QV w.V*w.V *v%v,rv.V tv.V t*vQ{X wV *V 6X a-a(wwC9?%aC( Gs\NssOBVNG Y GsPBR Y GsQBSN{Y GsENPN] Y GsJNsspssGNWsmMvMPT GHsoss@3f3333f333ff3fffff3f3f3f3333f3333333333f333333f3f33f3ff3f3f33333f3333333f3333333f333ff3fffff3f3f33ff3f3f3fffff3fffffffffff3fffffff3fffffff3fffff3f3333f333ff3fffff3f̙̙3̙f̙̙̙3f3f̙3333f3̙33ff3fff̙ff3f̙3f̙3f̙3f3333f333ff3fffff3f3f3fsRINc`g#+(BckQc  GssskMssZBss[BssTB[\]sH]Mj Q JXw*29:!9:$9:!9:$ -b Gs]B_`as_BUMfsPMST&EpmrRSbwSx*RSx[SxZ ?mZ  GsHMsswwLX [> GspLtLx> GssscLzd7zi zw*w.e*w.eN*-~.eN-J#-~-J#n  9?99 K Gs|sseL"sjB@xsdxsf"scxsssmBs sZss`BLLJsMLPLw//  GsZL"sssssJ~ O(-~'* Gs@Lss}KsswBssxBssyBsswKss{Bss|Bss}Bss~BssnKssjKssgKssdKssaKssDCss[KssqJ ssFCs&sWKssICssJCssRKssLCssNKssKKssHKssQ(ssQCssRCssSCssssUCssVCssAssXCssYCssN sgJss]eJqf Gs\CsspBaJs_CRJBs]CCY mP-[Ca  N-[C #Ca+Cf'(/Q.C-[ Gs`CLJCsw ssIssaC|IM{ Gsa ssfCssdss`IssYIssRIssCI slC sH WsmB b GsoCD { Gsh skH snsUscH@ stC@ suC@ s^ssszCss{C@ss@ssqGsUs`s|sCss@D@ss@sskgGZ ^  GsM8sYG8sCD8s{ssD8sFD8sssJDss@ss@ss_ssstsssss@RRRkkksvFssR0S0T0U0V0sssBFssssUDssL NsOlEZscEUVs[D~s\D~sSE~sPEssD !J st ss{ !J s`D!J saD!J su!J sEEPsCEPsDssgDss{DssiDsgsnDssD@ssssss@v%#vn&i@ GsoDyi8D/a0 dy@?yQvjkDy0 10 GssTsBpDy}'61r6ay hvv hy GsC @sqDsssspssstsisljDl/JMHwl*l @iDjD q l9?%l GsAE sOsDa|uw ra*(<a J |ao|(| -a '| +#' GssseCxDhDM"A>wl*l @lMhDgD GUW$* *99;   " " " " Gd"s=@OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOkwOOOOXwwwwwwwwwwwwwwwwOOwOOOOwwwwwwwwwwwwwwwwwwOOOOOOOOOOOOOOOwwwwwwwwwwwwwwwwwwOOkOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOkwOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO sssfDPsDE sXDi$* *   " " " " Gd"s˴@mooomoqmmttqttqtmottottttoommq060# # ##88 6`m068 0  8660086 0 688806686 0888888888888888668888686888 seDPsJE ssPssssD @svDscDJ_$* r(*   " " " " Gd"s@ܠ̱eػ2['2JIﱱq,Ż/NVN֭ՍgRRYd}}u}pT' sm ssGE ssDOEWufH  -W (PB-MB-bW {B'B-}W BBWWW {B'( GsssYD^EmVs GsmVEIsW MB-}rI qBI ]n-W B-}'I BBIII {B( Gsss_D ssQE sg sRE ss@k @%Br |k a(((#-{ i@%@7|Kw.|@|KS*@|K-Y'@|KV@|KV@*@ GsTETiX bD *s*/a9 T^]TQwOrD *D T]sT0 10 GsBXE]D}B rB*>9:BX9:$]DE*y-v-W B-MB-bwt*w.pt*t }]Dt GsaCUE\Y oo  r\*(v!3_\ -ug\ 6_6w}*6_6\ 6} uw.\*9:9:$b Uwb *rb ~\b b\b b Sc.\a  pp9V Teleport failed for 9V\(9:9:$"|?6_%.\a+_.\ y_.\ I_|"aw.\ *.\ Z .\[.\Y\f('\a  u!3(-u\a+_u!3-cD\ ^Do-u9:\!9:$6g%c99gf\ c\ \ fcf99\ -bD6\ -aD6\ -`D6\ ' GspCYED 8*-Z-v-B-W -v GsoCnEB 26*-Z-v-B-W -v Gs_ssZD~s~~s\E~sss@sg s^WEaE~8-{ -{ 5-{ /a3 @4e@10 GsbEss@ssd @~_EsA`En31k-{  rn* hn-KnF(H nH nH  GsZsj!dEKez|~k /%~k #%9:9:$w.K*.Kl#..K k y/a0 |j|9Wjwk  wjw ]jw w ,10w w yww ]*8Ka/!^Kf('w ] Y Kyw.K*/Q.K GseEZsgEZshEZsiEZsBfES}r-{ "w.|&S @h*,|9W&S @hwk 6 6S  6S6Z S  6ZZASAeSrD *irD **iws*Cs  S  D   S  sD  GsjEZsZss@@GB%t!s/a0 tt((10wt*B t  6Bt66BBtAt*-Z-v-B-W -v@ GssssE$*+ *C   " " " " Gd"s@ '%' {'&...&&#''''& sANspEssDf~u@]#rL *r~ *(9:~!9:$~}9?%~ Z @ ~  ~}(or~3L aw.f~[*$r.f~[ML ~p~['qq~(~ ]9P ~  ~ {L 'XTUXwT*AwT*rTmL TS~ Tp~ ]9P ~  ~ {L 'TTS( GssEssTssuEssMHE$*+ *-   " " " " Gd"s@ s_Is{EIs{lv [l{M9:d9:$ r*SceneManager : Affected actor is NULL!_Dm-z(-t( Gs^}EAFk-z'-t(v! Gs@xE%B2)B!s/a9 pSB((10@ GsBETD}" rM*KMa!IHM-g wS*S||9:MX9:$TDE* GsYFssssD@FRu8 rR3M(a M  UDa*M}M-CsRR {M'( Gs|EIsssmCFQsPa.k Q[2rQ *(wa*9:aA,Q pa9:M59:aA'w.k Q R*Qp.k Q R qqQN Q  6NCN6 66Q  Q6 B@6 66Q  Q69? CVD'M-gQY}Q'( GsDFIsassGFIsIFIs@{sPFDGs^NF V $ G sOFssssm MFQF@ V $  G sRFssssLFTFF-G@s^UF(69:r9:$ V $339:r9:$V $  G sVFssssvssWFSD}  SD  GsssqsV< 7F% GsZFF\CHCwF*c%Cc7F9rcFF'c( Gs]F s;s^F ss_Fsst s;sD]$QPMw *49:S& `?!i/M `?!m/ G sEbFP0@ GscFssdFssss~EK V.wt*%9:d9:$tK UwK *lK a/!ntK y.twy*y #y +#.tC~!s/a9 pG~10wG*G xy.t-m'.tL.tn-u -\DK K S9tL/ZD*V.* GsgFdRDshFssiFssjFsskFsslFssmFdsnFdsRDdscss@%%.&)"3+ 4, 5-:2<4>6?7@8A:D<E=G?IA JB"H@"LD$NF'LE,MG%PH&PH'SK(RJ*SK*TL.SL,VN.XP0VN0ZR3]U4^V:ZS9ZT?ZU7aY8bZ:bZ:d\=e^g_8i_?iax@XSAZU@_YF_[Cf_AkcBiaAmeCmeDmeDnfFogHkdKjdApgAqhBqhCsiCrjDskDtkFvlGwnIrjKslIumHwoJtlJunLvnIypJzqJ{rNxpM}tNwQd`RjeXifXlhXok^lj^pmPyqPzrRzrR|tW{tT~v^vqboljjjbtpevsezujsqkusmtsnutj~zpppptsqxvsxxwzzyzzy||x}~~OwPyQzR{S{VxT|U}VXzY}Z|\~_g}i|n~WYY[^\]^`ce`bikeghjknklpqult{z}swz{~}~VVþĿ»s@%%.&)"3+ 4, 5-:2<4>6?7! @8A:D<G?IA JB"H@"LD$NF'LE,MG&PH)RJ*TL+VN.SL,VN.XP0VN0ZR3]U4^V:ZS9ZT?ZU7aY8bZ:bZ8d[:d\=e^g_8i_?ia>jbxIII@XSAZU@_YB_YF_[WWWCf_AkcBiaCmeFh`DmeDnfFogHkdKjdNmgApgAqhBqhCsiCrjDskFsjDtkFvlGwnIrjKslIumHwoJtlJunLvnIypJzqJ{rNxpM}tNwQd`RjeXifXmi^lj^pmPyqR|tW{tT~v^vqYxrbolbtpevsezud|wjsqkusmtsnutptsqxvsxxy||~~OwPyQzR{S{VxT|U}VXzZ|\~_n~WYY[^\]^`ce`bikeghjknkl|pult{z}swz{~}~%$+ %+-2-?UþĿ»s[FKmP\W{KJ%WJ7FMzJFC(KJFJ* GsiW(sRQDs)QD Gsss@{  1 )   )) 1  9 ) 1 ) )1 9 J9 ))1))))Z9)1)1) 9)A)9))1 11J)91J)11)9111191)J119)J199s b)99)J9Z1999J9Z1J9 A99b19A1JAs1AAAJA)ZAJAAbAZA1JJZA)bAJJ1bA)sAJJAbJ1JJJsARJAJRAAbRsJRRRbR)ZRA1AsRbRAsR jR9RZZJAZZZRRsZ)R)bb9sb RbbRbbbbsb9jbRAZb)bsj9b9jjZZjjjjZsjjjAj1jsssZZssjj1s1ssssJ{sjsZsJsjssZj {{js1ssJ{{{sAZjs1s1jZss)9A{RŃs̓Js)sRŔ sՔRŔRŜZJs՜Jͬ)ZAެ)ͬb Zʹ޴j)9Žsb9JŬjŔ)ՃsՋսJsfJCR#efCM@CapAssociatedActor 9VR(@MC)@@ GsJseUV$* />*'   " " " " Gd"s#@OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO s@   !""#%$$&%")(#/.%((%,+'/-(***+*,/..10,53/><1657886;;8889<;<>=7JH=BA?HG;OM?QO@BAAEDDFFCIHGMLHHHCPN@USE]ZKUTQRQRWVVVVUXXWYX^_^ApgAqhBqhCsiCrjDskDtkFvlGwnHwoIypJzqJ{rM}tNwRmk[mkTpmXqncdccgghihklkmnmazwl~}pqppuuuvuyzy|}|OwPyQzR{S{T|U}VWYY[\]^j`bneghjkklp{}szpsvv|lwty|sw{{|z{}~þĿsxFAGz <=G`sAOD3-_R 3OD GseFH.-t(9:d9:$w.t*Lwy*.t dy.t-m(.t-C(.tn-u (t_ u!/[D*H.* GsR}FND`2R `ND GsB^sFN'9 /a3 N3N10 G{F$*npe*   " " " " Gd"s@¿=ڶ=."8Y=N5*1R=T L()<[?'+{4 "7Y@3kV!;[YBY-  $MzȄ,-D[96UÄOWEP%  0wvzZGS2&yU I   J"}~݄~|~ KеՄᄊ戊 ]ɄՄ̈́Մn_ acd/#Xxxfxx/x:x:hQx::xٺjQ:x/:::l:x:xXxx#x#m:xoQ#xXxxXp//Qx:rt>>>=>ACDFHIJ\^`bcegilmoqrsu sDGxsEGxs@xFGsssJFIsj!MGLDe;|_.LD`r_*9:_!9:$w.eLD*w_[* w.g_ *_ RL_ qL9:_!9:$_ Z @_~"LA-9:_!9:$_o$_ ED_ +#yws*_as GsOGKD6]; KD!c GsKG8sH 8sWG"MDsAUJ30f?r.J*9:J!9:$w.eJ* H JH JH  GsQ8sQGIDtVP 6ppppThe Server has determined that your client is illegal and you have been removed! Code: 9SID [JD]$aa Gsa4J #tapp%E,&E GsVGPGuL1 GUG$*n*ƽ   " " " " Gd"s@ sGD8ssPs@B{{seGWj9dMaW%EV&ETvWVTaHD(q!u GsZG"sMssBD8slG"s@ss[Gss^G]s_G]s`G]saG]sbGscGs|ss(soG\G~-'a(q!s G sDmGIuH%rI *(MU I fIy6Im {6MnMp(mI( GsssADiGq.`  GssshGkGZ.a  GsssnG"swGtm7+t-B(t Rt  g t-R#'-ft t  b tM t t  b tM t +#to$t Ft~"A GsrG"sp~Cv(w~CC@D GsXx}Cq r}C|(-D|a /a3 `ts`-[`-K2|`-`'10-`|a GsPssc"s^pGtGU_\H 9?%-D-D\-D?r|*|a |/a3 v[|v10 GsuGssvssAsGL3uALrL* J9:L9:$L-Ip-DDw.L*rL$*LE ? G-CD|#9:L!9:$L |GGrL3*La/!O 9:L!9:$Lo$L |J-DpL-A3La JL-[L-K2|LrL* J9:9:$r|*|a |JJw.L*/a3 \,+w\L\-[-_',10J-_| a?'r-MLop L G s]C`Hrq)9:r!9:$,d2w.er*PU |Cry6rm {6PnPp,d GsvGgp %HwQ*gaQ$gT$Hwg *b?"wS*9:9:$Ug  g6#L?gA9?%Tg 6TT9?,dUUTAaS U"@ GsMH"sayCw#)yC)zC){C GsssRxGb` `+(-Mbosb G sbCs{Gs|GxCs,wR*xCaR$xCT$ws*9:9:$as xC  xC6#L?"@ GsHss}Gssss~Gc|vB^?.cH 9?%\6ah-s9:c!9:$ c,-9DH ^* #Pw*w * E ??w*!9??Gi?9DGi9D9??^H  GsMsAHsssCHsDHsGH^s\^sssEHsHHsssIHsJHswC^saH"sssDFH{ %<DF99\9-wC6F9?%u#?{ fw{ *y fwy *wy { My   {   Mu9?%M9?uMy y xf{ { xPuu9u#?9?%u9? GsKH@sNHsssPH@sQHsOHgJ 2C /a3 NKJwNgN-r N-|0'10wo*ro *o-r o-| r.Zo R*)w.Zo Rao*wo* wog GsssNssRH@sTHsZSHeO GZe!eS  Qe 6Q%99QFfff?;w.ge * w.Ze R*epe-@we *a w'e G sVHssss]WHx P X wx V ]x x V*x XWrx oo*J x jUwj*j-a w.ZjR* r.ZjRaj-a (oj jjS{ G sXHsYHs[HssADZHr Z p w9:r !9:$9:r !9:$ r -@r.r *r.r  * a w'r  G s\HssjA |p9V destroyed! ( GstHqU J rq*%H%EH,;rHsCqHH% GsbH"sBI"sdH seH sfH FsX@ ssTBsiH srC ssCsslH smH snH soH spH sqH srH ssH so sfss^HsgHsuHssvHsss.swHssyHsszHsss.sssss@I smC s~Hss_I"sDI s~ s s{Hs}HsssIIslsvCKIy0M G sss@MIhVw vC G sNIssOIss@ssLIkCx0[$kC-~uC!tC G sss@ssPITIt c8 a&wj*j5Cw4g-jCUwF*FdCO"{wh*hCO" G sUIssVIssCssFIsGIsQIsssFsSI[Iu |1f+ a&wk*k(*cM-iCHwnC*nCJ*cawi*ic* G s\Iss]Iss^IssiCssMJ"ssWsZIbIv X5 a07G%7GG2*US7J%7JJU* G ss.saIor0"pomCpo G s@sbCspssWIsdIscIhIq0q G siIs}sssgIkIp0 G s@ssfI ssqnI^  GsssmIpIw  GssslIIsqIIsssrIIsspBstI@IuIsvI I`BsyIsszIssgCsssIss{IsswIIsss@JssAJssBJssCJssDJssxss}IIsGJsscCss~IssEJIsIJIs@s`Cs@sKJsfJ"sssZ ssNJsss_CsPJ@sQJsssssTJssUJssXJs&sYJss{ssHssVJss]Jss^Jssuss[Jssh@ss_JssSJsUsmJs^CssbJssTK"sBssOsscJJsiJJsjJJsrsskJJ_BsmJJsnJJsoJJshJssNssrJsspJJsvJsswJssasstJJsxJJs 503szJWC\0L)WC)VC)UC G ssJss|Jss}Jss{JTCY0)TC)SC)RC)QC)Q( G s~Jss@KssAKssBKssyJJsJX04 G sEKPCX)PC GsCKssssFKOCW0)OC GsGKSsssIKNCQ0 )NC GsJKSsssLKMCO0j )MC)LC GsMKSsPKSsssOKKCM0)KC)JC)IC GsUK"s_K"sO ssssSKHCJ0G )HC)FC GsVK ssGC ssssXK]KH0  G ss&s\KECG0 )EC)DC G smK"s\ssss^KCCF0!)CC G s`Ks&sssbKBCD0!)BC GscKs&ssseKACC0$#)AC GsfKs&ssshKB0# G skK@CA0$)@C GsvK"sss@0$ GsoK/$ GspKB~/%)B)~B)}B)|B){B Gs]ssrKsssKSstKSsK"sssqKzB|/%)zB)yB)xB)wB G_$*h*   " " " " Gd"s.@ӂVr'N;e''>N3VVVȷIvVVjήvȷvvм/jƦecƮ/qϱ*~}L}}'v*Ie}g}} i컡tjR }_}HRR  i$* *   " " " " Gd"s2@LJKJEHKMMPPU6LIGJKKKJFIPSKIIJHDGGEBGLOPMKJJIGEGFHFILLLMJJIHGGHFHHJLKLMKIIIGHHGHHKMKLOMKIIHHHFFHKKILOLJHIHGHFFIJIHLROMJJIHIKJKLJKPQOMMKKKKKLJJMQOMNLKLLKKJLQQMMMKLLJJHMNLJLKJGIKOINQPJL ssUsuK@s{KsssxKvB{/H&)vB Gsf"sss~Kz/& GsALX' GsBP/' GsAFLj3-fcw.j*5{e.j 6ecw.g.j *c.j GsuBsB (1.-cCasBa9?9Da%9Dv GsJ;ftBc/QtB GsELHLu/_)3w*F av GsssDKJsILJsJLJsKLJsZ yNL|(/'w*H.9V Gs@ssssssOLssHSL@ N1( GsssRLoBBW2a+Z66N66No66Z6N6Z6Nw*6Z%a+Za oB G;s^iBQL @-c-c''-lB{!db}!iBjB-c(fb%m:bdWARNING: invalid song handle Gs ssTLJIm4?a+J<w*6J%6J%a+J G;sVLfsWLnBDx574w*jnBmBq!\ G;s[L"sd"sYL]LD/Y7 Gs^Lss_Lss`Ls.saLssbLssss\LdLL|7 Gs@ssYM@ssLsXLfsfhLA : GsssfLss^vLhfrh*h|%c|7v Yw|v *|v hgB| GsiLfs{A$< GskLfsoLs(sssOqL.= GsrLs(sssssuLssss=v {% J{%G{7v =w{v *{v #{ GsxLssyLssssG{LF/> Gs|LsssszL~L@#? GsLsss%s}L~"1? Gs@M{"L? GsLCMC ? GsssBMOD H@1.wO* wOA O9?bB GsmLf]BsbBs_$*+QA*   " " " " Gd"s@@Ic>v>$V/Ӧ>$>$ڀ>$cҘN$u' ΦS<Ęҋ/,S$v6z+jSccSSI>NcjcjjvSSccjvIIIISIIII>>?>SSSSII>cĮcS/'>>/ScjjS3)'  '   '    !''   '% !'''%'.  "%)=J)2)=JMa   u sIMs sssDMF@ GsJMLME A Gss(sEMfsMMfsNMfsJ@SD4 r@*(I@Rd GsOMfsssssQMfsTMfsBWMJ';G' GsXMs&sss[M"O(sD ss\M"shM"sss^BG VJ&w*-`'q!s Gs^MH ]K q!s G;s~NaMNlL G ss sXBjMl`$kliBliQ!s/a0 mkhgkjQk@ll 10 GsssCeM]qM$ GsfMssssdM\B_/M"I \B[BZBYB GsiM"slM"sLBe3 GBeiQ!s/a0 mmhgmjQmee 10{X e 6X -a( GsYBssHN"srEI Oj-rW* r.g*u_L oUgwo*w.o*roEjroWPrc*1c.oEoPEWLBrW*9:9:$VB!A-q (rE`o`rc*1c.oEoPEWLBPPL!B #rW*rWooJ LBooSA GBxssss ssM@ss@ ##iijjsoMsstM@ss{@ssrMsswMssxMssyMssssUB{MJ T Gs|Mss}MsssszMM[/U( Gs@NssANssss~MCNZ/U( GsDNssssBN} Y/vW.6B 6x9?,@fx6f6B xfB } xxB @ m fB } } y@ 6y6@ 6@ 6x6B yx @ m xB } } %-RB} @ +@  GE$*650*   " " " " Gd"s6R@򣣣򣣣k(k򣣣HOH򣣣k(Hk򣣣Hkk((H򣣣H HkkO(HR""򣣣k((kO&&"򣣣k(H"(H" . 򣣣"" & "k &'""" """.,  & """."" ,&"# "" 'm"&#"" .""&{. && '' &"" "&# ' ,"'&""' ".'.'&m" . .""".. , .{{"""&'m""' , &%#{ " && """'& .'' "" {.""".#&"". ",.&'{"" .&''"򣣙. .&.'" &.' 򣣣" ""mm."򣣣"""""""" """򣣣""" snMssON"sHTNSB-J -J9:@9:$9?SB] wp*}y9?%i"vy v"/Qp{X p 6X -a(w.gp *rp \Jp ] GsfssssKN@ssw LNT'i' G(sUN @sRNsQNs&ssUssss%saLBr4:.P-r(/a3 q:9Bq-r'3q10M-raC( GshN @s[Nss%sNBjN &Z r* bj m%]m,SrmA*mAj m#m%m,  mA    j  mAj md GspMh  Gv $*}*Z   " " " " Gd"sY@nnnnnnnnnn sWNMBq [MB w GsssssLO\ Gs]N_NL/ \ Gs`Nssss^NbNN/ ] GsssaNdNI/ _] GssscNM/ ] GsSssssAP @sLOsjNsskNsslNssmNssnNssssJBpN|^r~IB~* GsqNssIBssHOQBwSBrQ-J(@ Q$w.Q*.Ql $w.Q*..QE.QJ  $w.Q*.QE $w.Q*.QS 8$aQZ)aZ e.SE ?$' q$w.ZQ*.ZQS]  GsssuNsssssNssxNssssGBzNQ }_ Gs{NssssyN]_-w*cdF$G$ Gs|N~NR '&`9<~NGf GsNs sss}NAOS ,v`  GsBOs sss^vN~ -J( GsFOssGOssssTOCO_.G@sJOssKOssssssbssDBT vh N G;sNOBB~.~Mipwp*G7G UapBBr*,. pew. p,. pK pp G;sMOsv $**   " " " " Gd"s!e@ s^PO)-b-J-J'&-bu  GsOO@BV kBz@B q@B ?wq*N q GBxsoORO].G@sq@sszA@ssUXOz.l' GsYOssssssszAsZOss~Ac#m Gs]OHv.n4YCHZCH  XCKK GsVO@1[OsP.s^ObOu.n( GsssaOdOt.n( GseOsssscOmaVog&|m%A9S9DaAdrenaline^w* |m%S9S9Dy5Shieldm Gs`O ss@ss^\O!-J-J-Ju  Gs[ kO_p GsssRjOmO\p969:9:$p9V Pawndied while dead GsssgOPs|OiO\.G@s[ qO_q GsssHpOsO-!r GstOssuOssvOsswOsss sEBrOyO 1r GszOss{OssssLP\ Gv $*H6*   " " " " Gd"sn@汩};+zՖq,Lggdz z[[pȠ,}R#^Ȉz#N;Ȉr;,rr#^/r߽ѶʽӽZP8("   (""-7(CCTC88"--A=<-""ͦv8<--$""Į 3-/"F>$ Ħ  -$jvޘc"ҦĀ('v޸jf v ""jSҀj/Ҁvj"c/cjvjIS $jf">/cSj/jc Scv/c  jccc$Ivvc/$Ztfltt~ʓ s@ ///000222444555999BBBHHHIIIJJJKKKMMMQQQRRRSSSWWWZZZbbbVUUZYYgffihhlkkrqqxww|{{~}}RQQ766?>>,++'&& QON631_ZVYXWedc<;:765321.-,*)("! |xYVSB?<FB>wsnURN962db_KIF?=:42/*(%qnikhc6530/-%$"da[;95GE@ONK-,(VVUYYX[[Z\\[^^]__^aa`llknnmoonssrttsxxwyyx{{z||{}}|~~}~OONTTSUUTkkivvt--, ~O$*@@@   " "" "Gd"s5@:8%[bYrxqmVg[s~{6KMHK:8~_Iΐ@tw^׋WPOPOMKPSSTTTSSTTSSRRQMƖ:^^gZOPRTS˱蝠KSSRRN¿PXVPSUN$韣JSSROʿMMMWXPPRSQ蝡QSRRK¿vKPUOPRUQ젢젠򯰱=RRR9yGSSTK78]c_RQSJ汹OSSP7t,d\URSPh9QSSRñ78XPRRɬ"NSRT˴86bfQRRNu9:MTSTK5ubSQS)RRSO8 Yc=QRRȭm8{SRSRȶ(6v63杝XPRRͮ 𥶴RRTJtx88v3M\PRR8v2LSRTO¸PRS<ߥRRSRɹ2^SPSSǬ-8:wÊSRSLľ`_SQRP!*"LRRSOċcXPRSLA8;nPSSSYc[RPSRG󭮲bgdXOQSRI,JKĊSRSTRWRPRTSM678:LKRTSRSSSRSTRQSST<Ʊ-JIHPTSRSSRRRTSOQSSSP̷x7{=ꧫLQTSRRSSRRSSTS<˹*!IHȮ!JOTSSRSSRRRSTTOH/v:|PŠ墪 NQSTTTTRHĹ!蝠,IHGG멧KPSTTTTSPKȽxBv`z|SSSSSSSRRRRQRKIHGjƊZI4*^`z|SSSSSRRRQQPPOOOO|SSRS>ZZYYYYXWWWVVVVTPPЊNNNMKɴHMMJFGZ>^4MVWZY4|SRRSMYSRQPPO0iQlSqW~avwxw|{|A2D4J9tVB^HnTuZz^ŗŘ˜˛͝ѡҡԤץצئإݪުdgjnpsuw}ŗ˜͝ѡҡԣצץئإ۩ܩݪު߬0%;-`JeNrX*!ΠԤ  bbbGP$*fx}   " "" "Gd"s@-0479:;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<======:962.+*-16:>?@ABBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBCCCA?>94/+')-06:>?@BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCA?>83.,(#$(,07=?ACDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDEEDD@>94.+'% "(,07;>?@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@?>93.&"""(*+% $'!!# "           "  " # # "% # "#& #!"$' #!"$'" #!"$'  #!"$'L  #!"$' #!"$' #!"$'* #!"$' #!"$'܃ #!"$' ق #!"$'ɍ  #!"$'ϿkO #!"$'*̮̮̮̽K #!"$'ʪ||ʪ] #!"$''X #!"$'k{{ #!"$' Lzzz #!"$' NbN N #!"$' #!"$'jjM #!"$'qqqqqqqqrrqqrqqqrqrqrM #!"$''`nnnnnnnnnnnnnn` nnnnnnni " #!"$'llllllllllllllllllllllli " #!"$'ggggggggggggggggJgggghggL #!"$' bZZZeZZZeZZZZZZZZbKKKKKZeZZZZZbKKKKK #!"$'*N`V`V``uX```V``X`V`V`aI````V`aV``IIa #!"$'WUUUUUUQWUUUUUUOUUUUUaUUUUUUUaUUUUU\ #!"$'jSSSSSSMSSSSSSPSSSSS\SSSSSSS\SSSSS\ #!"$'PSSSSSSz\SSSSSSRSSSSS\SSSSSSS\SSSSS\ #!"$'SSSSSSSz\SSSSSSSSSSSS\SSSSSSS\SSSSS\ #!"$' #!"$' #!"$' #!"$' #!"$' #!"$' #!"$' #!"$' #!"$' #!"$' #!"$' #!"$''  #!"$'' #!"$'' #!"$'' #!"$'   #!"$' "  " #!"$' " #!"$'  #!"$'aʼaa  #!"$'aN  #!"$'݅  #!"$'¢ں٢ڄ  #!"$'׷ֶַ׶׹\  #!"$'ӲеСGѲOҵѴѴѲ}Ѵв}  #!"$'OͯͯOͰͯuͯΰͯͯίOͯί;ᯰͯ " #!"$'ˬˬˬˬˬ˟ˬˬˬˬˬˬKˬˬ " #!"$'G|ʪtJK||  #!"$'GX  #!"$'iJ{  #!"$'uƗƘƗƘƗƗߗƘuƗƘu  #!"$'LĒLēztt  #!"$'qbNNNNNHNss  #!"$'xxyx  #!"$'wwwwkkwwwwwwwwkk  #!"$'vvMvvvvvvvvvvvvvvvvvvMvvvvvvvv #!"$'soopo~pzopoppoo~pp~oopop~z~oo~~oppoop~o~~pop~poioo~o~~oppoop #!"$'mmmmmmi_mmmmmmiummmmmm\emmmmm\mmmmmmmmmmmmmmmmmmmmmimmmmmm}mmmmmm #!"$'lllllllllllllll]lllllltlllllllllllllllllllllllllllllllljlllllllj #!"$' ughghhhhghghhhP^hhghhghghghhLhghhghggghhghghgghhghhhgghhhhOJggggghgh| #!"$'"t[ee[efeffeeH`ef[fffe[[[zee[[e[[f[eefff[eeefefkff[eff`kff[[eef #!"$'NYddcdccc|NGscdccdcd}acccccccdcdccccddddddcddcdTH]uddcdcu #!"$'%GiXXXiGaXXXNH_______GXXN #!"$'%TUTTTUT #!"$'*"SSSSSSS  #!"$'**" "*' )\\\\\\\ ' #!"$' #!"$' #!"$' #!"$' #!"$' #!"$' #!"$' #!"$' $"#%( $"$'* %$&(+''(,-(*,.1+-.37-/49;.69>?@A?>;9877666666666666666666666666666666666666666666666666666666666666666666666666666666666666530-+'"2;?BEFE@>;8877666666666666666666666666666666666666666666666666666666666666666666666666666666666666531.,(#5?CFEA><87544444444444444444444444444444444444444444444444444444444444444444444444444444444444444321.-&"7AFFD?>:86444333333333333333333333333333333333333333333333333333333333333333333333333333333333333321/-,)&".9===:864211000000000000000000000000000000000000000000000000000000000000000000000000000000000000000//.-,+)'$"%*         s@  &'(+ ./2 5 6 7 7 8 8 : : ; < ? @ @ @ A B BF F GIJ JJKKLGOSTSTUWYYZ\]^_aacbfddfghkkklonomoqqrupquuwwyxz{~|! !"!""!""#!""%$!"%&$&#$%%$$&%&'((%&'&&'&''))()*()(*()()*')()**+((*+*,,)*+*,++,/-,-.,//,./01..//.//01001010122011231232323234443334334IP$*U>   " " " " Gd"s"@ 2_Ǻ_2 XٚQIŢڞ@ ow3:wf]^ *1pVzuS(fJNכB(>).}ܸy{r5X]}[&&dmjJU?D?/w7R_3Z\L;iJKMx&H54h a{꽽{㧽䎌x!WG,n b_:Vc>6lEKM/DTGDT8#|X^se+0j`t>1q޾`@ I%BΓ8-5h$PpkC-[ 1=~g#u~ fډ<F[@ֳч5OȀA YvbM sOssXPau  /a3 a3a10 GsssAsWP sssA@},MPsusPPusUssQPusSPus`ssvAssYP ssBcPR}i- -r *@9:@9:$Rl*h9:@9:$RE*-JrU *irU **wn*Cn  R  U   R  nU (9:@9:$&Ri'RdBR/a3 `a`r`R3R10 GsoP ssTPusZPu_$*6\L*   " " " " Gd"s@汩};+zՖq,Lggdz z[[pȠ,}R#^Ȉz#N;Ȉr;,rr#^r߽ѶʽӽZP8("   ("-87(!.AC{{tk]TC88" "!8:PZTAA=<-$"" !-8:TF8v>$V/Ӧ>$>$ڀ>$cҘN$u' ΦS<Ęҋ/,S$v6z+jSccSSI>NcjcjjvSSccjvIIIISIIII>>?>SSSSII>cĮcS/'>>/ScjjS3)'  '    '        !''      '%    !''   '%'.   "%)=J)2   )=JMa   u ss sEQckpc!s /a9 ac@a@bAcA10LKwL*L-K2LwcL@bAcALL]U GssEsssCQss^f/f!s /a9 ef@e_A`A10TKwT*T-K2TwfT_A`ATT]U G sGQssHQssm ss^KQDQ&j -UA' GsWssLQ]Al" %/Q]A-VA' Gs=WQ%N=ZA9?YAI@9?,KY!s/a0 XAYJJ10 GsNQssOQssPQssQQssRQssgss[QbU uW b  C6W6b6(6WWAbA GsAuP\3{EA\.r\*\-X$ e \  [e f\G\A6e 6 wf* Le (-hBaf e 9P\ af e  GsUAss\ssUQiskM~-F/aA MABAwqM.gM C 10 GsAFP3 cFCw.P*wq.P.P N  Gs ssfSAS L\ SA*6\6(6\\A GsZQzs@ss`Q]Q}k .9V GsssaQ_Q~B Gso Gs@ssbQsseQs sf sscQssfQss\QzshQzsF@ss@B{{kQ$*k*   " " " " Gd"s;&@ siQzsoQ@DsspQ@DsswsVsmQzo(sss@suQs@ss|Q'Ԁ a( Gs~@}QXp ]X3o$a*XZ-M>6N9?6N9?6N9? Gs}@Wo >#-A'W3o$a*W GsP@ss~@{Qv-Gs^DRvc|c-gB9:5&9:59:Z &@9?V59=@x5c59:59:Z 5$Vx5c Gsss=_{(+-]3'!u!squ(q!m- G sARss^CR]k|x$cq!a  Gs^R@R` {L~G@sGR'S{-M(-b( Gs^]RvJX{$!9:5%x$cq!`  GsssDu@I p"5 xu@v@w@x@y@ GsHRssLR@ssMRssNRssssPREsQREsRREsHEsTREsUREsWR@sVRs@st@sXR s^sr s^ssa(s~YRd [. Gss sss^JR?zRB9:Z ,LeadInOutLooper detected with <3 movement keys x$c GsgRFRa W|G@slRr@GN )r@)s@ G(4sssbR')y-M(-b( Gs^vwc-gB9:5%9:59:Z &@9?V59=@x5cx9C9<9=9:5&9<Z c9:5%V Gs@ssC eR}-C Gs@ssc3dRo@VC )o@)C GsmRaRb -4y9x$ca-q!b !Z Z rsG s@ssfRjR|-D GsssiRz- Hwi*ai$9<XC(Z9<UB Gsvm@WD)m@)l@)j@ G s{:pR|@s-h( *q!n !P Gsz:qRLs -h' GsTi ipq$9:X9:$r.i * Q9:X9:$.i E |9:X9:$i s9?,  8ii Wi  .i   {q!n !W GsssHoRn s-kv!-g(v!i<X9?%-b'aXXa-d[-kq!kfe-hUa-MNp(u!i PeWsGs@ssS h@w-E)h@ Gs~R')e ^% GsuRxR\-#F Gs@sswRg@k&eF)g@ G vsssyRf@PF)f@ G @szRssJe@Z-G)e@ G sm AS|R@d6^3^%^%W* *q!m !P Gsss}Rb@G'?H )b@)a@)`@)]@)Z@)Y@ G@ s^zc@0d,^Wc@ d@q!m !W GstvRm ,e-kv!-g(5X9?%-b'aXXa-aK>Ua-amNp(n-kq!@fwW* !W PFWsGsDS'` ^% Gsm ES^@@^X^U^%^%W^@ _@IwW*WLq!D!P Gs^s[@]Q^W[@ \@7wW*WLN-Mq!D!W GsISCSD3`-g(%X9?%-b'aX6-MXa-dYwW*W|i-kq!sey-MUa-MNp( PjWsGs^pW@ZpWW@ X@0wW*WLa9:5%9:59:q!F!Wmq!F!P Gs[SHSF[-g(%X9?%-b'aXXa-dNwW*W|Ua-MNp( POWsG@hs~AIz _U  GsuBq~ _-~'*q!U  GsKSW o`85rn*9:9:$n z@ GsLSg `r{* w*w*wX*rX`&*AdminClass is None{ X`& GsaBMSF T0b(FF x# F  GsZSU@GL2 )U@)V@ G&4sNST@V bb'rT@*w#a |v`_-qw#T@vT@_-qT@Cq( GvsWS'aW-M(-b( Gsyh ena @ GsHRSA#eA.e+wA*Ab'Aw*\HvV k,(-<(W"9?,{-jq!oq!b GsG J7hZ9wc*G cVcacG WwJ*JaJ* Gsss^XSv]V Gsm YSQ@@S-V3v!@u!WQ@ R@q!G!F  Gs^lN@ATjv!u!@WN@ O@>wW*WL-M'ak$U_q!G!Z GshSM@yK )M@)P@ G%4seSQSGeCWqa-x9C9<9=9:5&9<Z cq!G!Za-dkQ -M( F 3ZsGXsTSM%JbjC b Gs\SK@j RkqK@J@ Gvs^_SP5S u! GsZbSO0S v! Gs]SHWTkfa!sj !s!rc<a!Tpj !Tp!rcUw*U c-k(l G@s`SvU fl6 rv* vv s Gvs^jH@'R?WH@ I@0wW*WLq!c !W GsCaSdSi xm wN D@D +mN D9?%9D9?9?@wD9D9?@9?@wD Gswss[nS^Sc 7TG@s^gSPR u!i GsZjSOQ v!i GsxSE@jG9)E@)F@)G@)L@ GAsfBcSydn-j z,yi y-~(QJw.e*w.eN*-~.eN-J#-~-J#H kK -]K GsTXi"P$9:X9:$r.X* Q9:X9:$.XE |9:X9:$Xs9?,  8iXW* .X  {q!e !W Gsf@CriXw*a   t$JXr#v*q!o GskSL-otwn*na  GsRlSO \tXwO  }3w*t$Jr#-<'RO  Gs[SfSe RGslzk vwn*na,rz*n*nazrn*pPlayerController::ClientSetHUD(): Could not spawn a HUD of class 9Vz!on R?{D){D)NoneiaD)$ Gvs^qSPO u!g GsZsSOKO v!g GsoS}?Mry&#-Sw.>*b6}? GsE;zS~?gN(S~? W*q!I!W GsrSP R'z&#-Sw.>*b7P  GsHstSQ l z&#-Sw.>*b7Q  GsPss@T{?hB){?)|?)@@)A@)B@ G8sx?]s~SUS MP.U/9:X9:$ rP*(W9:X9:$PE(9:X9:$Us9?, (/uP' GsYssss~v?t |T =v?@?^ #w*a-<i V|ui_@6i GD^ i FD_ ?T F6m ~6m _ @m 6m #???6j~6j_ 6^ 6j~6j_ 6^ 6j~6j_ 6^  Gss?{Sb 'L<Y%7Y7$-SY$'Y( Gs[hpSIOG sFTu?g<+)u?)w?)y?)z? G7sssp?]ss sCTssDTss_Tm?f6R)m?)n?)q?)t? G6sHTk?-yD-}9?k?X>lw.gZ *rZ qZ ] Zw.gZ *rZ \JZ ] Gsj ss|]sKTGm ; rG*(w.G*r.G *Ga/!cG,-'*G  # N(Ga/!TG-SrG$*Ga(Ga/!|Ga/!g/Ga/!| Ga(c{%G0-{ G  # Nj .G1wj *wj  *j Ev!siG1wj *wj  *wj 3rj  mj  G Crx*xg9:b9:$x\ '9:b9:$x] Ga/!^.G[ '9:b9:$G _ (9:b9:$( GsMT] 9-C(f"9?&U*d-w rx\9:59:q !Wdq !P~wz*z]  GsAZ \bp(9:9:$ r\* K_sZ HPuo_eH!ZuH!Rwn*nZ p}oHw>*w>Q *}wZ *\wZ `*\-v$#Z `}%}ppp,,&&\\Z `}&}ppp,,},,oppZ H: o>Q r`p}o@Z  GsA\ 9M-C(f"9?&U*q !sJwz*z\  Gs@sRAs=STa%U4GOu  Ku-c-^ -h/a9 %aw~}a-haq!saa*10-wx/a9 %awaa~ ~ axazzza10DDrx*/a9 %a<;waa~ ~ 0 10x GsLTP ~J GsL^?D-o9:]?9:wA A-\?"h9?& h"QA"m@=9<ufff>L>?N ^?'m$ GBs@sPAs{TTbv .0YKG!s/a0 nbGJ7}7}&7}&}b109:9:$9:9:$-Ca@'a?'9:9:$ u  O{59=9:5%,&c ~5a \9:5v a+a<V9:5wH~ !s~ wx*z* GsVTU|--M(-b(x9=%9:5&cb?a`>$9<XC(Z9<UBkQ U_/f> wz*zU Gs[?N }XJ?+-Z?JX?@Uw#*#a[?W?J ( GBsWTXnf,-M'-b(x$cb?ak$9<XC(Z9<UBU_/h wz*zX GsXTd` +qa_>$9<XC(Z9<UB/Q /e> hwo *o B X  GsZT{ MFv(aa>$9<XC(Z9<UB/g> WwW*W|W* *wo *o D -g'X { xw{ *{ -g { { zkh  Gsq ss^fX ;k'rfUowf*Xwf*rfmfR ffS GsUTO?B-N O?-K? GvsxP?[-"@59=9:P?%,&9:5vQ?9:5wR? GsR ssB[TlAw{*{t b7w*k.ewk*[ kNkb'w[ *[ ?%[ u s&[   ?%u s&  wn*na w[*[aBw|*l|V|a|l {wc*lcVcaclBwr*rar*wK*KaB G scTV?b1%)V?)_?)`?)a?)b?)e?)j? G5saaT4l *#(-O -O ( 9:9:$ -CF%-O u  9?,a u u  a+O-O (u  -O '-O (-r OOu  u   Gs^AaLq!s-C'o$ Gs^T\ m BG? %$b@c@@ C$b@@c@@ a$b?c? $b@c@ {!c{\ }!\ bOA\ NAG?w>*w>Q *>Q ja\  GvsuTI?a- )I?)J? G3ssnsX@-Qsfff? GvseTn )Vrfff? GvsfT~,b -H( GvsgT}4`enEe-H(`e GvshT{#$de`eee GsiT^ {,`^ d^  GsnT@ssjTz, `ede GtslT_ [dfc_ B9:9:$-je_ ?*C`eb GvspT@ssZD?y,LC WD? GsrT@ssoTC?x,C VC? GsvT@ss@w,C$!w*w* Gs\D zԯ+D D ,(krD CsD  Gs|TE?`) )E?)F? G2sxT@ss`` R+` ` ,(kr` at`  Gsw@ssc|>K 1-]-|> GB3sf_syTUr,6A -]-U -]-UK -U GsPUA?_%E )A?)B? G1s{T{>H A'Lk{>Iw*w* Tk GB3szT_s}Ta THŶ\k9?a bNw*w* TkH k Gs~TssTao,R|aLeftkz=|aRightk?z]|aCenterkzz|aHiddenk@T9Dk GsO@ssQ@sssss>l,d7k9?,k?'k@T9Dk GsEUDnPreClientTravell  GsFUr>k,t-^-r> Gvsc ssGUq>r {^-\-<-<-q>qqG-<-\#Cq'~w.e*.e-M-q>b Gvs^ssVssKUssOU@MsRU@MsfUn>^!)n>)t>)z> G9so>s g"9?,  Gsc@Ms M{'sBUU~% Gss{'sTUY>_%)Y>)W>)V> GsssYT>u 0?NT>#S>-R>-L>-H>($G>D> GBsVUQ>AZ&)Q>)O>)N> Gsw2sZU2sss~2s]U2sssJ>=B.')=)}=)y= GsX2@>sWssbUss^eUcU6fJW%GW7L =wWL *WL W G sYgUK I'=xYK %uK 7L kwK L *kwK L F&*aK L F&K   GsmU{=\-){=)A>)C> G0sL D,! GspU ss si(ssshU sskU ssrUs=Z )s=)t= Gsss{ ssiU sslU ss{p=X<)p=)q=)r= GsqU sssU sstU ssUAs{Ul=V )l=)m=)n=)o= Gs@ssvUAsYAs}Uj=T i )j=)k= Gs@ss\V{S "){ G#szUAs~UAsYf=v e6Gz6G,z6G6G9?,6G%a+GTf=e=|-d= GB3s@s`sssE`=D')`= GsssFVss]ssssYJVDV@  G sa=ssEQVA?wN*Na6wd*ad  E GsLVslsssssCV\=E( )\=)[= G$sJ ss@ss^XVW=H ^D. 3rD*wD#(W=J  a#B@ \J @ -ne@ e,J #g%geJ g\gJ 9?e@ ,@ %-n(J a#Y=YwaL]=J (# A A A*L' GsDNVj(BH?paKpo@e_ GsjRVA)U*j GsYSVI*y Gs{@TVg e*w GsCO=`,_uw*A `JO=!l$M=L=K=J=6A6A6A GBspssZZVN=b rN*($-aN-Y'Na''-m(o%o7c -m(} aocwaS=T=} (*Na }-m'oF$-m -N=Could not place driver.N-Y(Na(((p. `ppCp dNp V N *NON-zN-z-aN +#FNo$Na**N*UW-} (- (' GsUV[Vy* G sW_VO`u O-<(O-W(On-aOn-aOn-q On-q On-n On-n @ %-n' GssstV^=N)^=)_=)b=)h=)i= G!sVVI=x Oxw*@ `JI=H=G=F=E=C=A=6@6@6@ GBsYV`Vw+ G s[aVUC WNUNa((N-Y(N-z(N #No$Na*^U U CNa^^dB .^wB *B V B q!LD B  GsssXcVF D GF n-a(F n-q (F n-n (F -<'F -W'F a+9Pa# GsgD=J+:\p JD=4w\*\H Gs]hVqj+7 Vq-T#rq * wN*q -X(qlq a!LC q'( Gs@ss]Vyy]= GsBEz Cw*29:!9:$ 9:!9:$ -\(k 9:a l 9:B-n -_Ec-k'wE*rJE w*J B(ETNcEVEV||E|bEcCEJE-H E-F E-xE-vEJE +"lw*E |&  E }& Ew3lwEw*Ew-l E a  Ew  EEV-k(B9=l a 9=k -_-n  GsDWE&u6^serverquit Gs`o;:Wp-v$-q pt$Lp` 9Vpx-O Gs_TWU; Gsssm9MWj Ia GsCssNWIWB GsssSW_<@1)_< Gs`<u Z !?u %u u ,6u 9D9?u ,,u  GsssssOWAHE )c VVYAAVwc*Qc]QJm TwQV*QkoQ22w*ro*okwo*fo +fJ2Q +fQ +f33s?oQ]QQQV[tQkoQw*ro*okwo*fo +fJQ +fQ +f33s?oQ]`<0r]* ]A'Am q -u(G]J] +]J\<wJ* w*9:!9:$&]JJJVm #9:JH9:$J-x]-x!J-H ]-H !J-F ]-F !J-v]-v9:JJ9:$9:]J9:$!J +m p}?Yfff?a J Fu J RwJU3a*JU `J @]JJJ] BrQJ6rcJcV||cc*{JV||J{w]*]V*Q]|bJ*w*o]JoA]{*rc*c]QV]rJ*T>h&' w\*7\M, FX94<Fܵ<@b9?>h&"nYh?FJ] n"wo*r C"oT9?`L=o +#???s Z9D6`,Z9D6`,Z9D6`,o-H s ,@o-vs , o-xs ,s 9:oJd9=9:9=6,,SwJ*FJ-x---B-t]-x--r*L L  bd]T] +9?, L]-H ]-F -B-]-v]Jd6,6,9Cr s J* GsZe)e Gs@ssXW^<~)^< G7s[W[<|)[< G6sssHWtV<6p?tUp`6l?t9V~9V.6i?t9V~9V.&6g?tR`6f?t\ 6x?t6r?t]\9Jf%,6Vt9S\76Ot%76d t% GssWZ<{)Z< Gsss_6u\WE# -S'-M GsXug@_puServerModeʚ9:9:$non-dedicateddedicated_puAdminNamepZ_puAdminEmailpX_puServerVersionzwX*X_puGamePasswordTrue_puGameStats9Twd*`Kr R ?_puGameSpeed9U9?9DR 9?,dB_puMaxSpectators9Sw>w^*^ gulWwl*l gunllLSx)wS*S guSSie%ye76Ouo|6ve6OuMutatorne0n&lWLwl*ml|e%-e76Ou#|6Se6Oum!|6ve6OuMutator-t'-e-tq76Ou76Ouq&6ve6OuMutator6Se6OumllL Gs^WW k ף;9?L9?L#<#???L> GBsqWI+{ L" GsJBmt b UCt W W t Y H<QF<#???v \ \ v YE<{D<#??? GsssrWpW}y (" G stWGsuWOq ! GswWN p \! GsHBoMA  [96wM* wM B<9?%~M GsxWk"o :! G s{Wh"n ! G svWw { [G-P-w Dw*-l-o-P G@sss~WzWKk ( Gsss@<~;@,1 ]ps~;};y; GsNW;lc ^ ;%O G sAXIZ 0!w * -dC ON  G sz;ssCX@X@K = z;% o{;v :wo*So$ Gsx;w;~+C _*'9:9:$Ww;$' GsLXrD  -Q3( G sBX}+O `]Zw*?%9:9:$6KAVSaveGame 9 GsDX|+\ a.+9:9:$W?load=9$( GsEXv;}f b3F$G$ }-v; G@ss sssFX{+p ~cPG-s4rQ*QDQ*Mrt Gsz@z+ dwn*-@n-t n-GXn-t n-t ({n-Gn-G(-@ Cf' Gspu;y+ g<P.z [u;9wP*Pw GsPXGXA V GsssMXssy T@ iwt{ T99wTT T9?#zC {TT  G@sSXNX`@ ( GsssQXs sUXRXj4 CU*q!\8-z-i(-l'E"o$-I5' G sssiYTX@. [ G sRTs+ bn0r*r* rT* w*rTr,*k  w,*,-R  n wn *rn T,. n ,E6p,t ,B#,* K C!C! n n  Gs`X|' 2-l9:9:$E ?;a@A(o$-~'w *x -X \ a|%|7$w|$*|$`u| GslW]r iRv9:W9:$/a9 ]rq]-W%]-u]-r]a109:W9:$/a9 ]]-u]-r]a10/a0 mLLB10 GsXXP\UzP&?_P&E~_?%__~_?PP&}~P?%PP~P?P'( G sVXzr+! ur#wQ* r* `ro*oY wo*zowz*rz*za/!e.zz-C K.zzzzzwzoArz*~za/!e.zz-C K.zzzzwK*oK G@slssai;vi%)i;)j;)k;)l;)m;)n;)o; GsZXq+: uRwQ* Ow*wo*ow G@s[Xssssd aX[- o$<9:!9:$6l9?%6l9?9?,ls9?,f-~ [JqC?[[,a ?KJl Gs`9gXf 6r3*o$33w.3*K? G"s~ B c x E  GsbXF!E k myG9:9:$ 3rQ}( Vr*-m i.ewi*ib( /a8 eB`vB utwv*v j+0 10/ a3 F!F! c10Dw3*3 c GB3seXf;s )f;)h; GskX|  GsmXH ]-@P Q  GsWG!F ~#rG!v6NameG!'b Gssst[r `}[,[[,[ _[" r[' G@sxXiXr GsjXb+ G=r`*`}&Sq%DSq& GsNnXc;l I c;% &9:!9:$HFFm-M-@'H GsqXP 89:!9:$-@' Gsss`;a+ LI9:9:$9:9:$ C`;( GsuXQ a(( GspX][! Lppppppp9W.ProgressCommand Cmd ']' Msg1 'J!' Msg2 'K!']:L!M!|L!menuzM!(J!K! GvsYXq [=XZD~q =%Sq ~q =Tq ~q =&WSq T G sGssS:vXtXB O69? -9D9?&69?,  # NG6G%6G%a+Go$a'(a%H Gsa|X4 ybaa@( GssXD;9YF@\D;Y[YZ[=|ZC;[ G sR[;k-)[;)\;)];)^;)_; GsrXeG Ue%Re,ef eI P9=,9=,9=,e GvsssyXdm1.d,df Y;dIX; G vsO8CYUd *$9:U9:$9:U9:$ a Gsss}Xs s{XW;n 8GW;" G vs~Xss{XKL{i QT-<Esv GsAY{Tzjm-MS_-MY M{P~{sa{'q{ GsJ:DY@Yu  GsOY~* n GsU;T;^+JP9:9:$-s-Nw.e*-j-Z  a/!lr.e*.e-Sr -T;-<-T; G@ss sAxenn^[w*w* Tk@ GsuGY_w%41?%?? GsFYssWYV;luĻ )V;)Z; G$sssssFBO@X d99L-6L@V aY iP9?'dP'zV aY iP9?dP'wV *V -lbV -w'rY Gb    M fff?V9:9:$-AM {n?3-6L@M Qx?Sde9?,M p}?oo-6L@M ?bbM GdP6v@rb*-< rPdGvsb@dN.bG-A9:9:$A-< G-6L@r6t@VGb  b ? ף<GrP-z'db  b ? ף<GrPFPGd-6x@1b #G9?V aY iFb6#@F(wV *b$Y #@P9PY #@P&db  PFPGdjFr-w(-z6jb66F6r6j9?%6F6b  >b66F6b  333?b6-z-w\ 9PFPhde9?,6\ 6\ ,6\ 6\ w\ b$Pիfff?GdPdb  PFPGd9PFP GsIYssSYNY@ B GsQYssdsss sVYRY  GsssTYss_YUY`  GsTL;gn(%)L;)M;)N;)O;)P;)Q;)R; Gss sXYssYYssZYss[YsssssfsdYr  GsssbYssssHS!|_%<d`Od`dd@fff?|d`}ddfff?|d`d`9?, d`-Hx x |s`Bx B?*C GsgYI l GscY] S>K6K%6] 9?, a>K`~a#?KF;~~xwaU!G;] ~99K] (# A A A*_] U!~~_~F-X -O,_9?, #A#6-O'b] _~nKNa+n] bKnaX!]!^!_!aX!K`!a]!Ka!a^!KK_!`!a! GsI;T/Pm Gs]:h M GsssZWX\% g)aL>-~(Z  rsG isssssjYsskYssssnYssssE;pY]/F$ GsssNZmYK H ]W9:9:$ w *K -X \W aa GseYd!H ng!i!k!%-YXQ9?%"Qj-Y(%Q9?%^?"Qj^^?^?In^"m9?,I@Kaal^"k9?,I@B;a 4GameProfile1zwU*U B1SINGLEPLAYER GameInfo::InitGame failed to find GameProfile1U-FU*rU*|9V,TUT-['\ vZMaxPlayers\ %, w>vZMaxSpectatorsw>%, \9?vZDifficulty9D\wU*-[wU*\Uf'q?w^~rm> ~~ca~19ZAccessControlH{1pY1 rp*pYp> rp*p YW9ZAdminName19ZAdminPassword{W {1p-\&'m9:9:$9:9:$XapmwX* {W {1XBW1q?19ZGameRules{1Game Rules1{1H~1,H%W1H11}1H&"W11pAdd game rules WHIW wH*~rx*xaHxraH19ZMutatorM{1Mutators1M{1H~1,+H%W1H11}1H&>W11wW'rU* -[19ZGameSpeed{1GameSpeed1q9L119ZGamePassword{1 wX*X @1GamePassword119ZAllowThrowingK{1-O9K119ZAllowBehindview{1-N9K119ZGameStats{1-_9K1GameInfo::InitGame : bEnableStatLogging9T-_#x`ZDemoReco9ZDemoRecEx`ZAttractCam-'ht19ZVotingHandler{1va1 rv*{cvac vaEngine.VotingHandler  vv9:9:$ wv*vW^avr^*WARNING: Failed to spawn VotingHandler-Bx`ZCheckErrors GszY@;[:GY%DY7T :rYT @;AT Y& Y Gs1@sssms}Y:Z+ad  : Gs|Y~:wsr~: p *~: :rp * {p i wW*iWwi*ziip ipppNot adding 9Vp  because already have a mutator in the same group - 9Vi iiLgiWwi*rip pppNot adding 9Vp  because this mutator is already added - 9Vi iiLiap ri* i-q2-}:rW*WiW wi GsqB@ZCZw.%-< w*  GsssHq!mڻbS" wN*N  Xq!NX|MU w*-k3 r#H q!XMfpq!XM `r#*#-@-Q wn*na `@w*-@v`YwS*vS`vq!#X#  r#-<SXMqAH XMfpq!XM 3r#-UMn F'Mfpq!XM #a/!| .Z#-N*.Z#H q!XM-<fpq!XM -<X#6#?Mfpq!XM M# R.#-wR*9:9:$"-s9:9:$R ygMxRNWAREMR w R-k3 RCrq!XMfpq!XM --<XR T-<XXկ#6#6#?SXMq#Afpq!XM GsVYU/> GsssYLZEyVppppppppR) ~,\tx>\t9SR`/9S\  Gsss|@ n:]@  ]@ @9?&i@@ ^9?&@ @ 9?&@9?&w@ 9?@y:^9?@ ]^ GsHZssj ss@ssssPZm Y F < r[* ?m 9?%r * -j m 9?[lCjj  L 'E[@t j m h-p 9:W9:$VwE*KիL>Aj6K6K?zh96z9?%6z?aE j K9PzG[@u j m h-p 9:W9:$wG*aG j j9Pj?%m-Xwms*ams "X"=wwKZ* w[*[-H}.KZ w}*}-'@j 9Dm [w}*}-(X"" GsIZx:}Sl 9D9?l u!x!Fl l b9?l nx:bu!w:x!l 9Db GsSZZ = " GsMZssssgZ[ ;  GsRZssssOZnG^Y#6Bn6Yn6\ 6B6Y6{n6Bn6Yn6\ 6B6Y6{n6Bn6Yn6\ 6B6Y6{nY #}6W 6G6Y 6Qn}6W 6G6Y 6Qn}6W 6G6Y 6Qn GsssVZYZI s GsssXZJ wZ/-Nj6j-N']j-A 6]6 GsssUZssbZ\Za/%- Gsy!ssssjaZd/$  Gsu:P+"wC*C{ GscZeZO+LOwC*C-xL<wb*b-xL P-x GsssdZz!N+WI!wC*C-x-z!b-x-z!b GsqZ^Zm -T# -B29:!9:$9:!9:$ 9:!9:$ 9:9:$w*\9?,b=\-K3 w* r!o-9:!9:$ y`S'9:!9:$ 6SC-\6yS6yw3*3-l 663 o$'( GsfZ~Zls rsGsOs:O'"s:-MqP( Gsssssz iZmZG8 r* q: +M +r: +r:-u-k^  ` -k-_ m-kae659:!9:$-p:-B9:B%U(55-}2U' Gsr:ssjZslspZslsq:ssNnZm* c( GsssOlZ~hhr*q!O  |!}l:| ||!A}6| | ?| #C"Ť?~YP%[9:!9:$9:|%6 +#-u -{_-t-uPb ~6[P-x6[6[6[6[6[9D9?6[9?&9?, 1=~9?6[9?,6[,d6[-{ 9:|%-x6[6[~6[6[6[9D9?6[9?&9?, 1=~9?6[9?,6[,d6[i~}a+[@g~?-u(^-_K-A'-_(f-A(9:9:$H~| a=@G~| a=@-_-A GsrZsstZsssuZ]   Gsssss{ZwZ^  > GsssM[zZ`   GsK[i:V`)i: GssZ'_w$-_(P%w*Er|*SU(9:!9:$9:!9:$ o$ Gs}ZUnr4P%1w* 9:B%U( GshZT[K NGsOh:O}:%h:-MqP5qs( GsGZmYzW~cm-g:^mapchangeProcessServerTravel:m/a9 f w.f >*f 3Wʗ~m?%m~m?m$-g:e f f D109:9:$ we *\pppppppp\?Team=e S Team?Name=e S Name?Class=e S Class?Character=e S Character9:9:$9:9:$t' Gsssz @[D[Gb: +@ +f: +f:~-_ m-k~9:!9:$q!l Gsf:ssA[r]>b-v|9rSpectatorOnly1_wX*X%]re:nd:c:-v GsG[slsb:ssE[\:vo3[9\:y*{[9J[Y: GsOC[BhX!B"_:wV*@ |V u|V-@ AB"@ |!AB"@ ?@ #D"a+D"DgB?&9:9:$HB@ C"a=DHGB@ C"a=D-_-[: GsQ ss^:a:U0)a: GsssO[`:a i+w.g *j+6jOj#j996jLjj ի?ALQ aumj 'adwQ *r.Q *`:9?mL 6Ľ? BjLի9?,ALQ aumjL'drQ *6m333?'( GsL[sGs]:b j GsssP[ss_ssI['U(-_( GsS[U w*U( GsZj[L<d Gsz W[GG GsX[ssY[ssZ[slsss`[Q[L%ު Gsb[|$ Gsc=V[H"Tq.erq* qUH"@E?qWI"@E?qBL@E? GsU:D$ũ GsssnAm[R[|^/a3 (_XW_-Dw_Pw_H 9?%0'10( Gsc[ssOa[X:hI.egX:@9:9:$2"V9?, w* -sV"c9LVGETPINGY;Y=o:cYp}?Y8cV9=9D9?,Y,-T'YYt`9D9?Y-b>h&'"nܵ<-_-|]v #<|x #<Aw #<-b' -b(n"-|-_v]x|wAwI*IU|@E?IWA@E?IB]@E?v |A]-_6,6,T|A]-_wI*T9:F%I-xIgp(9:G%I-rIgp' Gszsse[ssf['4 -T(J Gsi[U:I  J GsU[N\J+!G2scBW:X F* )o$  a*V:W:' Gss[g[[,/a3 (z&%z-M0'10( Gs[ssssu:l[ggQ *-C-CGg t*-A (-N(r3* `#L#?L ` LdSLLի9?,gLկ9?&9?,gdSLw?LS ~SdN~LO~drLdr~~rNOrrrLLdL~~LNOLLLdL^Lr_^9?% i9?%c^9?%rr9?,^o:g^Ki9?%J rrr9?,Lo:giLr^KLL4?J J LLJ #rL9?%rJ L7rJ LLr^^LrLr^La+LGgtgGLg Gsh[ssLssS:{S/(9:9:$ r * _-M{-M -X Y 9?% Y 9?,k Y {-MY M Gsssv[t[Q Gsw[P Gsy[O  GsssK\T:N٧)T: GsS!p[{[xo$ -k Gs|[ssssOz[R:O5'"R:-MqP( Gsssssz }[A\GEaP: +@ +Q: +Q:^-_ m-k GsQ:ss~[ssD\slsP:ssDG\B\F GsO@\RhPP%K"iR#a+K"RgR?u|rddrA^u?u#-_K-U'-_(-U(9:9:$HRuJ"a=R@GRuJ"a=R-_-U Gs|:Mg 2w * F GsUM:w#@y9:9:$(\-M:yw>$9:9:$ J %v\ % J \  GssseA B$KcUcWrA cI 9cName,X 9=vcTeam,E9cAdminNameI9cPasswordD:9cChecksumx`cLoadLoading Savegameo-_'/a9 ]r]>*|]`I ^]hw^*^a+^  pFOUND 9V]]H0]10-B|9cSpectatorOnly1wX*-{X gc-{ w-BRF G*8-{w(-B'X @X *O h*X A rO *RF _/*rs*sl> has O   O  ,rh*pCouldn't spawn player controller of class 9VsRF `/*h_O h\pFTL wF*hraFhrhr*pCould not spawn security for player 9Vh!c>zLNo value for Engine.GameInfo.SecurityClass -- System is not secure.!cppUnknown security class [L] -- System is not secure.!c-hq!\ hq!ozI I n9:9:$zhHnrhI (h[9cVoiceM 9cCharacterhV FM M9cSex|M,Fhasht%v>c-Bh-jjh9:X (h-j'h-i'h-~%'yhh_O wX*X[hEIX_hEJ J ,-L'-{'-Bau-Khq!bhh GsqK:J)K:)L:)N:)O: GsZ\I GsF\'#r|*Sd#?r^Lw$U(-_(9:!9:$o$ P%-G'a66 GsM\U lP%iw*aA6U(-G-G Gsk[m\Hk)/Gs^BQ\j s"-b GsssS!P\S\x"F,m-Mo$<qs-k GsT\ssssOR\I:OE$I:-Mo$6 9?%-] a M"6 yC9?,Aqs6 9?,[qsX  6X6@L"aH:M"X  (ywL"*qsu!4a333?(v!4o$( GsssL"ssss^\V\e IX   Gsg\X\Ha GssMsz U\]\G:)N"C:B:A: +V +F: +F:-fN" +9?%/6 +9?%6-]-f-]-f m-MOm GsF:ssP[\\*@CXwT*T`Sw[*w[T*[T`* Gs`\slsN"ssO ssQqSwd*dN/a0 S :S 10qUwq*qa/!nrq*-] .qc AqqqSOqUgwq*Pq-Xqa/!n;9:9:$AqPq q!O!n-qqS-n (p-|-' GsOGA/.uA-w9:9:$9:9:$ rG*rG`*C,CG`}ohG9=Cro* Player start not found!!! 3wGc*wGN GcW ^GwGN *GaGN o  o rG*X RGGaX o  o xrG*pppCouldn't spawn player of type 9VGN  at 9VoGq!Ovw.G*.Gj !O!r w.G*.Gg ̽G[oGH.v oGG""GcGGdGGN GGf''GIG NG/oQoGr-C9:9:$w.G*[DF99G sxDws*-s-]"GRd9:spvs  G  Fs  G  9?%v9?,-v[Zs[vssKUrwZ*Zm"9?, Gsc\@:R}|M.@:cwM*] M S ClassN] cwN*NF  GsO\\HhJs+Q"e}9{|Q"Ae]#?p{?{#iHeYgH@9:9:$HH{$a=YGH{$a=Y-_( GsMssi\9E4)9)E:)G: Gsd\b^" -_swd*dMbd7HNameChangebHb-K-w(-n SAb-w-wzANo HUDType specified in GameInfo!d 3V@A 3rV*pCan't find HUD class A!o{zcDz rc*pCan't find ScoreBoard class z!obk Vc^cb-_ wb*bIb "w^*^ qsbJwX*beXPbpbb>h&Utbt%pNew PlayerbHid=b{ Gsp\~9D)~9 GsuuOB-m'w.u*ZwX*Xb.uXa.u.u-j-m(yJ -m29:9:$9:9:$I F ,u w^*^ Cuu4wd*dLuJeu Gsssae\4`!.I?m-M9:9:$qsv!4 Gsl\'h.v!4o$ GsO\t\D~2GsOfhu/2R"S"z9 +|R"AS"u +? +#-O +# #gf@9:9:$Hf +$"/Gf +$" Gsr\|9Bk)|9 GsssJ]q\A GsD]{9g u {9 Gso\'X2o$ GsES TOGsZeiNnE&Ni JiN-}"c9?,pPossible speed hack by Hc"6Speed Hack Detected!!G-}'wyA]$x\#oiNNii " GBsssy\ssz\ss{\ss|\ss}\ss~\ss\sls@]ssA]ssB]ssss^>v\x9E TI-8Nx9w9v9(-q(($t9s9 GBsG]w\h 1( GsssFW]Y') GsH]u9U*/*?h ?h ?u9'( GsL]i U GsOtlhK] l^ia+ j9:9:$Hl +$"Gl +$" GsN]y9)y9 Gs@'IN,w*o$6N  GsR]k 5 GsssTr9}E)r9 GsT"P]I_' Gsssz O]q9GF`&+p9oE+q9 GsS]S w|* Q#| Gsfj gsN@-p 9:W9:$W9=,9:WR9:9:$ w *r * w. *r. # . v9:9:$-e 'wT*rT$*Ta |TH,PRESSgSwg*|TH,PRESS-n'O G sU]slsssOQ]ohaw.#*9:9:$N.#-el6g%6xRbo6x6g6xRbo6x6g6xRbo6x6gU"V"l9+ ף<|U"AV"]#?go?v9:9:$Ho+$"Go+$" GsssF]|Y1pWNwp*r| [p*qap |  wq*q K|q-E( Gssn9z )n9)o9 GsX]lNFcWNwc*rl [c*hac l  wh*h Klh-E(Ml Gsm^]U eGs{ ]]B8e Gsss~ \]k9D{eBk9 Gsss[]JV "f-Y"-j-G-< w# w#-j'H`JU^wJ*-Y"wJ*`J`GH-Y"J rC*CJ#-W"CJ^G-W"rSJ r#JJJS|`HvCV Cr#-G-<(-<'r -<-j-Y" GB3sd]_]TXN#?b GsZ]lMZGlv"lv"lM lM lXlXl}l}l +l +lylyW ql Gsb]e9|gDWRUTwR*R|e9d9c9RRS Gs`9x K/Hr *N 6-lN_-e ( u as i9 ծ6 B9?,#? 6#?'ru *[6 B[6s 6 9?,6 L9?,-b(-e(-bQfff? Ax YA9?&Q j f9NNN6 L9?&Q_Q6[NN9?&Q_Q[1-eQfff? Ax f9NNN9?&?Q_?Q_A9?&QN_9?&-b(-e(N_1Qff&? Ax f9NNN9?&?Q[A<f9N1N>_9?& A9?,-e'N>_9?& _x  Gs`]W jSa #  B#  -<(vV 6p!~ GB3se]JskX r\* J%UJ7\MJ\MIJ Gsss\PUuwj*j-Xjd9?&jfjf">JPjVrPj rP*rP*ZK*jV ZKPjV-q wP*1rP`j`ZTKPjVZKPjVwj*hPjA} |Pj} -C9:9:$w.j*xw*yjRd9:pmK6 GsRj]tEt Gsssx;i] Et GsU;k]sEt GsWl]{Et Gsy m]vFu Gs{ n]p]BJru<3-k1D  D ?-k( V  Gsss~ o]r]DWpv-<(W  GsssO'bw8"w*a   C-Y'qq Gss]Umw-i(-Y( Gsa9a9\ tuxGsmu]K^b}GsHx]-xx Gsy]ssz]ss{]ss|]sss s| w]Vxy Gs{ }]Zxy GsDB~]Nx#y Gs@<]A^x|_y GsssW@^{y Gsd^m Wծ9?,dA6HC6o$-R#'Tw * F GspB^ly"W 59:9:$ d-n -}%'}A Gs{ E^G^B({4s1-N"L>l Gsss~ F^^9D{B^9 Gsh]\9r4 rx*(xr\9Y9W9V9 GsH^U|@w*S5w*x(-Y( GsJ^'|1qq&w*x'-Y' Gsmv]g^_ (G s[ N^_} GsssRM^P^t ~ Gsss{ O^R^BD~ H Gsss~ Q^T^D~ Gsssg S^V^J*'Z"!s Z"!TpqZ" GBsZ"sshg]w GsY^s`sZ^ss[^ss\^ss]^ss^^ss_^ss`^ssa^ssb^ssssS;U^]9C w8C ]9Ew* -e 'sttD  D ?aL>'H Gs[9 o \9:9:$ Hw. *u.  D* Yu* F,  Gsac^4R H Gse^'aL>'H Gsf^U-<(a( Gs|AL^g_sT rsGs[ j^_g GsssHi^l^-ă Gsm^ssn^sso^ssp^sss sWk^{̓ Gspq^l GsT"r^t^I"' Gsssy Qv GsRjq_q ' GsssMp_lZ) re M Gs{ r_t_B]3-k1D  D ?-k( sT-~-~(Cf(Zl Gsss~ s_|8DmB|8 Gsy_}8{A7k }8Q!P!@95} իL?AQ!ի?AP! GsZk{8Nݴ+8N{8z8y8((((x8w8v8 GBsss\x_{ 9=w*^ -O Gsss|_ss}_ss~_ssx8ssz_ssF`_z)0 GsssC`ssssOw_Mh<-k'-_B-_(u8t8s8_ 6_ 9DBM^6_ 9DBMiw*6_ @6_ a+_ 9:9:$HM#$"##D  D ?-k(GMtM GsssH`A`y)/k GsssK`G`x).F GsM`E`m GsD`FQ=e6eO%H%I\"6eO%O,F#  a+emn8Fq8JF#  JIIJHO6eOK6e\"Ha+e GsP`w)* GsssO`r8k)r8 GsssQ`N`j| GsS`L`u)) Gsd`p8hO)p8 GsssZ`R`F%( GsaJ`4:-  -k -k(-_( GsT`C'E;Gw*(r r * *}qqd`*~*-<'-k'-(-_(-X'-O(-W(w.>*/a9 CCtt10Qa?(RMDamageJ GsU`U_R-X(J#+#V-~%-<(-_(zwn*n-t (Ot Gsi_m8e*w!-t-m8-t-j( Gs@ssW`l8d*~{!-j-l8-j-t( Gs\`X`r)"ݙ Gsmi8z2>tki8g8f8Dq-h8vw>Q *>Q zDISCONNECTVDisconnect Gvspj8D\'$w * Dj8k8 GsssW__8m"wX*X m_8 Gsa`R!G ]$9:!9:$ a+V \ZR9:!9:$9:!9:$6R!%a+R! GsFd8H'L+-d8>t o -]"'I>t p -]" Gvsb`e8Io"w * Ie8 Gsh`b8Bݕ'$w * Bb8c8 Gs@^"RG-^"CRD t-p-^" t Gs{`a8g )a8)o8 Gsc`f`c -j Gsssj`sE#+#__N_O Gs^``IKF-q  w`*b`Rd9b,(b\8( Gsm`T!@ UD6f9:9:$b?69?f{6[{{9?,d{9?f-9D9?{ff* # Cw *T!?6f E 9DT!AA633yb? Gsbss[ p`W!_>?%&wW!*V!W! uV! s&  Gsi`r`H' Gsq`]A ~$-}]# R9:!9:$w.g *l]9:!9:$69:!9:$ 9:!9:$ 6]yo$69?|6]9?%6]?] Gst`AL Gsu`ssv`Y!B:NY!LY!_L?`"`"9?,  Gsx`ssw`Z!U&/&NZ!LZ!__ GsO8R8U9!-B-R8-B-R8 Gsz`sse`N8l0w{*WrX*)X w"Xc ]VN8X-YY]{]6] GMsssBaY8dş )Y8)Z8 Gssb"[C"d d"eQub" Gs`\!c)zMLg \!X+\!I46Cy-]' GsuYV*`|Y, AdminLogin [Y, Upadv=9TXa/!yv|Y, AdminLogoutbUwX*X-Y'lYX-Y( GMsI;Ea_ u Q  Gs~`tU0w{*{-GwX*gpname=X~{taBgp;tgname=Admin{taBgp;tgtYg Gs@ac"YEd85w>t*>tCl-|c" Gvs|aL8cz )L8)M8 GsAabK85w{*{t 5{-G{* GMsLAIaUew@@JJ-q-q=w*Ul-^  w*-^ 'n-^ ( GsCaM*Uq GsE % `E -X( GsGaL*GsGAOaH8c Ud@H8JI8-q-J8Mw*c @J-q|-^  w*-^ 'n-^ ( GsHam fHWebAdmin-i'-j'-~%'-W( Gsn`LF:e!L0Km-BDL%GKW7%wK* L%QKKLGDwQ* L%oQ`LQX LGDQo1wx*x)ze!LKE8Dl7GL GsRaD8bJ!ZC D8 .w[C* AaCWwA*AK Gs@ssVaQa`)C GsssSaspsWaTaS>e' Gs^Xa|76'$w * |7}7 GsYay7601.w. *. 6y7z7 GsZas7F*/@=w. *. Fs7t7u7v7w7 Gslaq7T#*bL>'w * Tq7 GsjassLssssraka\)π  Gsia@*` G s|maj]|-@ Cw*V\VV@@ GsHna#%d-ia(-L(H Gs^Mm71D} m7k7 Gsssf7b!mn# -gC r**a+9Pb!    qb! Q b!b! Gspaj7z <K@[7 j7 [ -e7']( Gssssssssaxa} J+&wO*Oc7'( Gsc7ssad7X~"w * bd7 Gsssywa]RZ {y]TF6]B9=,w* wR* pR]appppppp Skill 9UV NAVIGATION MoveTarget .9VR(REACHED) PendingMover 9Vm MoveTimer 9UZ (j]wappppppp Skill 9UV NAVIGATION MoveTarget .9VR PendingMover 9Vm MoveTimer 9UZ (FT])@FQppp Destination 9Xg Focus .9Vq-a QpQ (Preparing Move)] aQ(FT])@F]=appp RouteGoal .9V^C RouteDist 9U\C(FT])@FV%1V,rVh*V,QppQ--.9VV&h1''V,QppQ.9VVh-V]apRouteCache: Q(FT])@F Gs~an7`. )n7)o7 Gsss@b}a_} GsJbb7Y}"w * Rb7 GsHba7^T)a7 GsGB{aBb@   GsCbssssCAbEbi Xn6XN  6Nhg6h^XNd"hNT^d"e"^#?e"hN9?%9D9?9?@T9D9?@9?@T GsTsssJsssKb`7]#)`7 GsssNbGby} r ** R GsOb_7[)_7 GsssHDbl _BHl !-e  Esr~*6E%l L>6s6s6s6sO9?6O9?6s9?O9?6sO9?O9?O9?6s9?&9?,l O9?,l 6E9DON9?6N9?6s9?N9?6sN9?N9?N9?6s9?&9?,l N9?,l 6E9DNa+E Gs[7LbS)|$w *9: G% GsQb]7Y )]7)^7 Gsssbb\7W7)\7 GsssMbTbl) GsUbssssSbWbi)* GsssVbYbg)D !s GsssQBXb[b] Q Gs\bs&ssUsPBZbZ7{i7w~*"u@@q~mZ7-a ' +# GsssOB]bR 2/mo sm*-a ( GsNB_bY7G :-a (m*rR*Ra/!HAKwA*Aa/!N$.k AWDY7w bARA AA]D GsW7^bQ)|{;#r *r R*(p R GsvRbV Gs`bdbB ( GssscbfbC  GssssslbV7yzw * a+V7 G_$* `.*   " " " " Gd"s@X@yJ\yiG4ב̅}q\U@Jгdia6 W}ǖ}rW JxdiܪiX̴B;;, xzi *H yxiqiiiz[J,5, H ,iLO\i\draB,,5,,H \H5O\OxЖ555,,,L;kqL\ii55;55,,a?qyB;5;B5 xio=[61BJB5 ',a\yaoJBek i\ 4MXM;;yHU@5 5'eiJ,#,,LWiWULG91*&5)qå@ , ),,HsOWUHU5@5,G;, ,,, ,,;,!XLGGHGG9L@,, ,)#),; J\WWLGH:x@,, ,, O*)@aqUHL 5 ;,& )qaO)5,6G# sss{ssvbjbwz$r *  w GsnbS7S)S7 GspbRF G- sf"D srbQ Gse!ssMPΚ GsUssubtst tsybsbI kyMU. wU*U-<w.U>* GsBDG : DArk*kaQ7$.M k} ckf"9?&jDq j!ska D  ka*DDk5kj Gsss|bxbnwY9:9:$'(r *(:r. *'w.. >* GswbM7U)T d6GM76GL76GK7kG4k u2k D4G Gsss~b{blww. * GsssAc}bJ v( GsssssGbEu w * -X GsNaF7E049:9:$(F7z GsZ H7Dc|t7(zt t .9Vt  Gs@ssD7I7MB)I7)J7)N7)O7)P7 Gssssssss sSca igE6-G#-bR b# zz # #<_9:!9:$QQ9?, R L>a R a >333?QM bh!zQAR ~~9?&?Aa 6b~\Q9?, 6b6b@?zQAR B9:!9:$R a Q6666bh!z?Q@R 6bz?QAR BR bb9?&?Aa  Gsuj"_,uf.$ Gs@ssBcPDu9wx*xuPl!n!9:n!&RrP*'rP al! Gsv6C7J=)C7 GsssNssn!ssssVcm!K fVNm!b6Nff> ?m!6b6NAN Gsszsss_c~6L af~6 i GsMcLA %OL*Lo*LwL*La  Gs6YcB B GsssWcr!r,=zs! s!Us!r! us!-z6x Uwx *w.x *w..x >*.x F a,r!x x SY GsZc\cj=w' Gs`csss sw!ssfc^coec . !rc *Tc  w!v!t!T6c  Bw!6c  Bv!6c  Bt!T Gsdcsss so ssssgcsss skcodb8r *ao i_#?o aիfff?^9?,dL own6o _6o N-G#o K oR7o oo  Gsss[co6@D o6 GswcssssfsfmccR\fc}OcI9=,9=,9=,c4apppAnimation Action 9W4 Health 9S?O}c)@OcFapppppAnchor 9V[ Serpentine Dist 9UA4 Time 9UB4O}c)@OrpppppppFloor 9X` DesiredSpeed 9Up3 Crouched 9T-T# Try to uncrouch 9UC4wV*9:!9:$ rppr on ladder 9VVcarO}c)@OcPapppppEyeHeight 9UN BaseEyeHeight 9U_ Physics Anim 9T-zO}c)@Or *cI9=,$$caNO CONTROLLERO}c)@OeGw *cI9=,$$c'apOwned by  HO}c)@O Rc}Or*cI$9=,$caNO WEAPONO}c)@ORc}O Gsr6k6r'"w* rk6 Gsrcl6p[=Vl6a+V \o$ :l q!K  Gslcn.w*n Gsncpck(4 t  G s@sssrsvcqcXZ2w * X/9:!9:$ o$ Gsssucssg6ss{xcscoYup"M> 9:!9:$9:!9:$69?,dM"'( Gsss@d~!oz:Y'$-~!-\-\-~!I GsssAdssOdd6@)d6)f6)i6)j6)m6 Gss"s ssscsst"s.sEdycS rpXS-E3 w *9:!9:$ &9:!9:$6y Gs| ss\W 4"+(R%.$a  GsBdyU :%-a6 RyyR<RyW (Ryf"9?&9:9:$9:9:$W ' GsFdQ d_WH-Y'-C(E?%a''o$U*El qs GsDA_6s_#W -e ' GsssDdIdEN R% Gsss~b6~ )b6)c6 GsssTdKUDf"9?&/w[*Ml@T*a* * GshcK5KyK5WJ5$' Gsnfi 0(S fV3@@MlBf"9?&vwf*Tfq"THfa/!n-ffa+9:9:$t$stta N_I GsfHdw"RSsw"BapppppAmmunition .9V amount 9SR Max 9S\x"Z6w")@x" Gsss^dssoAed_df!Q b? Gsq]d`aZlr`~)R\'`A.$c .v'`~`k 'yr*( a` Gs@ssssadW6c nz u/K@?R\WWR\R\RW6f"9?&' GsZ Rbd|WQ#wT*TH[ Gsssssidssjdsskdsss sZmdsO GsN6e.szO6BK"w* BO6 Gsj"V6`j"-@w Gsh"qdGf"Ikh"G:-C rGo*Goh-C -y"G-I#w Gs^N#II@r * -X:w * \aF^ Gs@7rdudY/T. -C )w*Y+* GsszsssqL6@ aIEr@ ~+-U6V6-T7ow@ *}}@ }}}@ ~}(@ A.$@ k 'r*( a@  Gs}K6phD)K6 Gssswd{d[(aO  Gs|dsssszdZ(bg  Gs}dY(i w.$*-C (.$yr.$o.$yr.$o.$o* Fx#%**$ aN6$a Gso~d@eJ P6 G sAessBessCess@ssssKeJ6yE)J6)M6)Q6)S6 GsIeDe`\C G sL6{"wZ LCw.$*.$-I#-y" }% 8w GsssJeHem([B GsFD6j(ZB )D6)E6 Gs_eF6x)F6)G6)H6 GsWCX *P-XY @6;wP* rWP%UP-XCRCM,dR}R}a}RCR Gsc ssMe ssNe!^{5sRssYsLeE]'?E-X%6wE* rWE@BC6 GsQeYsssReVeY 3i GsssI6UeYel DGsz"'9-z"*wW*.$wW Gs{"XeU@,M{"Jw.$*wW.$w.$w* Gsr6We}5KM~2w*I K}5Pz59I *MrI *`*~I ]P]P`I K I wK `*+K ` ]P]PK K ``K `K `I  GsSeY s[eYsI sfsee|5uS)|5)~5)5)A6)B6 Gs 2sy5s$*t Q  " " " " Gd"s@@AAAj{{Rbj)19 ssssj{{ 111bbb999AAAAAA999)91111sssbbbRRRARbAAJ99AAAJRbjjsAAA111JJJ)))AAJ)) ))9)9)9 9)9 ))AZAJR JJJjs{{{{ AAA 9J))) )))) ) ) ) ) ) 9 )1 )))9AAJRRRJJJRRR)AZ)19AAJ 9J)19)19)19)9AAJ)J1Z)AZ)J)9AAJZZZRRR999sssAAJ)1999AAAJAAJAAJAJR))  9AAJ)J99AAAJZZZ{{{jjjAJR99A)19)999AAAJ)J   9 AAJ)J)999AZZZjjjRRRAAAAAJ999)1999AAJR111111 )))ARbAAJ9Rj99A)JRRRARb99A99A 9 ZZZRbj1Zjs99A)JJJJARb )))999bbb)J9b99A)19AAJ111)ZsARbZZZjjsZZZZ99A 9AAJ99AZs9Rj 9sss)J99A99A)19AAJJJJ9bsZs 9J)AbAJRAjRAAJ)J99A 9AAJJJJ )1)191J9Rj9bAAJ 999A)9AAJAAJ111)Ab)199)9AAJAAJ bbbAAJ)9 )1111))) jjjjjjbbbRRR99AAAJ sbesskev5r)v5)w5)x5 Gsdesshe&sie&s|"&sfessvet5p])t5 Gsjessne&soe&sr5&slesspe@ssssqe@sresssXssk5n5o()n5 Gsxe&sye&szessEssssuess~e &skssA#s s|ess@fssssIfBfl GsAfssssGf@&sHf@&se &sdfEfk` GsRKf~' Gsssti5{'zr%P* 8-di59?n<%h59?%U Gr%/* i59?%/\h59?%/R GsDfssMfssJPfz'- Gss sLRfy'/  GsssQfTfw'/( GsssLVfv'0( GsWfssssUfYfu'0 GsssXf[ft'1a-P2 GsssZf]fs'c2a-Y% Gsss\f_fW 2D#ras*AasP Gsss^faf| 3aX% Gsssff{R5m{I$9=,$w.$*w.$T*{@apppWEAPON .9V Owner .$TH{+apppWEAPON .9V Owner 9V$ZS{)@Z] pppp STATE: 9Wa Timer: 9Uo Client State g K$] p] None h$] p] Hidden $] p] BringUp $] p] PutDown $] p] ReadyToFire { a] (ZS{)@Z\9:r9:${@appp StaticMesh .9VB AmbientSound 9VU({:appp Mesh .9V| AmbientSound 9VU(ZS{)@Zkw|*~%D#E#H#] ppppp AnimSequence 9WD# Frame 9UE# Rate 9UH#U-[$] p]  Anim by Owner{ a] (ZS{)@Z] pppppppppEyeheight 9U N base 9U _ landbob 9U A just landed 9T -b land recover 9T -e{ a] (ZS{)@Zv%jv,rv*{apNO FIREMODE 9SvZS{)@ZvR{SZ{4apppAmmunition 9Sv amount 9So<vZS{)@Zvr Gsssffcfj) Gsssjfefi GsssNfsshfssd5f5g}Ñ )f5)g5 GsE7bfgj8J>/r *r  *gVgS  S w*x jzwx* zggzx Gsssxs sifssnfsskfqfr'I,@ GssspfsfZ P@\%9:  F%$GG9:  G%$V?$$ Gsssrfc5[ cBq  r9:Z Rr%qF$qG$tqF$qG$-c5'aQar'xaS r9:g9:$(arRr' Gsofsswfssrssufssxfsstf`5aEE(a a`5_5^5 Gsyfss{fss|fssssLfPn' ([-d rPP*>r%PPPP%9?PU9?n<PurP/*9?P/R9?P/\ GssszfBgSE^EUU6r  *UU  R U GsssAgDgm'F g GsssCgFgl'_G  GsssEgHgk'G  GsssGgJgj'Ha-O2 GsssIgAi'I#r *r  *(|   A  |%`|&`(  bA(f%Kf,f-[%-P#'A_ _ ?fsV_ _ C_ _ A   f   M#N#O#xaM#N#O#-P#b aK#L#A  A6#L?x'=b aK#L#x_ A  A6#L? x'[rb * rb A'r.b *b LAr.b  *.  S.b  '( Gs}fss|ssUg]5cz+)]5)a5)b5 GsLgssOgssPgssQgssRgssSgssVgW5\yΐ )W5)X5)Y5)Z5)[5)\5 GsQ#[w GsTg|'sWgss=Kgb%Po=b%b,vwbF*b bFvwb*bPbk b Rb%b,wb*bZ bbTb] bNbObjbv b%b_bsb-p 9:W9:$W9=,9:WV#Vi)U#U^iVR-g wR*-J'Q#RlwK*xd GsXgssk"gnA#NVU*n%zn,@wn*n}pwn/*n/an/*nk" GsZgss[gk 4W GsH7NFNCX} r * >w  *e  k`e e? `%`,w`*` iF`gwR*-grR|~%Dno-J'-gQ#R Q#|aDo7ea-J]fnae9?%6]eKk]N IkkooppobobVVV#Vi-J( U#U^iVUUr|RU^BbobrVbe9?%6obe6obekqoppsN t,e9?%6ob6ob6ob6ob,6ob9D9?6obe6ob9D9?6obeaeW -]iVtr|RiBiie9?%6ip6iea      d!e9?%T  w6To6Tka+T3a+  wcf-f"'F a((^-f"(ze9?%6i G sdgS5Vu )S5)T5 GssslR5TheeR5 GsagS#f ea6r  *  S#U#V#^   S#U#V# Gsig`gUr+ Gs\gssb4ssPhgb g[ I "q`w`f KLR -]     d6UK6ULe6UR     d6^K6^Le6^RX    N#?99   B GsKssNO5Tq )O5)Q5 GsssfgssggM5\ kw.Yk*4M5%.YkS$J.YkS$kf"9?&.YkD.Yk] GskgsslgL5] lw.Yk*4L5%.YkS$J.YkS$kf"9?&.YkD$.Yk] Gsmgss{6ngTo9:B9:TE3r*Q*SQT-U-U rQ* l 6pt B#Qr**T-U GsvgN5S[)N5 GsssQs sH5ssw6pgDZqE)rD*&wND9:B9:NB9:\9:N\89:DB9:B9:\9:D\D9:B9:DB9:\9:D\DR9:B9:DBO9:B9:NB#9:DB9:NBD9:DB9:NB9:B9:NBDr*DZDN Gs~gG5RZU)G5 Gstgsss st6ugEVCvE)rE*&wQE9:B9:QB9:\9:Q\89:EB9:B9:\9:E\E9:B9:EB9:\9:E\ER9:B9:EBO9:B9:QB#9:EB9:QBE9:EB9:QB9:B9:QBEr*EVEQ GswgssSdA ~U$ !wx*xt ,-^ -^'Ww^*^t -S? -J {B-J'a}Bwa*A agaazA A by>A &{A  CA ( C?Restart( Gss sygi ` k#|pi %mi ,ci -@xi ci -r i ni  GsFhD5PX)D5)E5)F5 Gs}g@h^ zG}i%zi,Gi-r i-@(piD"(i-ED9:g9:$9:9:$9:9:$E Gsiss6gC5}7-E E _ P%`P,VP-@xPP'vw *a Oa{ C5wO*OCO  ?%.wO-w#'a Gszs`sEw}@;{wEEw ;wE*aE* GsE" s sg"AhW#a}g"W#W#U* Gs^A5OW )A5)B5 GsEhM_ U* U*29:9:$  WM%M,wM/* WM/MI G sDh ssl"GhX#Kw X#`.  [tr`*w`-Z#'l"X#-G'``E-G'rY#*-G'l %l ,wl *l ] `` l .wY#-Z#l <w `` Z -Gt-Z#l %ql ,l /*l Na GsssEsEsNh~4LU/)~4 GsS|4n!cn|4{4z4 GsRh}4KT)}4 G sssIhh` 1.wh*whk *h/.' [hk -r(-drhk *4h%'rhk %k  jhk h6>wD*,%DG %&DG %jhDG wh/*djh/Rh/adjc dh.rh/*whk *h/ahk   eh/-r'h%'whk %k -r-t4wD*D-I wD*,%DG %&DG %dhDG -rdh/h6h/ c dh/q!s GsMhx4Ay!cAx4v4u4 Gs[hy4JS)y4 GsQhq4x?0c$xq4p4o4n4m4a4 GssswssPh[#Z $ .$-A#-[#1r *q!}  T%T,wTF*rT*TwTk * -drT/*TH%q!}  T] TNT8g$q!y E9:9:$ l r r ,w ,* ei w ,* ,-R  r * , e-[# Qkw.  *.  -yA w ,*S ,S , KS S , K G sUhsszssVhk4Mn7O~.  Lw~*~-Q ~ Mk4 GsXhssrhl4IRk)l4)r4)s4 G&sYhj4RyHOE.  LwE*E-Q E Rj4 GsZhssss\h`hiPZz9:g9:$Sp5$ (Mo5i niw|* a|"a|"r5g$aO(p % p ,p -@(p Up -I(p -C(p -}(p Pw`h*`hE`h-kX`hWX* Gsp s s]hss_hchKޛ29:g9:$9:g9:$Fw ,* ,-R H%FH,H-r H-@(<HD"H} ?bRRHD"H} ?bH\ nH%H,H-@k HH_R9?%9:g9:$a&|"~a"a"q5g$K-bR)R9?%aR(2a~(H%}H,H-I(H-C(H9 U*X*' GsHssahssbhfhBV GsssehhhD Gsssghjhv G sssiha 7.r * nE b  Gskhb   N Gslhf~&H.$ a!s .$ a!Tp v9:9:$sRff9=fRf G sdhssmh]#k +9:9:$x]#c 9=]# G snhssus fKdw *w Ir * p *b s` 9:s D"9:s IR9:s 9:s R%"9:s -I(H.9:s q9:s -I'Hvt9:s o<9:s  Gs~hf4HQ )f4)g4)h4)i4 GsROc 8Tqa9:O-I'9:OR%"9:O-C'nx9:O GsssshTS HӬT%U&U%wUTU-U%U-@Tq;TD"TI(' GsphssUssvhssuhiR\OS i('i%V&.V%i-@'iD"iIV-U%iDiDVDJ n4iIi-r iqij%' Gsf ssVssSh_4kj-wx*xk_4^4(b Uwb *b H b G b b SA' Gsyhv x{/v -@v -}'r nv -r v sv -@(v ]v -r ] v  G sFi`4DP)`4)c4)d4)e4 Gsb ss@ss]4BiQ \9:9:$9:9:$%Q&Q9:g9:$(%Q&Q GsssAiDiP'K_8w&*&-@&-\%\Zw%*%-\%\( Gsssf`#e  "-d'r%P`#P`#%z9D\4e-t`#Uzz`#U`#UzW (`#Uzf"9?&9:9:$9:9:$W 'w`#/*`#/U 9D\4-t' Gsi@iCM Gss ss{IiENs%Q-dTr%P&Pw%P* w%*%U%Hw%P* w%*%U%H8w&P* w&*&U&Hw%/* w%*#%/R%HAw&/* w&*#&/R&H GsssCiKif ( GsLissMissNissOisss smo59wK*K@? -G'_w%*%o}w&*&o GsPiqA-G(AwK*K@? _w%*%q}w&*&q GsNQiSil5~%jY4X429:g9:$j%za%` a%` %Z2j&za&` a&` &Z22r%*%-@#r&*&-@v Gsjss|hZ4CSBkZ4_"-P' -]'/!C*^_" GsqssTiW4^?7 rd* d CW4dad* GsRiv;au5s5L> GsWi[i} 1Gs]44#3w.$*Z -A#0a!} aL=( GsYi'+ aL=( GsZiU0 GsXiy 5Gs\i^iC'9Y( Gs_iss`issaissss]iciB'? GsssqbilaF+-dI%I,rl~IPwIP*jIUn<I'lA.$c .v'l~Ilk 'Irl~o.wlwo*o` (r*( al Gsmi[4AG')[4 GsossVi[h&w[*w[_*9:9:$:-n /w[*[-W[_wx*]xh[Y_w]*]{_/a0 |k|9Wkw_0k10w[*w[*qw[`*n9=[`}|nYnY]Kw]*u C]n[u QQu L]]]]rL*/r.v L* w[*[-XWarning - PATHS NOT DEFINED or NO PLAYERSTART with positive ratingQ /a0 &]u C]$[w.z ]*u 9?,2u 9?,u QQu L]10L GsZii&( Gsjisskissss]s&ssiU4KF )U4)V4 G*s~s&sgiS4CZs.v S4Qws*Ks-fDEs-eDzDA A GsR4Tstiss (sziT4\C)T4 Gsvisssssss[ssoiwG/T ww*w}tFwx*xGw9Dtew Gsg @TsG4P4vBJ)P4 Gsfss{issL4~im 3  G sssj}iA7! 5wx*xl*2w*a Gsssb#n b  GsAjK4f&ij|~ aK4~ g g ~ zzpwx*xl~ ~ xxx*a~  GsxiJ4e=)&wx*x eJ4  Gs~ ssI4ssX^hOr^K r^*wK*wK*K}9?&Kf"9?&VKself_frag>>w^*^}9?&^f"9?&^E&V^?fragbwx*xh^Kw^* O%e^ GsHjssIjssssssFjMjYi( GsvssNjssssssA4sszss^j@4d<0)@4 G+sssj#3A3TaN4$ GsPjssTjk x+%E@(a GsoVjXjJ O4 G sYjssZjss[jss@ssAqj[q G s~"ssoj~3l;)~3 G s`jssssVo#bjBq!T!r Gsss|3|3ejs P_!G!srjT4I! q!h  Gsy3dj'NF! aA( Gs]jsso#hj@' GsijssssgjE t Tcr.E *.E -Z32r.E [*r.E  *(b$E    (D.E /Q.E '( GsssssAjjC3a^t Cp#r .CA.Ck ^wp#*p#f.C Gsfjs&sV {3I:){3 G smjq#u #  /a3 q#3q#10 GsGkssapj4)`- q!h  Gs[sssjss|3cjyjh g"G!sYv3@V!#N  #<IIv3 Gsw3_sy3vj'["#6N`o$E ? Gsx3xjUb".E N I+9:!9:$o$ Gswj_sssxBka ^&C9:9:$aA\9?,KaA !Qfaf a#n aa#wg *g Yq!T QfarQRfsGso#t3@$-Q4 s2t3 Gszj_sssj#}j@X% Gs@kq'%Nf"9?&-^ 'q%Kq,qm*q( GsAkU&$f"9?&-^ ( Gs~j_sd#|r#M'r#g?~r#w~*P. ~wP*NP mr~'N9?%Nur3~~; Gv $*V.*   " " " " Gd"s>@W,,O,,dx,dW,_g,},/_n,}O,,W,P_n,}dx,d,SEn,d_g,}O,,͘>d,_n,}dx,d>S_n,}_g,}SSjSEn,d_n,}SSI3>>d,_n,}SN/[SSS>En,dSBRNVcSv/>d,SحSS//?cvvccjvS$,SI,i';cccjj$?$SS'};[gO,eVc/Svvc$IS';pؔec'z/cj/>I,};p',VBOd?vv/IIN',;V/,pؔ,j>SS?N^c>;V6,j/IScc>3O6V?,v/>cVcV6O^NLj$SVcjj;Ov$>VcpN^zNj$VVvVVvvNcjvvSjv$ sKks3m6%)s3 GsMkss~ss@#ssvDks#w2 !s# -xAs#wA*K. AwK*IK mr~(I9?%IuAA5z.'s# [~wz*zRz\>u GsN q3o5)q3 GsAss@ssg#Jkn3r H3Dg#n3.'DR~D GsXssDssssvu#w M uz9?, -v#'\u# [~w\*{w*x}\}~}\}-v#Z.fu# [~ wZ*M 9?&9?Z}ZM7^w.f*M 9?} ף;M 9?.fM #<M 9?~} ף;M 9?f~M #<M  Gs\jC#ayX*wC#*wC#anwOwn*wn aww G s\ss`ssZkl3~3v )l3)m3 Gs@ssSkDlw X3 G sG#ssbkg3U2)g3)h3)j3 GsYkss=I % /=Bu? ~g Gs\kB}--I -I -R Gsj#~@h$- a!!-I q!a  Gs^k`k` %$-I -  -w# Gsssd#_kEM/${. E [~Sw{*-I {o<%%.gE B 2Eg?|9?L>| ~g| GsYf3s/e)f3 G ssss{ssye3o&C)e3 GsvakG wB` uG  @ e. G [~rwe*qG  -x` z9?, -^ eMq%eMq%>` leo<%%EeGt%rE*L=i>` Eu?>9?en<%9?eo<%rL=G  -x-u}?U?G g=rG *G g?@` `  Gs@ssessckssikssu3fklkf p qA9:9:$\9?,zz>Ga>\ Gsssn#kka3Cx Uy. a3Kwy*%G yo<%&G yo<&n#* Gsb3_sl (sb#mk# %G %&G %b# Gsok (snk_srk_ssk_srDstk_s]3 ssyksszkss{kss|kss}kss~ksskss@lssnsswksAlssBl ssKls*sCl ssElDsFlssGlDsHlDsIlDsX3ssOssV3ss@sst@,sw XkF+ w EbbGameDifficultyLdGameDifficulty$$Select%oXb7bWGoalScoreLdGoalScore$$Text3;0:9997bWTimeLimitLdTimeLimit$$Text3;0:9995bWMaxLivesLdMaxLives$$Text3;0:9997bWbWeaponStayLdbWeaponStay$$Check 'IbsbAllowWeaponThrowingLdbAllowWeaponThrowing$$Check 'AbsbAllowBehindViewLdbAllowBehindview$$Check ''MbsbWeaponShouldViewShakeLdbWeaponShouldViewShake$$Check 'DbsbEnableStatLoggingLdbEnableStatLogging$$Check '=bsbAdminCanPauseLdbAdminCanPause$$Check ''AbsMaxSpectatorsLdMaxSpectators$$Text3;0:32 '':bsMaxPlayersLdMaxPlayers$$Text3;0:32 '>bsMaxIdleTimeLdMaxIdleTime$$Text3;0:300 ''w* FbwA*A Fb(w~*~ F< r Fbw v* v FbGameInfo::FillPlayInfo class'Engine.GameInfo'.default.VotingHandlerClass = None G sRl@,sSl@,s|@,smssTlssUlssKsXlsYlsQ3ssZlO3s[lssss^lssI$ssalssmdlvr Gssse "sscl~2M ~2 Gs=[%*=O F/a0 s^&&10 G svss^gl#-z#(-t (^ GsilF GsjjlA7Ewh*hah*<wr *r ar *j G skln%-t -t  Gsbm%-M-M GsmlsY-*-Mw.9#*I G snlplG GsssolI3f +9F \ \ pI3 GsR#ss@ssc{dYFn`h{Z'y{B6{Z'?6{Z'?6{Z'?6{Z't9?,O U39?{Z DT39?{XCG9\ww*s9-<d9-s19:9:$w9wwo`par{(ar{(ww*w-F#w s{-M{P W{{X ${B_9#R{H3G3 w9#9;r.9#* r.9# *G3H39?,{)@G3{a----- VIEWER INFO -----G3H3{)@G39R{H3G3~-u -G3r*p`w*p{Z'{Z'h d{F {{Z'pQ -t wh*p{Z'{Z'hh d{ h-r0F {{Z'pQ{r9* rw* rh*$9I9-<K{w-i3s{g%g7CgC Y`{g2L{2w9*9G"J{22|&|,F-[3M{F {{-z# wr *r N{ww*H{9 N{9-m]u{ wz *z -| O{z qz V{Z'h{ByCm{{ G shl @rsrlssussGylH{)* Gss sxl{lg%|`* Gs@sszl}lf%}* Gs@ssJU I,P.9# /rP* lwPf*S Pfh)  S 9#  RS P-fCX P  P s P9=,$9=,S P srP97rPR%P@hwPR*rP9P g#Pb P gX P  P g P9=,9=,9=, PbP gU %U ,(rU P@h*-F'X S U P@h   P$9=,$S U P@h  U -FX RP g P9=,9=,9=,999# #X RP g P9=,9=,9=,JrP9 ~wPq*WPq  WP nX 9#  .9#_#?W P9=,$$ GssJslsJs@mssAmsJsss~lbJ4z9G">z@$~,\~9D9?9D9?,z@$\9\O %p%p,zp9f O p~&-I |,{%tO {&tO {,tO &{,tO bP S`bX $baAqRC ?X9?bZ?X@9?bZQ?X9?bX?X@9?bXQR9?O @p% p,Hzp9f bBp9I6bB9=~b!ap9f qRb)C q@Qbap9f QRpw\*9:9:$ |,|&bBW36bB9=~p%p,baptqRb)C q@QbaptQRp~ GsCmssEmssHm 0.7sV$ 35.0sul[ sImsswlssM$ss~ssMm(sDmPms; Gss sOmRmK < Gss sQmTmL4< GsUms sssSmWmM< Gss sMYmN#= GsZmsVs[mss\mss]mss^mss@ssXmrO*[>WrP WrrX $rB_raAC3Q$O$D$X9?rZ?X?9?rZP$F$X9?rX?X?9?rXQ$r)O$P$r=app(>D3y,ʖy}D3D3y_' GsqsE3ss`msbmsamsscms_mvR:@wh*ha,rv*h*hav$rh*pHud::SetScoreBoard(): Could not spawn a scoreboard of class 9Vv!o Gsemsfm]%JkB-u -u b GshmO PBG9.$2r9*z *w*h* fw9>*z 9>Q mz *w.9#* .9#?%w.9#w9*w9w*0ww*wwT*hwTDh9 GsimR$oJFq-}#9P YW$!z W$!RPppR$H: PTP VR$ GsA1st1sZ1B3sjmom[%vPG GsssnmKF }GI%I^3z6LIp6B$Ip"6LIpI^&a Ia ^&a pa &pa 6La pxI]$9D9?9DD$X9?KZ?X@9?KZK9D9?9DF$X9?KX?X@9?KXKP WKKB_KaA^$DK9DD9?x9?&K9DDI%Ix)z6LIpKa6LIp^$DK)9?]$9?KKB6A$IpKa6LIp(K9DDI GsdmsslmssKss[$sstmDsqmssA3Dswmsspm@3T@M7,-}#u-P.9P S%fS^\z6LSpfS3S^S%S^&SpS&pS|6LSp@36B$Sp"9?uk$6A$Spu t_$6P3Sp_$ GsvmssxmDsp(s|m(symU%Oo-q -q 'i,-I-I'iB-n -n 'iX-y-y'ii-\-\(b Gs~mT% Qi-\-\'c*-y-y(c>-n -n (cR-I-I(cc-q -q (b GsQAnS%R GsBnssCnssss@nEnR%R Gss sDnGnQ%%S GsssUBW+VK{pwo*oo.p Iwo*opWarning: HUD couldn't dynamically load font pptwB_9?tB_9? tB_9?tB_9?t8B_9?@tO`,t G s}m(stssOn(sd2J%3ZU}%I},?9?}J$2_O`}}O`, G szmss}ss@f$sO|2H%Ke\Qx%Ex,;rO`x|2O`%x,xO`, G s}2ssxss[n({2sRUnG%a^ Gss s@ssXnssvss^ssKn(sZn(sW!()s\n ss_ns.so$s.sssdinc * Gsxp$m-(wp$q$*w.`p$*'( Gsy!()sssAbny3x/ ry* ,y-ly-|oy#ya/!2py o* y-Rs$y2  9?,as$ pys$o*,9:9:$9:y9:$w.y*bcys$ G"scn(sq$sssx2sonsMsJshnssz$sjnsknstu$p41wu$ A x$x$u$   GssMsDnnpFd!9:9:$|$-K2|$-l or *r  *|$ spl|$*-9DS  m$n$P9?%w.e|$*.e|$?%.e|$$}pSPln$m$ c|$b?A  z2ppZwo$*9:9:$Bo$b$9?%BSBp o$b$ao$  9Pp??w *rB  ,B p @o$b$ao$  9PpZao$  9Ppc* G"slnss{sqnw2~$ :vSPn$m$w279:9:$b? Gsan}nt!  GstnwnA !a Gsxnssssvnt \!u]a@6N9Dt 9?,t 6N9Dt 9?,t 6N9Dt 9?,t  Gs"ss}$csrn"ssssvssss~nss$sB%ssAossCossDossm ssFos_$*l*   " " " " Gd"s! @jIlpcpe/Pp$pM/SIvi^/$Iގv>e>$NyڦeV>//Vr3Ҹjr>ҏ$jjjN6B/j?cƂB6vҎN^$ٮ[B,?jNzMIvpB^z"ڂVMB'6cSejN$$cvN?V)vvV7?KV͸veVvejƁ?3vvc?>$vvjSI>$ ss2ssKos&sss{BMoo"c^"G%>9:!9:$69?,dG%"'( GsssLoOor$, GsssVNoH%B2@69? -,d.$H%H%9?' N#Q6Q%6Q%a+Q GsIo ssQo ssDPor2F=Br2 Gs@ossssHSoo2-Cl n2%-v2 U% 8w *b?Uo2E%J`U%ao$6JzDJs GsY]op2@a L  Gs`o@JsJssRo sss sp!Vom2e Vm2-M-~$m-M sh"69?,d s9?% L=b-~$(o$m-M hsȟ?sh33s?hh ׃?shp}?h G"swo^#L FE-D '*wY*Y-^ %"YL%9?, wH*-g2H-_a*-e29:Yr9:$wY|*^#Y 0d5!sa 6^#a Y  #@a+9Pc#H-W0'U Gs^\o_oj > l2-  #?9? N Gsl2ssi@Jsc!^ofp O69? -9D9?&69?,  # Nr3*-C-}$9:!9:$o$@w.3*3V-9D9?9D9?&69?s3s  ? N6B(?69?,F869?,Fo$w.m3*69? 3O-9D9?&s3s69?,  L> N6B?69?,F69?,Fo$ * G"sjaoI%AHs9:9:$SwB%*-vI%aB%I% } /Q*s-xa@%$9:9:$m-X _% wD%*J%L?A69?_}%}_daD%$  Ad cE%OwC%*%dyC%dN J%?333?}j GsZo @sfsssdo@seosabo4fa@%$-x( Gsf!gosi-}$w.s*ss9?,(K%6ts s BAtt9:!9:$6A-xat2$-x'6K%o$a>( .s Gsfosu(sjo ssk@R sloR  G smoooV&  G spos sss@S ss_$*uv*   " " " " Gd"sm0 @vvvvvvv(((ڿ((ڿڿ(/ڿ(ڿ(ڿ(/ڿڿ((ڿ(ڿ/ڿ((ڿڿ(((ڿڿڿ sQ @srosssuosszo_#X%$wY*_#YD7x9D6_#9?,9?,u9?,I@H.ts w ti#HrwH*N u?9?xI@9?,?9?HFH-_(H-T0-f2HR&YH \0c#HZ0uHY09?xHS&b$u!@L p9W.InitShadow: Failed to allocate texturep9W.InitShadow: No actor Gsf ssj2sj{oAdcZwH*HR&*LH-_s l HH*i#*j Gs[2Y% ) = GsCp@JsCssDs}ossossBp.sd2.s@JsDLjA #va  -CH GsDpQpvIO &z) r * Gsb2ssssZssHpssHssJpssYGp@QD U Gs`2(sMpssRVp_2`a U_2 G sNpssssl ssRpss@sSpssA[2a 3V?  ra * a -]2'f#!sa wf#-}1ra B*3a -K2-K2wa B*Va  G sXpZ2U@)Z2 GsYpX2V?)X2 GsZpV2W=)V2 Gs[pT2D <U)T2 Gstr}U;)} Gs~ ssW% ssk# ss^p ss_p ss]pss`pssbp sz$sapsdp ssJshpsrscp ssip ssIsskp(snpsppsjp ssjJ2slpsJs^%2@9?H-r -S%'/-S%-^2' Gssp}O1w@*@a.w{*{a Gsupf69:N9:$w.g] * yw]%*r@*@-@@Ta]%wa%*r{*{-@{Taa% Gsvph Gswpb%iAaw{*w{3T{a T b b%a{((T^w@*w@3T@a T b b%a@((T^ Gsqpsxpk'$w@*@T] Gszpm=:N-p  w{*{T] Gs{pgb6Tg.] Qwg*g$_c\2Y2W2U2S2R2 GsJs|pI2MwOQ.] LwQ*Q-Q Q MI2 Gsx;s}ps~pH2R{OS.] LwS*S-Q S RH2 GsjEpA AQ =rWWLA WwA *rA LA LLA A LZj Gs@q!sAqEq^5 GsssDq|#U GsFq]t GsGqo9} } @?d d @?~o~o@? GsHqqD$} } d d ~o~o GsdKqQ -@ GsssJqMqi# GsssLqn q .UUUU9:T9:$Te Z @hUr]*r] * w.g] *.g] z X%']hf ]nb`kmoT \ Z l-r N-@DU} iDN"} D} DDN"@9?HUw],Tw],*-@(TK GsNqv#Y+!]nr GsOqQqq`!T o<Z H GsssPqof*"&TSQ%$R V ( GsRqqn"HEwT|*TaM%TaM%j2D GsSqrv# GsTq`z#wT|*oj%QTaO%TaO%h2lTazd DTazd DT%SQ%$R Vd d (Md2j GsUqs%HEwT|*Ta` Ta` ZD GsVqG2X&-6{J6pJk 6tJs6uJQ26vJ`-6oJ-N2-6xJ-Y%-6nJ-M2-6LJ-[%-6{J'] f7JG29DF2 Gsf#;sXq;sssb$(sWq]qa>)#]  ] T Gs^qss_qss`qssss\qfR)ufI$9=,$f-appp FIREMODE 9V IsFiring 9T-@c%E2f)@c% Gss~1sYq;s[qsbqsaqfq`+ @E GssshqoskqoUl$*'''*   " " " " Gd"s1I @{'kkk{'.HHHHHHH.%HHH HHkH HHkHH HHH HH H H( HH H 'H( HHH HH( HH H H(( (kkk (HH((((kk H H((((k H'H( " H  HH kk .kH """ yk(k kH(HkkH(  "HHkH(HkHH" ' kO"' % slqosmqososcq;ssss.snq;soqssqq;ssq;s1;s}1;sxqss{1ssvq;sBsz1syq;sdqss|qsw1sqssssU:dArY@"g%A2Q7f%XQ%k%Qak%f%$C2wd* LS(-B2ad S9Py1ad Sg%" GsSss}qss1sWx1rg'$wL*Lrx1v1 GsQssi#;k#sHrsi)sIrssJrssKrssLrssMrssNrssOrssPrssQrssRrssSrssTrssUrssVrssu1sf$$* Qec  " "@" "@Gd"s(O @{TTTTUUUU{TTTTUUUU {TTTTUUUU {TTTTUUUU {TTTTUUUU {TTTTUUUU {TTTTUUUU{TTTTUUUU{TTTTUUUU{TTTTUUUU{TTTTUUUU{TTTTUUUU{TTTTUUUU{TTTTUUUU{TTTTUUUU{TTTTUUUU@s^:Grt1e6p% -l%(t1u1-l%(' Gsss|1Yr]r-E  Gs^rss_rss`rssarsss UX$*@(   " " " " Gd"sKT @mi^Ăou|fї~LJfhnn]a}dx{~n~\wpހmʠƤ׈ܞ֣hgdouԍ٥r≖`|ÿ_v~n||ϖnljyz{}xxdi UO$*t*   " " " " Gd"sX @󱱱󱱱 srsgr*shr*sir*sjr*skrsslrssmrssnrssorssprssqrss*sp[H Gsrrr1z"JW)r1 GsFr;k#ssrq1x"K)q1 GsGm1qw"wL*L qm1 GsurxrK%N  Gssszr*s{r*s|r*s}r*s~r*sr*s@s*sAs*sBs*sCs*sDs*sEs*sFs*sssHs*sJs*UO$*p*   " " " " Gd"s_ @󱱱󱱱󱱱󱱱󱱱󱱱 s*s| ser!UO$*u*   " " " " Gd"sLd @ sOs*sPs*sQs*sq%*sLs!sTs*sB*sut!sUs!s[u-9G?sWsYsR"P)[$-B([ rsG@sdZsCN.9:[9:$q%s%-B([$6[$[E h Gs[sssssXs`sQ"r )[$-B([ rsGsd^s]V 0-9:[9:$[$[E h Gs_sssssm ]sas@hA C@9:[9:$q%s%-B([$[E h Gsbsssss\sdsP"G@sdes 4-B-B(-B'[E h GsfssssscsksO"Gsdis -B'[E h Gsjsssssm hsls@x -B([E h Gsmsssssazs4zq aq( GsrssUO$*t*   " " " " Gd"sFm @󱱱󱱱 sJlq/ROwl*] %O] 7FEr] FlAF] & ]  Gssssstsssusssvssswsssxssskss=z%l=a?(z$ Gs|s^n1s}s^s~s sss ss@t ssAt ssBt ssCt ssDt ssEt^sFt^sGt^sHt^sIt ssJt ssKt ssLt ssMtssNtssOt^sPt^sQt^sRt^sSt^sTt^sUtsWt @sVtsso1sn1 @sXtssKsss[tss\tss]tss^tssssat@s`tssl1sct@sbtsssdtws* as]wq* aqY Gsvpz_wu*p au>ws*p as]wq*p aq7y%p a%y G sz@ssEwR ar> .R -j)C-j'+(BBC-j'eR }C}(R }C}R dCd(R dCdw.C$*%w..C$>*(' Gss s@ssmwCwbn Gs@ssAw@sDws{S1Iwoc^"z%>9:!9:$69?,dz%"'( GsssHw{%cePX94<{%DX;{%333?PBB6?P GsGw@ssKwssDJwRF&?RRc-mc9?-m(-A '-A(6]%6]9D9?6]%6N9D9?6N@?6N9D9?6N@?6N9D9?6N@?:c9?,<6R333?o$-M$(q!\c9?,Py?aQ1$ CY?>'aP1$ CY?>' GsLw@sscssNw@sszvRwf=4re* {\#e \# e Gss sO1WwwrB Gsa4O q!\ Gsp!TwM1e TvM1-ML>u-m-m(-A '-A(6]%6]9D9?6]%Na L>Nq!\ G"sT @ssUw'h O1$G59?6N9?'6N'_9?6N9?'6N'Q#9D9?R1S19:9:$E A9?,(a@' GsSw`w\ GsHZw-y a Gs[wss\wss]wss^wsss saYw4~  ba Gs_w'i a?'a'(( Gs@$sQwy#wi0rL*Ly#-L wy# GUC$* {*   " " " " Gd"sv @ saw@$s_pgw[sa Xwp*%ap  Xw%*s%Q Gshwss%ssew@$siw@$sjw@$skw@$sqwdT$WFdCddCdp9SC:T d,<dT ,<T , dppd9ST :dpppd09ST :d, dpd9Sddppd09Sdd Gslw@$sssnw@$s{wowcH)rU*@ rU*(`' Gspw@$srw@$ssw@$stw@$sJ1me!n;m?@mm@@@mk@?mm@@@m Gsuw@$sss=vw%-=lCt C GsywG1~6iF1&i?i?o9:Z9:$Li?v!@} lit l9:Z9:$} lit lz "I1z z 9?9Dz } ez } 6G1`9C}  Gs|wH1dBcbH1 G sJxR>w Gsww@$s}w@$sYzwo@RYo9:Z9:$ {ga/!K .igZa/!]~.F.igZoga/!]~.Fgo Gs~w@$swE1ga)B& #$E1g]&  Gs@ssAxDxhn} Gss~'s^CxFxt9:B&9:$ C&]]A&A&C&-i-iiga/!Kg.igga/!Qh.~'gIncompatible material in xMaterialTrigger!c-ga/!K .igZa/!]?-il9<6.F.igZ`t Cxl9<6.F.igZ`t iZ $ $u!@  G sGxssC&ss@x@$s[ZWVUTSONMLKJIHFCBsKxBxQ$;=Ut$ GsOx@ 6U.$\ Gsbw{#M {# Gss ss@ssSx0N$,ss %^s ,|#Ts Y $K$0Y O`s |#s Y O`, GsHx@$sDYtz#'}# zw}*Va}Y$YwY  Y Ya/!Tfw.Yx*.Yxl.VNw.V*.Vx.YxV@a V  կV6Y6#?.Yx*Va/!T.VzwV*VQYQVwYw'( GsJss_xz0M$" TJ%OJ, {0E9?JY $K$z0_'J( GsUxasasVssXxZsZsdss[xXsXsQxq0d% wL*L dq0( Gs^xWsWsvxu0L$~d%id,C$_9?dY $J$u0_Y O`dC$dY O`, Gsaxssbxsscxssdxssexssfxssgxsshxssixssjxsskxsslxssmxssnxssoxsspxssqxssrxsssxsstxssuxssss=U% b=@ R GsxxD.syxDszxDs{xDs|xDsDsxW(sAys@ysBysDysEy@CysssIysFysGysHysKysJysQysMy@Lyssw0sNys|sPyysRyysTyysSyysVyysUyysXysWyPC1sYyPsZyPs_yP~0s[y~s\y~s]y~s}~sjy~s`y~s~@~sbyQscyQsdyQseyQ@1sfyQsgyQshyPsiyxskyx}0smyxslyxsqyxsnyxsoyxspyxstyxsryxssyxsyygsuygsvygswygsxygs{ygszygs|ygs@zgs~y@g}yssx0sygsAzcB1sEzcsBzcsCzcsDzcsFzcsHzcsGzcsJzcs{{sNz{sLz@{Kzssy0sMz{sC{s{sPzn|0sQznsRznsSznsUz@1Tzsss0sVz1D&sWz1sXz1sYz1D&sZz1s[z1s\zJs^zJsbzJsF&D1sPx@$sazsdzsczshzsfz@ezsssgzsizsnzsjz@skz@slzqsmzqspzqsozsyzsqzsrzsszCstzCsuzCsCswzCsxzCszzCA1s|Cs|z@C{zssv0s}zCs~zBszBs@{ sWsA{ ssJ{ ssC{ ssE{ @sD{sst0sF{ ssG{ ssH{ ssI{ ssM{ ssK{ ssL{ ssB{ ssN{ ssO{ ssP{ ssQ{ ssR{ ssS{ ssT{ ssU{ ssV{ ssW{ ssX{ ssY{ ssZ{ ss\{ @s[{sssD ss~xp0se,+)p0 Gsss]{fH+ Gs\xG$BEW-co G$H$M-c wL*-cLBG$H$-c Gsb{ssc{ssd{sse{sssscssh{ssi{ssFssk{~sl{~sm{~sK~sp{ @so{sso0sr{ @sq{ssn0ss{ sst{ ssu{ ssv{ ssY ssr@ssy{Pm0sz{Psm0 ss{w{g=Y[ b#'$z[ yx Gy%]y7NS|[ yN]y+Gy7N L^p[ r LdqN}y%y7} LOury}yGy7}y%;y7}1 LMury};yGy7}y%y7}|6tr6ty}yRGy7}pNo maplist entries found matching the current command line (mapname search). Performing blind switch to index 9Sx &of current maplist![pxqx &xqy& Gs}{ss~{ss{ssssA|WsB|WsC|WsE| @sD|ssl0sF| ssG| ssH| ssI| ssJ| ssl0 ssL|SsM|SsN|SsO|Ss ss`{L$t\1dL$'-N$BL$h0-N$ GsN$ssS|ssssV|zsW|zszs_z@$sZ|[s[s\|@s^|@@]|ssi0s_|@k0s`|@sa|@sb|@sc|@sd|Zse|Zsf|Zsg|Zsi|@Zh|ssI&sk|@Zj|ssI&sl|Zsm|Zsn|Zso|Zsp|Zsq|Zsr|Zss|Zst|vsu|vsv|vsw|vsx|vsy|vsz| ss{| ss|| ss}| ss~| ss@} @s|ssj0sB} @sA}sssD} @sC}sssI& ssX|@$sI}ssP|O}o A' GsJ} ssL} ssLHf0sE}@$sM}@$sh}ss@ssL&R}uQ* GsssQ}T}sRP GsssN}@$sX}rO&sU}@$sY}P&sZ}P&s[}ssFssW}@$s\}@$s_}sO&sa}Esb}sc}sd}sse}ssf}ssg} ssi} ssJ~ssj} sc0sk} ssl}~sm}~sn}~so}bsp}bsq}ssr}sss} ssu}ssssv}b0sw}sx}ssy} ssz}ps{} ss|}ps}} ss~}ps}ps@~ ssB~sA~sssnsO&s ssMt s]}@$$* Qec  " "" "Gd"sn @{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{W{UU{UU{UU{UUU{UU{U{{{{{{{{{{{{{{{{{{{{{{{{W{WUU{s{s{s{s{s{s{s{UUU{UU{{{{{{{{{{{{{{{{{{{{{_U{s{s{s~{sU{sUU{sUU{sUU{sUU{sU{s {s*{UU{{{{{{{{{{{{{{{{{{{_UU{s{s{s~_UsMksMk_sMkUUs cs csMkUsMksMk +{s{s *{s {{{{{{{{{{{{{{{{{WW{s{sz{s~_UUsMk~_Mk cMk c_UMkZ_ cZ cZMkZ*Mk cs csMk+{sU{s**{s{{{{{{{{{{{{{{{{s{s{s~_WUsMk^WMk cz^ cZ^ cRZR~UZIJZIJZR*U cR*MkZ*Mk c +sMk /{s{s **{UU{{{{{{{{{{{{{{___W{s{sz^^WsMk~^Mk cx^ cZz^ZIJRIJ^WRBUIJ9IJBURB*ZIJZR - cZ /Mk c -sMk /{s{s {{{{{{{{{{{{{{WUUU{ssMks c~ cZxZRxX^RB~IJ9~_B1B1UB1B9 UIJ9 *RB + cRMkZ++sMk{s{s **+{U{{{{{{{{{{{{{s{szz~sMkxxMk chxx^ cRzRIJxXXIJ9z~91xz1E)~1E)WU1E) U9E)*B1+IJ9 +/ZIJ+ cZ--%Mk c -sMk {s{s{{{{{{{{{{{{____{s{s~^^^sMk~~^^MkZZR`pxxRBzz~B9x^^^9E)~~E)!E)!WE)!*1E)U9E)++B9 ---RB ++/ cRMk c--%sMk/---{s{s{{{{{{{{{{{{____{s{s^^__sMk^^^^ cZZIJIJBxxxxB1zzz1E)xxxxE)!~~~!E)!UUUE)!////1E) B1++++RB/ cRMk csMk---{s{s {{{{{{{{{{{{___{s{s^_^^sMk^^^^MkZzZRXXxxIJBxpp`B1z1E)xxxE)!E)!UUWE)!E)!/ 9E)B955--RB//+ cRMk c%-sMk----{s{s{{{{{{{{{{{{___{s{s^^~~sMk~~~xMk c^^^Z cR~~zRBzB9^xx91W^Zx1E)UW~E)!E)!*1E)/ 91-- IJ9/+RIJ%- cR++Mk c--- sMk//+ {s{s{{{{{{{{{{{{{s{szsMkMk cxx cZ^~xZIJ~zIJB^XxB9W^z91W^9E)9E)*91 B9-+RB+ZIJ++ cZ- Mk c sMk {s+*{UU{{{{{{{{{{{{{UWWW{s誨{sWW_^sMkW_^~MkZ cR~ZIJ_~RBW_IJ9WB9UB9U*IJ9RB*ZIJ+ cZյ/Mk c- sMk+{s{s** {{{{{{{{{{{{{{_{s{s~zsMkMk c蠀MkZ~ cRZIJ~RIJU~RBRBZIJZRյ+ cZյ- MkZ* sMksMk {s**{s{{{{{{{{{{{{{{{UUW_{s{sW^~sMk~s cMk cU_z cZ_ cR cR cR cZU MkZMk cս+sMkUsMk/ {s{s {U{{{{{{{{{{{{{{{_{UUUW{sꪨ{sW~sMksMkWMk cMk cUMk cUMk cUMk c s csMk+ sMk+{s{s* {U{{{{{{{{{{{{{{{{{_{UUU_{s{s~ꪪ{sU_sMksMksMksMksMk{sUU{sU{s {s* {UU{{{{{{{{{{{{{{{{{{{{UU_{s{s{s{s{sU{s{s{s*{s*{s{U{{{{{{{{{{{{{{{{{{{{{{_{UU{UUU_{s|{UUUU{s*{s{UUU{UU{{{{{{{{{{{{{{{{{{{{{{{{{{{{W{W{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{~ @@{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{_{U{U{{{{{{{{{{{{{_UU{s~{sU{sU{s*{U{{{{{{{{{{s{Mk~s c_MkZMkZs c {Mk *{s {{{{{{{{_WW{MkzsZ~ cIJ_ZBWZB cIJ*sZ +{s+-{{{{{{{{ss cx cIJxzIJ1~9E)_BE)*R9 / cR --s c +/{s {{{{{{{shhxxs czz~^ZBxxxBE)zz~E)!^^E)! /55BE)+//-ZIJ ---s c----{s {{{{{ꪪ{{sxhh`s c~zzxZBxxBE)zz1!_1!*B15-- ZIJ-- s c---/{s {{{{{{{sࠀs cx cR^xR9^zB1WB1տ*R9/ MkR/+{Mk{s {{{{{{{___{s^^xs c^~MkR_ cIJU cIJMkR s c+ {s-+ {{{{{{{ꪪ{{UW_{sW^sMkWs cWs c{Mk{s+{U{{{{{{{{ꪪ{{U_{s{s{s{s*{{{{{{{{{{{ꪪ{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{@@ @{{{{{{{{{{{_s_s{{{{{{ c~MkIJWMkIJ { c +-{{{szzsIJxxxB!~^IJ! /sIJ /--s{{ꪪszsIJxxIJE)V^IJE)/ sR--- s{{{~{ cxsRWsRտ*{ c- {{{{ꪪ{sꪪs{{{{{{{ꪪ{{{{  @{{W{{{zz~Mk!xs! /-{{~zs!xsE)-/ {{ꪪ{_{{ @{1`{1 {9`{9   {Z, {Z@AK Z*JRsssM~[0zLG>wi*i)z[0S$]0^0_0`0a0S$ GsssO~X0jx4 +&wi*i jX0'( GsH~@$sY~U0hr '$wi*ihU0V0 GsN~@$sR~sss~sU~ ssV~ssW~ ssD ssCQ0X )Q0)P0 GsUR0Gl" '$wi*iGR0S0 GsssX~K0c?)K0)J0)F0)E0)C0 Gs^~L0r^c :5wi*$irL0M0N0O0'( Gsss`~G0uWk 50wi*iuG0H0I0'( Gsssc~D0eK% wi*i eD0( Gs[~B0d)B0)/)~/)}/ Gssse~@0k?*%wi*ik@0A0' Gssssd~t5w&!wi*it'( Gsa~|/e4)|/){/)z/)y/)u/)s/)r/)q/)p/)o/ GsG}t/^"wL*L ^t/ Gsa@ssk~h~l%0'ri*apaila Gss&sl~v/h&/*wi*ihv/w/x/* GsiU$r0ri*iU$-i rU$ Gsg~^g& c\76O^76O^\&6v\6O^Mutator6S\6O^| Gs@ssm~r~k.! GsY$ssf~n/f /)n/)l/)b/)[/)Z/)Y/)X/)V/)U/ Gs@sr sh$\/m/t$m/ %c/ B&)r[*k/p[Ha/ ~,Ur[*[r%d/[H ,r[*rY$*p[He/.MY$|f/ ,r[*p[H]/ ,\/ ,\$ +,G 9,g/ W, [Hh/ e, i/ s, j/ , F , D ,[HB ,] ,r[*\p[H[  G so~^/a4="3*wL*ELa^/EE Gs@ssu~ssv~ssw~ssh$QW/tW/%,R/ G sss@ss}~ss~~s~sssA@s@ssT/sBssT/ssD s~sE ssF ssG ssH ssI ssJ ssK ssL ssM ssN ssO ssP ss ssR/vpI|vNEEDPW%)|vWRONGPW&C|vGAMESTARTED,, G sSs~sTssUssssWssXssYssZss[s~s\ss]ss^ss_ss`ssa ssb ssS/ sS/ssselsflsglshlsQ/lQ/sP~@$si@$sj@$sVOsP@Osm@OsEssqKssKscsstKP/suKsvKswssxKsKsK&P/#$w~*~#4w|*|#Nwg*g#hwZ*Z#ww*w#wn*n#wv*v# GsL&y|6$w~*~|}Hw|*||}lwg*g|}wZ*Z|}ww*w|}wn*n|}wv*v|} Gsoss{ss|ss}ss~ssss@ssCssssfrh# 9?k$ G sssGYsHYsYO/sEssL/@fKssN/sIsszfsOssUssNssM/ssmJ#.#&V&W&-z-z GslRT5RL/ %$V&W&O <$-z-zO L$-z'O  GsUssssPssVssssmA# aA%#7N%O%N*O*DwO*O#^wv*v# GslYX&AA7NA%>7N%OANEO*iwO*OX&Y&wv*vX&Y& GsWss[ssLss_[K/s`[sa[sb[sc[sK/[s]ssgsJ/sGde#{2 Y. G shwI/sqwsLsssE/ssD/X D/s\ssovspvsqvsrvssvstvsuvZ&svvZ&swvsxvsysszss{ss|ssZ&ssmss}ssEnslb&c&n-\b& E$-\(Ec&"-C'k h$-\(E-C'k 9:b&9:$-\'Ec&"-C( GsssmC#5-\(E-C( GsGk`#s /E/U.F/V.G/W.H/X. G sIssJpC/sKpsL ssMpsNpsOpsPpsC/psRssScsTcsUcscsWmsXmsss{isH//============================================================================= // ZoneTrigger. //============================================================================= class ZoneTrigger extends Trigger; // // Called when something touches the trigger. // function Touch( actor Other ) { local ZoneInfo Z; if( IsRelevant( Other ) ) { // Broadcast the Trigger message to all matching actors. if( Event != '' ) foreach AllActors( class 'ZoneInfo', Z ) if ( Z.ZoneTag == Event ) Z.Trigger( Other, Other.Instigator ); if( Message != "" ) // Send a string message to the toucher. Other.Instigator.ClientMessage( Message ); if( bTriggerOnceOnly ) // Ignore future touches. SetCollision(False); } } // // When something untouches the trigger. // function UnTouch( actor Other ) { local ZoneInfo Z; if( IsRelevant( Other ) ) { // Untrigger all matching actors. if( Event != '' ) foreach AllActors( class 'ZoneInfo', Z ) if ( Z.ZoneTag == Event ) Z.UnTrigger( Other, Other.Instigator ); } } sj9//============================================================================= // ZoneInfo, the built-in Unreal class for defining properties // of zones. If you place one ZoneInfo actor in a // zone you have partioned, the ZoneInfo defines the // properties of the zone. // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class ZoneInfo extends Info native placeable; #exec Texture Import File=Textures\ZoneInfo.pcx Name=S_ZoneInfo Mips=Off MASKED=1 //----------------------------------------------------------------------------- // Zone properties. var skyzoneinfo SkyZone; // Optional sky zone containing this zone's sky. var() name ZoneTag; var() localized String LocationName; var() float KillZ; // any actor falling below this level gets destroyed var() eKillZType KillZType; // passed by FellOutOfWorldEvent(), to allow different KillZ effects var() bool bSoftKillZ; // 2000 units of grace unless land //----------------------------------------------------------------------------- // Zone flags. var() bool bTerrainZone; // There is terrain in this zone. var() bool bDistanceFog; // There is distance fog in this zone. var() bool bClearToFogColor; // Clear to fog color if distance fog is enabled. var const array Terrains; //----------------------------------------------------------------------------- // Zone light. var vector AmbientVector; var(ZoneLight) byte AmbientBrightness, AmbientHue, AmbientSaturation; var(ZoneLight) color DistanceFogColor; var(ZoneLight) float DistanceFogStart; var(ZoneLight) float DistanceFogEnd; var transient float RealDistanceFogEnd; var(ZoneLight) float DistanceFogEndMin; var(ZoneLight) float DistanceFogBlendTime; var(ZoneLight) const texture EnvironmentMap; var(ZoneLight) float TexUPanSpeed, TexVPanSpeed; var(ZoneLight) float DramaticLightingScale; var(ZoneSound) editinline I3DL2Listener ZoneEffect; //------------------------------------------------------------------------------ var(ZoneVisibility) bool bLonelyZone; // This zone is the only one to see or never seen var(ZoneVisibility) editinline array ManualExcludes; // No Idea.. just sounded cool //============================================================================= // Iterator functions. // Iterate through all actors in this zone. native(308) final iterator function ZoneActors( class BaseClass, out actor Actor ); simulated function LinkToSkybox() { local skyzoneinfo TempSkyZone; // SkyZone. foreach AllActors( class 'SkyZoneInfo', TempSkyZone, '' ) SkyZone = TempSkyZone; if(Level.DetailMode == DM_Low) { foreach AllActors( class 'SkyZoneInfo', TempSkyZone, '' ) if( !TempSkyZone.bHighDetail && !TempSkyZone.bSuperHighDetail ) SkyZone = TempSkyZone; } else if(Level.DetailMode == DM_High) { foreach AllActors( class 'SkyZoneInfo', TempSkyZone, '' ) if( !TempSkyZone.bSuperHighDetail ) SkyZone = TempSkyZone; } else if(Level.DetailMode == DM_SuperHigh) { foreach AllActors( class 'SkyZoneInfo', TempSkyZone, '' ) SkyZone = TempSkyZone; } } //============================================================================= // Engine notification functions. simulated function PreBeginPlay() { Super.PreBeginPlay(); // call overridable function to link this ZoneInfo actor to a skybox LinkToSkybox(); } // When an actor enters this zone. event ActorEntered( actor Other ); // When an actor leaves this zone. event ActorLeaving( actor Other ); sld&f&zn-dd& E$-d({f&"-z'k h$-d({-z'k 9:d&9:$-d'{f&"-z( Gsu//============================================================================= // xWeatherEffect // Copyright 2001 Digital Extremes - All Rights Reserved. // Confidential. //============================================================================= class xWeatherEffect extends Actor native exportstructs placeable; #exec Texture Import File=Textures\S_Wind.tga Name=S_Wind Mips=Off struct WeatherPcl { var Vector Pos; var Vector Vel; var float Life; var float Size; var float HitTime; var float InvLifeSpan; var float DistAtten; var byte frame; var byte Dummy1; var byte Visible; var byte Dummy2; }; var() enum EWeatherType { WT_Rain, WT_Snow, WT_Dust, } WeatherType; var() int numParticles; var transient int numActive; var transient Box box; var transient Vector eyePos; var transient Vector eyeDir; var transient Vector spawnOrigin; var transient Vector eyeMoveVec; var transient float eyeVel; var() float deviation; var() float maxPclEyeDist; var() float numCols; var() float numRows; var transient float numFrames; var transient float texU; var transient float texV; var transient bool noReference; // this effect isn't referenced by any volume var Vector spawnVecU; var Vector spawnVecV; var() Vector spawnVel; var() RangeVector Position; var() Range Speed; var() Range Life; var() Range Size; var() Range EyeSizeClamp; var(Force) bool bForceAffected; var transient array pcl; var transient array pclBlockers; sssm^#,A-d({-z( GscOsdOsOsssesshQB/siQA/sjQskQslQsmQsnQsA/Qsspsss ss~ Tsfsssssss@/.ivs&i/.i.i GsQ.//============================================================================= // xProcMesh - Procedural mesh actor // Copyright 2001 Digital Extremes - All Rights Reserved. // Confidential. //============================================================================= class xProcMesh extends Actor placeable exportstructs native; struct ProcMeshVertex // struct reordering breaks this { var Vector Position; var Vector Normal; var Color Color; var float U,V; }; var const array Vertices; var const array SectionOffsets; var() float Dampening; // should be less than < 1.0f var() Range DampeningRange; var() Range MovementClamp; var() Range ForceClamp; var() float ForceAttenuation; var() float Tension; var() float RestTension; var() bool CheckCollision; var() float Noise; var() Range NoiseForce; var() Range NoiseTimer; var transient float NoiseCounter; var() enum EProcMeshType { MT_Water, MT_Deform, } ProcType; var(Force) bool bForceAffected; var() bool bRigidEdges; var const transient pointer pProcData; // todo: take this out and serialize most things var() class HitEffect; var() class BigHitEffect; var() float BigMomentumThreshold; var() float BigTouchThreshold; var() float ShootStrength; var() float TouchStrength; var() float InfluenceRadius; // support fluid funcs // Ripple water at a particlar location. // Ignores 'z' componenet of position. native final function ProcPling(vector Position, float Strength, float Radius, out vector EffectLocation, out vector EffectNormal); // Default behaviour when shot is to apply an impulse and kick the KActor. simulated function TakeDamage(int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, class damageType) { local vector EffectNormal; local vector EffectLocation; ProcPling(hitLocation, ShootStrength, 0, EffectLocation, EffectNormal); if(VSize(Momentum) > BigMomentumThreshold && BigHitEffect != None ) spawn(BigHitEffect, self, , EffectLocation, rotator(EffectNormal)); else if ( HitEffect != None ) spawn(HitEffect, self, , EffectLocation,rotator(EffectNormal)); } simulated function Touch(Actor Other) { local vector touchLocation; local vector EffectNormal; local vector EffectLocation; local float touchValue; Super.Touch(Other); if ( (Other == None) || !Other.bDisturbFluidSurface ) return; touchLocation = Other.Location; touchValue = VSize(Velocity); ProcPling(touchLocation, TouchStrength, Other.CollisionRadius, EffectLocation, EffectNormal); if(touchValue > BigTouchThreshold && BigHitEffect != None ) spawn(BigHitEffect, self, , EffectLocation, rotator(EffectNormal)); else if ( HitEffect != None ) spawn(HitEffect, self, , EffectLocation,rotator(EffectNormal)); } sA sz_.s{_s_s}isisTs@TsATsBTsCTsDTsETsFTs ss\u_#n] i$ G sIIsJIsKIsLIsMIsNIssIsQssRssSsssssscqUY$*fg^*   " " " " Gd"sbT @ѷ]]㹹]ʹ]ɹR R6 `ȹS=WtR6 %N|aǹ ~"R5 %N|cƹ! %N|eƹ̱.fŹ nù̮NNp{qwxruiuslYk\hL^[wvZJUTmmXHIDggKCG>VX;?>9EFNN/:20A<&'+(),74-$ #*%N|} QO#18R5 %N|3BPR6 %N|@yzR6 M任___]_bdejopq sTsU[$*moe*   " " " " Gd"sX @GиGzzzzzzzzzzzzzzzzzzzzzzzzzzGzzzzzzzzzzzzzzzzzzzzzzzzzzGzzzzzzzzzzzzzzzzzzzzzzzzzzIzzzzzzzzt79=zzzzzzzzzzzzzzJzzzzzzz<9;zzzzzzzzzzzzzLzzzzzzl 'zzzzzzzzzzzzNzzzzzz&0:zzzzzzzzzzzOzzzzzzh!;yzzzzzzzzzQzzzzzzz8oqҮ>>Dpo""bA??am""x ZXXXYXZ[ZYXXV33422BV""135E43,+*++**#"$(("" h ]e1,,+)))#"" dthhyzzshggggggggggdc===cggghuzzzzwuuuttttttttjfcc=hwwxzzzzzzzzzzzzzzzzzzygcdfxzzzzzzzzzzzzzzzzzzzzzxhfivzzzzzzzzzzzzzzzzzzzzzzzzzyzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzѦHHHGHKMNPRST{} s@   ! %#""$#)&(%0- !!!'&"&%!('!)) ,)",+$.-&/.,,,$0.#52%31%41%42'95'<9(53+43(:7(>:+<8*?;.=:,?=666888)@<.B?,D@,GC.KF/PJ6DB1JF0MH8LI1PJ;PL5WQ7UP7ZS7]V:ZU:aZ<`Xvț/xțț`tyqwȂ-`ȅ[K;O" HțȽbȆ}}-țȫcȁu&-ȭŮdm|7N}ȿҮdȃNo]ȆȻ殬ekCE 1/ȪళL@3 ?\Ȇ "ȨѴY<  9$I" TȨ³<4  5832XGȪ嵩JAErQ(Ȼ鴹Ɇi% :M=VȿӯuS6,+#ȭƯȃn5C%'zȫȅL*9CFp.!țȽgfDBsZ)0țȅȆ~lW{PțȆțȆț___^_`abcdde s@ "!$#"""&&&'))****,,...+32.33/433432664653876885<;8999=<===8A?;AAEE?HG?IH>XRAAABDDAHF@JHALKBNLEMKIIINNNCPNDPNDRPFTRGVTD^YKUSJVTMRQOXWJZXJ\ZL^[N_\RRRUVUR]ZVYYYZZ\\\]^^^^^E`[Fa\Jb^Id_Ma_Ld^KfaOb`OicApgAqhBqhCsiCrjDskDtkFvlGwnHwoIypJzqJ{rM}tNwPeaWcaRifTkhUmiVol[aa^bbZkhYsn_wsZxr^|w```bbbagfdddfffhhhjjjmmmlnmooobvs`xtezuc|xf~yn~{qqqrrrtttwwwxxx{{{|||~~~OwPyQzR{S{T|U}Va{g|i|WYY[\]^n`beghjkklqx}{}~ltswz{}½Ŀý½soWte i$ G s@       !&!$!%"($+(.*0+51$&&"*(%,*&0-)0-"60!;6&:5%<7*42-31/74)<7-96(;82330=:5994=:'A<'E>(B=(D?-A<-D?/F@-HB.LF1GB5GC0JD3NI9GC2QL4QK7UO5\U9YR8\V>\U;_XAECEGGFKJBWSA[UEZV@]XG\YKTQMSQJYUMZVH]YSVVPYWS\[Db\Jb]Hd_Sb_Wa_GibJgbApgAqhDskDtkFvmHwoJzqM}uRgcWjfZa`Xgd]dc\jgXjh_jh^njVuoXso]pmW~w\wrahebmldkheolhiiinmlmlnpog}xjrqkusnvuqrrruttvvuyxyzyz||~~~OwQzS{U}WY[_\^iim`behjkl~qt}ltswz} /269;<9&*() , . ,3<6L=R3IK[N]\g]hosjprvy|oyuCZEZRc]l½ĿƿUa$*_]g*   " " " " Gd"sm @ywusssss0;0ϛ0RLNR0Q'%P2GO F3+ )5KJ7F /9;=CM?B $,#-++(A  T*VHDE.*X*ZIII*\&&&~*^&&&*`&&&}b&&&!&dz&&&|{"!!&fx&&&!!&hv&&&&&&&&&&&&&&&&&&!&it&lt&nt*ptПrtq11101468:<>@SUWY[]_acegjkmprro s@%%.&)"3+ 4, 5-:2<4>6,,,..-000555556565655;;;;;<;<;;<<<;;<;<@8A:D<G?IA!IB"LD%NF,MG&PH)RJ*TL.SL,VN.XP0UN0ZR3]U4^V:ZS8ZT?ZU7aY9bZ:d\<`Y=f^8i_?iaBBBJJJ@XSAZU@_YF_[SSSSSTSTSSTTTSS\\\Cc\Cf_AjbBldDnfIjdApgAqhBqhCsiCrjDskDtkFvlGwnIrjKslIumHwoJtlJunLvnIypJzqJ{rNxpM}tNwQd`RjeXifXmi^ljSpkSsm^pmPyqR|tW{tU~v^vqaaaeeebolmmmbtpevsb{vezucze~zjsqkusmtsnuti}zo|ptsuuuqxvsxxwzzyzzy}||{|}}}OwPyQzR{S{VxT|U}VXzZ|]~s}WYY[^\]^`ce`bikeghjknkl~pult{z}swz~}½Ŀ»Uu$*cbg   " " " " Gd"sv @Ð;ѿ;׳; $%((((%%%% -;׳=\]ֳ>9:[puֳ@ZRikt~ֳBbalQyqLK_ֳC231.nmֳE 0+'OÏֳG J`o^M8JֳH" !ֳI )#*# ,ֳS  &/׳7Uѿ7W7YNNN7c6667e6667g666j66646r6665446s666446v66666666666666666646w6z6|7ش<<<; Tags; // Perform Actions here ? event Created() { // Build a list of accessible privileges ? } sT///============================================================================= // xPickUpBase. // This is the base class of all pickup-spawners. When placing pickups in // levels, place pickup bases instead since these will spawn the actual // pickups. //============================================================================= class xPickUpBase extends Actor abstract placeable native; var(PickUpBase) class PowerUp; // pick-up class to spawn with this base var(PickUpBase) float SpawnHeight; // height above this base at which the power up will spawn var(PickUpBase) class SpiralEmitter; // emitter which spawns particles when myPickup is available var(PickUpBase) float ExtraPathCost; // assigned to the inventory spot var PickUp myPickUp; // reference to the pick up spawned with this base var Emitter myEmitter; // reference to the emitter spawned with this base var InventorySpot myMarker; // inventory spot marker associated with this pick-up base var(PickUpBase) bool bDelayedSpawn; /* The UnrealEd console command "NewPickupBases" will apply the following properties to this pickup base * Used to apply UT2004's new pickup base staticmeshes because we can't just universally change StaticMesh * as that would cause them to be unlit in all old maps */ var StaticMesh NewStaticMesh; var vector NewPrePivot; var float NewDrawScale; simulated event PostBeginPlay() { Super.PostBeginPlay(); if ( PowerUp != None ) { if( Level.NetMode != NM_Client ) { SpawnPickup(); if ( bDelayedSpawn && (myPickup != None) ) { if ( myPickup.IsInState('Pickup') ) myPickup.GotoState( 'WaitingForMatch' ); if ( myPickup.myMarker != None ) myPickup.myMarker.bSuperPickup = true; } } if ( Level.NetMode != NM_DedicatedServer ) PowerUp.static.StaticPrecache(Level); } if( !bHidden && (Level.NetMode != NM_DedicatedServer) ) { myEmitter = Spawn(SpiralEmitter,,,Location + vect(0,0,40)); SetDrawScale(Default.DrawScale); } } function bool CheckForErrors() { local Actor HitActor; local vector HitLocation, HitNormal; HitActor = Trace(HitLocation, HitNormal,Location - Vect(0,0,10), Location,false); if ( HitActor == None ) { log(self$" FLOATING"); return true; } return Super.CheckForErrors(); } function byte GetInventoryGroup() { return 0; } function TurnOn(); function SpawnPickup() { if( PowerUp == None ) return; myPickUp = Spawn(PowerUp,,,Location + SpawnHeight * vect(0,0,1), rot(0,0,0)); if (myPickUp != None) { myPickUp.PickUpBase = self; myPickup.Event = event; } if (myMarker != None) { myMarker.markedItem = myPickUp; myMarker.ExtraCost = ExtraPathCost; if (myPickUp != None) myPickup.MyMarker = MyMarker; } else log("No marker for "$self); } sQ ssRssS ssJ ssX.class xMaterialTrigger extends Actor; // deprecated /* var() editinline Material Target; var() Material MaterialA; var() Material MaterialB; var() enum EMatAction { MTA_SwapShaderDiffuse, MTA_SwapShaderSelfIllum, MTA_SwapShaderSpecular, MTA_SwapCombinerMat1, MTA_SwapCombinerMat2, MTA_TickShaderSpecMaskColor, MTA_NoAction, } MatTrigAction; var() enum EMatTick { MTT_FadeSpecularConst, MTT_PulseSpecularConst, MTT_NoAction, } MatTrigTick; var() float MatTickValue; var transient float tickAccum; var transient float tickPtA; var transient float tickPtB; var transient bool triggerOn; simulated function float Pulse( float x ) { if ( x < 0.5 ) { return 2.0 * ( x * x * (3.0 - 2.0 * x) ); } else { return 2.0 * (1.0 - ( x * x * (3.0 - 2.0 * x) )); } } simulated function TickConstantColor( ConstantColor cc, float t ) { local float f; local float alpha; tickAccum += t; if ( tickAccum >= 1.0 ) { tickAccum = 1.0; } if ( MatTrigTick == MTT_FadeSpecularConst ) { if ( tickAccum >= 1.0 ) { Disable('Tick'); } alpha = tickPtA + tickAccum * ( tickPtB-tickPtA ); } else if ( MatTrigTick == MTT_PulseSpecularConst ) { alpha = tickPtA + tickAccum * ( tickPtB-tickPtA ); f = Level.TimeSeconds * MatTickValue; f = f - int(f); cc.Color.A = Pulse(f) * alpha; } cc.Color.A = alpha; //log("TickConst"); } simulated function Tick( float t ) { Super.Tick(t); if( Target.IsA('Shader') && Shader(Target).SpecularityMask.IsA('ConstantColor') ) TickConstantColor( ConstantColor(Shader(Target).SpecularityMask), t ); } simulated function ShaderAction( Shader sh ) { //log("ShaderAction " $ sh ); switch( MatTrigAction ) { case MTA_SwapShaderSpecular: sh.Specular = MaterialA; break; } } simulated function CombinerAction( Combiner cb ) { //log("CombinerAction " $ cb ); } simulated event Trigger( Actor Other, Pawn EventInstigator ) { local Material tmp; tmp = MaterialA; MaterialA = MaterialB; MaterialB = tmp; triggerOn = !triggerOn; if(Target.IsA('Shader')) { ShaderAction(Shader(Target)); } else if (Target.IsA('Combiner')) { CombinerAction(Combiner(Target)); } else { log("Incompatible material in xMaterialTrigger",'Warning'); } if( Target.IsA('Shader') && Shader(Target).SpecularityMask.IsA('ConstantColor') ) { if( triggerOn ) { // fade up tickPtA = ConstantColor(Shader(Target).SpecularityMask).Color.A; tickPtB = 255.0; } else { // fade down tickPtA = ConstantColor(Shader(Target).SpecularityMask).Color.A; tickPtB = 0.0; } tickAccum = 0.0; switch( MatTrigTick ) { case MTT_FadeSpecularConst: case MTT_PulseSpecularConst: Enable('Tick'); break; } } } */ sV@ssW@ssy.ssc sTlY+Oʁ)sss-sl2class xMaterialController extends Actor placeable; var() Material Target; var() Material SwapMaterialA; var() Material SwapMaterialB; var() enum EMatAction { MTA_SwapShaderDiffuse, MTA_SwapShaderSelfIllum, MTA_SwapShaderSpecular, MTA_SwapCombinerMat1, MTA_SwapCombinerMat2, MTA_NoAction, } MatTriggerAction; var() enum EMatTickFunc { MTF_PulseConstantColor, MTF_FadeConstantColor, MTF_NoAction, } MatTickFunc; var() float MatTickValue; var transient float tickAccum; var transient float tickPtA; var transient float tickPtB; var transient bool triggerOn; simulated function float Pulse( float x ) { if ( x < 0.5 ) { return 2.0 * ( x * x * (3.0 - 2.0 * x) ); } else { return 2.0 * (1.0 - ( x * x * (3.0 - 2.0 * x) )); } } simulated function PostBeginPlay() { tickPtA = 255.0; tickPtB = 255.0; } simulated function TickConstantColor( ConstantColor cc, float t ) { local float f; local float alpha; tickAccum += t; if ( tickAccum >= 1.0 ) { tickAccum = 1.0; } if ( MatTickFunc == MTF_FadeConstantColor ) { if ( tickAccum >= 1.0 ) { Disable('Tick'); } alpha = tickPtA + tickAccum * ( tickPtB-tickPtA ); } else if ( MatTickFunc == MTF_PulseConstantColor ) { alpha = tickPtA + tickAccum * ( tickPtB-tickPtA ); f = Level.TimeSeconds * MatTickValue; f = f - int(f); alpha = Pulse(f) * alpha; } cc.Color.A = alpha; //log("TickConst alpha:" $ alpha ); } simulated function Tick( float t ) { Super.Tick(t); if ( MatTickFunc == MTF_NoAction ) return; if( Target.IsA('Shader') && Shader(Target).SpecularityMask.IsA('ConstantColor') ) TickConstantColor( ConstantColor(Shader(Target).SpecularityMask), t ); else if ( Target.IsA('ConstantColor')) TickConstantColor( ConstantColor(Target), t ); } simulated function ShaderAction( Shader sh ) { //log("ShaderAction " $ sh ); switch( MatTriggerAction ) { case MTA_SwapShaderSpecular: sh.Specular = SwapMaterialA; break; } } simulated function CombinerAction( Combiner cb ) { //log("CombinerAction " $ cb ); } simulated event Trigger( Actor Other, Pawn EventInstigator ) { local Material tmp; if ( MatTriggerAction == MTA_NoAction ) return; tmp = SwapMaterialA; SwapMaterialA = SwapMaterialB; SwapMaterialB = tmp; triggerOn = !triggerOn; if(Target.IsA('Shader')) { ShaderAction(Shader(Target)); } else if (Target.IsA('Combiner')) { CombinerAction(Combiner(Target)); } else { log("Incompatible material in xMaterialTrigger",'Warning'); } if( Target.IsA('Shader') && Shader(Target).SpecularityMask.IsA('ConstantColor') ) { if( triggerOn ) { // fade up tickPtA = ConstantColor(Shader(Target).SpecularityMask).Color.A; tickPtB = 255.0; } else { // fade down tickPtA = ConstantColor(Shader(Target).SpecularityMask).Color.A; tickPtB = 0.0; } tickAccum = 0.0; switch( MatTickFunc ) { case MTF_FadeConstantColor: case MTF_PulseConstantColor: Enable('Tick'); break; } } } st0s\1s]2s^3s_4s`5sa6sf ssessw.s0si ssv@ssm.H sk@ssu.@ssmsswss}ssAN uZ60EwN n*N nNe$d$c$a$wN Q*N QnNe$d$c$a$-Oqe$wN >*wN >Q *N >y.<Kte$d$c$a$@N >p G [ExB@p&ʁ)|;|;|;iH|;iHF)UiHF)UiH|;iH|;iH|;3}F)Um`$?>+ss@sx.st@ssss0sv@susssx@sws@ssx.@ssgWV1 Gs@ssz@ssQ_//============================================================================= // xEmitter - particle emission! renamed to avoid conflict with Emitter // Copyright 2001 Digital Extremes - All Rights Reserved. // Confidential. //============================================================================= class xEmitter extends Actor native placeable; #exec Texture Import File=Textures\S_Emitter.tga Name=S_Emitter Mips=Off replication { unreliable if (Role == ROLE_Authority) mSpawnVecA, blockOnNet; } // particle system config... var(PclEmitter) enum ExParticleTypes { PT_Sprite, PT_Stream, PT_Line, PT_Disc, PT_Mesh, PT_Branch, PT_Beam, } mParticleType; // particle system config... var(PclEmitter) enum ExSpawningTypes { ST_Sphere, ST_Line, ST_Disc, ST_Cylinder, ST_AimedSphere, ST_StaticMesh, ST_Explode, ST_ExplodeRing, ST_OwnerSkeleton, ST_Test, } mSpawningType; var(PclEmitter) bool mRegen; var(PclEmitter) bool mRegenPause; var(PclEmitter) float mRegenOnTime[2]; var(PclEmitter) float mRegenOffTime[2]; var(PclEmitter) int mStartParticles; // at runtime also, you can set this > 0 to spawn this many next tick var(PclEmitter) private int mMaxParticles; var(PclEmitter) float mDelayRange[2]; var(PclEmitter) float mLifeRange[2]; var(PclEmitter) float mRegenRange[2]; var(PclEmitter) float mRegenDist; var(PclEmitter) Name mSourceActor; var(PclEmitter) Name mChildName; var xEmitter mChildEmitter; var(PclEmitter) StaticMeshActor SourceStaticMesh; var(PclEmitter) bool bSuspendWhenNotVisible; var(PclVisuals) bool mDistanceAtten; var(PclMovement) vector mDirDev; var(PclMovement) vector mPosDev; var(PclMovement) vector mSpawnVecA; var(PclMovement) vector mSpawnVecB; var(PclMovement) float mSpeedRange[2]; var(PclMovement) bool mPosRelative; var(PclMovement) float mMassRange[2]; var(PclMovement) float mAirResistance; var(PclMovement) bool mCollision; var(PclMovement) float mOwnerVelocityFactor; var(PclVisuals) bool mRandOrient; var(PclMovement) float mSpinRange[2]; var(PclVisuals) float mSizeRange[2]; var(PclVisuals) float mGrowthRate; var(PclVisuals) color mColorRange[2]; // attenuation var(PclVisuals) bool mAttenuate; var(PclVisuals) float mAttenKa; var(PclVisuals) float mAttenKb; var(PclVisuals) enum EAttenFunc { ATF_LerpInOut, ATF_ExpInOut, ATF_SmoothStep, ATF_Pulse, ATF_Random, ATF_None, } mAttenFunc; var int mpAttenFunc; var(PclVisuals) bool mRandTextures; // choose a random texture for each instance of this emitter var(PclVisuals) bool mTileAnimation; // animate the particle from the set of tiles throughout life var(PclVisuals) int mNumTileColumns; var(PclVisuals) int mNumTileRows; var(PclVisuals) bool mUseMeshNodes; var(PclVisuals) bool mRandMeshes; var(PclVisuals) StaticMesh mMeshNodes[8]; // if using meshes as particle nodes var(PclVisuals) Texture mPosColorMapXY; var(PclVisuals) Texture mPosColorMapXZ; var(PclVisuals) Texture mLifeColorMap; var(PclSoftBody) float springK; var(PclSoftBody) float springD; var(PclSoftBody) float springMaxStretch; var(PclSoftBody) float springMaxCompress; // ver 1.1 var(PclMovement) float mColElasticity; // bounciness of particle collision 0-1 var(PclMovement) float mAttraction; // attractive force between particles var(PclMovement) bool mColMakeSound; var(pclBeam) float mWaveFrequency; var(pclBeam) float mWaveAmplitude; var(pclBeam) float mWaveShift; var(pclBeam) float mBendStrength; var(pclBeam) bool mWaveLockEnd; var(Force) bool bForceAffected; // native stuff. var transient int SystemHandle; var transient int Expire; var transient pointer mpParticles; // ptr to tarray var transient int mNumActivePcl; var transient pointer mpIterator; var transient int mbSpinningNodes; var transient vector mLastPos; var transient vector mLastVector; var transient float mTime; var transient float mT; // delta var transient float mRegenBias; var transient float mRegenTimer; var transient float mPauseTimer; var transient Box mBounds; var transient plane mSphere; var transient vector mDir; var transient int mNumUpdates; var transient int mAtLeastOneFrame; var transient int mRenderableVerts; var transient float mTexU; var transient float mTexV; var transient float mTotalTiles; var transient float mInvTileCols; var transient pointer mpSprings; // ptr to Spring class var transient int mNumSprings; var transient float mWavePhaseA; var transient float mWavePhaseB; var bool blockOnNet; var bool bCallPreSpawn; // v 1.4 var transient int mHeadIndex; event CollisionSound(); //amb event PreSpawned() { if ( !Level.bStartup ) { bSuspendWhenNotVisible = false; if ( Level.bDropDetail && (mMaxParticles > 5) && ((mParticleType == PT_Sprite) || (mParticleType == PT_Mesh) || (mParticleType == PT_Line)) ) { mMaxParticles = mMaxParticles * 0.65; mRegenRange[0] *= 0.8; mRegenRange[1] *= 0.8; mStartParticles = 0.65 * mStartParticles; } } } simulated final function float ClampToMaxParticles(float InPart) { return FMin(InPart, mStartParticles); } event Trigger( Actor Other, Pawn EventInstigator ) { mRegenPause = !mRegenPause; } simulated function UpdatePrecacheMaterials() { if ( mPosColorMapXY != None ) Level.AddPrecacheMaterial(mPosColorMapXY); if ( mPosColorMapXZ != None ) Level.AddPrecacheMaterial(mPosColorMapXZ); if ( mLifeColorMap != None ) Level.AddPrecacheMaterial(mLifeColorMap); super.UpdatePrecacheMaterials(); } static function PrecacheContent(LevelInfo Level) { if ( Default.mPosColorMapXY != None ) Level.AddPrecacheMaterial(Default.mPosColorMapXY); if ( Default.mPosColorMapXZ != None ) Level.AddPrecacheMaterial(Default.mPosColorMapXZ); if ( Default.mLifeColorMap != None ) Level.AddPrecacheMaterial(Default.mLifeColorMap); if ( Default.Skins.Length > 0 ) Level.AddPrecacheMaterial(Default.Skins[0]); } sSFclass XBoxPlayerInput extends PlayerInput config(User) transient; const InputMax = 32768; var() config float HScale; var() config float HExponent; var() config float HLookRateMax; var() config float VScale; var() config float VExponent; var() config float VLookRateMax; var() config bool bInvertVLook; var() config bool bLookSpring; var() float HLook; var() float VLook; var() float abx, abz; //tmp var() float wfor,wstr; //tmp var() float wafor,wastr; //tmp struct LookPreset { var() localized string PresetName; var() float HScale; var() float HExponent; var() float VScale; var() float VExponent; }; const NumPresets=4; var() config LookPreset LookPresets[NumPresets]; var() config string SelectedPresetName; var() float VelScale; var() float AccelScale; var() float DampeningFactor; var() float MinAccelComponent; const MaxFilterEntries=4; var() float ForwardFilter[MaxFilterEntries]; var() float StrafeFilter[MaxFilterEntries]; // Postprocess the player's input. function PlayerInput( float DeltaTime ) { local float FOVScale; if (bSnapLevel != 0) bCenterView = true; else if (aBaseZ != 0) bCenterView = false; abx = aBaseX; //tmp abz = aBaseZ; //tmp if (bInvertVLook) aBaseZ *= -1.f; // Remap the turn inputs to an exponential curve HLook = Remap(aBaseX, HScale, HExponent, HLookRateMax); VLook = Remap(aBaseZ, VScale, VExponent, VLookRateMax); // Check for Double click move // flag transitions bEdgeForward = (bWasForward ^^ (aBaseY > 0)); bEdgeBack = (bWasBack ^^ (aBaseY < 0)); bEdgeRight = (bWasRight ^^ (aStrafe > 0)); bEdgeLeft = (bWasLeft ^^ (aStrafe < 0)); bWasForward = (aBaseY > 0); bWasBack = (aBaseY < 0); bWasRight = (aStrafe > 0); bWasLeft = (aStrafe < 0); // Map to other input axes aForward = aBaseY; // if (Pawn != None) // VelToAccel(deltaTime); FOVScale = DesiredFOV * 0.01; //should be 1/defaultFOV aTurn = HLook * FOVScale; aLookUp = VLook * FOVScale; // Handle walking. HandleWalking(); } // exp remap + linear remap static function float Remap(float in, float scale, float exp, float ratemax) { local float out; local bool bNeg; in /= InputMax; if (in < 0) { bNeg = true; in *= -1.f; } out = (in * scale) + (in**exp); if (bNeg) out *= -1.f; out *= ratemax/(1.f + scale); return out; } //try doing this a a vector, instead of components function VelToAccel(float dt) { local vector x, y, z; // tmp wfor = aForward*VelScale; wstr = aStrafe*VelScale; GetAxes(Pawn.Rotation, x, y, z); aForward = GetComponentAccel(aForward, x, dt, ForwardFilter); aStrafe = GetComponentAccel(aStrafe, y, dt, StrafeFilter); // tmp wafor = aForward; wastr = aStrafe; } function float GetComponentAccel(float input, vector dir, float dt, out float filter[MaxFilterEntries], optional bool blog) { local float speed; local float error; local float output; // No input ... early out if (input == 0.f) return FilterOutput(filter, input); speed = Pawn.Velocity dot dir; error = input*VelScale - speed; output = DampeningFactor * error * AccelScale * dt; if (sign(output) != sign(input)) output = MinAccelComponent * sign(input); output = FilterOutput(filter, output); if (blog) log(Level.TimeSeconds$" "$input*VelScale$" "$speed$" "$error$" "$output); return output; } function float sign(float in) { if (in != 0.f) return Abs(in) / in; return 0.f; } function float FilterOutput(out float filter[MaxFilterEntries], float output) { local int i; local float total; output /= MaxFilterEntries; for (i=0; i // ==================================================================== class xAdminUserList extends xAdminBase; var private array Users; // Returns the number of Users in the list function int Count() { return Users.Length; } ///////////////////////////////////////////////// // CreateUser : Creates a new user function xAdminUser Create(string UserName, string Password, string Privileges) { local xAdminUser NewUser; NewUser = new(None) class'xAdminUser'; if (NewUser != None) NewUser.Init(UserName, Password, Privileges); return NewUser; } function Add(xAdminUser NewUser) { if (NewUser != None && !Contains(NewUser)) { Users.Length = Users.Length + 1; Users[Users.Length - 1] = NewUser; } } function xAdminUser Get(int i) { return Users[i]; } function Remove(xAdminUser User) { local int i; if (User != None) { for (i=0; i // ==================================================================== class xAdminUser extends xAdminBase; var string UserName; var string Password; var string Privileges; var string MergedPrivs; // Set on load or any Groups change var xAdminGroupList Groups; var xAdminGroupList ManagedGroups; // Post Load information var bool bMasterAdmin; function Created() { Groups = new(None) class'xAdminGroupList'; ManagedGroups = new(None) class'xAdminGroupList'; } function Init(string uname, string Pass, string privs) { UserName = uname; Password = Pass; Privileges = privs; MergedPrivs = privs; } function AddGroup(xAdminGroup Group) { if (Group != None) { if (!Groups.Contains(Group)) Groups.Add(Group); if (!Group.Users.Contains(self)) Group.Users.Add(self); if (Group.bMasterAdmin) bMasterAdmin = true; else MergePrivs(Group.Privileges); } } function RemoveGroup(xAdminGroup Group) { if (Group != None && Groups.Contains(Group)) { Group.Users.Remove(self); Groups.Remove(Group); RedoMergedPrivs(); } } function AddManagedGroup(xAdminGroup Group) { if (Group != None) { if (!ManagedGroups.Contains(Group)) ManagedGroups.Add(Group); if (!Group.Managers.Contains(self)) Group.Managers.Add(self); } } function RemoveManagedGroup(xAdminGroup Group) { if (Group != None && ManagedGroups.Contains(Group)) { Group.Managers.Remove(self); ManagedGroups.Remove(Group); } } function AddGroupsByName(xAdminGroupList lGroups, array aGroupNames) { local int i; for (i = 0; i aGroupNames) { local int i; for (i=0; i.,", Mid(upass,i,1)) == -1) return false; return true; } static function bool ValidName(string uname) { local int i; if (Len(uname) < 1) return false; for (i=0; i.,", Mid(uname,i,1)) == -1) return false; return true; } // Game Security Level relies only on Groups, not on ManagedGroups. // Or it would allow to create a Group with a higher sec than what i have. function int MaxSecLevel() { local int i, m; if (bMasterAdmin) return 255; m = 0; for (i=0; i m) m = Groups.Get(i).GameSecLevel; return m; } function xAdminGroup GetGroup(string Groupname) { return Groups.FindByName(Groupname); } function xAdminGroup GetManagedGroup(string Groupname) { return ManagedGroups.FindByName(Groupname); } function xAdminUserList GetManagedUsers(xAdminGroupList uAllGroups) { local xAdminUserList retList, uList; local xAdminGroupList uGroups; local int i, j; retList = new(None) class'xAdminUserList'; if (bMasterAdmin) uGroups = uAllGroups; else uGroups = ManagedGroups; for (i = 0; i // ==================================================================== class xAdminGroupList extends xAdminBase; var private array Groups; function int Count() { return Groups.Length; } function xAdminGroup CreateGroup(string GroupName, string Privileges, byte GameSecLevel) { local xAdminGroup NewGroup; NewGroup = FindByName(GroupName); if (NewGroup == None) { NewGroup = new(None) class'xAdminGroup'; if (NewGroup != None) { // Log("Group"@GroupName@" was created"); NewGroup.Init(GroupName, Privileges, GameSecLevel); } return NewGroup; } return None; } function Add(xAdminGroup Group) { if (Group != None && !Contains(Group)) { Groups.Length = Groups.Length + 1; Groups[Groups.Length - 1] = Group; } } function Remove(xAdminGroup Group) { local int i; if (Group != None) { for (i = 0; i= Groups.Length) return None; return Groups[index]; } function xAdminGroup FindByName(string GroupName) { local int i; for (i = 0; i // ==================================================================== class xAdminGroup extends xAdminBase; var string GroupName; var string Privileges; var byte GameSecLevel; // List of Users and Managers for quick display var xAdminUserList Users; var xAdminUserList Managers; var bool bMasterAdmin; function Created() { Users = new(None) class'xAdminUserList'; Managers = new(None) class'xAdminUserList'; } function Init(string sGroupName, string sPrivileges, byte nGameSecLevel) { GroupName = sGroupName; Privileges = sPrivileges; GameSecLevel = nGameSecLevel; if (GroupName == "Admin") bMasterAdmin = true; } function SetPrivs(string privs) { local int i; Privileges = privs; for (i=0; i.,", Mid(uname,i,1)) == -1) return false; return true; } function UnlinkUsers() { local int i; for (i=0; i // ==================================================================== class xAdminConfigBase extends xAdminBase; static function bool Load(xAdminUserList Users, xAdminGroupList Groups, bool bDontAddDefaultAdmin); static function bool Save(xAdminUserList Users, xAdminGroupList Groups); vawobKvCkssDs-sa//============================================================================= // XAdminBase. // // Simple container to group all xAdmin types // //============================================================================= class xAdminBase extends object abstract; sX>class WeaponPickup extends Pickup notplaceable abstract; var bool bWeaponStay; var() bool bThrown; // true if deliberatly thrown, not dropped from kill var() int AmmoAmount[2]; function PostBeginPlay() { Super.PostBeginPlay(); SetWeaponStay(); MaxDesireability = 1.2 * class(InventoryType).Default.AIRating; } function SetWeaponStay() { bWeaponStay = ( bWeaponStay && Level.Game.bWeaponStay ); } simulated static function UpdateHUD(HUD H) { H.LastPickupTime = H.Level.TimeSeconds; H.LastWeaponPickupTime = H.LastPickupTime; } function StartSleeping() { if (bDropped) Destroy(); else if (!bWeaponStay) GotoState('Sleeping'); } function bool AllowRepeatPickup() { return (!bWeaponStay || (bDropped && !bThrown)); } /* 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) { local Weapon AlreadyHas; AlreadyHas = Weapon(Other.FindInventoryType(InventoryType)); if ( (AlreadyHas != None) && (bWeaponStay || (AlreadyHas.AmmoAmount(0) > 0)) ) return 0; if ( AIController(Other.Controller).PriorityObjective() && ((Other.Weapon.AIRating > 0.5) || (PathWeight > 400)) ) return 0.2/PathWeight; return class(InventoryType).Default.AIRating/PathWeight; } // tell the bot how much it wants this weapon pickup // called when the bot is trying to decide which inventory pickup to go after next function float BotDesireability(Pawn Bot) { local Weapon AlreadyHas; local class AmmoPickupClass; local float desire; // bots adjust their desire for their favorite weapons desire = MaxDesireability + Bot.Controller.AdjustDesireFor(self); // see if bot already has a weapon of this type AlreadyHas = Weapon(Bot.FindInventoryType(InventoryType)); if ( AlreadyHas != None ) { if ( Bot.Controller.bHuntPlayer ) return 0; // can't pick it up if weapon stay is on if ( !AllowRepeatPickup() ) return 0; if ( (RespawnTime < 10) && ( bHidden || AlreadyHas.AmmoMaxed(0)) ) return 0; if ( AlreadyHas.AmmoMaxed(0) ) return 0.25 * desire; // bot wants this weapon for the ammo it holds if( AlreadyHas.AmmoAmount(0) > 0 ) { AmmoPickupClass = AlreadyHas.AmmoPickupClass(0); if ( AmmoPickupClass == None ) return 0.05; else return FMax( 0.25 * desire, AmmoPickupClass.Default.MaxDesireability * FMin(1, 0.15 * AlreadyHas.MaxAmmo(0)/AlreadyHas.AmmoAmount(0)) ); } else return 0.05; } if ( Bot.Controller.bHuntPlayer && (MaxDesireability * 0.833 < Bot.Weapon.AIRating - 0.1) ) return 0; // incentivize bot to get this weapon if it doesn't have a good weapon already if ( (Bot.Weapon == None) || (Bot.Weapon.AIRating < 0.5) ) return 2*desire; return desire; } function float GetRespawnTime() { if ( (Level.NetMode != NM_Standalone) || (Level.Game.GameDifficulty > 3) ) return ReSpawnTime; return RespawnTime * (0.33 + 0.22 * Level.Game.GameDifficulty); } function InitDroppedPickupFor(Inventory Inv) { local Weapon W; W = Weapon(Inv); if (W != None) { AmmoAmount[0] = W.AmmoAmount(0); AmmoAmount[1] = W.AmmoAmount(1); } Super.InitDroppedPickupFor(None); } function Reset() { AmmoAmount[0] = 0; AmmoAmount[1] = 0; Super.Reset(); } state FallingPickup { /* ValidTouch() Validate touch (if valid return true to let other pick me up and trigger event). */ function bool ValidTouch( actor Other ) { // make sure thrower doesn't run over own weapon if ( bThrown && (Physics == PHYS_Falling) && (Velocity.Z > 0) && ((Velocity dot Other.Velocity) > 0) && ((Velocity dot (Location - Other.Location)) > 0) ) return false; return super.ValidTouch(Other); } } s`\ e T w\ G*y%y7\ Gpry\ Gp\ A\ Gpy& yy%y7HryH\ AHy& yppCould not remove interaction [9V\ ] (Not Found)!B GsO class WeaponFire extends Object native; var() bool bSplashDamage; var() bool bSplashJump; var() bool bRecommendSplashDamage; var() bool bTossed; var() bool bLeadTarget; var() bool bInstantHit; // other useful stuff // var() bool bPawnRapidFireAnim; // for determining what anim the firer should play var() bool bReflective; var bool bTimerLoop; var() bool bFireOnRelease; // if true, shot will be fired when button is released, HoldTime will be the time the button was held for var() bool bWaitForRelease; // if true, fire button must be released between each shot var() bool bModeExclusive; // if true, no other fire modes can be active at the same time as this one var bool bIsFiring; var bool bNowWaiting; var bool bServerDelayStopFire; var bool bServerDelayStartFire; var bool bInstantStop; // muzzle flash & smoke // var() bool bAttachSmokeEmitter; var() bool bAttachFlashEmitter; // timer var float TimerInterval; var float NextTimerPop; var() Weapon Weapon; var pawn Instigator; var LevelInfo Level; var Actor Owner; var float NextFireTime; var() float PreFireTime; // seconds before first shot var() float MaxHoldTime; var() float HoldTime; var() int ThisModeNum; var float TransientSoundVolume; var float TransientSoundRadius; // animation // var() Name PreFireAnim; var() Name FireAnim; var() Name FireLoopAnim; var() Name FireEndAnim; var() Name ReloadAnim; var() float PreFireAnimRate; var() float FireAnimRate; var() float FireLoopAnimRate; var() float FireEndAnimRate; var() float ReloadAnimRate; var() float TweenTime; // sound // var() Sound FireSound; var() Sound ReloadSound; var() Sound NoAmmoSound; // jdf --- // Force Feedback // var() String FireForce; var() String ReloadForce; var() String NoAmmoForce; // --- jdf // timing // var() float FireRate; // seconds between shots var float ServerStartFireTime; // ammo // var() class AmmoClass; var() int AmmoPerFire; var() int AmmoClipSize; var() float Load; // camera shakes // var() vector ShakeRotMag; // how far to rot view var() vector ShakeRotRate; // how fast to rot view var() float ShakeRotTime; // how much time to rot the instigator's view var() vector ShakeOffsetMag; // max view offset vertically var() vector ShakeOffsetRate; // how fast to offset view vertically var() float ShakeOffsetTime; // how much time to offset view // AI // var() class ProjectileClass; var() float BotRefireRate; var() float WarnTargetPct; var() class FlashEmitterClass; var() xEmitter FlashEmitter; var() class SmokeEmitterClass; var() xEmitter SmokeEmitter; var() float AimError; // 0=none 1000=quite a bit var() float Spread; // rotator units. no relation to AimError var() enum ESpreadStyle { SS_None, SS_Random, // spread is max random angle deviation SS_Line, // spread is angle between each projectile SS_Ring } SpreadStyle; var int FireCount; var() float DamageAtten; // attenuate instant-hit/projectile damage by this multiplier var Actor.FireProperties SavedFireProperties; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) simulated function SetTimer( float NewTimerRate, bool bLoop ) { bTimerLoop = bLoop; TimerInterval = NewTimerRate; NextTimerPop = Level.TimeSeconds + TimerInterval; } event Timer(); simulated function PreBeginPlay(); simulated function BeginPlay(); simulated function PostNetBeginPlay(); simulated event SetInitialState() { GotoState( 'Auto' ); } simulated function PostBeginPlay() { Load = AmmoPerFire; if (bFireOnRelease) bWaitForRelease = true; if (bWaitForRelease) bNowWaiting = true; } simulated function DestroyEffects() { if (FlashEmitter != None) FlashEmitter.Destroy(); if (SmokeEmitter != None) SmokeEmitter.Destroy(); } simulated function InitEffects() { // don't even spawn on server if ( (Level.NetMode == NM_DedicatedServer) || (AIController(Instigator.Controller) != None) ) return; if ( (FlashEmitterClass != None) && ((FlashEmitter == None) || FlashEmitter.bDeleteMe) ) { FlashEmitter = Weapon.Spawn(FlashEmitterClass); } if ( (SmokeEmitterClass != None) && ((SmokeEmitter == None) || SmokeEmitter.bDeleteMe) ) { SmokeEmitter = Weapon.Spawn(SmokeEmitterClass); } } function DoFireEffect() { } function DrawMuzzleFlash(Canvas Canvas) { // Draw smoke first if (SmokeEmitter != None && SmokeEmitter.Base != Weapon) { SmokeEmitter.SetLocation( Weapon.GetEffectStart() ); Canvas.DrawActor( SmokeEmitter, false, false, Weapon.DisplayFOV ); } if (FlashEmitter != None && FlashEmitter.Base != Weapon) { FlashEmitter.SetLocation( Weapon.GetEffectStart() ); Canvas.DrawActor( FlashEmitter, false, false, Weapon.DisplayFOV ); } } function FlashMuzzleFlash() { if (FlashEmitter != None) FlashEmitter.Trigger(Weapon, Instigator); } function StartMuzzleSmoke() { if ( !Level.bDropDetail && (SmokeEmitter != None) ) SmokeEmitter.Trigger(Weapon, Instigator); } function ShakeView() { local PlayerController P; P = PlayerController(Instigator.Controller); if ( P != None ) P.WeaponShakeView(ShakeRotMag, ShakeRotRate, ShakeRotTime, ShakeOffsetMag, ShakeOffsetRate, ShakeOffsetTime); } // jdf --- function ClientPlayForceFeedback( String EffectName ) { local PlayerController PC; PC = PlayerController(Instigator.Controller); if (PC != None && PC.bEnableWeaponForceFeedback ) { PC.ClientPlayForceFeedback(EffectName); } } function StopForceFeedback( String EffectName ) { local PlayerController PC; PC = PlayerController(Instigator.Controller); if (PC != None && PC.bEnableWeaponForceFeedback ) PC.StopForceFeedback(EffectName); } // --- jdf function Update(float dt) { } function StartFiring() { } function StopFiring() { } function StartBerserk() { FireRate = default.FireRate * 0.75; FireAnimRate = default.FireAnimRate/0.75; ReloadAnimRate = default.ReloadAnimRate/0.75; } function StopBerserk() { FireRate = default.FireRate; FireAnimRate = default.FireAnimRate; ReloadAnimRate = default.ReloadAnimRate; } function StartSuperBerserk() { FireRate = default.FireRate/Level.GRI.WeaponBerserk; FireAnimRate = default.FireAnimRate * Level.GRI.WeaponBerserk; ReloadAnimRate = default.ReloadAnimRate * Level.GRI.WeaponBerserk; } function bool IsFiring() { return bIsFiring; } event ModeTick(float dt); event ModeDoFire() { if (!AllowFire()) return; if (MaxHoldTime > 0.0) HoldTime = FMin(HoldTime, MaxHoldTime); // server if (Weapon.Role == ROLE_Authority) { Weapon.ConsumeAmmo(ThisModeNum, Load); DoFireEffect(); HoldTime = 0; // if bot decides to stop firing, HoldTime must be reset first if ( (Instigator == None) || (Instigator.Controller == None) ) return; if ( AIController(Instigator.Controller) != None ) AIController(Instigator.Controller).WeaponFireAgain(BotRefireRate, true); Instigator.DeactivateSpawnProtection(); } // client if (Instigator.IsLocallyControlled()) { ShakeView(); PlayFiring(); FlashMuzzleFlash(); StartMuzzleSmoke(); } else // server { ServerPlayFiring(); } Weapon.IncrementFlashCount(ThisModeNum); // set the next firing time. must be careful here so client and server do not get out of sync if (bFireOnRelease) { if (bIsFiring) NextFireTime += MaxHoldTime + FireRate; else NextFireTime = Level.TimeSeconds + FireRate; } else { NextFireTime += FireRate; NextFireTime = FMax(NextFireTime, Level.TimeSeconds); } Load = AmmoPerFire; HoldTime = 0; if (Instigator.PendingWeapon != Weapon && Instigator.PendingWeapon != None) { bIsFiring = false; Weapon.PutDown(); } } event ModeHoldFire() { if (Instigator.IsLocallyControlled()) PlayStartHold(); } simulated function bool AllowFire() { return ( Weapon.AmmoAmount(ThisModeNum) >= AmmoPerFire); } //// server propagation of firing //// function ServerPlayFiring() { Weapon.PlayOwnedSound(FireSound,SLOT_Interact,TransientSoundVolume,,TransientSoundRadius,,false); } //// client animation //// function PlayPreFire() { if ( Weapon.Mesh != None && Weapon.HasAnim(PreFireAnim) ) { Weapon.PlayAnim(PreFireAnim, PreFireAnimRate, TweenTime); } } function PlayStartHold() { } function PlayFiring() { if ( Weapon.Mesh != None ) { if ( FireCount > 0 ) { if ( Weapon.HasAnim(FireLoopAnim) ) { Weapon.PlayAnim(FireLoopAnim, FireLoopAnimRate, 0.0); } else { Weapon.PlayAnim(FireAnim, FireAnimRate, TweenTime); } } else { Weapon.PlayAnim(FireAnim, FireAnimRate, TweenTime); } } Weapon.PlayOwnedSound(FireSound,SLOT_Interact,TransientSoundVolume,,TransientSoundRadius,Default.FireAnimRate/FireAnimRate,false); ClientPlayForceFeedback(FireForce); // jdf FireCount++; } function PlayFireEnd() { if ( Weapon.Mesh != None && Weapon.HasAnim(FireEndAnim) ) { Weapon.PlayAnim(FireEndAnim, FireEndAnimRate, TweenTime); } } function Rotator AdjustAim(Vector Start, float InAimError) { if ( !SavedFireProperties.bInitialized ) { SavedFireProperties.AmmoClass = AmmoClass; SavedFireProperties.ProjectileClass = ProjectileClass; SavedFireProperties.WarnTargetPct = WarnTargetPct; SavedFireProperties.MaxRange = MaxRange(); SavedFireProperties.bTossed = bTossed; SavedFireProperties.bTrySplash = bRecommendSplashDamage; SavedFireProperties.bLeadTarget = bLeadTarget; SavedFireProperties.bInstantHit = bInstantHit; SavedFireProperties.bInitialized = true; } return Instigator.AdjustAim(SavedFireProperties, Start, InAimError); } simulated function vector GetFireStart(vector X, vector Y, vector Z) { return Instigator.Location + Instigator.EyePosition(); } simulated function DisplayDebug(Canvas Canvas, out float YL, out float YPos) { Canvas.SetDrawColor(0,255,0); Canvas.DrawText(" FIREMODE "$self$" IsFiring "$bIsFiring); YPos += YL; Canvas.SetPos(4,YPos); /* Canvas.DrawText(" FireOnRelease "$bFireOnRelease$" HoldTime "$HoldTime$" MaxHoldTime "$MaxHoldTime); YPos += YL; Canvas.SetPos(4,YPos); Canvas.DrawText(" NextFireTime "$NextFireTime$" NowWaiting "$bNowWaiting); YPos += YL; Canvas.SetPos(4,YPos); */ } function float MaxRange() { return 5000; } // for convenience/ backwards compatibility function actor Spawn ( class SpawnClass, optional actor SpawnOwner, optional name SpawnTag, optional vector SpawnLocation, optional rotator SpawnRotation ) { return Weapon.Spawn(SpawnClass,SpawnOwner,SpawnTag,SpawnLocation,SpawnRotation); } function Actor Trace ( out vector HitLocation, out vector HitNormal, vector TraceEnd, optional vector TraceStart, optional bool bTraceActors, optional vector Extent, optional out material Material ) { return Weapon.Trace(HitLocation,HitNormal,TraceEnd,TraceStart,bTraceActors,Extent,Material); } sJ#class WeaponAttachment extends InventoryAttachment native nativereplication; var byte FlashCount; // when incremented, draw muzzle flash for current frame var byte FiringMode; // replicated to identify what type of firing/reload animations to play var byte SpawnHitCount; // when incremented, spawn hit effect at mHitLocation var bool bAutoFire; // When set to true.. begin auto fire sequence (used to play looping anims) var float FiringSpeed; // used by human animations to determine the appropriate speed to play firing animations var vector mHitLocation; // used for spawning hit effects client side var bool bMatchWeapons; // for team beacons (link gun potential links) var color BeaconColor; // if bMatchWeapons, what color team beacon should be var class SplashEffect; replication { // Things the server should send to the client. reliable if( bNetDirty && (!bNetOwner || bDemoRecording || bRepClientDemo) && (Role==ROLE_Authority) ) FlashCount, FiringMode, bAutoFire; reliable if ( bNetDirty && (Role==ROLE_Authority) ) mHitLocation, SpawnHitCount; } /* ThirdPersonEffects called by Pawn's C++ tick if FlashCount incremented becomes true OR called locally for local player */ simulated event ThirdPersonEffects() { // spawn 3rd person effects // have pawn play firing anim if ( Instigator != None ) { if ( FiringMode == 1 ) Instigator.PlayFiring(1.0,'1'); else Instigator.PlayFiring(1.0,'0'); } } simulated function CheckForSplash() { local Actor HitActor; local vector HitNormal, HitLocation; if ( !Level.bDropDetail && (Level.DetailMode != DM_Low) && (SplashEffect != None) && !Instigator.PhysicsVolume.bWaterVolume ) { // check for splash bTraceWater = true; HitActor = Trace(HitLocation,HitNormal,mHitLocation,Instigator.Location,true); bTraceWater = false; if ( (FluidSurfaceInfo(HitActor) != None) || ((PhysicsVolume(HitActor) != None) && PhysicsVolume(HitActor).bWaterVolume) ) Spawn(SplashEffect,,,HitLocation,rot(16384,0,0)); } } /* UpdateHit - used to update properties so hit effect can be spawn client side */ function UpdateHit(Actor HitActor, vector HitLocation, vector HitNormal); sfk&j~"wy*fyp-fHj7f%Attempt to SetFocus on an empty Array.!B c |%|7fr|fk&c |||c %ppppInteraction 9Vk& is not in 9Vy.!B c % l&c f|%\|c |&f|f|)%fl&%f-N '%f-u ' Gs_class Weapon extends Inventory abstract native nativereplication HideDropDown CacheExempt; #exec Texture Import File=Textures\Weapon.tga Name=S_Weapon Mips=Off Alpha=1 replication { // Things the server should send to the client. reliable if( Role==ROLE_Authority ) Ammo, AmmoCharge; // Functions called by server on client reliable if( Role==ROLE_Authority ) ClientWeaponSet, ClientWeaponThrown, ClientForceAmmoUpdate, ClientWriteStats, ClientWriteFire; // functions called by client on server reliable if( Role FireModeClass[NUM_FIRE_MODES]; var() protected WeaponFire FireMode[NUM_FIRE_MODES]; var() protected Ammunition Ammo[NUM_FIRE_MODES]; // animation // var() Name IdleAnim; var() Name RestAnim; var() Name AimAnim; var() Name RunAnim; var() Name SelectAnim; var() Name PutDownAnim; var() float IdleAnimRate; var() float RestAnimRate; var() float AimAnimRate; var() float RunAnimRate; var() float SelectAnimRate; var() float PutDownAnimRate; var float PutDownTime; var float BringUpTime; var() Sound SelectSound; var() String SelectForce; // jdf // AI // var() int BotMode; // the fire Mode currently being used for bots var() float AIRating; var float CurrentRating; // rating result from most recent RateSelf() var() bool bMeleeWeapon; var() bool bSniping; // other useful stuff // var bool bShowChargingBar; var bool bMatchWeapons; // OBSOLETE - see WeaponAttachment var() bool bCanThrow; var() bool bForceSwitch; // if true, this weapon will prevent any other weapon from delaying the switch to it (bomb launcher) var() deprecated bool bNotInPriorityList; // Should be displayed in a GUI weapon list - refer to 'Description' documentation var bool bNotInDemo; var bool bNoVoluntarySwitch; var bool bSpectated; var bool bDebugging; var bool bNoInstagibReplace; var bool bInitOldMesh; var config bool bUseOldWeaponMesh; var bool bEndOfRound; // don't allow firing var bool bNoAmmoInstances; // if true, replicated ammocount using the Weapons AmmoCharge property - true by default, included to allow mod authors to fallback to old style var bool bBerserk; // properties needed if no instantiated ammunition var int AmmoCharge[2]; var class AmmoClass[2]; var Mesh OldMesh; var string OldPickup; var(OldFirstPerson) float OldDrawScale, OldCenteredOffsetY; var(OldFirstPerson) vector OldPlayerViewOffset, OldSmallViewOffset; var(OldFirstPerson) rotator OldPlayerViewPivot; var(OldFirstPerson) int OldCenteredRoll, OldCenteredYaw; /* A note about weapons & the caching system: You must now perform two commands on your mod's final package file: 'ucc dumpint ' - this exports the localized text to a localization file, which is used by the caching system to load the ItemName and Description 'ucc exportcache ' - this exports the information that will be used to load the weapon into the caching system. Type 'ucc help exportcache' at the command-line for more info. Ex: (ACoolWeaponMod.u) ucc dumpint ACoolWeaponMod.u - creates 'ACoolWeaponMod.int' file, (file extension will vary if a different language is specified in the UT2004.ini file) ucc exportcache ACoolWeaponMod.u - creates an entry in the 'CacheRecords.ucl' file, containing caching information for your package Weapons must have values for both ItemName & Description in order to appear in the game. The caching system will not recognize inherited values for these properties. If creating a custom crosshair for your weapon, it will FIXME -- rjp */ var() localized cache string Description; var class DemoReplacement; var transient bool bPendingSwitch; var(FirstPerson) vector EffectOffset; // where muzzle flashes and smoke appear. replace by bone reference eventually var() Localized string MessageNoAmmo; var(FirstPerson) float DisplayFOV; var() enum EWeaponClientState { WS_None, WS_Hidden, WS_BringUp, WS_PutDown, WS_ReadyToFire } ClientState; // this will always be None on the server var() config byte ExchangeFireModes; var() config byte Priority; var() deprecated byte DefaultPriority; var float Hand; var float RenderedHand; var Color HudColor; var Weapon OldWeapon; var(FirstPerson) vector SmallViewOffset; // Offset from view center with small weapons option. var(FirstPerson) vector SmallEffectOffset; var(FirstPerson) float CenteredOffsetY; var(FirstPerson) int CenteredRoll, CenteredYaw; var config int CustomCrosshair; var config color CustomCrossHairColor; var config float CustomCrossHairScale; var config string CustomCrossHairTextureName; var texture CustomCrossHairTexture; var float DownDelay, MinReloadPct; // Used to delay putting down weapons which have jsut been fired native final function InitWeaponFires(); simulated function float ChargeBar(); //========================================================================= // Ammunition Interface (to remove the need for instantiated ammunition) simulated function class GetAmmoClass(int mode) { return AmmoClass[mode]; } simulated function MaxOutAmmo() { if ( bNoAmmoInstances ) { if ( AmmoClass[0] != None ) AmmoCharge[0] = MaxAmmo(0); if ( (AmmoClass[1] != None) && (AmmoClass[0] != AmmoClass[1]) ) AmmoCharge[1] = MaxAmmo(1); return; } if ( Ammo[0] != None ) Ammo[0].AmmoAmount = Ammo[0].MaxAmmo; if ( Ammo[1] != None ) Ammo[1].AmmoAmount = Ammo[1].MaxAmmo; } simulated function SuperMaxOutAmmo() { if ( bNoAmmoInstances ) { if ( AmmoClass[0] != None ) AmmoCharge[0] = 999; if ( (AmmoClass[1] != None) && (AmmoClass[0] != AmmoClass[1]) ) AmmoCharge[1] = 999; return; } if ( Ammo[0] != None ) Ammo[0].AmmoAmount = 999; if ( Ammo[1] != None ) Ammo[1].AmmoAmount = 999; } simulated function int MaxAmmo(int mode) { if ( AmmoClass[mode] != None ) return AmmoClass[mode].Default.MaxAmmo; return 0; } simulated function FillToInitialAmmo() { if ( bNoAmmoInstances ) { if ( AmmoClass[0] != None ) AmmoCharge[0] = Max(AmmoCharge[0], AmmoClass[0].Default.InitialAmount); if ( (AmmoClass[1] != None) && (AmmoClass[0] != AmmoClass[1]) ) AmmoCharge[1] = Max(AmmoCharge[1], AmmoClass[1].Default.InitialAmount); return; } if ( Ammo[0] != None ) Ammo[0].AmmoAmount = Max(Ammo[0].AmmoAmount,Ammo[0].InitialAmount); if ( Ammo[1] != None ) Ammo[1].AmmoAmount = Max(Ammo[1].AmmoAmount,Ammo[1].InitialAmount); } simulated function int AmmoAmount(int mode) { if ( bNoAmmoInstances ) { if ( AmmoClass[0] == AmmoClass[mode] ) return AmmoCharge[0]; return AmmoCharge[mode]; } if ( Ammo[mode] != None ) return Ammo[mode].AmmoAmount; return 0; } simulated function class AmmoPickupClass(int mode) { if ( AmmoClass[mode] != None ) return FireMode[mode].AmmoClass.Default.PickupClass; return None; } simulated function bool AmmoMaxed(int mode) { if ( AmmoClass[mode] == None ) return false; if ( bNoAmmoInstances ) { if ( AmmoClass[0] == AmmoClass[mode] ) mode = 0; return AmmoCharge[mode] >= MaxAmmo(mode); } if ( Ammo[mode] == None ) return false; return (Ammo[mode].AmmoAmount >= MaxAmmo(mode)); } simulated function GetAmmoCount(out float MaxAmmoPrimary, out float CurAmmoPrimary) { if ( AmmoClass[0] == None ) return; if ( bNoAmmoInstances ) { MaxAmmoPrimary = MaxAmmo(0); CurAmmoPrimary = AmmoCharge[0]; return; } if ( Ammo[0] == None ) return; MaxAmmoPrimary = Ammo[0].MaxAmmo; CurAmmoPrimary = Ammo[0].AmmoAmount; } simulated function float AmmoStatus(optional int Mode) // returns float value for ammo amount { if ( bNoAmmoInstances ) { if ( AmmoClass[Mode] == None ) return 0; if ( AmmoClass[0] == AmmoClass[mode] ) mode = 0; return float(AmmoCharge[Mode])/float(MaxAmmo(Mode)); } if (Ammo[Mode] == None) return 0.0; else return float(Ammo[Mode].AmmoAmount) / float(Ammo[Mode].MaxAmmo); } simulated function bool ConsumeAmmo(int Mode, float load, optional bool bAmountNeededIsMax) { local int AmountNeeded; if ( bNoAmmoInstances ) { if ( AmmoClass[0] == AmmoClass[mode] ) mode = 0; AmountNeeded = int(load); if (bAmountNeededIsMax && AmmoCharge[mode] < AmountNeeded) AmountNeeded = AmmoCharge[mode]; if (AmmoCharge[mode] < AmountNeeded) { CheckOutOfAmmo(); return false; // Can't do it } AmmoCharge[mode] -= AmountNeeded; NetUpdateTime = Level.TimeSeconds - 1; if (Level.NetMode == NM_StandAlone || Level.NetMode == NM_ListenServer) CheckOutOfAmmo(); return true; } if (Ammo[Mode] != None) return Ammo[Mode].UseAmmo(int(load), bAmountNeededIsMax); return true; } function bool AddAmmo(int AmmoToAdd, int Mode) { if ( bNoAmmoInstances ) { if ( AmmoClass[0] == AmmoClass[mode] ) mode = 0; if ( Level.GRI.WeaponBerserk > 1.0 ) AmmoCharge[mode] = MaxAmmo(Mode); else if ( AmmoCharge[mode] < MaxAmmo(mode) ) AmmoCharge[mode] = Min(MaxAmmo(mode), AmmoCharge[mode]+AmmoToAdd); NetUpdateTime = Level.TimeSeconds - 1; return true; } if (Ammo[Mode] != None) return Ammo[Mode].AddAmmo(AmmoToAdd); } simulated function bool HasAmmo() { if ( bNoAmmoInstances ) { if ( AmmoClass[0] == AmmoClass[1] ) return ( (AmmoClass[0] != None && FireMode[0] != None && AmmoCharge[0] >= FireMode[0].AmmoPerFire) ); return ( (AmmoClass[0] != None && FireMode[0] != None && AmmoCharge[0] >= FireMode[0].AmmoPerFire) || (AmmoClass[1] != None && FireMode[1] != None && AmmoCharge[1] >= FireMode[1].AmmoPerFire) ); } return ( (Ammo[0] != None && FireMode[0] != None && Ammo[0].AmmoAmount >= FireMode[0].AmmoPerFire) || (Ammo[1] != None && FireMode[1] != None && Ammo[1].AmmoAmount >= FireMode[1].AmmoPerFire) ); } // for AI simulated function bool NeedAmmo(int mode) { if ( bNoAmmoInstances ) { if ( AmmoClass[0] == AmmoClass[mode] ) mode = 0; if ( AmmoClass[mode] == None ) return false; return ( AmmoCharge[Mode] < AmmoClass[mode].default.InitialAmount ); } if ( Ammo[mode] != None ) return (Ammo[mode].AmmoAmount < Ammo[mode].InitialAmount); return false; } simulated function float DesireAmmo(class NewAmmoClass, bool bDetour) { local int i; local float curr, max; for ( i=0; i<2; i++ ) if ( NewAmmoClass == AmmoClass[i] ) { if ( AmmoMaxed(i) ) return -100; curr = AmmoAmount(i); if ( curr == 0 ) return 1; max = MaxAmmo(i); return ( FMin(0.5*(max-curr),AmmoClass[i].Default.AmmoAmount)/max ); } return 0; } simulated function CheckOutOfAmmo() { if (Instigator != None && Instigator.Weapon == self) { if ( bNoAmmoInstances ) { if ( (AmmoCharge[0] <= 0) && (AmmoCharge[1] <= 0) ) OutOfAmmo(); return; } if ( Ammo[0] != None ) Ammo[0].CheckOutOfAmmo(); if ( Ammo[1] != None ) Ammo[1].CheckOutOfAmmo(); } } simulated function PostNetReceive() { CheckOutOfAmmo(); } //========================================================================= simulated function DrawWeaponInfo(Canvas C); simulated function NewDrawWeaponInfo(Canvas C, float YPos); function StartDebugging() { } simulated function ClientWriteStats(byte Mode, bool bMatch, bool bAllowFire, bool bDelay, bool bAlt, float wait) { log(self$" Same weapon "$bMatch$" Mode "$Mode$" Allow fire "$bAllowFire$" delay start fire "$bDelay$" alt firing "$bAlt$" next fire wait "$wait); } function class GetDamageType(); function HackPlayFireSound() { if ( (FireMode[0] != None) && (FireMode[0].FireSound != None) ) PlaySound(FireMode[0].FireSound, SLOT_None, 1.0); } //================================================================= // AI functions function float RangedAttackTime() { return 0; } function bool RecommendRangedAttack() { return false; } function bool RecommendLongRangedAttack() { return false; } function bool FocusOnLeader(bool bLeaderFiring) { return false; } function FireHack(byte Mode); // return true if weapon effect has splash damage (if significant) // use by bot to avoid hurting self // should be based on current firing Mode if active function bool SplashDamage() { return FireMode[BotMode].bSplashDamage; } // return true if weapon should be fired to take advantage of splash damage // For example, rockets should be fired at enemy feet function bool RecommendSplashDamage() { return FireMode[BotMode].bRecommendSplashDamage; } function float GetDamageRadius() { if (FireMode[BotMode].ProjectileClass == None) return 0; else return FireMode[BotMode].ProjectileClass.default.DamageRadius; } // Repeater weapons like minigun should be 0.99, other weapons based on likelihood // of firing again right away function float RefireRate() { return FireMode[BotMode].BotRefireRate; } // tells AI that it needs to release the fire button for this weapon to do anything function bool FireOnRelease() { return FireMode[BotMode].bFireOnRelease; } simulated function Loaded(); simulated function DisplayDebug(Canvas Canvas, out float YL, out float YPos) { local int i; local string T; local name Anim; local float frame,rate; Canvas.SetDrawColor(0,255,0); if ( (Pawn(Owner) != None) && (Pawn(Owner).PlayerReplicationInfo != None) ) Canvas.DrawText("WEAPON "$GetItemName(string(self))$" Owner "$Pawn(Owner).PlayerReplicationInfo.PlayerName); else Canvas.DrawText("WEAPON "$GetItemName(string(self))$" Owner "$Owner); YPos += YL; Canvas.SetPos(4,YPos); T = " STATE: "$GetStateName()$" Timer: "$TimerCounter$" Client State "; Switch( ClientState ) { case WS_None: T=T$"None"; break; case WS_Hidden: T=T$"Hidden"; break; case WS_BringUp: T=T$"BringUp"; break; case WS_PutDown: T=T$"PutDown"; break; case WS_ReadyToFire: T=T$"ReadyToFire"; break; } Canvas.DrawText(T, false); YPos += YL; Canvas.SetPos(4,YPos); if ( DrawType == DT_StaticMesh ) Canvas.DrawText(" StaticMesh "$GetItemName(string(StaticMesh))$" AmbientSound "$AmbientSound, false); else Canvas.DrawText(" Mesh "$GetItemName(string(Mesh))$" AmbientSound "$AmbientSound, false); YPos += YL; Canvas.SetPos(4,YPos); if ( Mesh != None ) { // mesh animation GetAnimParams(0,Anim,frame,rate); T = " AnimSequence "$Anim$" Frame "$frame$" Rate "$rate; if ( bAnimByOwner ) T= T$" Anim by Owner"; Canvas.DrawText(T, false); YPos += YL; Canvas.SetPos(4,YPos); T = "Eyeheight "$Instigator.EyeHeight$" base "$Instigator.BaseEyeheight$" landbob "$Instigator.Landbob$" just landed "$Instigator.bJustLanded$" land recover "$Instigator.bLandRecovery; Canvas.DrawText(T, false); YPos += YL; Canvas.SetPos(4,YPos); } for ( i=0; i rating) ) { rating = oldRating; return Recommended; } } return self; } function SetAITarget(Actor T); /* BestMode() choose between regular or alt-fire */ function byte BestMode() { if ( Instigator.Controller.bFire != 0 ) return 0; else if ( Instigator.Controller.bAltFire != 0 ) return 1; if ( FRand() < 0.5 ) return 1; return 0; } /* BotFire() called by NPC firing weapon. Weapon chooses appropriate firing Mode to use (typically no change) bFinished should only be true if called from the Finished() function FiringMode can be passed in to specify a firing Mode (used by scripted sequences) */ function bool BotFire(bool bFinished, optional name FiringMode) { local int newmode; local Controller C; C = Instigator.Controller; newMode = BestMode(); if ( newMode == 0 ) { C.bFire = 1; C.bAltFire = 0; } else { C.bFire = 0; C.bAltFire = 1; } if ( bFinished ) return true; if ( FireMode[BotMode].IsFiring() ) { if (BotMode == newMode) return true; else StopFire(BotMode); } if ( !ReadyToFire(newMode) || ClientState != WS_ReadyToFire ) return false; BotMode = NewMode; StartFire(NewMode); return true; } // this returns the actual projectile spawn location or trace start simulated function vector GetFireStart(vector X, vector Y, vector Z) { return FireMode[BotMode].GetFireStart(X,Y,Z); } // need to figure out modified rating based on enemy/tactical situation simulated function float RateSelf() { if ( !HasAmmo() ) CurrentRating = -2; else if ( Instigator.Controller == None ) return 0; else CurrentRating = Instigator.Controller.RateWeapon(self); return CurrentRating; } function float GetAIRating() { return AIRating; } // tells bot whether to charge or back off while using this weapon function float SuggestAttackStyle() { return 0.0; } // tells bot whether to charge or back off while defending against this weapon function float SuggestDefenseStyle() { return 0.0; } // return true if recommend jumping while firing to improve splash damage (by shooting at feet) // true for R.L., for example function bool SplashJump() { return FireMode[BotMode].bSplashJump; } // return false if out of range, can't see target, etc. function bool CanAttack(Actor Other) { local float Dist, CheckDist; local vector HitLocation, HitNormal,X,Y,Z, projStart; local actor HitActor; local int m; local bool bInstantHit; if ( (Instigator == None) || (Instigator.Controller == None) ) return false; // check that target is within range Dist = VSize(Instigator.Location - Other.Location); if ( (Dist > FireMode[0].MaxRange()) && (Dist > FireMode[1].MaxRange()) ) return false; // check that can see target if ( !Instigator.Controller.LineOfSightTo(Other) ) return false; for (m = 0; m < NUM_FIRE_MODES; m++) { if ( FireMode[m].bInstantHit ) bInstantHit = true; else { CheckDist = FMax(CheckDist, 0.5 * FireMode[m].ProjectileClass.Default.Speed); CheckDist = FMax(CheckDist, 300); CheckDist = FMin(CheckDist, VSize(Other.Location - Location)); } } // check that would hit target, and not a friendly GetAxes(Instigator.Controller.Rotation, X,Y,Z); projStart = GetFireStart(X,Y,Z); if ( bInstantHit ) HitActor = Trace(HitLocation, HitNormal, Other.Location + Other.CollisionHeight * vect(0,0,0.8), projStart, true); else { // for non-instant hit, only check partial path (since others may move out of the way) HitActor = Trace(HitLocation, HitNormal, projStart + CheckDist * Normal(Other.Location + Other.CollisionHeight * vect(0,0,0.8) - Location), projStart, true); } if ( (HitActor == None) || (HitActor == Other) ) return true; if ( Pawn(HitActor) == None ) return !HitActor.BlocksShotAt(Other); if ( (Pawn(HitActor).Controller == None) || !Instigator.Controller.SameTeamAs(Pawn(HitActor).Controller) ) return true; return false; } //================================================================= simulated function PostBeginPlay() { local int m; Super.PostBeginPlay(); for (m = 0; m < NUM_FIRE_MODES; m++) { if (FireModeClass[m] != None) { FireMode[m] = new(self) FireModeClass[m]; if ( FireMode[m] != None ) AmmoClass[m] = FireMode[m].AmmoClass; } } InitWeaponFires(); for (m = 0; m < NUM_FIRE_MODES; m++) { if (FireMode[m] != None) { FireMode[m].ThisModeNum = m; FireMode[m].Weapon = self; FireMode[m].Instigator = Instigator; FireMode[m].Level = Level; FireMode[m].Owner = self; FireMode[m].PreBeginPlay(); FireMode[m].BeginPlay(); FireMode[m].PostBeginPlay(); FireMode[m].SetInitialState(); FireMode[m].PostNetBeginPlay(); } } if ( Level.bDropDetail || (Level.DetailMode == DM_Low) ) MaxLights = Min(4,MaxLights); if ( SmallViewOffset == vect(0,0,0) ) SmallViewOffset = Default.PlayerviewOffset; if ( SmallEffectOffset == vect(0,0,0) ) SmallEffectOffset = EffectOffset + Default.PlayerViewOffset - SmallViewOffset; if ( bUseOldWeaponMesh && (OldMesh != None) ) { bInitOldMesh = true; LinkMesh(OldMesh); } if ( Level.GRI != None ) CheckSuperBerserk(); } simulated function SetGRI(GameReplicationInfo G) { CheckSuperBerserk(); } simulated function Destroyed() { local int m; AmbientSound = None; for (m = 0; m < NUM_FIRE_MODES; m++) { if ( FireMode[m] != None ) FireMode[m].DestroyEffects(); if (Ammo[m] != None) { Ammo[m].Destroy(); Ammo[m] = None; } } Super.Destroyed(); } simulated function Reselect() { } simulated function bool WeaponCentered() { return ( bSpectated || (Hand > 1) ); } simulated event RenderOverlays( Canvas Canvas ) { local int m; local vector NewScale3D; local rotator CenteredRotation; local name AnimSeq; local float frame,rate; if (Instigator == None) return; if ( Instigator.Controller != None ) Hand = Instigator.Controller.Handedness; if ((Hand < -1.0) || (Hand > 1.0)) return; // draw muzzleflashes/smoke for all fire modes so idle state won't // cause emitters to just disappear for (m = 0; m < NUM_FIRE_MODES; m++) { if (FireMode[m] != None) { FireMode[m].DrawMuzzleFlash(Canvas); } } if ( (OldMesh != None) && (bUseOldWeaponMesh != (OldMesh == Mesh)) ) { GetAnimParams(0,AnimSeq,frame,rate); bInitOldMesh = true; if ( bUseOldWeaponMesh ) LinkMesh(OldMesh); else LinkMesh(Default.Mesh); PlayAnim(AnimSeq,rate,0.0); } if ( (Hand != RenderedHand) || bInitOldMesh ) { newScale3D = Default.DrawScale3D; if ( Hand != 0 ) newScale3D.Y *= Hand; SetDrawScale3D(newScale3D); SetDrawScale(Default.DrawScale); CenteredRoll = Default.CenteredRoll; CenteredYaw = Default.CenteredYaw; CenteredOffsetY = Default.CenteredOffsetY; PlayerViewPivot = Default.PlayerViewPivot; SmallViewOffset = Default.SmallViewOffset; if ( SmallViewOffset == vect(0,0,0) ) SmallViewOffset = Default.PlayerviewOffset; bInitOldMesh = false; if ( Default.SmallEffectOffset == vect(0,0,0) ) SmallEffectOffset = EffectOffset + Default.PlayerViewOffset - SmallViewOffset; else SmallEffectOffset = Default.SmallEffectOffset; if ( Mesh == OldMesh ) { SmallEffectOffset = EffectOffset + OldPlayerViewOffset - OldSmallViewOffset; PlayerViewPivot = OldPlayerViewPivot; SmallViewOffset = OldSmallViewOffset; if ( Hand != 0 ) { PlayerViewPivot.Roll *= Hand; PlayerViewPivot.Yaw *= Hand; } CenteredRoll = OldCenteredRoll; CenteredYaw = OldCenteredYaw; CenteredOffsetY = OldCenteredOffsetY; SetDrawScale(OldDrawScale); } else if ( Hand == 0 ) { PlayerViewPivot.Roll = Default.PlayerViewPivot.Roll; PlayerViewPivot.Yaw = Default.PlayerViewPivot.Yaw; } else { PlayerViewPivot.Roll = Default.PlayerViewPivot.Roll * Hand; PlayerViewPivot.Yaw = Default.PlayerViewPivot.Yaw * Hand; } RenderedHand = Hand; } if ( class'PlayerController'.Default.bSmallWeapons ) PlayerViewOffset = SmallViewOffset; else if ( Mesh == OldMesh ) PlayerViewOffset = OldPlayerViewOffset; else PlayerViewOffset = Default.PlayerViewOffset; if ( Hand == 0 ) PlayerViewOffset.Y = CenteredOffsetY; else PlayerViewOffset.Y *= Hand; SetLocation( Instigator.Location + Instigator.CalcDrawOffset(self) ); if ( Hand == 0 ) { CenteredRotation = Instigator.GetViewRotation(); CenteredRotation.Yaw += CenteredYaw; CenteredRotation.Roll = CenteredRoll; SetRotation(CenteredRotation); } else SetRotation( Instigator.GetViewRotation() ); PreDrawFPWeapon(); // Laurent -- Hook to override things before render (like rotation if using a staticmesh) bDrawingFirstPerson = true; Canvas.DrawActor(self, false, false, DisplayFOV); bDrawingFirstPerson = false; if ( Hand == 0 ) PlayerViewOffset.Y = 0; } simulated function PreDrawFPWeapon(); simulated function SetHand(float InHand) { Hand = InHand; } simulated function GetViewAxes( out vector xaxis, out vector yaxis, out vector zaxis ) { if ( Instigator.Controller == None ) GetAxes( Instigator.Rotation, xaxis, yaxis, zaxis ); else GetAxes( Instigator.Controller.Rotation, xaxis, yaxis, zaxis ); } simulated function vector CenteredEffectStart() { return Instigator.Location; } simulated function vector GetEffectStart() { local Vector X,Y,Z; // jjs - this function should actually never be called in third person views // any effect that needs a 3rdp weapon offset should figure it out itself // 1st person if (Instigator.IsFirstPerson()) { if ( WeaponCentered() ) return CenteredEffectStart(); GetViewAxes(X, Y, Z); if ( class'PlayerController'.Default.bSmallWeapons ) return (Instigator.Location + Instigator.CalcDrawOffset(self) + SmallEffectOffset.X * X + SmallEffectOffset.Y * Y * Hand + SmallEffectOffset.Z * Z); else return (Instigator.Location + Instigator.CalcDrawOffset(self) + EffectOffset.X * X + EffectOffset.Y * Y * Hand + EffectOffset.Z * Z); } // 3rd person else { return (Instigator.Location + Instigator.EyeHeight*Vect(0,0,0.5) + Vector(Instigator.Rotation) * 40.0); } } simulated function IncrementFlashCount(int Mode) { if ( WeaponAttachment(ThirdPersonActor) != None ) { if (Mode == 0) WeaponAttachment(ThirdPersonActor).FiringMode = 0; else WeaponAttachment(ThirdPersonActor).FiringMode = 1; ThirdPersonActor.NetUpdateTime = Level.TimeSeconds - 1; WeaponAttachment(ThirdPersonActor).FlashCount++; WeaponAttachment(ThirdPersonActor).ThirdPersonEffects(); } } simulated function ZeroFlashCount(int Mode) { if ( WeaponAttachment(ThirdPersonActor) != None ) { if (Mode == 0) WeaponAttachment(ThirdPersonActor).FiringMode = 0; else WeaponAttachment(ThirdPersonActor).FiringMode = 1; ThirdPersonActor.NetUpdateTime = Level.TimeSeconds - 1; WeaponAttachment(ThirdPersonActor).FlashCount = 0; WeaponAttachment(ThirdPersonActor).ThirdPersonEffects(); } } simulated function Weapon WeaponChange( byte F, bool bSilent ) { local Weapon newWeapon; if ( InventoryGroup == F ) { if ( !HasAmmo() ) { if ( Inventory == None ) newWeapon = None; else newWeapon = Inventory.WeaponChange(F,bSilent); if ( !bSilent && (newWeapon == None) && Instigator.IsHumanControlled() ) Instigator.ClientMessage( ItemName$MessageNoAmmo ); return newWeapon; } else return self; } else if ( Inventory == None ) return None; else return Inventory.WeaponChange(F,bSilent); } simulated function Weapon PrevWeapon(Weapon CurrentChoice, Weapon CurrentWeapon) { if ( HasAmmo() ) { if ( (CurrentChoice == None) ) { if ( CurrentWeapon != self ) CurrentChoice = self; } else if ( InventoryGroup == CurrentWeapon.InventoryGroup ) { if ( (GroupOffset < CurrentWeapon.GroupOffset) && ((CurrentChoice.InventoryGroup != InventoryGroup) || (GroupOffset > CurrentChoice.GroupOffset)) ) CurrentChoice = self; } else if ( InventoryGroup == CurrentChoice.InventoryGroup ) { if ( GroupOffset > CurrentChoice.GroupOffset ) CurrentChoice = self; } else if ( InventoryGroup > CurrentChoice.InventoryGroup ) { if ( (InventoryGroup < CurrentWeapon.InventoryGroup) || (CurrentChoice.InventoryGroup > CurrentWeapon.InventoryGroup) ) CurrentChoice = self; } else if ( (CurrentChoice.InventoryGroup > CurrentWeapon.InventoryGroup) && (InventoryGroup < CurrentWeapon.InventoryGroup) ) CurrentChoice = self; } if ( Inventory == None ) return CurrentChoice; else return Inventory.PrevWeapon(CurrentChoice,CurrentWeapon); } simulated function Weapon NextWeapon(Weapon CurrentChoice, Weapon CurrentWeapon) { if ( HasAmmo() ) { if ( (CurrentChoice == None) ) { if ( CurrentWeapon != self ) CurrentChoice = self; } else if ( InventoryGroup == CurrentWeapon.InventoryGroup ) { if ( (GroupOffset > CurrentWeapon.GroupOffset) && ((CurrentChoice.InventoryGroup != InventoryGroup) || (GroupOffset < CurrentChoice.GroupOffset)) ) CurrentChoice = self; } else if ( InventoryGroup == CurrentChoice.InventoryGroup ) { if ( GroupOffset < CurrentChoice.GroupOffset ) CurrentChoice = self; } else if ( InventoryGroup < CurrentChoice.InventoryGroup ) { if ( (InventoryGroup > CurrentWeapon.InventoryGroup) || (CurrentChoice.InventoryGroup < CurrentWeapon.InventoryGroup) ) CurrentChoice = self; } else if ( (CurrentChoice.InventoryGroup < CurrentWeapon.InventoryGroup) && (InventoryGroup > CurrentWeapon.InventoryGroup) ) CurrentChoice = self; } if ( Inventory == None ) return CurrentChoice; else return Inventory.NextWeapon(CurrentChoice,CurrentWeapon); } function HolderDied() { local int m; for (m = 0; m < NUM_FIRE_MODES; m++) { if (FireMode[m].bIsFiring) { StopFire(m); if (FireMode[m].bFireOnRelease) FireMode[m].ModeDoFire(); } } } simulated function bool CanThrow() { local int Mode; for (Mode = 0; Mode < NUM_FIRE_MODES; Mode++) { if ( FireMode[Mode].bFireOnRelease && FireMode[Mode].bIsFiring ) return false; if ( FireMode[Mode].NextFireTime > Level.TimeSeconds) return false; } return (bCanThrow && (ClientState == WS_ReadyToFire || (Level.NetMode == NM_DedicatedServer) || (Level.NetMode == NM_ListenServer)) && HasAmmo() ); } function DropFrom(vector StartLocation) { local int m; local Pickup Pickup; if (!bCanThrow || !HasAmmo()) return; ClientWeaponThrown(); for (m = 0; m < NUM_FIRE_MODES; m++) { if (FireMode[m].bIsFiring) StopFire(m); } if ( Instigator != None ) { DetachFromPawn(Instigator); } Pickup = Spawn(PickupClass,,, StartLocation); if ( Pickup != None ) { Pickup.InitDroppedPickupFor(self); Pickup.Velocity = Velocity; if (Instigator.Health > 0) WeaponPickup(Pickup).bThrown = true; } Destroy(); } simulated function DetachFromPawn(Pawn P) { Super.DetachFromPawn(P); P.AmbientSound = None; } simulated function ClientWeaponThrown() { local int m; AmbientSound = None; Instigator.AmbientSound = None; if( Level.NetMode != NM_Client ) return; Instigator.DeleteInventory(self); for (m = 0; m < NUM_FIRE_MODES; m++) { if (Ammo[m] != None) Instigator.DeleteInventory(Ammo[m]); } } function GiveTo(Pawn Other, optional Pickup Pickup) { local int m; local weapon w; local bool bPossiblySwitch, bJustSpawned; Instigator = Other; W = Weapon(Instigator.FindInventoryType(class)); if ( W == None || W.Class != Class ) // added class check because somebody made FindInventoryType() return subclasses for some reason { bJustSpawned = true; Super.GiveTo(Other); bPossiblySwitch = true; W = self; } else if ( !W.HasAmmo() ) bPossiblySwitch = true; if ( Pickup == None ) bPossiblySwitch = true; for (m = 0; m < NUM_FIRE_MODES; m++) { if ( FireMode[m] != None ) { FireMode[m].Instigator = Instigator; W.GiveAmmo(m,WeaponPickup(Pickup),bJustSpawned); } } if ( Instigator.Weapon != W ) W.ClientWeaponSet(bPossiblySwitch); if ( !bJustSpawned ) { for (m = 0; m < NUM_FIRE_MODES; m++) Ammo[m] = None; Destroy(); } } function GiveAmmo(int m, WeaponPickup WP, bool bJustSpawned) { local bool bJustSpawnedAmmo; local int addAmount, InitialAmount; if ( FireMode[m] != None && FireMode[m].AmmoClass != None ) { Ammo[m] = Ammunition(Instigator.FindInventoryType(FireMode[m].AmmoClass)); bJustSpawnedAmmo = false; if ( bNoAmmoInstances ) { if ( (FireMode[m].AmmoClass == None) || ((m != 0) && (FireMode[m].AmmoClass == FireMode[0].AmmoClass)) ) return; InitialAmount = FireMode[m].AmmoClass.Default.InitialAmount; if ( (WP != None) && ((WP.AmmoAmount[0] > 0) || (WP.AmmoAmount[1] > 0)) ) { InitialAmount = WP.AmmoAmount[m]; } if ( Ammo[m] != None ) { addamount = InitialAmount + Ammo[m].AmmoAmount; Ammo[m].Destroy(); } else addAmount = InitialAmount; AddAmmo(addAmount,m); } else { if ( (Ammo[m] == None) && (FireMode[m].AmmoClass != None) ) { Ammo[m] = Spawn(FireMode[m].AmmoClass, Instigator); Instigator.AddInventory(Ammo[m]); bJustSpawnedAmmo = true; } else if ( (m == 0) || (FireMode[m].AmmoClass != FireMode[0].AmmoClass) ) bJustSpawnedAmmo = ( bJustSpawned || ((WP != None) && !WP.bWeaponStay) ); if ( (WP != None) && ((WP.AmmoAmount[0] > 0) || (WP.AmmoAmount[1] > 0)) ) { addAmount = WP.AmmoAmount[m]; } else if ( bJustSpawnedAmmo ) { addAmount = Ammo[m].InitialAmount; } Ammo[m].AddAmmo(addAmount); Ammo[m].GotoState(''); } } } simulated function ClientWeaponSet(bool bPossiblySwitch) { local int Mode; Instigator = Pawn(Owner); bPendingSwitch = bPossiblySwitch; if( Instigator == None ) { GotoState('PendingClientWeaponSet'); return; } for( Mode = 0; Mode < NUM_FIRE_MODES; Mode++ ) { if( FireModeClass[Mode] != None ) { // laurent -- added check for vehicles (ammo not replicated but unlimited) if( ( FireMode[Mode] == None ) || ( FireMode[Mode].AmmoClass != None ) && !bNoAmmoInstances && Ammo[Mode] == None && FireMode[Mode].AmmoPerFire > 0 ) { GotoState('PendingClientWeaponSet'); return; } } FireMode[Mode].Instigator = Instigator; FireMode[Mode].Level = Level; } ClientState = WS_Hidden; GotoState('Hidden'); if( Level.NetMode == NM_DedicatedServer || !Instigator.IsHumanControlled() ) return; if( Instigator.Weapon == self || Instigator.PendingWeapon == self ) // this weapon was switched to while waiting for replication, switch to it now { if (Instigator.PendingWeapon != None) Instigator.ChangedWeapon(); else BringUp(); return; } if( Instigator.PendingWeapon != None && Instigator.PendingWeapon.bForceSwitch ) return; if( Instigator.Weapon == None ) { Instigator.PendingWeapon = self; Instigator.ChangedWeapon(); } else if ( bPossiblySwitch && !Instigator.Weapon.IsFiring() ) { if ( PlayerController(Instigator.Controller) != None && PlayerController(Instigator.Controller).bNeverSwitchOnPickup ) return; if ( Instigator.PendingWeapon != None ) { if ( RateSelf() > Instigator.PendingWeapon.RateSelf() ) { Instigator.PendingWeapon = self; Instigator.Weapon.PutDown(); } } else if ( RateSelf() > Instigator.Weapon.RateSelf() ) { Instigator.PendingWeapon = self; Instigator.Weapon.PutDown(); } } } // jdf --- simulated function ClientPlayForceFeedback( String EffectName ) { local PlayerController PC; PC = PlayerController(Instigator.Controller); if ( PC != None && PC.bEnableWeaponForceFeedback ) { PC.ClientPlayForceFeedback( EffectName ); } } simulated function StopForceFeedback( String EffectName ) { local PlayerController PC; PC = PlayerController(Instigator.Controller); if ( PC != None && PC.bEnableWeaponForceFeedback ) { PC.StopForceFeedback( EffectName ); } } // --- jdf simulated function BringUp(optional Weapon PrevWeapon) { local int Mode; if ( ClientState == WS_Hidden ) { PlayOwnedSound(SelectSound, SLOT_Interact,,,,, false); ClientPlayForceFeedback(SelectForce); // jdf if ( Instigator.IsLocallyControlled() ) { if ( (Mesh!=None) && HasAnim(SelectAnim) ) PlayAnim(SelectAnim, SelectAnimRate, 0.0); } ClientState = WS_BringUp; SetTimer(BringUpTime, false); } for (Mode = 0; Mode < NUM_FIRE_MODES; Mode++) { FireMode[Mode].bIsFiring = false; FireMode[Mode].HoldTime = 0.0; FireMode[Mode].bServerDelayStartFire = false; FireMode[Mode].bServerDelayStopFire = false; FireMode[Mode].bInstantStop = false; } if ( (PrevWeapon != None) && PrevWeapon.HasAmmo() && !PrevWeapon.bNoVoluntarySwitch ) OldWeapon = PrevWeapon; else OldWeapon = None; } simulated function bool PutDown() { local int Mode; if (ClientState == WS_BringUp || ClientState == WS_ReadyToFire) { if ( (Instigator.PendingWeapon != None) && !Instigator.PendingWeapon.bForceSwitch ) { for (Mode = 0; Mode < NUM_FIRE_MODES; Mode++) { if ( FireMode[Mode].bFireOnRelease && FireMode[Mode].bIsFiring ) return false; if ( FireMode[Mode].NextFireTime > Level.TimeSeconds + FireMode[Mode].FireRate*(1.f - MinReloadPct)) DownDelay = FMax(DownDelay, FireMode[Mode].NextFireTime - Level.TimeSeconds - FireMode[Mode].FireRate*(1.f - MinReloadPct)); } } if (Instigator.IsLocallyControlled()) { for (Mode = 0; Mode < NUM_FIRE_MODES; Mode++) { if ( FireMode[Mode].bIsFiring ) ClientStopFire(Mode); } if ( DownDelay <= 0 ) { if ( ClientState == WS_BringUp ) TweenAnim(SelectAnim,PutDownTime); else if ( HasAnim(PutDownAnim) ) PlayAnim(PutDownAnim, PutDownAnimRate, 0.0); } } ClientState = WS_PutDown; if ( Level.GRI.bFastWeaponSwitching ) DownDelay = 0; if ( DownDelay > 0 ) SetTimer(DownDelay, false); else SetTimer(PutDownTime, false); } for (Mode = 0; Mode < NUM_FIRE_MODES; Mode++) { FireMode[Mode].bServerDelayStartFire = false; FireMode[Mode].bServerDelayStopFire = false; } Instigator.AmbientSound = None; OldWeapon = None; return true; // return false if preventing weapon switch } simulated function Fire(float F) { } simulated function AltFire(float F) { } simulated event WeaponTick(float dt); // only called on currently held weapon simulated function OutOfAmmo() { if ( Instigator == None || !Instigator.IsLocallyControlled() || HasAmmo() ) return; DoAutoSwitch(); } simulated function DoAutoSwitch() { Instigator.Controller.SwitchToBestWeapon(); } //// client only //// simulated event ClientStartFire(int Mode) { if ( Pawn(Owner).Controller.IsInState('GameEnded') || Pawn(Owner).Controller.IsInState('RoundEnded') ) return; if (Role < ROLE_Authority) { if (StartFire(Mode)) { ServerStartFire(Mode); } } else { StartFire(Mode); } } simulated event ClientStopFire(int Mode) { if (Role < ROLE_Authority) { //Log("ClientStopFire"@Level.TimeSeconds); StopFire(Mode); } ServerStopFire(Mode); } simulated function ClientWriteFire(string Result) { log(self$" ServerStartFire! "$Result); } //// server only //// event ServerStartFire(byte Mode) { if ( (Instigator != None) && (Instigator.Weapon != self) ) { if ( Instigator.Weapon == None ) Instigator.ServerChangedWeapon(None,self); else Instigator.Weapon.SynchronizeWeapon(self); return; } if ( (FireMode[Mode].NextFireTime <= Level.TimeSeconds + FireMode[Mode].PreFireTime) && StartFire(Mode) ) { FireMode[Mode].ServerStartFireTime = Level.TimeSeconds; FireMode[Mode].bServerDelayStartFire = false; } else if ( FireMode[Mode].AllowFire() ) { FireMode[Mode].bServerDelayStartFire = true; } else ClientForceAmmoUpdate(Mode, AmmoAmount(Mode)); } simulated function ClientForceAmmoUpdate(int Mode, int NewAmount) { log(self$" ClientForceAmmoUpdate mode "$Mode$" newamount "$NewAmount); if ( bNoAmmoInstances ) AmmoCharge[Mode] = NewAmount; else if ( Ammo[mode] != None ) Ammo[mode].AmmoAmount = NewAmount; } function SynchronizeWeapon(Weapon ClientWeapon) { Instigator.ServerChangedWeapon(self,ClientWeapon); } function ServerStopFire(byte Mode) { // if a stop was received on the same frame as a start then we need to delay the stop for one frame if (FireMode[Mode].bServerDelayStartFire || FireMode[Mode].ServerStartFireTime == Level.TimeSeconds) { //log("Stop Delayed"); FireMode[Mode].bServerDelayStopFire = true; } else { //Log("ServerStopFire"@Level.TimeSeconds); StopFire(Mode); } } simulated function bool ReadyToFire(int Mode) { local int alt; if ( Mode == 0 ) alt = 1; else alt = 0; if ( ((FireMode[alt] != FireMode[Mode]) && FireMode[alt].bModeExclusive && FireMode[alt].bIsFiring) || !FireMode[Mode].AllowFire() || (FireMode[Mode].NextFireTime > Level.TimeSeconds + FireMode[Mode].PreFireTime) ) { return false; } return true; } //// client & server //// simulated function bool StartFire(int Mode) { local int alt; if (!ReadyToFire(Mode)) return false; if (Mode == 0) alt = 1; else alt = 0; FireMode[Mode].bIsFiring = true; FireMode[Mode].NextFireTime = Level.TimeSeconds + FireMode[Mode].PreFireTime; if (FireMode[alt].bModeExclusive) { // prevents rapidly alternating fire modes FireMode[Mode].NextFireTime = FMax(FireMode[Mode].NextFireTime, FireMode[alt].NextFireTime); } if (Instigator.IsLocallyControlled()) { if (FireMode[Mode].PreFireTime > 0.0 || FireMode[Mode].bFireOnRelease) { FireMode[Mode].PlayPreFire(); } FireMode[Mode].FireCount = 0; } return true; } simulated event StopFire(int Mode) { if ( FireMode[Mode].bIsFiring ) FireMode[Mode].bInstantStop = true; if (Instigator.IsLocallyControlled() && !FireMode[Mode].bFireOnRelease) FireMode[Mode].PlayFireEnd(); FireMode[Mode].bIsFiring = false; FireMode[Mode].StopFiring(); if (!FireMode[Mode].bFireOnRelease) ZeroFlashCount(Mode); } //hack to stop all firing and release any charging firemodes RIGHT THIS INSTANT //used when getting into vehicles simulated function ImmediateStopFire() { local int i; for (i = 0; i < NUM_FIRE_MODES; i++) { ClientStopFire(i); if (FireMode[i].bFireOnRelease) { if (Level.TimeSeconds > FireMode[i].NextFireTime && (FireMode[i].bInstantStop || !FireMode[i].bNowWaiting)) FireMode[i].ModeDoFire(); if (FireMode[i].bWaitForRelease) FireMode[i].bNowWaiting = true; } } } simulated function Timer() { local int Mode; local float OldDownDelay; OldDownDelay = DownDelay; DownDelay = 0; if (ClientState == WS_BringUp) { for( Mode = 0; Mode < NUM_FIRE_MODES; Mode++ ) FireMode[Mode].InitEffects(); PlayIdle(); ClientState = WS_ReadyToFire; } else if (ClientState == WS_PutDown) { if ( OldDownDelay > 0 ) { if ( HasAnim(PutDownAnim) ) PlayAnim(PutDownAnim, PutDownAnimRate, 0.0); SetTimer(PutDownTime, false); return; } if ( Instigator.PendingWeapon == None ) { PlayIdle(); ClientState = WS_ReadyToFire; } else { ClientState = WS_Hidden; Instigator.ChangedWeapon(); if ( Instigator.Weapon == self ) { PlayIdle(); ClientState = WS_ReadyToFire; } else { for( Mode = 0; Mode < NUM_FIRE_MODES; Mode++ ) FireMode[Mode].DestroyEffects(); } } } } simulated function bool IsFiring() // called by pawn animation, mostly { if (Level.NetMode == NM_DedicatedServer || Level.NetMode == NM_ListenServer) return (FireMode[0].IsFiring() || FireMode[1].IsFiring()); return ( ClientState == WS_ReadyToFire && (FireMode[0].IsFiring() || FireMode[1].IsFiring()) ); } function bool IsRapidFire() // called by pawn animation { if (FireMode[1] != None && FireMode[1].bIsFiring) return FireMode[1].bPawnRapidFireAnim; else if (FireMode[0] != None) return FireMode[0].bPawnRapidFireAnim; else return false; } // called every time owner takes damage while holding this weapon - used by shield gun function AdjustPlayerDamage( out int Damage, Pawn InstigatedBy, Vector HitLocation, out Vector Momentum, class DamageType) { } simulated function CheckSuperBerserk() { if ( Level.GRI.WeaponBerserk > 1.0 ) { if (FireMode[0] != None) FireMode[0].StartSuperBerserk(); if (FireMode[1] != None) FireMode[1].StartSuperBerserk(); } } simulated function StartBerserk() { if ( (Level.GRI != None) && Level.GRI.WeaponBerserk > 1.0 ) return; bBerserk = true; if (FireMode[0] != None) FireMode[0].StartBerserk(); if (FireMode[1] != None) FireMode[1].StartBerserk(); } simulated function StopBerserk() { bBerserk = false; if ( (Level.GRI != None) && Level.GRI.WeaponBerserk > 1.0 ) return; if (FireMode[0] != None) FireMode[0].StopBerserk(); if (FireMode[1] != None) FireMode[1].StopBerserk(); } simulated function AnimEnd(int channel) { local name anim; local float frame, rate; GetAnimParams(0, anim, frame, rate); if (ClientState == WS_ReadyToFire) { if (anim == FireMode[0].FireAnim && HasAnim(FireMode[0].FireEndAnim)) // rocket hack { PlayAnim(FireMode[0].FireEndAnim, FireMode[0].FireEndAnimRate, 0.0); } else if (anim== FireMode[1].FireAnim && HasAnim(FireMode[1].FireEndAnim)) { PlayAnim(FireMode[1].FireEndAnim, FireMode[1].FireEndAnimRate, 0.0); } else if ((FireMode[0] == None || !FireMode[0].bIsFiring) && (FireMode[1] == None || !FireMode[1].bIsFiring)) { PlayIdle(); } } } simulated function PlayIdle() { LoopAnim(IdleAnim, IdleAnimRate, 0.2); } state PendingClientWeaponSet { simulated function Timer() { if ( Pawn(Owner) != None ) ClientWeaponSet(bPendingSwitch); if ( IsInState('PendingClientWeaponSet') ) SetTimer(0.05, false); } simulated function BeginState() { SetTimer(0.05, false); } simulated function EndState() { } } state Hidden { } function bool CheckReflect( Vector HitLocation, out Vector RefNormal, int AmmoDrain ) { return false; } function DoReflectEffect(int Drain) { } function bool HandlePickupQuery( pickup Item ) { local WeaponPickup wpu; local int i; if ( bNoAmmoInstances ) { // handle ammo pickups for ( i=0; i<2; i++ ) { if ( (item.inventorytype == AmmoClass[i]) && (AmmoClass[i] != None) ) { if ( AmmoCharge[i] >= MaxAmmo(i) ) return true; item.AnnouncePickup(Pawn(Owner)); AddAmmo(Ammo(item).AmmoAmount, i); item.SetRespawn(); return true; } } } if (class == Item.InventoryType) { wpu = WeaponPickup(Item); if (wpu != None) return !wpu.AllowRepeatPickup(); else return false; } if ( Inventory == None ) return false; return Inventory.HandlePickupQuery(Item); } simulated function bool WantsZoomFade() { return false; } /* CanHeal() used by bot AI should return true if this weapon is able to heal Other */ function bool CanHeal(Actor Other) { return false; } //called by AI when camping/defending //return true if it is useful to fire this weapon even though bot doesn't have a target //for example, a weapon that launches turrets or mines function bool ShouldFireWithoutTarget() { return false; } // ugly hack for tutorial function bool ShootHoop(Controller B, Vector ShootLoc) { return false; } simulated function PawnUnpossessed(); // FIXME - hack to get classes building again after fixing the bug that was allowing all protected variables to // be referenced in other classes - maybe there's already an accessor that does this and I just don't know about it // ...in that case, just remove this function -- rjp simulated function WeaponFire GetFireMode( byte Mode ) { if ( Mode < NUM_FIRE_MODES ) return FireMode[Mode]; return None; } sG//============================================================================= // WarpZoneMarker. //============================================================================= class WarpZoneMarker extends SmallNavigationPoint native; var WarpZoneInfo markedWarpZone; // AI related var Actor TriggerActor; //used to tell AI how to trigger me var Actor TriggerActor2; function PostBeginPlay() { if ( markedWarpZone.numDestinations > 1 ) FindTriggerActor(); Super.PostBeginPlay(); } function FindTriggerActor() { local ZoneTrigger Z; ForEach AllActors(class 'ZoneTrigger', Z) if ( Z.Event == markedWarpZone.ZoneTag) { TriggerActor = Z; return; } } /* 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 */ /* FIXME - how to figure out if other side actor is OK and use intelligently for all dests? */ function Actor SpecialHandling(Pawn Other) { if (Other.Region.Zone == markedWarpZone) markedWarpZone.ActorEntered(Other); return self; } /* if ( markedWarpZone.numDestinations <= 1 ) return self; if ( markedWarpZone.OtherSideActor is OK ) return self; if (TriggerActor == None) { FindTriggerActor(); if (TriggerActor == None) return None; } return TriggerActor; } */ scM//============================================================================= // WarpZoneInfo. For making disjoint spaces appear as if they were connected; // supports both in-level warp zones and cross-level warp zones. //============================================================================= class WarpZoneInfo extends ZoneInfo native; //----------------------------------------------------------------------------- // Information set by the level designer. var() string OtherSideURL; var() name ThisTag; var() bool bNoTeleFrag; //----------------------------------------------------------------------------- // Internal. var const int iWarpZone; var const coords WarpCoords; var transient WarpZoneInfo OtherSideActor; var transient object OtherSideLevel; var() string Destinations[8]; var int numDestinations; //----------------------------------------------------------------------------- // Network replication. replication { reliable if( Role==ROLE_Authority ) OtherSideURL, ThisTag, OtherSideActor; } //----------------------------------------------------------------------------- // Functions. // Warp coordinate system transformations. native(314) final function Warp ( out vector Loc, out vector Vel, out rotator R ); native(315) final function UnWarp( out vector Loc, out vector Vel, out rotator R ); function PreBeginPlay() { Super.PreBeginPlay(); // Generate the local connection. Generate(); // Setup destination list. numDestinations = 0; While( numDestinations < 8 ) if (Destinations[numDestinations] != "") numDestinations++; else numDestinations = 8; // Generate URL if necessary. if( numDestinations>0 && (OtherSideURL == "") ) OtherSideURL = Destinations[0]; } function Trigger( actor Other, pawn EventInstigator ) { local int nextPick; if (numDestinations == 0) return; nextPick = 0; While( (nextPick < 8) && (Destinations[nextPick] != OtherSideURL ) ) nextPick++; nextPick++; if ( (nextPick > 7) || (Destinations[nextPick] == "") ) nextPick = 0; OtherSideURL = Destinations[nextPick]; ForceGenerate(); } // Set up this warp zone's destination. simulated event Generate() { if( OtherSideLevel != None ) return; ForceGenerate(); } // Set up this warp zone's destination. simulated event ForceGenerate() { if( InStr(OtherSideURL,"/") >= 0 ) { // Remote level. //log( "Warpzone " $ Self $ " remote" ); OtherSideLevel = None; OtherSideActor = None; } else { // Local level. OtherSideLevel = XLevel; foreach AllActors( class 'WarpZoneInfo', OtherSideActor ) if( string(OtherSideActor.ThisTag)~=OtherSideURL && OtherSideActor!=Self ) break; //log( "Warpzone " $ Self $ " local, connected to " $ OtherSideActor ); } } // When an actor enters this warp zone. simulated function ActorEntered( actor Other ) { local vector L; local rotator R; local Controller P; //if ( Other.Role == ROLE_AutonomousProxy ) // return; // don't simulate for client players if( !Other.bJustTeleported ) { Generate(); if( OtherSideActor != None ) { // This needs to also perform a coordinate system transformation, // in case the portals aren't directionally aligned. This is easy to // do but UnrealScript doesn't provide coordinate system operators yet. Other.Disable('Touch'); Other.Disable('UnTouch'); L = Other.Location; if( Pawn(Other) != None ) R = Pawn(Other).GetViewRotation(); UnWarp( L, Other.Velocity, R ); OtherSideActor.Warp( L, Other.Velocity, R ); if( Other.IsA('Pawn') ) { Pawn(Other).bWarping = bNoTelefrag; if ( Other.SetLocation(L) ) { //tell enemies about teleport if ( Role == ROLE_Authority ) For ( P=Level.ControllerList; P!=None; P=P.NextController ) if (P.Enemy == Other) P.LineOfSightTo(Other); R.Roll = 0; Pawn(Other).SetViewRotation(R); Pawn(Other).ClientSetLocation(L, R ); if ( Pawn(Other).Controller != None ) Pawn(Other).Controller.MoveTimer = -1.0; } else { // set up to keep trying to teleport GotoState('DelayedWarp'); } } else { Other.SetLocation(L); Other.SetRotation( R ); } Other.Enable('Touch'); Other.Enable('UnTouch'); // Change rotation according to portal's rotational change. } } } event ActorLeaving( actor Other ) { If ( Other.IsA('Pawn') ) Pawn(Other).bWarping = false; } State DelayedWarp { function Tick(float DeltaTime) { local Controller P; local bool bFound; For ( P=Level.ControllerList; P!=None; P=P.NextController ) if ( P.Pawn.bWarping && (P.Pawn.Region.Zone == Self) ) { bFound = true; ActorEntered(P); } If ( !bFound ) GotoState(''); } } ss-sEclass VolumeTimer extends info; var Actor A; var float TimerFrequency; function PostBeginPlay() { super.PostBeginPlay(); SetTimer(1.0, false); A = Owner; } function Timer() { A.TimerPop( Self ); SetTimer(TimerFrequency, false); } sC//============================================================================= // Volume: a bounding volume // touch() and untouch() notifications to the volume as actors enter or leave it // enteredvolume() and leftvolume() notifications when center of actor enters the volume // pawns with bIsPlayer==true cause playerenteredvolume notifications instead of actorenteredvolume() // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class Volume extends Brush native; var Actor AssociatedActor; // this actor gets touch() and untouch notifications as the volume is entered or left var() name AssociatedActorTag; // Used by L.D. to specify tag of associated actor var() int LocationPriority; var() localized string LocationName; var() edfindable decorationlist DecoList; // A list of decorations to be spawned inside the volume when the level starts native function bool Encompasses(Actor Other); // returns true if center of actor is within volume function PostBeginPlay() { Super.PostBeginPlay(); if ( AssociatedActorTag != '' ) ForEach AllActors(class'Actor',AssociatedActor, AssociatedActorTag) break; if ( AssociatedActor != None ) { GotoState('AssociatedTouch'); InitialState = GetStateName(); } } function DisplayDebug(Canvas Canvas, out float YL, out float YPos) { Super.DisplayDebug(Canvas,YL,YPos); Canvas.DrawText("AssociatedActor "$AssociatedActor, false); YPos += YL; Canvas.SetPos(4,YPos); } State AssociatedTouch { event touch( Actor Other ) { AssociatedActor.touch(Other); } event untouch( Actor Other ) { AssociatedActor.untouch(Other); } function BeginState() { local Actor A; ForEach TouchingActors(class'Actor', A) Touch(A); } } sl //============================================================================= // VoicePack. //============================================================================= class VoicePack extends Info abstract; var() localized string VoicePackName; var() localized string VoicePackDescription; // Do I need this? Hint text maybe? /* ClientInitialize() sets up playing the appropriate voice segment, and returns a string representation of the message */ function ClientInitialize(PlayerReplicationInfo Sender, PlayerReplicationInfo Recipient, name messagetype, byte messageIndex); static function PlayerSpeech(name Type, int Index, string Callsign, Actor PackOwner); static function byte GetMessageIndex(name PhraseName) { return 0; } static function int PickRandomTauntFor(controller C, bool bNoMature, bool bNoHumanOnly) { return 0; } sihu!|h %{h 7hqh h-N h h-t h h[ Z.T.'h ( Gs^class Vignette extends Actor abstract transient native ; var() string MapName; var() class GameClass; simulated event Init(); simulated event DrawVignette( Canvas C, float Progress ); ss-sj$_W#0  G s{ssh ssJclass VertexColor extends RenderedMaterial native editinlinenew; sqbw!i %i 7bvi b-N i b-t%i bMS.R.Q.'i ( GsQclass VehiclePart extends Actor native abstract placeable; var bool bUpdating; // set true if currently updating // Update() called each tick by the Vehicle which owns this vehiclepart function Update(float DeltaTime); function Activate(bool bActive); ss-sssi$VsZ CH|!?6zvv'},}m.v9S}v Gsi ssZ//============================================================================= // Vehicle // this abstract base class contains gameplay and AI code for vehicles //============================================================================= class Vehicle extends Pawn native nativereplication abstract; var globalconfig bool bVehicleShadows; // Global config option for vehicle shadows var bool bDriving; // Vehicle is being driven var bool bOldDriving; var bool bDrawVehicleShadow; // Vehicle Shadow var (Vehicle) bool bDrawDriverInTP; // Whether to draw the driver when in 3rd person mode. var (Vehicle) bool bDriverCollideActors; // if driver is drawn in vehicle, is Driver.bCollideActors true ? var (Vehicle) bool bRelativeExitPos; // relative vector to vehicle? var bool bDefensive; // should be used by defenders var bool bAutoTurret; // controlled by AI if no player controlling (FIXME Move to subclass) var bool bRemoteControlled; // destroying vehicle won't kill player var bool bEjectDriver; // If vehicle is destroyed, don't kill and eject driver(s) var bool bTurnInPlace; // whether vehicle can turn in place var bool bFollowLookDir; // used by AI to know that controller's rotation determines vehicle rotation var bool bNonHumanControl; // Cannot be controlled by humans var bool bStalled; // Vehicle is stalled (can't apply acceleration) var bool bVehicleDestroyed; // Vehicle has been destroyed (no more need to simulate special vehicle physics) var bool bShowDamageOverlay; // Vehicle should display the normal pawn damage overlay when hit by a weapon var bool bDropDetail; // Vehicle should reduce its detail level var bool bNoFriendlyFire; // FriendlyFire disabled for this vehicle var bool bCanHover; // Actor can hover above water var bool bCanDoTrickJumps; // AI hint // Cameras var (Vehicle) bool bDrawMeshInFP; // Whether to draw the vehicle mesh when in 1st person mode. var (Vehicle) bool bZeroPCRotOnEntry; // If true, set camera rotation to zero on entering vehicle. If false, set it to the vehicle rotation. var bool bPCRelativeFPRotation; // In 1st person, PlayerController rotation is relative to vehicle rotation var bool bWeaponisFiring; var bool bWeaponisAltFiring; var bool bTeamLocked; // Team defines which players are allowed to enter the vehicle var bool bEnterringUnlocks; // Vehicle is unlocked when a player enterred it.. var bool bCanFlip; var bool bAllowViewChange; var bool bAllowWeaponToss; //if the driver dies, will he toss his weapon? var(Vehicle) bool bHUDTrackVehicle; // If true, Vehicle will tracked on HUD. (For Objectives in Assault) var bool bHasRadar; var bool bHasHandbrake; // hint for AI var bool bScriptedRise; // hint for AI var bool bKeyVehicle; // hint for AI var bool bSeparateTurretFocus; // hint for AI (for tank type turreted vehicles) var() bool bHighScoreKill; // vehicle is considered important, and awards 5 points upon destruction. var bool bAdjustDriversHead; // rotate driver's head depending on view rotation var bool bEnemyLockedOn; var config bool bDesiredBehindView; var bool bHideRemoteDriver; // If Set to true, the remote controlling driver will be hidden var bool bShowChargingBar; var bool bDriverHoldsFlag; var bool bCanCarryFlag; var bool bSpawnProtected; // Cannot be destroyed by a player before its been possessed. var() bool bFPNoZFromCameraPitch; // Ignore any vehicle-space Z due to FPCamViewOffset (so looking up and down doesn't change camera Z rel to vehicle) var byte StuckCount; // used by AI var() byte Team; var byte OldTeam, PrevTeam; // OldTeam is used for replication purposes, PrevTeam is the team of the previous driver. var Rotator PlayerEnterredRotation; // Original rotation when player enterred vehicle var float EjectMomentum; var class AutoTurretControllerClass; // generic controls (set by controller, used by concrete derived classes) var (Vehicle) float Steering; // between -1 and 1 var (Vehicle) float Throttle; // between -1 and 1 var (Vehicle) float Rise; // between -1 and 1 var int DriverViewPitch; // The driver's view pitch var int DriverViewYaw; // The driver's view yaw var float ThrottleTime; // last time at which throttle was 0 (used by AI) var float StuckTime; var float VehicleMovingTime; // used by AI C++ var (Vehicle) vector DrivePos; // Position (rel to vehicle) to put player while driving. var (Vehicle) rotator DriveRot; // Rotation (rel to vehicle) to put driver while driving. var (Vehicle) name DriveAnim; // Animation to play while driving. //Info for EntryPositions var (Vehicle) array ExitPositions; // Positions (rel to vehicle) to try putting the player when exiting. var (Vehicle) vector EntryPosition; // Offset for the entry trigger var (Vehicle) float EntryRadius; // Radius for the entry trigger var (Vehicle) vector FPCamPos; // Position of camera when driving first person. var (Vehicle) vector FPCamViewOffset; // Offset in reference frame of camera. //clientside settings var config float TPCamDistance; // force feedback var string CenterSpringForce; var int CenterSpringRangePitch; var int CenterSpringRangeRoll; var (Vehicle) vector TPCamLookat; // Look at location in vehicle space var (Vehicle) vector TPCamWorldOffset; // Applied in world space after vehicle transform. var float DesiredTPCamDistance, LastCameraCalcTime, CameraSpeed; //for smoothly interpolating TPCamDistance to new value var (Vehicle) Range TPCamDistRange; var (Vehicle) int MaxViewYaw; // Maximum amount you can look left and right var (Vehicle) int MaxViewPitch; // Maximum amount you can look up and down var Pawn Driver; // Can be None if Controller spawns right away with vehicle var SVehicleFactory ParentFactory; // FX var String TransEffects[2]; // Spawning effects var ShadowProjector VehicleShadow; // Shadow projector var float ShadowMaxTraceDist; var float ShadowCullDistance; var float MomentumMult; //damage momentum multiplied by this value before being applied to vehicle var float DriverDamageMult; //damage to the driver is multiplied by this value // Missle warning var String LockOnClassString; var float LastLockWarningTime; var float LockWarningInterval; var Vehicle NextVehicle; var localized string VehiclePositionString; var localized cache string VehicleNameString; var localized cache string VehicleDescription; var Texture TeamBeaconTexture, NoEntryTexture; var Material TeamBeaconBorderMaterial; var AIMarker myMarker; // used for stationary turrets //VEHICULAR MANSLAUGHTER var float MinRunOverSpeed; //speed must be greater than this for running into someone to do damage var class RanOverDamageType, CrushedDamageType; var sound RanOverSound; var name StolenAnnouncement; var sound StolenSound; var float LinkHealMult; // If > 0, Link Gun secondary heals an amount equal to its damage times this var float OldSteering; var float VehicleLostTime, TeamUseTime, PlayerStartTime; var float MaxDesireability; var const float AIMoveCheckTime; var float ObjectiveGetOutDist; //if AI controlled and bot needs to trigger an objective not triggerable by vehicles, it will try to get out this far away var name FlagBone; var vector FlagOffset; var rotator FlagRotation; var float WheelsScale; // HORN var array HornSounds; var float LastHornTime; // BULLET HITS var() array BulletSounds; // WATER DAMAGE var() float WaterDamage; var class VehicleDrowningDamType; // HUD OVERLAY var class HUDOverlayClass; var Actor HUDOverlay; var() vector HUDOverlayOffset; var() float HUDOverlayFOV; // SPAWN OVERLAY MATERIAL var() Material SpawnOverlay[2]; struct native SVehicleIcon { var Material Material; var float X, Y, SizeX, SizeY; var bool bIsGreyScale; }; var SVehicleIcon VehicleIcon; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) replication { reliable if ( Role==ROLE_Authority ) ClientKDriverEnter, ClientKDriverLeave, FixPCRotation, ClientClearController; unreliable if( bNetDirty && Role==ROLE_Authority ) bDriving, bTeamLocked, Driver, Team, bVehicleDestroyed, WheelsScale; unreliable if( bNetInitial && Role==ROLE_Authority ) bHUDTrackVehicle; reliable if ( Role < ROLE_Authority ) VehicleFire, VehicleCeaseFire; } function PreBeginPlay() { if ( !Level.Game.bAllowVehicles && !bDeleteMe ) { Destroy(); return; } Super.PreBeginPlay(); } function PlayerChangedTeam() { if ( Driver != None ) Driver.KilledBy(Driver); else Super.PlayerChangedTeam(); } simulated function SetBaseEyeheight() { BaseEyeheight = Default.BaseEyeheight; Eyeheight = BaseEyeheight; } simulated function string GetVehiclePositionString() { return VehiclePositionString; } function Suicide() { if ( Driver != None ) Driver.KilledBy(Driver); else KilledBy(self); } function bool CheatWalk() { return false; } function bool CheatGhost() { return false; } function bool CheatFly() { return false; } simulated function PostBeginPlay() { local controller NewController; super.PostBeginPlay(); if ( bDeleteMe ) return; // Glue a shadow projector on if ( bVehicleShadows && bDrawVehicleShadow && (Level.NetMode != NM_DedicatedServer) ) { VehicleShadow = Spawn(class'ShadowProjector', self, '', Location); VehicleShadow.ShadowActor = Self; VehicleShadow.bBlobShadow = false; VehicleShadow.LightDirection = Normal(vect(1,1,6)); VehicleShadow.LightDistance = 1200; VehicleShadow.MaxTraceDistance = ShadowMaxTraceDist; VehicleShadow.CullDistance = ShadowCullDistance; VehicleShadow.InitShadow(); } if ( Role == Role_Authority ) { if ( bAutoTurret && (Controller == None) && (AutoTurretControllerClass != None) ) { NewController = spawn(AutoTurretControllerClass); if ( NewController != None ) NewController.Possess(self); } if ( !bAutoTurret && !bNonHumanControl && IndependentVehicle() ) Level.Game.RegisterVehicle(self); } OldTeam = Team; PrevTeam = Team; } simulated event SetInitialState() { Super.SetInitialState(); Disable('Tick'); } function bool StronglyRecommended(Actor S, int TeamIndex, Actor Objective) { return bKeyVehicle; } //return a value indicating how useful this vehicle is to bots function float BotDesireability(Actor S, int TeamIndex, Actor Objective) { local bool bSameTeam; local PlayerController P; bSameTeam = ( GetTeamNum() == TeamIndex ); if ( bSameTeam ) { if ( Level.TimeSeconds < TeamUseTime ) return 0; if ( !bKeyVehicle && (Level.TimeSeconds < PlayerStartTime) ) { P = Level.GetLocalPlayerController(); if ( (P == None) || ((P.Pawn != None) && (Vehicle(P.Pawn) == None)) ) return 0; } } if ( !bKeyVehicle && !bStationary && (Level.TimeSeconds < VehicleLostTime) ) return 0; else if (Health <= 0 || Occupied() || (bTeamLocked && !bSameTeam)) return 0; if (bKeyVehicle) return 100; return ((MaxDesireability * 0.5) + (MaxDesireability * 0.5 * (float(Health) / HealthMax))); } simulated function Destroyed() { local Vehicle V, Prev; if ( ParentFactory != None ) ParentFactory.VehicleDestroyed( Self ); // Notify parent factory of death if ( VehicleShadow != None ) VehicleShadow.Destroy(); // Destroy shadow projector if ( bAutoTurret && (Controller != None) && ClassIsChildOf(Controller.Class, AutoTurretControllerClass) && !Controller.bDeleteMe ) { Controller.Destroy(); Controller = None; } if ( Driver != None ) Destroyed_HandleDriver(); if ( Level.Game != None ) { if ( Level.Game.VehicleList == Self ) Level.Game.VehicleList = NextVehicle; else { Prev = Level.Game.VehicleList; if ( Prev != None ) for ( V=Level.Game.VehicleList.NextVehicle; V!=None; V=V.NextVehicle ) { if ( V == self ) { Prev.NextVehicle = NextVehicle; break; } else Prev = V; } } } super.Destroyed(); } simulated function Destroyed_HandleDriver() { local Pawn OldDriver; Driver.LastRenderTime = LastRenderTime; if ( Role == ROLE_Authority ) { // if Driver wasn't visible in vehicle, destroy it if ( Driver != None && !bRemoteControlled && !bEjectDriver && !bDrawDriverInTP && Driver.Health > 0 ) { OldDriver = Driver; Driver = None; OldDriver.DrivenVehicle = None; if ( !OldDriver.bDeleteMe ) OldDriver.Destroy(); } else if ( !bRemoteControlled && !bEjectDriver ) { // otherwise spawn dead karma body if (!bDrawDriverInTP && PlaceExitingDriver()) { Driver.StopDriving(self); Driver.DrivenVehicle = self; } Driver.TearOffMomentum = Velocity * 0.25; Driver.Died(Controller, class'DamRanOver', Driver.Location); } } else if ( Driver.DrivenVehicle == self ) Driver.StopDriving(self); } simulated function vector GetCameraLocationStart() { return Location; } simulated function SpecialCalcBehindView(PlayerController PC, out actor ViewActor, out vector CameraLocation, out rotator CameraRotation ) { local vector CamLookAt, HitLocation, HitNormal, OffsetVector; local Actor HitActor; local vector x, y, z; if (DesiredTPCamDistance < TPCamDistance) TPCamDistance = FMax(DesiredTPCamDistance, TPCamDistance - CameraSpeed * (Level.TimeSeconds - LastCameraCalcTime)); else if (DesiredTPCamDistance > TPCamDistance) TPCamDistance = FMin(DesiredTPCamDistance, TPCamDistance + CameraSpeed * (Level.TimeSeconds - LastCameraCalcTime)); GetAxes(PC.Rotation, x, y, z); ViewActor = self; CamLookAt = GetCameraLocationStart() + (TPCamLookat >> Rotation) + TPCamWorldOffset; OffsetVector = vect(0, 0, 0); OffsetVector.X = -1.0 * TPCamDistance; CameraLocation = CamLookAt + (OffsetVector >> PC.Rotation); HitActor = Trace(HitLocation, HitNormal, CameraLocation, CamLookAt, true, vect(40, 40, 40)); if ( HitActor != None && (HitActor.bWorldGeometry || HitActor == GetVehicleBase() || Trace(HitLocation, HitNormal, CameraLocation, CamLookAt, false, vect(40, 40, 40)) != None) ) CameraLocation = HitLocation; CameraRotation = Normalize(PC.Rotation + PC.ShakeRot); CameraLocation = CameraLocation + PC.ShakeOffset.X * x + PC.ShakeOffset.Y * y + PC.ShakeOffset.Z * z; } simulated function SpecialCalcFirstPersonView(PlayerController PC, out actor ViewActor, out vector CameraLocation, out rotator CameraRotation ) { local quat CarQuat, LookQuat, ResultQuat; local vector VehicleZ, CamViewOffsetWorld, x, y, z; local float CamViewOffsetZAmount; GetAxes(PC.Rotation, x, y, z); ViewActor = self; if (bPCRelativeFPRotation) { CarQuat = QuatFromRotator(Rotation); CameraRotation = Normalize(PC.Rotation); LookQuat = QuatFromRotator(CameraRotation); ResultQuat = QuatProduct(LookQuat, CarQuat); CameraRotation = QuatToRotator(ResultQuat); } else CameraRotation = PC.Rotation; // Camera position is locked to car CamViewOffsetWorld = FPCamViewOffset >> CameraRotation; CameraLocation = GetCameraLocationStart() + (FPCamPos >> Rotation) + CamViewOffsetWorld; if(bFPNoZFromCameraPitch) { VehicleZ = vect(0,0,1) >> Rotation; CamViewOffsetZAmount = CamViewOffsetWorld Dot VehicleZ; CameraLocation -= CamViewOffsetZAmount * VehicleZ; } CameraRotation = Normalize(CameraRotation + PC.ShakeRot); CameraLocation = CameraLocation + PC.ShakeOffset.X * x + PC.ShakeOffset.Y * y + PC.ShakeOffset.Z * z; } // Special calc-view for vehicles simulated function bool SpecialCalcView(out actor ViewActor, out vector CameraLocation, out rotator CameraRotation ) { local PlayerController pc; pc = PlayerController(Controller); // Only do this mode we have a playercontroller if( (pc == None) || (pc.Viewtarget != self) ) return false; if( pc.bBehindView ) SpecialCalcBehindView(PC,ViewActor,CameraLocation,CameraRotation); else SpecialCalcFirstPersonView(PC,ViewActor,CameraLocation,CameraRotation); LastCameraCalcTime = Level.TimeSeconds; return true; } simulated function bool SpectatorSpecialCalcView(PlayerController Viewer, out Actor ViewActor, out vector CameraLocation, out rotator CameraRotation) { local rotator DummyRotation; if (Viewer.ViewTarget != self) return false; if (Viewer.bBehindView) { DesiredTPCamDistance = (TPCamDistRange.Max - TPCamDistRange.Min) * (Viewer.CameraDist / Viewer.CameraDistRange.Max) + TPCamDistRange.Min; SpecialCalcBehindView(Viewer, ViewActor, CameraLocation, CameraRotation); } else SpecialCalcFirstPersonView(Viewer, ViewActor, CameraLocation, DummyRotation); //use rotation set by playercontroller LastCameraCalcTime = Level.TimeSeconds; Viewer.SetLocation(CameraLocation); return true; } // Events called on driver entering/leaving vehicle function Vehicle FindEntryVehicle(Pawn P) { if ( AIController(P.Controller) != None ) return self; if (VSize(P.Location - (Location + (EntryPosition >> Rotation))) < EntryRadius) return self; return None; } // The pawn Driver has tried to take control of this vehicle function bool TryToDrive(Pawn P) { if ( P.bIsCrouched || bNonHumanControl || (P.Controller == None) || (Driver != None) || (P.DrivenVehicle != None) || !P.Controller.bIsPlayer || P.IsA('Vehicle') || Health <= 0 ) return false; if( !Level.Game.CanEnterVehicle(self, P) ) return false; // Check vehicle Locking.... if ( !bTeamLocked || P.GetTeamNum() == Team ) { if ( bEnterringUnlocks && bTeamLocked ) bTeamLocked = false; KDriverEnter( P ); return true; } else { VehicleLocked( P ); return false; } } event VehicleLocked( Pawn P ); // Pawn tried to enter vehicle, but it's locked!! function PossessedBy(Controller C) { local PlayerController PC; if ( bAutoTurret && (Controller != None) && ClassIsChildOf(Controller.Class, AutoTurretControllerClass) && !Controller.bDeleteMe ) { Controller.Destroy(); Controller = None; } super.PossessedBy( C ); // Stole another team's vehicle, so set Team to new owner's team if ( C.GetTeamNum() != Team ) { //add stat tracking event/variable here? if ( Team != 255 && PlayerController(C) != None ) { if( StolenAnnouncement != '' ) PlayerController(C).PlayRewardAnnouncement(StolenAnnouncement, 1); if( StolenSound != None ) PlaySound( StolenSound,, 2.5*TransientSoundVolume,, 400); } if ( C.GetTeamNum() != 255 ) SetTeamNum( C.GetTeamNum() ); } NetPriority = 3; NetUpdateFrequency = 100; ThrottleTime = Level.TimeSeconds; bSpawnProtected = false; PC = PlayerController(C); if ( PC != None ) ClientKDriverEnter( PC ); if ( ParentFactory != None && ( !bAutoTurret || !ClassIsChildOf(C.Class, AutoTurretControllerClass) ) ) ParentFactory.VehiclePossessed( Self ); // Notify parent factory } function UnPossessed() { local PlayerController PC; local Controller NewController; local bool bWasPlayer; StopWeaponFiring(); PC = PlayerController(Controller); if ( PC != None ) { bWasPlayer = true; ClientKDriverLeave(PC); if (bPCRelativeFPRotation && !PC.bBehindView) FixPCRotation(PC); } else ClientClearController(); NetPriority = Default.NetPriority; // restore original netpriority changed when possessing NetUpdateTime = Level.TimeSeconds - 1; NetUpdateFrequency = 8; super.UnPossessed(); if ( ParentFactory != None && ( !bAutoTurret || (Controller == None) || !ClassIsChildOf(Controller.Class, AutoTurretControllerClass) ) ) ParentFactory.VehicleUnPossessed( Self ); // Notify parent of UnPossessed() if ( Health > 0 && !bDeleteMe ) { if ( bWasPlayer && bAutoTurret && (AutoTurretControllerClass != None) ) { Controller = None; NewController = spawn(AutoTurretControllerClass); if ( NewController != None ) NewController.Possess( Self ); } } } function KDriverEnter(Pawn P) { local Controller C; bDriving = True; StuckCount = 0; // We don't have pre-defined exit positions here, so we use the original player location as an exit point if ( !bRelativeExitPos ) { PlayerEnterredRotation = P.Rotation; ExitPositions[0] = P.Location + Vect(0,0,16); } // Set pawns current controller to control the vehicle pawn instead C = P.Controller; if ( !bCanCarryFlag && (C.PlayerReplicationInfo.HasFlag != None) ) P.DropFlag(); Driver = P; Driver.StartDriving( Self ); // Disconnect PlayerController from Driver and connect to SVehicle. C.bVehicleTransition = true; // to keep Bots from doing Restart() C.Unpossess(); Driver.SetOwner( Self ); // This keeps the driver relevant. C.Possess( Self ); C.bVehicleTransition = false; DrivingStatusChanged(); if ( PlayerController(C) != None ) VehicleLostTime = 0; AttachFlag(PlayerReplicationInfo.HasFlag); Level.Game.DriverEnteredVehicle(self, P); } function AttachFlag(Actor FlagActor) { if ( !bDriverHoldsFlag && (FlagActor != None) ) { AttachToBone(FlagActor,FlagBone); FlagActor.SetRelativeRotation(FlagRotation); FlagActor.SetRelativeLocation(FlagOffset); } } simulated event SetWheelsScale(float NewScale) { WheelsScale = NewScale; } // Called from the PlayerController when player wants to get out. event bool KDriverLeave( bool bForceLeave ) { local Controller C; local PlayerController PC; local bool havePlaced; if( !bForceLeave && !Level.Game.CanLeaveVehicle(self, Driver) ) return false; if ( (PlayerReplicationInfo != None) && (PlayerReplicationInfo.HasFlag != None) ) Driver.HoldFlag(PlayerReplicationInfo.HasFlag); // Do nothing if we're not being driven if (Controller == None ) return false; // Before we can exit, we need to find a place to put the driver. // Iterate over array of possible exit locations. if ( (Driver != None) && (!bRemoteControlled || bHideRemoteDriver) ) { Driver.bHardAttach = false; Driver.bCollideWorld = true; Driver.SetCollision(true, true); havePlaced = PlaceExitingDriver(); // If we could not find a place to put the driver, leave driver inside as before. if (!havePlaced && !bForceLeave ) { Driver.bHardAttach = true; Driver.bCollideWorld = false; Driver.SetCollision(false, false); return false; } } bDriving = False; // Reconnect Controller to Driver. C = Controller; if (C.RouteGoal == self) C.RouteGoal = None; if (C.MoveTarget == self) C.MoveTarget = None; C.bVehicleTransition = true; Controller.UnPossess(); if ( (Driver != None) && (Driver.Health > 0) ) { Driver.SetOwner( C ); C.Possess( Driver ); PC = PlayerController(C); if ( PC != None ) PC.ClientSetViewTarget( Driver ); // Set playercontroller to view the person that got out Driver.StopDriving( Self ); } C.bVehicleTransition = false; if ( C == Controller ) // If controller didn't change, clear it... Controller = None; Level.Game.DriverLeftVehicle(self, Driver); // Car now has no driver Driver = None; DriverLeft(); // Put brakes on before you get out :) Throttle = 0; Steering = 0; Rise = 0; return true; } // DriverLeft() called by KDriverLeave() function DriverLeft() { DrivingStatusChanged(); } simulated event UpdateTiltForceFeedback() { local rotator SpringCenter; local float pitch, roll; local PlayerController PC; PC = PlayerController(Controller); if ( PC != None ) { SpringCenter = rotation; pitch = Clamp(SpringCenter.Pitch, -CenterSpringRangePitch, CenterSpringRangePitch); roll = Clamp(SpringCenter.Roll, -CenterSpringRangeRoll, CenterSpringRangeRoll); pitch /= CenterSpringRangePitch; roll /= CenterSpringRangeRoll; PC.ChangeSpringFeedbackEffect(CenterSpringForce, roll, pitch); } } simulated function ClientKDriverEnter(PlayerController PC) { // PC.bFreeCamera = true; // Set rotation of camera when getting into vehicle based on bZeroPCRotOnEntry if ( bZeroPCRotOnEntry ) PC.SetRotation( rot(0, 0, 0) ); //set starting camera distance to local player's preferences TPCamDistance = default.TPCamDistance; DesiredTPCamDistance = TPCamDistance; if (!PC.bBehindView) ActivateOverlay(True); if ( PC.bEnableGUIForceFeedback && PC.bForceFeedbackSupported && (Viewport(PC.Player) != None) ) { if ( (CenterSpringRangePitch > 0) && (CenterSpringRangeRoll > 0) ) UpdateTiltForceFeedback(); PC.ClientPlayForceFeedback(CenterSpringForce); } if (Driver!=None) { Driver.AmbientSound=none; if (Driver.Weapon!=None) Driver.Weapon.AmbientSound=none; } } simulated function ClientClearController() { ActivateOverlay(False); } simulated function ClientKDriverLeave(PlayerController PC) { // PC.bFreeCamera = false; // Stop messing with bOwnerNoSee if ( Driver != None ) Driver.bOwnerNoSee = Driver.default.bOwnerNoSee; if (PC.bEnableGUIForceFeedback) PC.StopForceFeedback(CenterSpringForce); bWeaponisFiring = False; bWeaponisAltFiring = False; ActivateOverlay(False); } simulated function ActivateOverlay(bool bActive) { if (bActive) { if (HUDOverlayClass != None && HUDOverlay == None) HUDOverlay = spawn(HUDOverlayClass); } else if (HUDOverlay != None) HUDOverlay.Destroy(); } //seperate replicated function called from UnPossessed() to make PC rotation no longer relative to vehicle //needed because PC.bBehindView will get screwed around with as a result of unpossessing vehicle and repossessing Driver simulated function FixPCRotation(PlayerController PC) { PC.SetRotation(rotator(vector(PC.Rotation) >> Rotation)); } simulated function AttachDriver(Pawn P) { local vector AttachPos; P.bHardAttach = true; AttachPos = Location + (DrivePos >> Rotation); P.SetLocation( AttachPos ); P.SetPhysics( PHYS_None ); P.SetBase( Self ); P.SetRelativeRotation( DriveRot ); } simulated function DetachDriver(Pawn P) {} function bool PlaceExitingDriver() { local int i, j; local vector tryPlace, Extent, HitLocation, HitNormal, ZOffset, RandomSphereLoc; local float BestDir, NewDir; if ( Driver == None ) return false; Extent = Driver.default.CollisionRadius * vect(1,1,0); Extent.Z = Driver.default.CollisionHeight; ZOffset = Driver.default.CollisionHeight * vect(0,0,1); //avoid running driver over by placing in direction perpendicular to velocity if ( VSize(Velocity) > 100 ) { tryPlace = Normal(Velocity cross vect(0,0,1)) * (CollisionRadius + Driver.default.CollisionRadius ) * 1.25 ; if ( (Controller != None) && (Controller.DirectionHint != vect(0,0,0)) ) { if ( (tryPlace dot Controller.DirectionHint) < 0 ) tryPlace *= -1; } else if ( FRand() < 0.5 ) tryPlace *= -1; //randomly prefer other side if ( (Trace(HitLocation, HitNormal, Location + tryPlace + ZOffset, Location + ZOffset, false, Extent) == None && Driver.SetLocation(Location + tryPlace + ZOffset)) || (Trace(HitLocation, HitNormal, Location - tryPlace + ZOffset, Location + ZOffset, false, Extent) == None && Driver.SetLocation(Location - tryPlace + ZOffset)) ) return true; } if ( (Controller != None) && (Controller.DirectionHint != vect(0,0,0)) ) { // first try best position tryPlace = Location; BestDir = 0; for( i=0; i BestDir ) { BestDir = NewDir; tryPlace = ExitPositions[i]; } } Controller.DirectionHint = vect(0,0,0); if ( tryPlace != Location ) { if ( bRelativeExitPos ) { if ( ExitPositions[0].Z != 0 ) ZOffset = Vect(0,0,1) * ExitPositions[0].Z; else ZOffset = Driver.default.CollisionHeight * vect(0,0,2); tryPlace = Location + ( (tryPlace-ZOffset) >> Rotation) + ZOffset; // First, do a line check (stops us passing through things on exit). if ( (Trace(HitLocation, HitNormal, tryPlace, Location + ZOffset, false, Extent) == None) && Driver.SetLocation(tryPlace) ) return true; } else if ( Driver.SetLocation(tryPlace) ) return true; } } if ( !bRelativeExitPos ) { for( i=0; i> Rotation) + ZOffset; // First, do a line check (stops us passing through things on exit). if ( Trace(HitLocation, HitNormal, tryPlace, Location + ZOffset, false, Extent) != None ) continue; // Then see if we can place the player there. if ( !Driver.SetLocation(tryPlace) ) continue; return true; } return false; } function Pawn CheckForHeadShot(Vector loc, Vector ray, float AdditionalScale) { return None; } function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, class damageType) { local int ActualDamage; local Controller Killer; // Spawn Protection: Cannot be destroyed by a player until possessed if ( bSpawnProtected && instigatedBy != None && instigatedBy != Self ) return; NetUpdateTime = Level.TimeSeconds - 1; // force quick net update if (DamageType != None) { if ((instigatedBy == None || instigatedBy.Controller == None) && DamageType.default.bDelayedDamage && DelayedDamageInstigatorController != None) instigatedBy = DelayedDamageInstigatorController.Pawn; Damage *= DamageType.default.VehicleDamageScaling; momentum *= DamageType.default.VehicleMomentumScaling * MomentumMult; if (bShowDamageOverlay && DamageType.default.DamageOverlayMaterial != None && Damage > 0 ) SetOverlayMaterial( DamageType.default.DamageOverlayMaterial, DamageType.default.DamageOverlayTime, false ); } if (bRemoteControlled && Driver!=None) { ActualDamage = Damage; if (Weapon != None) Weapon.AdjustPlayerDamage(ActualDamage, InstigatedBy, HitLocation, Momentum, DamageType ); if (InstigatedBy != None && InstigatedBy.HasUDamage()) ActualDamage *= 2; ActualDamage = Level.Game.ReduceDamage(ActualDamage, self, instigatedBy, HitLocation, Momentum, DamageType); if (Health - ActualDamage <= 0) KDriverLeave(false); } if ( Physics != PHYS_Karma ) { super.TakeDamage(Damage,InstigatedBy,HitLocation,Momentum,DamageType); return; } if (Weapon != None) Weapon.AdjustPlayerDamage(Damage, InstigatedBy, HitLocation, Momentum, DamageType ); if (InstigatedBy != None && InstigatedBy.HasUDamage()) Damage *= 2; ActualDamage = Level.Game.ReduceDamage(Damage, self, instigatedBy, HitLocation, Momentum, DamageType); Health -= ActualDamage; PlayHit(actualDamage, InstigatedBy, hitLocation, damageType, Momentum); // The vehicle is dead! if ( Health <= 0 ) { if ( Driver!=None && (bEjectDriver || bRemoteControlled) ) { if ( bEjectDriver ) EjectDriver(); else KDriverLeave( false ); } // pawn died if ( instigatedBy != None ) Killer = instigatedBy.GetKillerController(); if ( Killer == None && (DamageType != None) && DamageType.Default.bDelayedDamage ) Killer = DelayedDamageInstigatorController; Died(Killer, damageType, HitLocation); } else if ( Controller != None ) Controller.NotifyTakeHit(instigatedBy, HitLocation, actualDamage, DamageType, Momentum); MakeNoise(1.0); if ( !bDeleteMe ) { if ( Location.Z > Level.StallZ ) Momentum.Z = FMin(Momentum.Z, 0); KAddImpulse(Momentum, hitlocation); } } function bool HealDamage(int Amount, Controller Healer, class DamageType) { if ( PlayerController(Healer) != None ) PlayerStartTime = Level.TimeSeconds + 3; if (Health <= 0 || Health >= HealthMax || Amount <= 0 || Healer == None || !TeamLink(Healer.GetTeamNum())) return false; Health = Min(Health + (Amount * LinkHealMult), HealthMax); NetUpdateTime = Level.TimeSeconds - 1; return true; } //determine if radius damage that hit the vehicle should damage the driver function DriverRadiusDamage(float DamageAmount, float DamageRadius, Controller EventInstigator, class DamageType, float Momentum, vector HitLocation) { local float damageScale, dist; local vector dir; //if driver has collision, whatever is causing the radius damage will hit the driver by itself if (EventInstigator == None || Driver == None || Driver.bCollideActors || bRemoteControlled) return; dir = Driver.Location - HitLocation; dist = FMax(1, VSize(dir)); dir = dir/dist; damageScale = 1 - FMax(0,(dist - Driver.CollisionRadius)/DamageRadius); if (damageScale <= 0) return; Driver.SetDelayedDamageInstigatorController(EventInstigator); Driver.TakeDamage( damageScale * DamageAmount, EventInstigator.Pawn, Driver.Location - 0.5 * (Driver.CollisionHeight + Driver.CollisionRadius) * dir, damageScale * Momentum * dir, DamageType ); } function DriverDied() { local Controller C; Level.Game.DiscardInventory( Driver ); if (PlayerReplicationInfo != None && PlayerReplicationInfo.HasFlag != None) PlayerReplicationInfo.HasFlag.Drop(0.5 * Velocity); if ( Driver == None ) return; C = Controller; Driver.StopDriving( Self ); Driver.Controller = C; Driver.DrivenVehicle = self; //for in game stats, so it knows pawn was killed inside a vehicle if ( Controller == None ) return; if ( PlayerController(Controller) != None ) { Controller.SetLocation(Location); PlayerController(Controller).SetViewTarget( Driver ); PlayerController(Controller).ClientSetViewTarget( Driver ); } Controller.Unpossess(); if ( Controller == C ) Controller = None; C.Pawn = Driver; Level.Game.DriverLeftVehicle(self, Driver); // Car now has no driver Driver = None; bDriving = false; // Put brakes on before you get out :) Throttle = 0; Steering = 0; Rise = 0; } function Died(Controller Killer, class damageType, vector HitLocation) { local PlayerController PC; local Controller C; if ( bDeleteMe || Level.bLevelChange ) return; // already destroyed, or level is being cleaned up if ( Physics != PHYS_Karma ) { super.Died(Killer, damageType, HitLocation); return; } if ( Level.Game.PreventDeath(self, Killer, damageType, HitLocation) ) { Health = max(Health, 1); //mutator should set this higher return; } Health = Min(0, Health); if ( Controller != None ) { C = Controller; C.WasKilledBy(Killer); Level.Game.Killed(Killer, C, self, damageType); if( C.bIsPlayer ) { PC = PlayerController(C); if ( PC != None ) ClientKDriverLeave(PC); // Just to reset HUD etc. else ClientClearController(); if ( (bRemoteControlled || bEjectDriver) && (Driver != None) && (Driver.Health > 0) ) { C.Unpossess(); C.Possess(Driver); if ( bEjectDriver ) EjectDriver(); Driver = None; } else C.PawnDied(self); } if ( !C.bIsPlayer && !C.bDeleteMe ) C.Destroy(); } else Level.Game.Killed(Killer, Controller(Owner), self, damageType); if ( Killer != None ) TriggerEvent(Event, self, Killer.Pawn); else TriggerEvent(Event, self, None); if ( IsHumanControlled() ) PlayerController(Controller).ForceDeathUpdate(); if ( !bDeleteMe ) Destroy(); // Destroy the vehicle itself (see Destroyed) } function AdjustDriverDamage(out int Damage, Pawn InstigatedBy, Vector HitLocation, out Vector Momentum, class DamageType) { if ( InGodMode() ) Damage = 0; else Damage *= DriverDamageMult; } function EjectDriver() { local Pawn OldPawn; local vector EjectVel; OldPawn = Driver; KDriverLeave( true ); if ( OldPawn == None ) return; EjectVel = VRand(); EjectVel.Z = 0; EjectVel = (Normal(EjectVel)*0.2 + Vect(0,0,1)) * EjectMomentum; OldPawn.Velocity = EjectVel; // Spawn Protection OldPawn.SpawnTime = Level.TimeSeconds; OldPawn.PlayTeleportEffect( false, false); } // Input function UsedBy( Pawn user ) { if ( Driver != None ) return; // Enter vehicle code TryToDrive( User ); } function Fire( optional float F ) { VehicleFire( false ); bWeaponIsFiring = true; } function AltFire( optional float F ) { VehicleFire( true ); bWeaponIsAltFiring = true; } function ClientVehicleCeaseFire(bool bWasAltFire) { if (bWasAltFire) bWeaponIsAltFiring = false; else bWeaponIsFiring = false; VehicleCeaseFire(bWasAltFire); } // Do some server-side vehicle firing stuff function VehicleFire(bool bWasAltFire) { if ( bWasAltFire ) bWeaponIsAltFiring = true; else bWeaponIsFiring = true; } function VehicleCeaseFire(bool bWasAltFire) { if ( bWasAltFire ) bWeaponIsAltFiring = false; else bWeaponIsFiring = false; } state UnDeployed { function VehicleFire(bool bWasAltFire) { Global.VehicleFire(bWasAltFire); } function VehicleCeaseFire(bool bWasAltFire) { Global.VehicleCeaseFire(bWasAltFire); } } state Deployed { function VehicleFire(bool bWasAltFire) { Global.VehicleFire(bWasAltFire); } function VehicleCeaseFire(bool bWasAltFire) { Global.VehicleCeaseFire(bWasAltFire); } } function bool StopWeaponFiring() { local bool bResult; if ( bWeaponIsFiring ) { ClientVehicleCeaseFire( false ); bWeaponIsFiring = false; bResult = true; } if ( bWeaponIsAltFiring ) { ClientVehicleCeaseFire( true ); bWeaponIsAltFiring = false; bResult = true; } return bResult; } event UpdateEyeHeight( float DeltaTime ) { local Controller C; if ( Controller != None && Controller.IsA('PlayerController') ) Controller.AdjustView( DeltaTime ); for ( C=Level.ControllerList; C!=None; C=C.NextController ) if ( C.IsA('PlayerController') && (PlayerController(C).ViewTarget == self) ) return; bUpdateEyeHeight =false; Eyeheight = BaseEyeheight; } // Vehicles ignore 'face rotation'. simulated function FaceRotation( rotator NewRotation, float DeltaTime ) {} simulated event SetAnimAction(name NewAction) { if ( bDrawDriverInTP && (Driver != None) ) Driver.SetAnimAction(NewAction); } // Vehicles dont get telefragged. event EncroachedBy(Actor Other) {} // RanInto() called for encroaching actors which successfully moved the other actor out of the way event RanInto(Actor Other) { local vector Momentum; local float Speed; if (Pawn(Other) == None || Vehicle(Other) != None || Other == Instigator || Other.Role != ROLE_Authority) return; Speed = VSize(Velocity); if (Speed > MinRunOverSpeed) { Momentum = Velocity * 0.25 * Other.Mass; if (Controller != None && Controller.SameTeamAs(Pawn(Other).Controller)) Momentum += Speed * 0.25 * Other.Mass * Normal(Velocity cross vect(0,0,1)); if (RanOverSound != None) PlaySound(RanOverSound,,TransientSoundVolume*2.5); Other.TakeDamage(int(Speed * 0.075), Instigator, Other.Location, Momentum, RanOverDamageType); } } // This will get called if we couldn't move a pawn out of the way. function bool EncroachingOn(Actor Other) { if ( Other == None || Other == Instigator || Other.Role != ROLE_Authority || (!Other.bCollideActors && !Other.bBlockActors) || VSize(Velocity) < 10 ) return false; // If its a non-vehicle pawn, do lots of damage. if( (Pawn(Other) != None) && (Vehicle(Other) == None) ) { Other.TakeDamage(10000, Instigator, Other.Location, Velocity * Other.Mass, CrushedDamageType); return false; } } simulated function bool FindValidTaunt( out name Sequence ) { if ( !bDrawDriverInTP || (Driver == None) ) return false; return Driver.FindValidTaunt(Sequence); } simulated function bool CheckTauntValid( name Sequence ) { if ( !bDrawDriverInTP || (Driver == None) ) return false; return Driver.CheckTauntValid(Sequence); } // AI code function bool Occupied() { return ( Controller != None ); } function float ReservationCostMultiplier() { return 1.0; } function float NewReservationCostMultiplier(Pawn P) { return ReservationCostMultiplier(); } function bool ChangedReservation(Pawn P) { return false; } function bool SpokenFor(Controller C) { return false; } function SetReservation(controller C); function Vehicle OpenPositionFor(Pawn P) { if ( Controller == None ) return self; return None; } simulated function bool IndependentVehicle() { return true; } function Actor GetBestEntry(Pawn P) { return self; } function Vehicle GetMoveTargetFor(Pawn P) { return self; } simulated event DrivingStatusChanged() { local PlayerController PC; PC = Level.GetLocalPlayerController(); if (bDriving && PC != None && (PC.ViewTarget == None || !(PC.ViewTarget.IsJoinedTo(self)))) bDropDetail = (Level.bDropDetail || (Level.DetailMode == DM_Low)); else bDropDetail = False; if (bDriving) Enable('Tick'); else Disable('Tick'); } // TakeWaterDamage() called every tick when WaterDamage>0 and PhysicsVolume.bWaterVolume=true event TakeWaterDamage(float DeltaTime) { local vector HitLocation,HitNormal; local actor EntryActor; TakeDamage(WaterDamage * DeltaTime, Self, vect(0,0,0), vect(0,0,0), VehicleDrowningDamType); if ( (Level.TimeSeconds - SplashTime > 0.3) && (PhysicsVolume.PawnEntryActor != None) && !Level.bDropDetail && (Level.DetailMode != DM_Low) && EffectIsRelevant(Location,false) && (VSize(Velocity) > 300) ) { SplashTime = Level.TimeSeconds; if ( !PhysicsVolume.TraceThisActor(HitLocation, HitNormal, Location - CollisionHeight*vect(0,0,1), Location + CollisionHeight*vect(0,0,1)) ) { EntryActor = Spawn(PhysicsVolume.PawnEntryActor,self,,HitLocation,rot(16384,0,0)); } } } // LockOnWarning() called every LockWarningInterval when bEnemyLockedOn is true (on server/standalone) event LockOnWarning() { local class LockOnClass; LockOnClass = class(DynamicLoadObject(LockOnClassString, class'class')); PlayerController(Controller).ReceiveLocalizedMessage(LockOnClass, 12); LastLockWarningTime = Level.TimeSeconds; } /* PointOfView() called by controller when possessing this pawn false = 1st person, true = 3rd person */ simulated function bool PointOfView() { if (!bAllowViewChange) return true; return default.bDesiredBehindView; } // Spawn FX function PlayTeleportEffect( bool bOut, bool bSound) { local Actor A; local class TransEffect; if ( (GetTeam() == None) || (GetTeam().TeamIndex == 0) ) TransEffect = class(DynamicLoadObject(TransEffects[0], class'Class')); else TransEffect = class(DynamicLoadObject(TransEffects[1], class'Class')); if ( TransEffect != None ) A = Spawn(TransEffect,,,Location + CollisionHeight * vect(0,0,0.75)); // for fast moving vehicles, make the effect sticky if ( A != None ) A.SetBase( Self ); super.PlayTeleportEffect( bOut, bSound ); } simulated event PlayDying(class DamageType, vector HitLoc) {} simulated function int GetTeamNum() { if ( Role == Role_Authority && Team == 255 && (Controller != None) ) SetTeamNum( Controller.GetTeamNum() ); return Team; } //Notify vehicle that an enemy has locked on to it event NotifyEnemyLockedOn() { bEnemyLockedOn = true; } function IncomingMissile(Projectile P); //Notify vehicle that an enemy has lost the lock event NotifyEnemyLostLock() { bEnemyLockedOn = false; } /* Team is changed when vehicle is possessed and PrevTeam is restored when vehicle is unpossessed */ function SetTeamNum(byte T) { PrevTeam = Team; Team = T; if ( PrevTeam != Team ) TeamChanged(); } simulated event TeamChanged() {} simulated function DisplayDebug(Canvas Canvas, out float YL, out float YPos) { super.DisplayDebug(Canvas, YL, YPos); Canvas.SetDrawColor(255,255,255); Canvas.DrawText("Steering "$Steering$" throttle "$Throttle$" rise "$Rise); if ( Driver != None ) { YPos += YL; YPos += YL; Canvas.SetPos(0, YPos); Canvas.SetDrawColor(0,0,255); Canvas.DrawText("--- DRIVER"); Canvas.SetPos(4, YPos); Driver.DisplayDebug( Canvas, YL, YPos ); } } function Actor ShootSpecial(Actor A) { local Controller OldController; if ( !Controller.bCanDoSpecial || (Weapon == None) ) return None; Controller = OldController; if ( KDriverLeave(false) && (OldController.Pawn != None) ) { OldController.Pawn.SetRotation(rotator(A.Location - OldController.Pawn.Location)); OldController.Focus = A; OldController.FireWeaponAt(A); } return A; } //Vehicles stall when they go above the level's StallZ simulated event Stalled(); simulated event UnStalled(); simulated function NextWeapon() { local PlayerController PC; if ( Level.Pauser != None ) return; PC = PlayerController(Controller); if (PC == None) return; if (!PC.bBehindView) { PC.BehindView(true); DesiredTPCamDistance = TPCamDistRange.Min; TPCamDistance = DesiredTPCamDistance; } else DesiredTPCamDistance = Min(DesiredTPCamDistance + 100, TPCamDistRange.Max); default.TPCamDistance = DesiredTPCamDistance; StaticSaveConfig(); } simulated function PrevWeapon() { local PlayerController PC; if ( Level.Pauser != None ) return; PC = PlayerController(Controller); if (PC == None || !PC.bBehindView) return; if (DesiredTPCamDistance ~= TPCamDistRange.Min) PC.BehindView(false); else { DesiredTPCamDistance = Max(DesiredTPCamDistance - 100, TPCamDistRange.Min); default.TPCamDistance = DesiredTPCamDistance; StaticSaveConfig(); } } function bool TeamLink(int TeamNum) { return (LinkHealMult > 0 && Team == TeamNum && Health > 0); } event bool NeedsFlip() { local vector worldUp, gravUp; local float GravMag; GravMag = VSize(PhysicsVolume.Gravity); if( GravMag < 0.1 ) gravUp = vect(0,0,1); else gravUp = -1.0 * (PhysicsVolume.Gravity/GravMag); worldUp = vect(0,0,1) >> Rotation; if (worldUp Dot gravUp < -0.5) return true; return false; } function Flip(vector HitNormal, float ForceScale); simulated function float ChargeBar(); simulated function ClientPlayForceFeedback( String EffectName ) { local PlayerController PC; PC = PlayerController(Controller); //if ( PC != None && PC.bEnableVehicleForceFeedback ) if ( PC != None && PC.bEnableGUIForceFeedback ) { PC.ClientPlayForceFeedback( EffectName ); } } simulated function StopForceFeedback( String EffectName ) { local PlayerController PC; PC = PlayerController(Controller); //if ( PC != None && PC.bEnableVehicleForceFeedback ) if ( PC != None && PC.bEnableGUIForceFeedback ) { PC.StopForceFeedback( EffectName ); } } function ServerPlayHorn(int HornIndex) { if( (Level.TimeSeconds - LastHornTime > 3.0) && (HornIndex >= 0) && (HornIndex < HornSounds.Length) ) { PlaySound( HornSounds[HornIndex],, 3.5*TransientSoundVolume,, 800); LastHornTime = Level.TimeSeconds; } } simulated function int NumPassengers() { if ( Driver != None ) return 1; return 0; } function Pawn GetInstigator() { return Self; } function AIController GetBotPassenger() { return AIController(Controller); } event bool IsVehicleEmpty() { return (Driver == None); } function bool HasOccupiedTurret() { return false; } function float AdjustedStrength() { if (bStationary && bDefensive) return 1.0; return 0; } static function StaticPrecache(LevelInfo L); function int GetSpree() { if (Driver != None) return Driver.GetSpree(); return 0; } function IncrementSpree() { if (Driver != None) Driver.IncrementSpree(); } simulated function POVChanged(PlayerController PC, bool bBehindViewChanged) { if (PC.bBehindView) { if (bBehindViewChanged && bPCRelativeFPRotation) PC.SetRotation(rotator(vector(PC.Rotation) >> Rotation)); bOwnerNoSee = false; if (Driver != None) { if (bDrawDriverInTP) Driver.bOwnerNoSee = false; else Driver.bOwnerNoSee = true; } if (PC == Controller) // No overlays for spectators ActivateOverlay(False); } else { if (bPCRelativeFPRotation) PC.SetRotation(rotator(vector(PC.Rotation) << Rotation)); if (bDrawMeshInFP) bOwnerNoSee = false; else bOwnerNoSee = true; if (Driver != None) { Driver.bOwnerNoSee = true; } if (bDriving && PC == Controller) // No overlays for spectators ActivateOverlay(True); } } function PlayTakeHit(vector HitLocation, int Damage, class DamageType) { local int SoundNum; if (IndependentVehicle() && DamageType.Default.bBulletHit && BulletSounds.Length > 0) { SoundNum = Rand(BulletSounds.Length); if (Controller != None && Controller == Level.GetLocalPlayerController()) PlayOwnedSound(BulletSounds[SoundNum], SLOT_None, 2.0, False, 400); else PlayOwnedSound(BulletSounds[SoundNum], SLOT_None, 2.0, False, 100); } } function array GetTurrets(); function CheckSuperBerserk(); // Used to override locking actors. Returns who the aggressor really should lock on to event bool VerifyLock(actor Aggressor, out actor NewTarget) { return true; } // Returns any alternate target actor for this vehicle if it has one simulated function actor AlternateTarget() { return None; } function ShouldTargetMissile(Projectile P) { local AIController C; C = AIController(Controller); if (C != None && C.Skill >= 5.0 && (C.Enemy == None || !C.LineOfSightTo(C.Enemy)) ) ShootMissile(P); } function ShootMissile(Projectile P) { Controller.Focus = P; Controller.FireWeaponAt(P); } function bool ImportantVehicle() { return false; } function bool IsArtillery() { return false; } //============================================================================= // defaultproperties //============================================================================= sx^j!1{k 7^xk %nk &^-u k &^-tk &^ LO.k   Gs] //============================================================================= // UseTrigger: if a player stands within proximity of this trigger, and hits Use, // it will send Trigger/UnTrigger to actors whose names match 'EventName'. //============================================================================= class UseTrigger extends Triggers; var() localized string Message; function bool SelfTriggered() { return true; } function UsedBy( Pawn user ) { TriggerEvent(Event, self, user); } function Touch( Actor Other ) { if ( Pawn(Other) != None ) { // Send a string message to the toucher. if( Message != "" ) Pawn(Other).ClientMessage( Message ); if ( AIController(Pawn(Other).Controller) != None ) UsedBy(Pawn(Other)); } } ss-sP.AADLp 2D{2A؂uhhss@]l!{o 7]xo %no &]-u o &]-to &] dN.o   Gsi//============================================================================= // Event. //============================================================================= class Triggers extends Actor abstract placeable native; // (cpptext) // (cpptext) // (cpptext) // (cpptext) ss-s@ssF//============================================================================= // Trigger: senses things happening in its proximity and generates // sends Trigger/UnTrigger to actors whose names match 'EventName'. //============================================================================= class Trigger extends Triggers native; #exec Texture Import File=Textures\Trigger.pcx Name=S_Trigger Mips=Off MASKED=1 //----------------------------------------------------------------------------- // Trigger variables. // Trigger type. var() enum ETriggerType { TT_PlayerProximity, // Trigger is activated by player proximity. TT_PawnProximity, // Trigger is activated by any pawn's proximity TT_ClassProximity, // Trigger is activated by actor of ClassProximityType only TT_AnyProximity, // Trigger is activated by any actor in proximity. TT_Shoot, // Trigger is activated by player shooting it. TT_HumanPlayerProximity, // Trigger activated by human player (not bot) TT_LivePlayerProximity, // Trigger only activated by live player, untriggered if player dies while touching } TriggerType; // Human readable triggering message. var() localized string Message; // Only trigger once and then go dormant. var() bool bTriggerOnceOnly; // For triggers that are activated/deactivated by other triggers. var() bool bInitiallyActive; var() class ClassProximityType; var() float RepeatTriggerTime; //if > 0, repeat trigger message at this interval is still touching other var() float ReTriggerDelay; //minimum time before trigger can be triggered again var float TriggerTime; var() float DamageThreshold; //minimum damage to trigger if TT_Shoot // AI vars var actor TriggerActor; // actor that triggers this trigger var actor TriggerActor2; // store for reset var bool bSavedInitialCollision; var bool bSavedInitialActive; /* ToucherDied() called when Pawn P dies, to untrigger player only triggers */ function PlayerToucherDied(Pawn P) { if ( bInitiallyActive && (TriggerType == TT_LivePlayerProximity) ) UntriggerEvent(event, self, P); } //============================================================================= // AI related functions function bool SelfTriggered() { return bInitiallyActive; } function PreBeginPlay() { Super.PreBeginPlay(); if ( (TriggerType == TT_PlayerProximity) || (TriggerType == TT_PawnProximity) || (TriggerType == TT_HumanPlayerProximity) || (TriggerType == TT_LivePlayerProximity) || ((TriggerType == TT_ClassProximity) && ClassIsChildOf(ClassProximityType,class'Pawn')) ) OnlyAffectPawns(true); } function PostBeginPlay() { if ( !bInitiallyActive ) FindTriggerActor(); if ( TriggerType == TT_Shoot ) { bHidden = false; bProjTarget = true; SetDrawType(DT_None); } bSavedInitialActive = bInitiallyActive; bSavedInitialCollision = bCollideActors; Super.PostBeginPlay(); } /* Reset() reset actor to initial state - used when restarting level without reloading. */ function Reset() { Super.Reset(); // collision, bInitiallyactive bInitiallyActive = bSavedInitialActive; SetCollision(bSavedInitialCollision, bBlockActors ); } function FindTriggerActor() { local Actor A; TriggerActor = None; TriggerActor2 = None; ForEach AllActors(class 'Actor', A) if ( A.Event == Tag) { if (TriggerActor == None) TriggerActor = A; else { TriggerActor2 = A; return; } } } function Actor SpecialHandling(Pawn Other) { local Actor A; if ( bTriggerOnceOnly && !bCollideActors ) return None; if ( (TriggerType == TT_HumanPlayerProximity) && !Other.IsHumanControlled() ) return None; if ( (TriggerType == TT_PlayerProximity) && !Other.IsPlayerPawn() ) return None; if ( !bInitiallyActive ) { if ( TriggerActor == None ) FindTriggerActor(); if ( TriggerActor == None ) return None; if ( (TriggerActor2 != None) && (VSize(TriggerActor2.Location - Other.Location) < VSize(TriggerActor.Location - Other.Location)) ) return TriggerActor2; else return TriggerActor; } // is this a shootable trigger? if ( TriggerType == TT_Shoot ) { if ( Other.CanAttack(self) ) return Other.ShootSpecial(self); return self; } // can other trigger it right away? if ( IsRelevant(Other) ) { ForEach TouchingActors(class'Actor', A) if ( A == Other ) Touch(Other); return self; } return self; } // when trigger gets turned on, check its touch list function CheckTouchList() { local Actor A; ForEach TouchingActors(class'Actor', A) Touch(A); } //============================================================================= // Trigger states. // Trigger is always active. state() NormalTrigger { } // Other trigger toggles this trigger's activity. state() OtherTriggerToggles { function Trigger( actor Other, pawn EventInstigator ) { bInitiallyActive = !bInitiallyActive; if ( bInitiallyActive ) CheckTouchList(); } } // Other trigger turns this on. state() OtherTriggerTurnsOn { function Trigger( actor Other, pawn EventInstigator ) { local bool bWasActive; bWasActive = bInitiallyActive; bInitiallyActive = true; if ( !bWasActive ) CheckTouchList(); } } // Other trigger turns this off. state() OtherTriggerTurnsOff { function Trigger( actor Other, pawn EventInstigator ) { bInitiallyActive = false; } } //============================================================================= // Trigger logic. // // See whether the other actor is relevant to this trigger. // function bool IsRelevant( actor Other ) { local Actor Inst; Inst = FindInstigator( Other ); if( !bInitiallyActive ) return false; switch( TriggerType ) { case TT_HumanPlayerProximity: return (Pawn(Other) != None) && Pawn(Other).IsHumanControlled(); case TT_PlayerProximity: return (Pawn(Other) != None) && (Pawn(Other).IsPlayerPawn() || Pawn(Other).WasPlayerPawn()); case TT_LivePlayerProximity: return (Pawn(Other) != None) && Pawn(Other).IsPlayerPawn(); case TT_PawnProximity: return (Pawn(Other) != None) && Pawn(Other).CanTrigger(self); case TT_ClassProximity: return ClassIsChildOf(Other.Class, ClassProximityType) && ( !ClassIsChildOf(ClassProximityType, class'Vehicle') || Pawn(Inst).IsPlayerPawn() ); // Force Pawns to be controlled case TT_AnyProximity: return true; case TT_Shoot: return ( (Projectile(Other) != None) && (Projectile(Other).Damage >= DamageThreshold) ); } } function Actor FindInstigator( Actor Other ) { // Hack if player is in turret and not controlling vehicle... if ( Vehicle(Other) != None && Vehicle(Other).Controller == None ) return Vehicle(Other).GetInstigator(); return Other; } // // Called when something touches the trigger. // function Touch( actor Other ) { local int i; if( IsRelevant( Other ) ) { Other = FindInstigator( Other ); if ( ReTriggerDelay > 0 ) { if ( Level.TimeSeconds - TriggerTime < ReTriggerDelay ) return; TriggerTime = Level.TimeSeconds; } // Broadcast the Trigger message to all matching actors. TriggerEvent(Event, self, Other.Instigator); if ( (Pawn(Other) != None) && (Pawn(Other).Controller != None) ) { for ( i=0;i<4;i++ ) if ( Pawn(Other).Controller.GoalList[i] == self ) { Pawn(Other).Controller.GoalList[i] = None; break; } } if( (Message != "") && (Other.Instigator != None) ) // Send a string message to the toucher. Other.Instigator.ClientMessage( Message ); if( bTriggerOnceOnly ) // Ignore future touches. SetCollision(False); else if ( RepeatTriggerTime > 0 ) SetTimer(RepeatTriggerTime, false); } } function Timer() { local bool bKeepTiming; local Actor A; bKeepTiming = false; ForEach TouchingActors(class'Actor', A) if ( IsRelevant(A) ) { bKeepTiming = true; Touch(A); } if ( bKeepTiming ) SetTimer(RepeatTriggerTime, false); } function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, class damageType) { if ( bInitiallyActive && (TriggerType == TT_Shoot) && (Damage >= DamageThreshold) && (instigatedBy != None) ) { if ( ReTriggerDelay > 0 ) { if ( Level.TimeSeconds - TriggerTime < ReTriggerDelay ) return; TriggerTime = Level.TimeSeconds; } // Broadcast the Trigger message to all matching actors. TriggerEvent(Event, self, instigatedBy); if( Message != "" ) // Send a string message to the toucher. instigatedBy.Instigator.ClientMessage( Message ); if( bTriggerOnceOnly ) // Ignore future touches. SetCollision(False); if ( (AIController(instigatedBy.Controller) != None) && (instigatedBy.Controller.Target == self) ) instigatedBy.Controller.StopFiring(); } } // // When something untouches the trigger. // function UnTouch( actor Other ) { if( IsRelevant( Other ) ) UntriggerEvent(event, self, Other.Instigator); } sEYh!@rq %oq 7Yeq Y-o&q Y-tq Y @M.q  Gsy//============================================================================= // Emitter: An Unreal Trail Particle Emitter. // Revision history: // * Created by Daniel Vogel // * Updated by Laurent Delayen //============================================================================= class TrailEmitter extends ParticleEmitter native; struct ParticleTrailData { var vector Location; var color Color; var float Size; var int DoubleDummy1; var int DoubleDummy2; }; struct ParticleTrailInfo { var int TrailIndex; var int NumPoints; var vector LastLocation; // last point location (to compute new points) var vector LastEmitterLocation; // Laurent -- Last Emitter Location, to process point interpolation }; enum ETrailShadeType { PTTST_None, // Full particle color PTTST_RandomStatic, // particle color * random opacity set once PTTST_RandomDynamic, // particle color * random opacity, updated every tick PTTST_Linear, // smooth linear fade out (begining = 100%, end = 0%) PTTST_PointLife // linear fade relative to point's life }; enum ETrailLocation { PTTL_AttachedToParticle, // Attached to Particle PTTL_FollowEmitter // Attached to Particle, with added emitter's velocity }; var (Trail) ETrailShadeType TrailShadeType; // Shading effect on trail var (Trail) ETrailLocation TrailLocation; // Trail Attachment var (Trail) int MaxPointsPerTrail; var (Trail) float DistanceThreshold; var (Trail) bool UseCrossedSheets; var (Trail) int MaxTrailTwistAngle; var (Trail) float PointLifeTime; // 0.f for unlimited var transient array TrailData; var transient array TrailInfo; var transient vertexbuffer VertexBuffer; var transient indexbuffer IndexBuffer; var transient int VerticesPerParticle; var transient int IndicesPerParticle; var transient int PrimitivesPerParticle; native final function ResetTrail(); ss-sl$s`(//============================================================================= // Texture: An Unreal texture map. // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class Texture extends BitmapMaterial safereplace native noteditinlinenew dontcollapsecategories noexport; // Palette. var(Texture) palette Palette; // Detail texture. var(Texture) Material Detail; var(Texture) float DetailScale; // Internal info. var const color MipZero; var const color MaxColor; var const int InternalTime[2]; // Deprecated stuff. var deprecated texture DetailTexture; // Detail texture to apply. var deprecated texture EnvironmentMap;// Environment map for this texture var deprecated enum EEnvMapTransformType { EMTT_ViewSpace, EMTT_WorldSpace, EMTT_LightSpace, } EnvMapTransformType; var deprecated float Specular; // Specular lighting coefficient. // Texture flags. var(Surface) bool bMasked; var(Surface) bool bAlphaTexture; var(Surface) bool bTwoSided; var(Quality) private bool bHighColorQuality; // High color quality hint. var(Quality) private bool bHighTextureQuality; // High color quality hint. var private bool bRealtime; // Texture changes in realtime. var private bool bParametric; // Texture data need not be stored. var private transient bool bRealtimeChanged; // Changed since last render. var const editconst private bool bHasComp; //!!OLDVER Whether a compressed version exists. // Level of detail set (gam) --- var() enum ELODSet { LODSET_None, LODSET_World, LODSET_PlayerSkin, LODSET_WeaponSkin, LODSET_Terrain, LODSET_Interface, LODSET_RenderMap, LODSET_Lightmap, } LODSet; var() int NormalLOD; var int MinLOD; var transient int MaxLOD; // --- gam // Animation. var(Animation) texture AnimNext; var transient texture AnimCurrent; var(Animation) byte PrimeCount; var transient byte PrimeCurrent; var(Animation) float MinFrameRate, MaxFrameRate; var transient float Accumulator; // Mipmaps. var private native const array Mips; var const editconst ETextureFormat CompFormat; //!!OLDVER // these "PS2" bytes were crammed into UTexture's alignment padding, // but weren't mentioned here. // DO NOT USE THESE IN UNREALSCRIPT UNLESS YOU KNOW WHAT YOU'RE DOING! // (I guess.) --ryan. var byte PS2FirstMip; var byte PS2NumMips; var const transient pointer RenderInterface; var const transient int __LastUpdateTime[2]; sJL.K CV%@V7m&Vm&L.K.V GsMsPsqclass TexScaler extends TexModifier editinlinenew native; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) var Matrix M; var() float UScale; var() float VScale; var() float UOffset; var() float VOffset; ss-sJ class TexRotator extends TexModifier editinlinenew native; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) enum ETexRotationType { TR_FixedRotation, TR_ConstantlyRotating, TR_OscillatingRotation, }; var Matrix M; var() ETexRotationType TexRotationType; var() rotator Rotation; var deprecated bool ConstantRotation; var() float UOffset; var() float VOffset; var() rotator OscillationRate; var() rotator OscillationAmplitude; var() rotator OscillationPhase; sFclass TexPannerTriggered extends TexPanner native; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) var() TexOscillatorTriggered.ERetriggerAction RetriggerAction; var() float StopAfterPeriod; var transient float TriggeredTime; var transient bool Reverse; var transient bool Triggered; function Trigger( Actor Other, Actor EventInstigator ) { if( Triggered ) { switch( RetriggerAction ) { case RTA_Reverse: Triggered = False; TriggeredTime = Other.Level.TimeSeconds; Reverse = True; break; case RTA_Reset: Triggered = False; TriggeredTime = -1.0; Reverse = True; break; } } else { if( RetriggerAction != RTA_Retrigger ) Triggered = True; TriggeredTime = Other.Level.TimeSeconds; Reverse = False; } } function Reset() { Triggered = False; TriggeredTime = -1.0; Reverse = False; } sNclass TexPanner extends TexModifier editinlinenew native; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) var() rotator PanDirection; var() float PanRate; var Matrix M; sTclass TexOscillatorTriggered extends TexOscillator native; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) enum ERetriggerAction { RTA_Reverse, RTA_Reset, RTA_Ignore, RTA_Retrigger, }; var() ERetriggerAction RetriggerAction; var() float StopAfterPeriod; var transient float TriggeredTime; var transient bool Reverse; var transient bool Triggered; function Trigger( Actor Other, Actor EventInstigator ) { if( Triggered ) { switch( RetriggerAction ) { case RTA_Reverse: Triggered = False; TriggeredTime = Other.Level.TimeSeconds; Reverse = True; break; case RTA_Reset: Triggered = False; TriggeredTime = -1.0; Reverse = True; break; } } else { if( RetriggerAction != RTA_Retrigger ) Triggered = True; TriggeredTime = Other.Level.TimeSeconds; Reverse = False; } } function Reset() { Triggered = False; TriggeredTime = -1.0; Reverse = False; } sc class TexOscillator extends TexModifier editinlinenew native; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) enum ETexOscillationType { OT_Pan, OT_Stretch, OT_StretchRepeat, OT_Jitter }; var() Float UOscillationRate; var() Float VOscillationRate; var() Float UOscillationPhase; var() Float VOscillationPhase; var() Float UOscillationAmplitude; var() Float VOscillationAmplitude; var() ETexOscillationType UOscillationType; var() ETexOscillationType VOscillationType; var() float UOffset; var() float VOffset; var Matrix M; // current state for OT_Jitter. var float LastSu; var float LastSv; var float CurrentUJitter; var float CurrentVJitter; sY class TexModifier extends Modifier noteditinlinenew native; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) var enum ETexCoordSrc { TCS_Stream0, TCS_Stream1, TCS_Stream2, TCS_Stream3, TCS_Stream4, TCS_Stream5, TCS_Stream6, TCS_Stream7, TCS_WorldCoords, TCS_CameraCoords, TCS_WorldEnvMapCoords, TCS_CameraEnvMapCoords, TCS_ProjectorCoords, TCS_NoChange, // don't specify a source, just modify it } TexCoordSource; var() enum ETexCoordCount { TCN_2DCoords, TCN_3DCoords, TCN_4DCoords } TexCoordCount; var() bool TexCoordProjected; var int texmodifier_dummy; // hammer padding. disregard. --ryan. sNclass TexMatrix extends TexModifier native; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) var Matrix Matrix; sN B# Gs[J.V$)J. GsQsss\I.X,)I.)H.)A. Gs}xE0&rx*Added none to team!!!(gw.Xx*Messaging spectator so returning false!Td(`$x`xf"9?&-o(xa/!nxU %xU &!-o-o'eUwe*e-X wex1re`x`1eU xU -o(eeS*-oxU xU &w.x*w}*}Sex}' GsessgB.x}qUzwq*M.qcwM*xB.MC.D.E.F.G.qqS Gsss_@.A1 )@.)-){- Gs`fpZn `$ Gsss{rA9lr}w$ -G-] wr*r-Z 6r-jr-~%nUwn*d.nswd*1rd`r`6d-jd-~%mrdw$~-nnS6nU6wn*d.nwd*1rd`r`mrdw$~-nnS Gsssj s=sx- s=sl@ssss` sMsosX sp@ssssZ!@Dg=sssX stsqsussssu-wLa8 Gss svydb_ Gss sxmkp& jG GsC]nol]}A% Ew.]*e.]Tnnw.]*e.]-G-] we*e-Z $e-je-~%cUwc*a.cowa*6a-ja-~%meaA%w-ccScUwc*a.cwa*meaA%w-ccS Gsss|ssn-s$*???? Q  " "" "Gd"s'q @$*? Q  " "" "Gd"swr @$*? Q  " "" "Gd"ss @s@ssZ~x` 0{qn-~o-p-q-r-s- pw_*_)x~n-o-p-q-r-s-n-Fo-p-q-r-s- Gsm-Ek(( GsF@ssG@ssH@ssssMJF 5z( GsK@ssL@ssN@ssssIOp :' GsPssssNRo <6 GsMssQTt@f*-N -T-u -T-o&-T Gs\class TexEnvMap extends TexModifier editinlinenew native; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) var() enum ETexEnvMapType { EM_WorldSpace, EM_CameraSpace, } EnvMapType; sSZ%H GsUWQ#J4 GsssVYPK Gs@ssPh-mV s!nri-h-j-k- Rw_*_mh-i-j-k-pi-\h-j-k- Gsrclass TexCoordSource extends TexModifier native editinlinenew collapsecategories; var() int SourceChannel; // (cpptext) // (cpptext) // (cpptext) // (cpptext) sHclass TerrainMaterial extends RenderedMaterial native noteditinlinenew; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) struct native TerrainMaterialLayer { var material Texture; var bitmapmaterial AlphaWeight; var matrix TextureMatrix; }; var const array Layers; var const byte RenderMethod; var const bool FirstPass; s^9class TerrainInfo extends Info noexport showcategories(Movement,Collision,Lighting,LightColor,Karma,Force) native placeable; #exec Texture Import File=Textures\Terrain_info.pcx Name=S_TerrainInfo Mips=Off MASKED=1 #exec Texture Import File=Textures\S_WhiteCircle.pcx Name=S_WhiteCircle Mips=Off MASKED=1 #exec Texture Import File=Textures\Bad.pcx Name=TerrainBad Mips=Off #exec Texture Import File=Textures\DecoPaint.pcx Name=DecoPaint Mips=Off struct NormalPair { var vector Normal1; var vector Normal2; }; enum ETexMapAxis { TEXMAPAXIS_XY, TEXMAPAXIS_XZ, TEXMAPAXIS_YZ, }; enum ESortOrder { SORT_NoSort, SORT_BackToFront, SORT_FrontToBack }; struct TerrainLayer { var() Material Texture; var() Texture AlphaMap; var() float UScale; var() float VScale; var() float UPan; var() float VPan; var() ETexMapAxis TextureMapAxis; var() float TextureRotation; var() Rotator LayerRotation; var Matrix TerrainMatrix; var() float KFriction; var() float KRestitution; var transient Texture LayerWeightMap; }; struct DecorationLayer { var() int ShowOnTerrain; var() Texture ScaleMap; var() Texture DensityMap; var() Texture ColorMap; var() StaticMesh StaticMesh; var() rangevector ScaleMultiplier; var() range FadeoutRadius; var() range DensityMultiplier; var() int MaxPerQuad; var() int Seed; var() int AlignToTerrain; var() ESortOrder DrawOrder; var() int ShowOnInvisibleTerrain; var() int LitDirectional; var() int DisregardTerrainLighting; var() int RandomYaw; var() EDetailMode DetailMode; }; struct DecoInfo { var vector Location; var rotator Rotation; var vector Scale; var vector TempScale; var color Color; var int Distance; }; struct DecoSectorInfo { var array DecoInfo; var vector Location; var float Radius; }; struct DecorationLayerData { var array Sectors; }; var() int TerrainSectorSize; var() Texture TerrainMap; var() Texture VertexLightMap; // sjs var() vector TerrainScale; var() TerrainLayer Layers[32]; var() array DecoLayers; var() float DecoLayerOffset; var() bool Inverted; // This option means use half the graphics res for Karma collision. // Note - Karma ignores per-quad info (eg. 'invisible' and 'edge-turned') with this set to true. var() bool bKCollisionHalfRes; // // Internal data // var transient int JustLoaded; var native const array DecoLayerData; var native const array Sectors; var native const array Vertices; var native const int HeightmapX; var native const int HeightmapY; var native const int SectorsX; var native const int SectorsY; var native const TerrainPrimitive Primitive; var native const array FaceNormals; var native const vector ToWorld[4]; var native const vector ToHeightmap[4]; var native const array SelectedVertices; var native const int ShowGrid; var const array QuadVisibilityBitmap; var const array EdgeTurnBitmap; var const array QuadDomMaterialBitmap; var native const array RenderCombinations; var native const array VertexStreams; var native const array VertexColors; var native const array PaintedColor; // editor only var native const Texture CollapsedLayers; // OLD var native const Texture OldTerrainMap; var native const array OldHeightmap; // Heightmap manipulation functions native final function PokeTerrain( vector WorldLocation, int Radius, int MaxDepth ); si~///============================================================================= // Teleports actors either between different teleporters within a level // or to matching teleporters on other levels, or to general Internet URLs. //============================================================================= class Teleporter extends SmallNavigationPoint placeable native; #exec Texture Import File=Textures\Teleport.pcx Name=S_Teleport Mips=Off MASKED=1 //----------------------------------------------------------------------------- // Teleporter URL can be one of the following forms: // // TeleporterName // Teleports to a named teleporter in this level. // if none, acts only as a teleporter destination // // LevelName/TeleporterName // Teleports to a different level on this server. // // Unreal://Server.domain.com/LevelName/TeleporterName // Teleports to a different server on the net. // var() string URL; //----------------------------------------------------------------------------- // Product the user must have installed in order to enter the teleporter. var() name ProductRequired; //----------------------------------------------------------------------------- // Teleporter destination flags. var() bool bChangesVelocity; // Set velocity to TargetVelocity. var() bool bChangesYaw; // Sets yaw to teleporter's Rotation.Yaw var() bool bReversesX; // Reverses X-component of velocity. var() bool bReversesY; // Reverses Y-component of velocity. var() bool bReversesZ; // Reverses Z-component of velocity. // Teleporter flags var() bool bEnabled; // Teleporter is turned on; //----------------------------------------------------------------------------- // Teleporter destination directions. var() vector TargetVelocity; // If bChangesVelocity, set target's velocity to this. // AI related var Actor TriggerActor; //used to tell AI how to trigger me var Actor TriggerActor2; var float LastFired; //----------------------------------------------------------------------------- // Teleporter destination functions. replication { reliable if( Role==ROLE_Authority ) bEnabled, URL; reliable if ( bNetInitial && (Role == ROLE_Authority) ) bChangesVelocity, bChangesYaw, bReversesX, bReversesY, bReversesZ, TargetVelocity; } function PostBeginPlay() { local int i; if (URL ~= "") SetCollision(false, false, false); //destination only if ( !bEnabled ) FindTriggerActor(); // retrofit hack for keeping bots in vehicles from trying to use teleporters // by making reachspecs between teleporters forced so the SpecialCost() event will be called for them for ( i=0; i 0.5) ) { newRot.Roll = 0; Pawn(Incoming).SetRotation(newRot); Pawn(Incoming).SetViewRotation(newRot); Pawn(Incoming).ClientSetRotation(newRot); LastFired = Level.TimeSeconds; } if ( Pawn(Incoming).Controller != None ) { Pawn(Incoming).Controller.MoveTimer = -1.0; Pawn(Incoming).Anchor = self; Pawn(Incoming).SetMoveTarget(self); } Incoming.PlayTeleportEffect(false, true); } else { if ( !Incoming.SetLocation(Location) ) { Enable('Touch'); return false; } if ( bChangesYaw ) Incoming.SetRotation(newRot); } Enable('Touch'); if (bChangesVelocity) Incoming.Velocity = TargetVelocity; else { if ( bChangesYaw ) { if ( Incoming.Physics == PHYS_Walking ) OldRot.Pitch = 0; oldDir = vector(OldRot); mag = Incoming.Velocity Dot oldDir; Incoming.Velocity = Incoming.Velocity - mag * oldDir + mag * vector(Incoming.Rotation); } if ( bReversesX ) Incoming.Velocity.X *= -1.0; if ( bReversesY ) Incoming.Velocity.Y *= -1.0; if ( bReversesZ ) Incoming.Velocity.Z *= -1.0; } return true; } //----------------------------------------------------------------------------- // Teleporter functions. function Trigger( actor Other, pawn EventInstigator ) { local Actor A; bEnabled = !bEnabled; if ( bEnabled ) //teleport any pawns already in my radius ForEach TouchingActors(class'Actor', A) PostTouch(A); } event Touch(Actor Other) { if ( !bEnabled || (Other == None) ) return; if( Other.bCanTeleport && Other.PreTeleport(Self)==false ) { PendingTouch = Other.PendingTouch; Other.PendingTouch = self; } } // Teleporter was touched by an actor. simulated function PostTouch( actor Other ) { local Teleporter D,Dest[16]; local int i; if( (InStr( URL, "/" ) >= 0) || (InStr( URL, "#" ) >= 0) ) { // Teleport to a level on the net. if( (Role == ROLE_Authority) && (Pawn(Other) != None) && Pawn(Other).IsHumanControlled() ) Level.Game.SendPlayer(PlayerController(Pawn(Other).Controller), URL); } else { // Teleport to a random teleporter in this local level, if more than one pick random. foreach AllActors( class 'Teleporter', D ) if( string(D.tag)~=URL && D!=Self ) { Dest[i] = D; i++; if ( i > arraycount(Dest) ) break; } i = rand(i); if( Dest[i] != None ) { // Teleport the actor into the other teleporter. if ( Other.IsA('Pawn') ) Other.PlayTeleportEffect(false, true); Dest[i].Accept( Other, self ); if ( Pawn(Other) != None ) TriggerEvent(Event, self, Pawn(Other)); } } } /* 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 */ function Actor SpecialHandling(Pawn Other) { local vector Dist2D; if ( bEnabled && (Teleporter(Other.Controller.RouteCache[1]) != None) && (string(Other.Controller.RouteCache[1].tag)~=URL) ) { if ( Abs(Location.Z - Other.Location.Z) < CollisionHeight + Other.CollisionHeight ) { Dist2D = Location - Other.Location; Dist2D.Z = 0; if ( VSize(Dist2D) < CollisionRadius + Other.CollisionRadius ) PostTouch(Other); } return self; } if (TriggerActor == None) { FindTriggerActor(); if (TriggerActor == None) return None; } if ( (TriggerActor2 != None) && (VSize(TriggerActor2.Location - Other.Location) < VSize(TriggerActor.Location - Other.Location)) ) return TriggerActor2; return TriggerActor; } event int SpecialCost(Pawn Other, ReachSpec Path) { // is this a teleport path? if ( (Teleporter(Path.Start) == None) || ((Path.reachFlags & 32) == 0) ) return 0; // vehicles can't teleport if ( Vehicle(Other) != None ) return 10000000; return 0; } sz'//============================================================================= // TeamInfo. //============================================================================= class TeamInfo extends ReplicationInfo native nativereplication; var localized string TeamName; var int Size; //number of players on this team in the level var float Score; var int TeamIndex; var color TeamColor, AltTeamColor; var Actor HomeBase; // key objective associated with this team var() class DefaultPlayerClass; var localized string ColorNames[4]; replication { // Variables the server should send to the client. reliable if( bNetDirty && (Role==ROLE_Authority) ) Score, HomeBase; reliable if ( bNetInitial && (Role==ROLE_Authority) ) TeamName, TeamColor, AltTeamColor, TeamIndex; } function bool BelongsOnTeam(class PawnClass) { return true; } simulated function string GetHumanReadableName() { if ( TeamName == Default.TeamName ) { if ( TeamIndex < 4 ) return ColorNames[TeamIndex]; return TeamName@TeamIndex; } return TeamName; } function bool AddToTeam( Controller Other ) { local Controller P; local bool bSuccess; // make sure loadout works for this team if ( Other == None ) { log("Added none to team!!!"); return false; } if (MessagingSpectator(Other) != None) { log("Messaging spectator so returning false",'VoiceChat'); return false; } Size++; Other.PlayerReplicationInfo.Team = self; Other.PlayerReplicationInfo.NetUpdateTime = Level.TimeSeconds - 1; bSuccess = false; if ( Other.IsA('PlayerController') ) Other.PlayerReplicationInfo.TeamID = 0; else Other.PlayerReplicationInfo.TeamID = 1; while ( !bSuccess ) { bSuccess = true; for ( P=Level.ControllerList; P!=None; P=P.nextController ) if ( P.bIsPlayer && (P != Other) && (P.PlayerReplicationInfo.Team == Other.PlayerReplicationInfo.Team) && (P.PlayerReplicationInfo.TeamId == Other.PlayerReplicationInfo.TeamId) ) bSuccess = false; if ( !bSuccess ) Other.PlayerReplicationInfo.TeamID = Other.PlayerReplicationInfo.TeamID + 1; } if ( PlayerController(Other) != None && Level.Game.VoiceReplicationInfo != None ) Level.Game.VoiceReplicationInfo.NotifyTeamChange(Other.PlayerReplicationInfo, TeamIndex); return true; } function RemoveFromTeam(Controller Other) { Size--; } // Stubs static function SetCharacters(array Chars); static function GetAllCharacters(out array Chars); s2class Suicided extends DamageType abstract; sH//============================================================================= // SubActionTrigger: // // Fires off a trigger. //============================================================================= class SubActionTrigger extends MatSubAction native; var(Trigger) name EventName; // The event to trigger sg//============================================================================= // SubActionSceneSpeed: // // Alters the speed of the scene without affecting the engine speed. //============================================================================= class SubActionSceneSpeed extends MatSubAction native; var(SceneSpeed) range SceneSpeed; sd msd msS//============================================================================= // SubActionOrientation: // // Changes the camera orientation. //============================================================================= class SubActionOrientation extends MatSubAction native; var(Orientation) Orientation CamOrientation; sf- msssE!@g=sj@msc-@ms}F%l>G-a-w.F%* .F%-Z @.F%-j.F%-~%(ke-w_*_ZrF%k(wQ* k, Gsy//============================================================================= // SubActionGameSpeed: // // Changes the game speed. //============================================================================= class SubActionGameSpeed extends MatSubAction native; var(GameSpeed) range GameSpeed; sb//============================================================================= // SubActionFOV: // // Changes the viewers FOV //============================================================================= class SubActionFOV extends MatSubAction native; var(FOV) range FOV; s@ssz-g-S#"f-?d-c- GsNZ#5 Gsyy k% Gsb-@LqSay V, GsrFS !qTeamSay V, GssyXi  GstxY  Gsu^Z  Gsvl` 7 ds9D9?,@sus%Couldn't find a random level to StartRollingDemo!o {@-]'~@NumBots%GQ (Wp@?SpectatorOnly=1$(4GQ :Wp@?SpectatorOnly=1?bAutoNumBots=true$( Gs^//============================================================================= // SubActionFade: // // Fades to/from a color //============================================================================= class SubActionFade extends MatSubAction native; var(Fade) color FadeColor; // The color to use for the fade var(Fade) bool bFadeOut; // If TRUE, the screen is fading out (towards the color) s@//============================================================================= // SubActionCameraShake: // // Shakes the camera randomly. //============================================================================= class SubActionCameraShake extends MatSubAction native; var(Shake) rangevector Shake; swu} (-](dVDISCONNECT Gsqz_-* x Gs{^-zt (7C 7C &7C &C ^- Gsssy-{a Gs@@ssssw ^N%F.w N%_-%N%4bsGamePassword_-H$$Text16 ''N%2bsIPPolicies_-H$$Text15 ''N%7bsAdminPassword_-H9=,$Text16 ''N%>bsLoginDelaySeconds_-H$$Text3;0:999 '' G sssfclass SubActionCameraEffect extends MatSubAction native noexport collapsecategories; var() editinline CameraEffect CameraEffect; var() float StartAlpha, EndAlpha; var() bool DisableAfterDuration; sEssss]-Q-| 'GwG*wGQ *GQ {-| q!{ GsF|m-| (GwG*wGQ *GQ {-| qV%ja!{q!s GsGU{n Gsb-|qV%| Gsv-It&[ 1 -Z'9:t&, X{u&qppqVu&q}qVqppqV9:t&q}qVV'( Gs{//============================================================================= // StaticMeshActor. // An actor that is drawn using a static mesh(a mesh that never changes, and // can be cached in video memory, resulting in a speed boost). //============================================================================= class StaticMeshActor extends Actor native placeable; var() bool bExactProjectileCollision; // nonzero extent projectiles should shrink to zero when hitting this actor sO //============================================================================= // Emitter: An Unreal Sprite Particle Emitter. //============================================================================= class SpriteEmitter extends ParticleEmitter native; enum EParticleDirectionUsage { PTDU_None, PTDU_Up, PTDU_Right, PTDU_Forward, PTDU_Normal, PTDU_UpAndNormal, PTDU_RightAndNormal, PTDU_Scale }; var (Sprite) EParticleDirectionUsage UseDirectionAs; var (Sprite) vector ProjectionNormal; var transient vector RealProjectionNormal; sss]-JC M9:v&9:$-Z(^9:C 9:$S{qqV%Tc'[|'}s9:v&9:$(}b9:C 9:$ W{qcWqc9D9?c&9?,b bcb9D9?b&9?,Tcw&qqV%JVw&}ErrorsExecCore@@|'}9:C 9:$&b%TbTcTT%T,&qTWV}q'}K9:C 9:$(Hb%TcTb*T9D9?T&9?,qTWV}q}9:C 9:$V%qpqV&q}qVV'}9:C 9:$.V}qqpqVq}qV&'}9:C 9:$%V%V&'}B9:C 9:$'V}qV&'}^9:C 9:$$V%'}}9:C 9:$#V}q'' GsO(//============================================================================= // Spline: A simple Hermite Spline for interpolation with position and // velocity continuity. //============================================================================= class Spline extends Object native; const mMaxTimes=5; var vector SplineA, SplineB, SplineC, SplineD; var rotator SplineE, SplineF, SplineG, SplineH; var float mStartT, mEndT; var bool mbInit; var float mTime; var float maDeltaTimes[mMaxTimes]; var int mIndex; var float mTotalTime; var bool mbRotatorSpline; var int mCnt; native final simulated function bool InitSplinePath(float t0, vector d0, vector v0, float t1, vector d1, vector v1); native final simulated function bool InitSplineRot( float t0, rotator d0, rotator v0, float t1, rotator d1, rotator v1); native final simulated function bool NextSplinePos( float dt, out vector d, out vector v, out vector a, out float outdt, optional bool bSmoothDt, optional bool bAccumDeltas); // gam native final simulated function bool NextSplineRot( float dt, out rotator d, out rotator v, out rotator a, out float outdt, optional bool bSmoothDt, optional bool bAccumDeltas); // gam sB//============================================================================= // Emitter: An Unreal Spark Particle Emitter. //============================================================================= class SparkEmitter extends ParticleEmitter native; struct ParticleSparkData { var float TimeBeforeVisible; var float TimeBetweenSegments; var vector StartLocation; var vector StartVelocity; }; var (Spark) range LineSegmentsRange; var (Spark) range TimeBeforeVisibleRange; var (Spark) range TimeBetweenSegmentsRange; var transient array SparkData; var transient vertexbuffer VertexBuffer; var transient indexbuffer IndexBuffer; var transient int NumSegments; var transient int VerticesPerParticle; var transient int IndicesPerParticle; var transient int PrimitivesPerParticle; sRssw&ss@class SoundGroup extends Sound native hidecategories(Object) noexport; var deprecated String Package; var(Sound) native array Sounds; var const transient native float TotalLikelihood; var const transient Sound RenderedSound; sN'c &-| '-u '-Z'Tc GsTUj &Vtoggleime 0-| (-u ( Gst-HW@s!:77C %GQ V%C AC %& G sssVYf $ GsZ@ss@ssJclass Sound extends Object native hidecategories(Object) noexport; var(Sound) native float Likelihood; var native const byte Data[44]; // sizeof (FSoundData) :( var native const Name FileType; var native const String FileName; var native const int OriginalSize; var native const float Duration; var native const pointer Handle; var native const int Flags; var native const int VoiceCodec; var native const float InitialSeekTime; var(Sound) float BaseRadius; var(Sound) float VelocityScale; sh ssXrGxuX[rZ--G'X _ GscP%zN.)$|P%&A|P%&G(' Gs[-]t KliX b-G(X a GsssWW-w"-.zX-(W--Z  Gs|// SmallNavigationPoint // Convenience class, to allow single point to specify small navigation point sizes class SmallNavigationPoint extends NavigationPoint native abstract; sW s_3sc ssd//============================================================================= // SkyZoneInfo. //============================================================================= class SkyZoneInfo extends ZoneInfo native; sd#class ShadowProjector extends Projector; var() Actor ShadowActor; var() vector LightDirection; var() float LightDistance; var() bool RootMotion; var() bool bBlobShadow; var() bool bShadowActive; var ShadowBitmapMaterial ShadowTexture; event PostBeginPlay() { Super(Actor).PostBeginPlay(); } event Destroyed() { if(ShadowTexture != None) { ShadowTexture.ShadowActor = None; if(!ShadowTexture.Invalid) Level.ObjectPool.FreeObject(ShadowTexture); ShadowTexture = None; ProjTexture = None; } Super.Destroyed(); } function InitShadow() { local Plane BoundingSphere; if(ShadowActor != None) { BoundingSphere = ShadowActor.GetRenderBoundingSphere(); FOV = Atan(BoundingSphere.W * 2 + 160, LightDistance) * 180 / PI; ShadowTexture = ShadowBitmapMaterial(Level.ObjectPool.AllocateObject(class'ShadowBitmapMaterial')); ProjTexture = ShadowTexture; if(ShadowTexture != None) { SetDrawScale(LightDistance * tan(0.5 * FOV * PI / 180) / (0.5 * ShadowTexture.USize)); ShadowTexture.Invalid = False; ShadowTexture.bBlobShadow = bBlobShadow; ShadowTexture.ShadowActor = ShadowActor; ShadowTexture.LightDirection = Normal(LightDirection); ShadowTexture.LightDistance = LightDistance; ShadowTexture.LightFOV = FOV; ShadowTexture.CullDistance = CullDistance; Enable('Tick'); UpdateShadow(); } else Log(Name$".InitShadow: Failed to allocate texture"); } else Log(Name$".InitShadow: No actor"); } function UpdateShadow() { local coords C; DetachProjector(true); if( (ShadowActor != None) && !ShadowActor.bHidden && (Level.TimeSeconds - ShadowActor.LastRenderTime < 4) && (ShadowTexture != None) && bShadowActive ) { if( ShadowTexture.Invalid ) Destroy(); else { if(RootMotion && ShadowActor.DrawType == DT_Mesh && ShadowActor.Mesh != None) { C = ShadowActor.GetBoneCoords(''); SetLocation(C.Origin); } else SetLocation(ShadowActor.Location + vect(0,0,5)); SetRotation(Rotator(Normal(-LightDirection))); ShadowTexture.Dirty = true; AttachProjector(); } } } function Tick(float DeltaTime) { UpdateShadow(); } T kWoY`lFoT צ9ʁ)3}ʁ)t ?ʁ)ʁ)ʁ)ʁ)t ?ʁ)3}Եt ?t ?t ?t ?t ?t ?t ?t ?t ?t ?3}ԵV%ZS}$@%B%C%XR&$DCSM ssT class ShadowBitmapMaterial extends BitmapMaterial native; #exec Texture Import file=Textures\blobshadow.tga Name=BlobTexture Mips=On UCLAMPMODE=CLAMP VCLAMPMODE=CLAMP DXT=3 var const transient pointer TextureInterfaces[2]; var Actor ShadowActor; var vector LightDirection; var float LightDistance, LightFOV; var bool Dirty, Invalid, bBlobShadow; var float CullDistance; var byte ShadowDarkness; var BitmapMaterial BlobShadow; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // // Default properties // s}class Shader extends RenderedMaterial editinlinenew native; var() editinlineuse Material Diffuse; var() editinlineuse Material Opacity; var() editinlineuse Material Specular; var() editinlineuse Material SpecularityMask; var() editinlineuse Material SelfIllumination; var() editinlineuse Material SelfIlluminationMask; var() editinlineuse Material Detail; var() float DetailScale; var() enum EOutputBlending { OB_Normal, OB_Masked, OB_Modulate, OB_Translucent, OB_Invisible, OB_Brighten, OB_Darken } OutputBlending; var() bool TwoSided; var() bool Wireframe; var bool ModulateStaticLighting2X; var() bool PerformLightingOnSpecularPass; var() bool ModulateSpecular2X; // sjs function Reset() { if(Diffuse != None) Diffuse.Reset(); if(Opacity != None) Opacity.Reset(); if(Specular != None) Specular.Reset(); if(SpecularityMask != None) SpecularityMask.Reset(); if(SelfIllumination != None) SelfIllumination.Reset(); if(SelfIlluminationMask != None) SelfIlluminationMask.Reset(); if(FallbackMaterial != None) FallbackMaterial.Reset(); } function Trigger( Actor Other, Actor EventInstigator ) { if(Diffuse != None) Diffuse.Trigger(Other,EventInstigator); if(Opacity != None) Opacity.Trigger(Other,EventInstigator); if(Specular != None) Specular.Trigger(Other,EventInstigator); if(SpecularityMask != None) SpecularityMask.Trigger(Other,EventInstigator); if(SelfIllumination != None) SelfIllumination.Trigger(Other,EventInstigator); if(SelfIlluminationMask != None) SelfIlluminationMask.Trigger(Other,EventInstigator); if(FallbackMaterial != None) FallbackMaterial.Trigger(Other,EventInstigator); } sU1// ==================================================================== // Class: Engine.Security // Parent: Engine.Info // // The security package is spawned and owned by each PlayerController as they // enter the game. It allows for the server to check various aspects // of the client. // ==================================================================== class Security extends Info Native; // When a command is executed, it's stored here in so we always know what the // last command was. var int LastType; var string LastParams[2]; replication { reliable if (Role==ROLE_Authority) ClientPerform, ClientMessage; reliable if (ROLE Results); simulated function ClientPerform(int SecType, string Param1, string Param2) { NativePerform(SecType, Param1, Param2); } event ServerCallback(int SecType, string Data) // Should be Subclassed { SetTimer(0,false); GotoState(''); } // ==================================================================== // Perform causes the security system to perform a command, and then // wait for a response. function Perform(int SecType, string Param1, string Param2, float TimeOut) { // Store the command LastType = SecType; LastParams[0] = Param1; LastParams[1] = Param2; ClientPerform(SecType, Param1, Param2); // Tell the client to perform the command SetTimer(TimeOut,false); // Setup a timeout for the command GotoState('Probation'); // Client is now on probation while we await the response } // ==================================================================== // When the Security actor performs a security command, it enters the probationary state while // it awaits a response. If the TimeOut value is exceeded, the client is removed from the server. state Probation { function Timer() // Should be SubClassed { BadClient(LastType,LastParams[0]$","$LastParams[1]); } } // ==================================================================== // The Final portion of the security is the communitcation system between // the server and the client when something goes wrong. function BadClient(int Code, string data) // Should be subclassed { ClientMessage("The Server has determined that your client is illegal and you have been removed! Code: "$Code$" ["$Data$"]"); Owner.Destroy(); Destroy(); } simulated function ClientMessage(string s) // Should be subclassed { log(S,'Security'); } sH//============================================================================= // ScriptedTexture: A scriptable Unreal texture // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class ScriptedTexture extends BitmapMaterial native; var const transient pointer RenderTarget; var const transient Viewport RenderViewport; var Actor Client; var transient int Revision; var transient const int OldRevision; var transient const int Invalid; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) native final function SetSize(int Width,int Height); native final function DrawText(int StartX,int StartY,coerce string Text,Font Font,Color Color); native final function TextSize(coerce string Text,Font Font,out int Width,out int Height); native final function DrawTile(float X,float Y,float XL,float YL,float U,float V,float UL,float VL,Material Material,Color Color); native final function DrawPortal(int X,int Y,int Width,int Height,Actor CamActor,vector CamLocation,rotator CamRotation,optional int FOV,optional bool ClearZ); s@//============================================================================= // Scout used for path generation. //============================================================================= class Scout extends Pawn native notplaceable; var const float MaxLandingVelocity; simulated function PreBeginPlay() { Destroy(); //scouts shouldn't exist during play } sf\T%sQ oK0rd*/a9 Sd//10/a9 T%LlT%10l9:9:$h Gsi4//============================================================================= // ScoreBoard //============================================================================= class ScoreBoard extends Info; var() GameReplicationInfo GRI; var() class HUDClass; var bool bDisplayMessages; simulated function PostBeginPlay() { Super.PostBeginPlay(); InitGRI(); Init(); } function Font GetSmallerFontFor(Canvas Canvas, int offset) { local int i; for ( i=0; i<8-offset; i++ ) { if ( HUDClass.default.FontScreenWidthMedium[i] <= Canvas.ClipX ) return HUDClass.static.LoadFontStatic(i+offset); } return HUDClass.static.LoadFontStatic(8); } function bool HaveHalfFont(Canvas Canvas, int Offset) { local int i; for ( i=0; i<9-offset; i++ ) if ( HUDClass.default.FontScreenWidthSmall[i] <= Canvas.ClipX ) return true; return false; } function Font GetSmallFontFor(int ScreenWidth, int offset) { local int i; for ( i=0; i<8-offset; i++ ) { if ( HUDClass.default.FontScreenWidthSmall[i] <= ScreenWidth ) return HUDClass.static.LoadFontStatic(i+offset); } return HUDClass.static.LoadFontStatic(8); } simulated function InitGRI() { GRI = PlayerController(Owner).GameReplicationInfo; } simulated function string InitTitle() { return Caps(GRI.GameName); } simulated function Init(); simulated event DrawScoreboard( Canvas C ) { UpdateGRI(); UpdateScoreBoard(C); } function bool UpdateGRI() { if (GRI == None) { InitGRI(); if ( GRI == None ) return false; } SortPRIArray(); return true; } simulated function String FormatTime( int Seconds ) { local int Minutes, Hours; local String Time; if( Seconds > 3600 ) { Hours = Seconds / 3600; Seconds -= Hours * 3600; Time = Hours$":"; } Minutes = Seconds / 60; Seconds -= Minutes * 60; if( Minutes >= 10 ) Time = Time $ Minutes $ ":"; else Time = Time $ "0" $ Minutes $ ":"; if( Seconds >= 10 ) Time = Time $ Seconds; else Time = Time $ "0" $ Seconds; return Time; } simulated function UpdateScoreBoard(Canvas Canvas); simulated function bool InOrder( PlayerReplicationInfo P1, PlayerReplicationInfo P2 ) { if( P1.bOnlySpectator ) { if( P2.bOnlySpectator ) return true; else return false; } else if ( P2.bOnlySpectator ) return true; if( P1.Score < P2.Score ) return false; if( P1.Score == P2.Score ) { if ( P1.Deaths > P2.Deaths ) return false; if ( (P1.Deaths == P2.Deaths) && (PlayerController(P2.Owner) != None) && (Viewport(PlayerController(P2.Owner).Player) != None) ) return false; } return true; } simulated function SortPRIArray() { local int i,j; local PlayerReplicationInfo tmp; for (i=0; i Actions; var() config enum EAffect { AFFECT_ViewportCamera, AFFECT_Actor, } Affect; var() Actor AffectedActor; // The name of the actor which will follow the matinee path (if Affect==AFFECT_Actor) var() bool bLooping; // If this is TRUE, the path will looping endlessly var() bool bCinematicView; // Should the screen go into letterbox mode when playing this scene? var() name PlayerScriptTag; // Tag of sequence that player's pawn should use during sequence var() name NextSceneTag; // The tag of the next scenemanager to execute when this one finishes var() name EventStart; // Fired when the scene starts var() name EventEnd; // Fired when the scene ends var() bool bHideHUD; // Hide the HUD while the scene runs? // These vars are set by the SceneManager in it's Tick function. Don't mess with them directly. var transient float PctSceneComplete; // How much of the scene has finished running var transient mataction CurrentAction; // The currently executing action var transient float SceneSpeed; var transient float TotalSceneTime; // The total time the scene will take to run (in seconds) var transient Actor Viewer; // The actor viewing this scene (the one being affected by the actions) var transient Pawn OldPawn; // The pawn we need to repossess when scene is over var transient bool bIsRunning; // If TRUE, this scene is executing. var transient bool bIsSceneStarted; // If TRUE, the scene has been initialized and is running var transient float CurrentTime; // Keeps track of the current time using the DeltaTime passed to Tick var transient array SampleLocations; // Sampled locations for camera movement var transient array SubActions; // The list of sub actions which will execute during this scene var transient Orientation CamOrientation; // The current camera orientation var transient Orientation PrevOrientation; // The previous orientation that was set var transient Interpolator RotInterpolator; // Interpolation helper for rotations var transient vector CameraShake; // The SubActionCameraShake effect fills this var in each frame var transient vector DollyOffset; // How far away we are from the actor we are locked to var transient bool bAbortCinematic; // Native functions native function float GetTotalSceneTime(); native function AbortScene(); simulated function BeginPlay() { Super.BeginPlay(); if( Affect == AFFECT_Actor && AffectedActor == None ) log( "SceneManager : Affected actor is NULL!" ); // // Misc set up // TotalSceneTime = GetTotalSceneTime(); bIsRunning = false; bIsSceneStarted = false; } function Trigger( actor Other, Pawn EventInstigator ) { bIsRunning = true; bIsSceneStarted = false; Disable( 'Trigger' ); } // Events event SceneStarted() // Called from C++ when the scene starts. { local Controller P; local AIScript S; // Figure out who our viewer is. Viewer = None; if( Affect==AFFECT_Actor ) Viewer = AffectedActor; else { for( P = Level.ControllerList ; P != None ; P = P.nextController ) if( P.IsA('PlayerController') ) { Viewer = P; OldPawn = PlayerController(Viewer).Pawn; if ( OldPawn != None ) { OldPawn.Velocity = vect(0,0,0); OldPawn.Acceleration = vect(0,0,0); PlayerController(Viewer).UnPossess(); if ( PlayerScriptTag != 'None' ) { ForEach DynamicActors( class'AIScript', S, PlayerScriptTag ) break; if ( S != None ) S.TakeOver(OldPawn); } } PlayerController(Viewer).bViewingMatineeCinematic = true; PlayerController(Viewer).StartInterpolation(); PlayerController(Viewer).MyHud.bHideHUD = bHideHUD; break; } } Viewer.StartInterpolation(); TriggerEvent( EventStart, Self, None); Level.Game.SceneStarted( Self, None ); } event SceneEnded() // Called from C++ when the scene ends. { bIsSceneStarted = false; if( Affect==AFFECT_ViewportCamera ) { if ( PlayerController(Viewer) != None ) { if ( OldPawn != None ) PlayerController(Viewer).Possess( OldPawn ); PlayerController(Viewer).bViewingMatineeCinematic = false; PlayerController(Viewer).bInterpolating = false; PlayerController(Viewer).MyHud.bHideHUD = false; } } Viewer.FinishedInterpolation(); Enable( 'Trigger' ); TriggerEvent( EventEnd, Self, None); Level.Game.SceneEnded( Self, None ); } s`*//============================================================================= // SavedMove is used during network play to buffer recent client moves, // for use when the server modifies the clients actual position, etc. // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class SavedMove extends Info; // also stores info in Acceleration attribute var SavedMove NextMove; // Next move in linked list. var float TimeStamp; // Time of this move. var float Delta; // amount of time for this move var bool bRun; var bool bDuck; var bool bPressedJump; var bool bDoubleJump; var EDoubleClickDir DoubleClickMove; // Double click info. var EPhysics SavedPhysics; var vector StartLocation, StartRelativeLocation, StartVelocity, StartFloor, SavedLocation, SavedVelocity, SavedRelativeLocation; var Actor StartBase, EndBase; final function Clear() { TimeStamp = 0; Delta = 0; DoubleClickMove = DCLICK_None; Acceleration = vect(0,0,0); StartVelocity = vect(0,0,0); bRun = false; bDuck = false; bPressedJump = false; bDoubleJump = false; } final function PostUpdate(PlayerController P) { bDoubleJump = P.bDoubleJump || bDoubleJump; if ( P.Pawn != None ) { SavedLocation = P.Pawn.Location; SavedVelocity = P.Pawn.Velocity; EndBase = P.Pawn.Base; if ( (EndBase != None) && !EndBase.bWorldGeometry ) SavedRelativeLocation = P.Pawn.Location - EndBase.Location; } SetRotation(P.Rotation); } final function bool IsJumpMove() { return ( bPressedJump || bDoubleJump || ((DoubleClickMove != DCLICK_None) && (DoubleClickMove != DCLICK_Active) && (DoubleClickMove != DCLICK_Done)) ); } function vector GetStartLocation() { if ( (Vehicle(StartBase) != None) || (Mover(StartBase) != None) ) return StartBase.Location + StartRelativeLocation; return StartLocation; } final function SetInitialPosition(Pawn P) { SavedPhysics = P.Physics; StartLocation = P.Location; StartVelocity = P.Velocity; StartBase = P.Base; StartFloor = P.Floor; if ( (StartBase != None) && !StartBase.bWorldGeometry ) StartRelativeLocation = P.Location - StartBase.Location; } final function SetMoveFor(PlayerController P, float DeltaTime, vector NewAccel, EDoubleClickDir InDoubleClick) { Delta = DeltaTime; if ( VSize(NewAccel) > 3072 ) NewAccel = 3072 * Normal(NewAccel); if ( P.Pawn != None ) SetInitialPosition(P.Pawn); Acceleration = NewAccel; DoubleClickMove = InDoubleClick; bRun = (P.bRun > 0); bDuck = (P.bDuck > 0); bPressedJump = P.bPressedJump; bDoubleJump = P.bDoubleJump; TimeStamp = Level.TimeSeconds; } s,class Resource extends Object abstract; wjx@Essn//============================================================================= // ReplicationInfo. //============================================================================= class ReplicationInfo extends Info abstract native; // (cpptext) // (cpptext) // (cpptext) // (cpptext) sNclass RenderedMaterial extends Material native noexport; var int renderedmaterial_dummy; // padding for hammer. disregard. --ryan. sb//============================================================================= // ReachSpec. // // A Reachspec describes the reachability requirements between two NavigationPoints // //============================================================================= class ReachSpec extends Object native; /* enum EReachSpecFlags { R_WALK = 1, //walking required R_FLY = 2, //flying required R_SWIM = 4, //swimming required R_JUMP = 8, // jumping required R_DOOR = 16, R_SPECIAL = 32, R_LADDER = 64, R_PROSCRIBED = 128, R_FORCED = 256, R_PLAYERONLY = 512 }; */ var int Distance; var const NavigationPoint Start; // navigationpoint at start of this path var const NavigationPoint End; // navigationpoint at endpoint of this path (next waypoint or goal) var int CollisionRadius; var int CollisionHeight; var int reachFlags; // see EReachSpecFlags definition in UnPath.h var int MaxLandingVelocity; var byte bPruned; var bool bForced; saclass ProjectorMaterial extends RenderedMaterial native noteditinlinenew; var const transient BitmapMaterial Gradient; var const transient Material Projected, BaseMaterial; var const transient byte BaseMaterialBlending, FrameBufferBlending; var const transient Matrix Matrix, GradientMatrix; var const transient bool bProjected, bProjectOnUnlit, bGradient, bProjectOnAlpha, bProjectOnBackfaces, bStaticProjector, bTwoSided; sy+class Projector extends Actor placeable native; #exec Texture Import File=Textures\Proj_IconMasked.pcx Name=Proj_Icon Mips=Off MASKED=1 #exec Texture Import file=Textures\GRADIENT_Fade.tga Name=GRADIENT_Fade Mips=Off UCLAMPMODE=CLAMP VCLAMPMODE=CLAMP DXT=3 #exec Texture Import file=Textures\GRADIENT_Clip.tga Name=GRADIENT_Clip Mips=Off UCLAMPMODE=CLAMP VCLAMPMODE=CLAMP DXT=3 // Projector blending operation. enum EProjectorBlending { PB_None, PB_Modulate, PB_AlphaBlend, PB_Add }; var() EProjectorBlending MaterialBlendingOp, // The blending operation between the material being projected onto and ProjTexture. FrameBufferBlendingOp; // The blending operation between the framebuffer and the result of the base material blend. // Projector properties. var() Material ProjTexture; var() int FOV; var() int MaxTraceDistance; var() bool bProjectBSP; var() bool bProjectTerrain; var() bool bProjectStaticMesh; var() bool bProjectParticles; var() bool bProjectActor; var() bool bLevelStatic; var() bool bClipBSP; var() bool bClipStaticMesh; var() bool bProjectOnUnlit; var() bool bGradient; var() bool bProjectOnBackfaces; var() bool bProjectOnAlpha; var() bool bProjectOnParallelBSP; var() name ProjectTag; var() bool bDynamicAttach; var() bool bNoProjectOnOwner; // Only for dynamic projectors var float FadeInTime; // Internal state. var const transient plane FrustumPlanes[6]; var const transient vector FrustumVertices[8]; var const transient Box Box; var const transient ProjectorRenderInfoPtr RenderInfo; var Texture GradientTexture; var transient Matrix GradientMatrix; var transient Matrix Matrix; var transient Vector OldLocation; // Native interface. native function AttachProjector(optional float FadeInTime); native function DetachProjector(optional bool Force); native function AbandonProjector(optional float Lifetime); native function AttachActor( Actor A ); native function DetachActor( Actor A ); simulated event PostBeginPlay() { if ( Level.NetMode == NM_DedicatedServer ) { GotoState('NoProjection'); return; } AttachProjector( FadeInTime ); if( bLevelStatic ) { AbandonProjector(); Destroy(); } if( bProjectActor ) SetCollision(True, False, False); } simulated event Touch( Actor Other ) { if( Other==None ) // sjs - rockets into projector return; if( Other.bAcceptsProjectors && (ProjectTag=='' || Other.Tag==ProjectTag) && (bProjectStaticMesh || Other.StaticMesh==None) && !(Other.bStatic && bStatic && Other.StaticMesh!=None) ) AttachActor(Other); } simulated event Untouch( Actor Other ) { DetachActor(Other); } state NoProjection { function BeginState() { Disable('Tick'); } } sE//============================================================================= // Projectile. // // A delayed-hit projectile that moves around for some time after it is created. //============================================================================= class Projectile extends Actor abstract native; //----------------------------------------------------------------------------- // Projectile variables. // Motion information. var float Speed; // Initial speed of projectile. var float MaxSpeed; // Limit on speed of projectile (0 means no limit) var float TossZ; var Actor ZeroCollider; var bool bSwitchToZeroCollision; // if collisionextent nonzero, and hit actor with bBlockNonZeroExtents=0, switch to zero extent collision var bool bNoFX; // used to prevent effects when projectiles are destroyed (see LimitationVolume) var bool bReadyToSplash; var bool bSpecialCalcView; // Use the projectile's SpecialCalcView function instead of letting the playercontroller handle the camera // Damage attributes. var float Damage; var float DamageRadius; var float MomentumTransfer; // Momentum magnitude imparted by impacting projectile. var class MyDamageType; // Projectile sound effects var sound SpawnSound; // Sound made when projectile is spawned. var sound ImpactSound; // Sound made when projectile hits something. // explosion effects var class ExplosionDecal; var float ExploWallOut; // distance to move explosions out from wall var Controller InstigatorController; var Actor LastTouched; var Actor HurtWall; var float MaxEffectDistance; var bool bScriptPostRender; // if true, PostRender2D() gets called simulated function PostBeginPlay() { local PlayerController PC; if ( Role == ROLE_Authority && Instigator != None && Instigator.Controller != None ) { if ( Instigator.Controller.ShotTarget != None && Instigator.Controller.ShotTarget.Controller != None ) Instigator.Controller.ShotTarget.Controller.ReceiveProjectileWarning( Self ); InstigatorController = Instigator.Controller; } if ( bDynamicLight && Level.NetMode != NM_DedicatedServer ) { PC = Level.GetLocalPlayerController(); if ( (PC == None) || (PC.ViewTarget == None) || (VSize(PC.ViewTarget.Location - Location) > 4000) ) { LightType = LT_None; bDynamicLight = false; } } bReadyToSplash = true; } function bool SpecialCalcView(out Actor ViewActor, out vector CameraLocation, out rotator CameraRotation, bool bBehindView); simulated function bool CanSplash() { return bReadyToSplash; } function Reset() { Destroy(); } simulated function bool CheckMaxEffectDistance(PlayerController P, vector SpawnLocation) { return !P.BeyondViewDistance(SpawnLocation,MaxEffectDistance); } /* HurtRadius() Hurt locally authoritative actors within the radius. */ simulated function HurtRadius( float DamageAmount, float DamageRadius, class DamageType, float Momentum, vector HitLocation ) { local actor Victims; local float damageScale, dist; local vector dir; if ( bHurtEntry ) return; bHurtEntry = true; foreach VisibleCollidingActors( class 'Actor', Victims, DamageRadius, HitLocation ) { // don't let blast damage affect fluid - VisibleCollisingActors doesn't really work for them - jag if( (Victims != self) && (Hurtwall != Victims) && (Victims.Role == ROLE_Authority) && !Victims.IsA('FluidSurfaceInfo') ) { dir = Victims.Location - HitLocation; dist = FMax(1,VSize(dir)); dir = dir/dist; damageScale = 1 - FMax(0,(dist - Victims.CollisionRadius)/DamageRadius); if ( Instigator == None || Instigator.Controller == None ) Victims.SetDelayedDamageInstigatorController( InstigatorController ); if ( Victims == LastTouched ) LastTouched = None; Victims.TakeDamage ( damageScale * DamageAmount, Instigator, Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius) * dir, (damageScale * Momentum * dir), DamageType ); if (Vehicle(Victims) != None && Vehicle(Victims).Health > 0) Vehicle(Victims).DriverRadiusDamage(DamageAmount, DamageRadius, InstigatorController, DamageType, Momentum, HitLocation); } } if ( (LastTouched != None) && (LastTouched != self) && (LastTouched.Role == ROLE_Authority) && !LastTouched.IsA('FluidSurfaceInfo') ) { Victims = LastTouched; LastTouched = None; dir = Victims.Location - HitLocation; dist = FMax(1,VSize(dir)); dir = dir/dist; damageScale = FMax(Victims.CollisionRadius/(Victims.CollisionRadius + Victims.CollisionHeight),1 - FMax(0,(dist - Victims.CollisionRadius)/DamageRadius)); if ( Instigator == None || Instigator.Controller == None ) Victims.SetDelayedDamageInstigatorController(InstigatorController); Victims.TakeDamage ( damageScale * DamageAmount, Instigator, Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius) * dir, (damageScale * Momentum * dir), DamageType ); if (Vehicle(Victims) != None && Vehicle(Victims).Health > 0) Vehicle(Victims).DriverRadiusDamage(DamageAmount, DamageRadius, InstigatorController, DamageType, Momentum, HitLocation); } bHurtEntry = false; } /* HurtRadius() Hurt locally authoritative actors within the radius. */ simulated function DelayedHurtRadius( float DamageAmount, float DamageRadius, class DamageType, float Momentum, vector HitLocation ) { HurtRadius(DamageAmount, DamageRadius, DamageType, Momentum, HitLocation); } //============== // Encroachment function bool EncroachingOn( actor Other ) { if ( (Other.Brush != None) || (Brush(Other) != None) ) return true; return false; } //============== // Touching simulated singular function Touch(Actor Other) { local vector HitLocation, HitNormal; if ( Other == None ) // Other just got destroyed in its touch? return; if ( Other.bProjTarget || Other.bBlockActors ) { LastTouched = Other; if ( Velocity == vect(0,0,0) || Other.IsA('Mover') ) { ProcessTouch(Other,Location); LastTouched = None; return; } if ( Other.TraceThisActor(HitLocation, HitNormal, Location, Location - 2*Velocity, GetCollisionExtent()) ) HitLocation = Location; ProcessTouch(Other, HitLocation); LastTouched = None; if ( (Role < ROLE_Authority) && (Other.Role == ROLE_Authority) && (Pawn(Other) != None) ) ClientSideTouch(Other, HitLocation); } } simulated function ClientSideTouch(Actor Other, Vector HitLocation) { Other.TakeDamage(Damage, instigator, Location, MomentumTransfer * Normal(Velocity), MyDamageType); } simulated function ProcessTouch(Actor Other, Vector HitLocation) { if ( Other != Instigator ) Explode(HitLocation,Normal(HitLocation-Other.Location)); } simulated singular function HitWall(vector HitNormal, actor Wall) { local PlayerController PC; if ( Role == ROLE_Authority ) { if ( !Wall.bStatic && !Wall.bWorldGeometry ) { if ( Instigator == None || Instigator.Controller == None ) Wall.SetDelayedDamageInstigatorController( InstigatorController ); Wall.TakeDamage( Damage, instigator, Location, MomentumTransfer * Normal(Velocity), MyDamageType); if (DamageRadius > 0 && Vehicle(Wall) != None && Vehicle(Wall).Health > 0) Vehicle(Wall).DriverRadiusDamage(Damage, DamageRadius, InstigatorController, MyDamageType, MomentumTransfer, Location); HurtWall = Wall; } MakeNoise(1.0); } Explode(Location + ExploWallOut * HitNormal, HitNormal); if ( (ExplosionDecal != None) && (Level.NetMode != NM_DedicatedServer) ) { if ( ExplosionDecal.Default.CullDistance != 0 ) { PC = Level.GetLocalPlayerController(); if ( !PC.BeyondViewDistance(Location, ExplosionDecal.Default.CullDistance) ) Spawn(ExplosionDecal,self,,Location, rotator(-HitNormal)); else if ( (Instigator != None) && (PC == Instigator.Controller) && !PC.BeyondViewDistance(Location, 2*ExplosionDecal.Default.CullDistance) ) Spawn(ExplosionDecal,self,,Location, rotator(-HitNormal)); } else Spawn(ExplosionDecal,self,,Location, rotator(-HitNormal)); } HurtWall = None; } simulated function BlowUp(vector HitLocation) { HurtRadius(Damage,DamageRadius, MyDamageType, MomentumTransfer, HitLocation ); if ( Role == ROLE_Authority ) MakeNoise(1.0); } simulated function Explode(vector HitLocation, vector HitNormal) { Destroy(); } simulated final function RandSpin(float spinRate) { DesiredRotation = RotRand(); RotationRate.Yaw = spinRate * 2 *FRand() - spinRate; RotationRate.Pitch = spinRate * 2 *FRand() - spinRate; RotationRate.Roll = spinRate * 2 *FRand() - spinRate; } simulated static function float GetRange() { if (default.LifeSpan == 0.0) return 15000; else return (default.MaxSpeed * default.LifeSpan); } function bool IsStationary() { return false; } // called if bScriptPostRender is true simulated event PostRender2D(Canvas C, float ScreenLocX, float ScreenLocY); s}// gam --- class ProceduralSound extends Sound native hidecategories(Object) noexport; var(Sound) Sound BaseSound; var(Sound) float PitchModification; var(Sound) float VolumeModification; var(Sound) float PitchVariance; var(Sound) float VolumeVariance; var transient float RenderedPitchModification; var transient float RenderedVolumeModification; sYtIj / a%e a&e Gsss=@%p1=EE,9W!@W9:9:$`ZXEk"aY' GsQclass PrecacheHack extends Actor native; var array Materials; sg7//============================================================================= // Powerup items - activatable inventory. //============================================================================= class Powerups extends Inventory abstract native nativereplication; var travel int NumCopies; var() bool bCanHaveMultipleCopies; // if player can possess more than one of this var() bool bAutoActivate; // automatically activated when picked up var() bool bActivatable; // Whether item can be activated/deactivated (if true, must auto activate) var travel bool bActive; // Whether item is currently activated. var() localized String ExpireMessage; // Messages shown when powerup charge runs out var() sound ActivateSound, DeActivateSound; replication { // Things the server should send to the client. reliable if( bNetOwner && bNetDirty && (Role==ROLE_Authority) ) NumCopies, bActivatable, bActive; } event TravelPreAccept() { Super.TravelPreAccept(); if( bActive ) Activate(); } function PickupFunction(Pawn Other) { Super.PickupFunction(Other); if (bActivatable && Other.SelectedItem==None) Other.SelectedItem=self; if (bActivatable && bAutoActivate && Other.bAutoActivate) Activate(); } // // Select first activatable item. // function Powerups SelectNext() { if ( bActivatable ) return self; if ( Inventory != None ) return Inventory.SelectNext(); else return None; } // // Toggle Activation of selected Item. // function Activate() { if( bActivatable ) { GoToState('Activated'); } } // // Advanced function which lets existing items in a pawn's inventory // prevent the pawn from picking something up. Return true to abort pickup // or if item handles the pickup function bool HandlePickupQuery( Pickup Item ) { if (item.InventoryType == class) { if (bCanHaveMultipleCopies) NumCopies++; else if ( bDisplayableInv ) { if ( Item.Inventory != None ) Charge = Max(Charge, Item.Inventory.Charge); else Charge = Max(Charge, Item.InventoryType.Default.Charge); } else return false; Item.AnnouncePickup(Pawn(Owner)); Item.SetRespawn(); return true; } if ( Inventory == None ) return false; return Inventory.HandlePickupQuery(Item); } function float UseCharge(float Amount); function FireEffect(); // // This is called when a usable inventory item has used up it's charge. // function UsedUp() { if ( Pawn(Owner) != None ) { bActivatable = false; Pawn(Owner).NextItem(); if (Pawn(Owner).SelectedItem == Self) { Pawn(Owner).NextItem(); if (Pawn(Owner).SelectedItem == Self) Pawn(Owner).SelectedItem=None; } Instigator.ReceiveLocalizedMessage( MessageClass, 0, None, None, Self.Class ); } Owner.PlaySound(DeactivateSound,SLOT_Interface); Destroy(); } static function string GetLocalString( optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2 ) { return Default.ExpireMessage; } //============================================================================= // Active state: this inventory item is armed and ready to rock! state Activated { function BeginState() { bActive = true; } function EndState() { bActive = false; } function Activate() { if ( (Pawn(Owner) != None) && Pawn(Owner).bAutoActivate && bAutoActivate && (Charge>0) ) return; Global.Activate(); } } sh class PotentialClimbWatcher extends Info native; simulated function Tick(float DeltaTime) { local rotator PawnRot; local LadderVolume L; local bool bFound; if ( (Owner == None) || Owner.bDeleteMe || !Pawn(Owner).CanGrabLadder() ) { destroy(); return; } PawnRot = Owner.Rotation; PawnRot.Pitch = 0; ForEach Owner.TouchingActors(class'LadderVolume', L) if ( L.Encompasses(Owner) ) { if ( (vector(PawnRot) Dot L.LookDir) > 0.9 ) { Pawn(Owner).ClimbLadder(L); destroy(); return; } else bFound = true; } if ( !bFound ) destroy(); } sP-O-h P O- Gs^B#"^`-* GsFN-i s 4R-N-?R-R- P Gsgqw #9:P %qq9?%[W [W A W \W qi-S-k, A \W fff?W =A 9?kA ik%\i9?%k9:O W W 9?9:O &A W 9<O A W qqW W 9<O A ?W iq9<O [O $9:P &q9?%s%s,y&9D9?s&=q9?y&ss ss s1,s q>q,s qs%s,q9?s&=ss ss s&s sq Gsq//============================================================================= // PolyMarker. // // These are markers for the polygon drawing mode. // // These should NOT be manually added to the level. The editor adds and // deletes them on it's own. // //============================================================================= class PolyMarker extends Keypoint placeable native; #exec Texture Import File=Textures\S_PolyMarker.pcx Name=S_PolyMarker Mips=Off MASKED=1 sOYclass PlayInfo extends object native; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) enum EPlayInfoType { PIT_Check, PIT_Select, PIT_Text, PIT_Custom }; struct native init PlayInfoData { var const Property ThisProp; // Pointer to property var const class ClassFrom; // Which class was this Property from var const string SettingName; // Name of the class member var const string DisplayName; // Display Name of the control (from .INT/.INI File ?) var const string Description; // Description of what the property does var const string Grouping; // Grouping for this parameter var const string Data; // Extra Data (like Gore Level Texts) var const string ExtraPriv; // Extra Privileges Required to set this parameter var const string Value; // Value of the setting var const EPlayInfoType RenderType; // Type of rendered control var const byte SecLevel; // Sec Level Required to set this param. (Read from Ini file afterwards) var const byte Weight; // Importance of the setting compared to others in its group var const bool bMPOnly; // This setting should only appear in multi-player context var const bool bAdvanced; // This setting is an advanced property (only displayed when user sets bExpertMode in GUIController) // Internal flags (set natively) var const bool bGlobal; // globalconfig property var const bool bStruct; // Property is a struct var const int ArrayDim; // -1: Not array, 0: dynamic array, >1: Static array }; var const array Settings; var const array > InfoClasses; var const array ClassStack; var const array Groups; var const string LastError; native(700) final function bool Clear(); native(701) final function bool AddClass(class AddingClass); native(702) final function bool RemoveClass(class RemovingClass); native(703) final function bool PopClass(); native(704) final function bool AddSetting(string Group, string PropertyName, string Description, byte SecLevel, byte Weight, string RenderType, optional string Extras, optional string ExtraPrivs, optional bool bMultiPlayerOnly, optional bool bAdvanced); native(705) final function bool SaveSettings(); // Saves stored settings to ini file native(706) final function bool StoreSetting(int index, coerce string NewVal, optional string RangeData); // Only validates and sets Settins[index].Value to passed value native(707) final function bool GetSettings(string GroupName, out array GroupSettings); // rjp native(708) final function int FindIndex(string SettingName); // 0 = Grouping, 1 = Weight, 2 = RenderType, 3 = DisplayName, 4 = SettingName, 5 = SecLevel // 6 = RevGroup, 1 = RevWeight, etc. // Equal items will be sorted by the next highest type native(709) final function Sort(byte SortingMethod); final function Dump( optional string group ) { local int i; log("** Dumping settings array for PlayInfo object '"$Name$"' **"); log("** Classes:"@InfoClasses.Length); for ( i = 0; i < InfoClasses.Length; i++ ) log(" "$i$")"@InfoClasses[i].Name); log(""); log("** Groups:"@Groups.Length); for (i = 0; i < Groups.Length; i++) log(" "$i$")"@Groups[i]); log(""); Log("** Settings:"@Settings.Length); for (i = 0; i > Classes, optional bool bStrict) { local int i, j; local bool b; if (Classes.Length == 0) return b; b = True; Clear(); for (i = 0; i < Classes.Length; i++) { if (Classes[i] == None) { log("Call in PlayInfo.Init() with 'None' value for Class array member. Index:"$i); Classes.Remove(i--, 1); continue; } Classes[i].static.FillPlayInfo(Self); } if ( bStrict ) { for ( i = InfoClasses.Length - 1; i >= 0; i-- ) { for (j = 0; j < Classes.Length; j++) if (InfoClasses[i] == Classes[j]) break; if (j < Classes.Length) continue; b = b && RemoveClass(InfoClasses[i]); } } return b; } final function class GetGameInfo() { local int i; for ( i = 0; i < InfoClasses.Length; i++ ) if ( class( InfoClasses[i] ) != None ) return class(InfoClasses[i]); return None; } final function SplitStringToArray(out array Parts, string Source, string Delim) { Split(Source, Delim, Parts); } s@ //============================================================================= // Player start location. //============================================================================= class PlayerStart extends SmallNavigationPoint placeable native; #exec Texture Import File=Textures\S_Player.pcx Name=S_Player Mips=Off MASKED=1 // Players on different teams are not spawned in areas with the // same TeamNumber unless there are more teams in the level than // team numbers. var() byte TeamNumber; // what team can spawn at this start var() bool bSinglePlayerStart; // use first start encountered with this true for single player var() bool bCoopStart; // start can be used in coop games var() bool bEnabled; var() bool bPrimaryStart; // None primary starts used only if no primary start available sQ//============================================================================= // PlayerReplicationInfo. //============================================================================= class PlayerReplicationInfo extends ReplicationInfo native nativereplication; var float Score; // Player's current score. var float Deaths; // Number of player's deaths. var Decoration HasFlag; var byte Ping; var Volume PlayerVolume; var ZoneInfo PlayerZone; var int NumLives; var string PlayerName; // Player name, or blank if none. var string CharacterName, OldCharacterName; var string OldName, PreviousName; // Temporary value. var int PlayerID; // Unique id number. var TeamInfo Team; // Player Team var int TeamID; // Player position in team. var class VoiceType; var string VoiceTypeName; var bool bAdmin; // Player logged in as Administrator var bool bIsFemale; var bool bIsSpectator; var bool bOnlySpectator; var bool bWaitingPlayer; var bool bReadyToPlay; var bool bOutOfLives; var bool bBot; var bool bWelcomed; // set after welcome message broadcast (not replicated) var bool bReceivedPing; var bool bNoTeam; // true if no teaminfo for this PRI var bool bTeamNotified; var byte PacketLoss; // Time elapsed. var int StartTime; var localized String StringDead; var localized String StringSpectating; var localized String StringUnknown; var int GoalsScored; // not replicated - used on server side only var int Kills; // not replicated var vehicle CurrentVehicle; // for performance on clients var LinkedReplicationInfo CustomReplicationInfo; // for use by mod authors // ======================================== // ======================================== // Voice chat // ======================================== // ======================================== var VoiceChatReplicationInfo VoiceInfo; var bool bRegisteredChatRoom; var VoiceChatRoom PrivateChatRoom; // not replicated - simulated spawn var int ActiveChannel; // this player's currently active channel var int VoiceMemberMask; // members of this player's private chatroom var byte VoiceID; // contains the player's unique ID used by voice channels replication { // Things the server should send to the client. reliable if ( bNetDirty && (Role == Role_Authority) ) Score, Deaths, PlayerVolume, PlayerZone, PlayerName, Team, TeamID, bIsFemale, bAdmin, bIsSpectator, bOnlySpectator, bWaitingPlayer, bReadyToPlay, StartTime, bOutOfLives, CharacterName, VoiceID, VoiceMemberMask, ActiveChannel; reliable if ( bNetDirty && (Role == ROLE_Authority) && bNetOwner && HasFlag == None ) HasFlag; reliable if ( bNetDirty && (Role == Role_Authority) && (!bNetOwner || bDemoRecording) ) PacketLoss, Ping; reliable if ( bNetDirty && (Role == Role_Authority) && bNetInitial ) PlayerID, bBot, VoiceTypeName, bNoTeam, CustomReplicationInfo; } event PostBeginPlay() { if ( Role < ROLE_Authority ) return; if (AIController(Owner) != None) bBot = true; StartTime = Level.Game.GameReplicationInfo.ElapsedTime; Timer(); SetTimer(1.5 + FRand(), true); } simulated event PostNetBeginPlay() { local GameReplicationInfo GRI; local VoiceChatReplicationInfo VRI; if ( Level.GRI != None ) Level.GRI.AddPRI(self); else { ForEach DynamicActors(class'GameReplicationInfo',GRI) { GRI.AddPRI(self); break; } } // VoiceInfo will only have a value if our PlayerID was replicated prior to our PostNetBeginPlay() & VoiceReplicationInfo had been initialized. foreach DynamicActors(class'VoiceChatReplicationInfo', VRI) { VoiceInfo = VRI; break; } if ( Team != None ) bTeamNotified = true; } simulated function bool NeedNetNotify() { return ( !bRegisteredChatRoom || (!bNoTeam && (Team == None)) ); } simulated event PostNetReceive() { local Actor A; local PlayerController PC; if ( !bTeamNotified && (Team != None) ) { bTeamNotified = true; PC = Level.GetLocalPlayerController(); ForEach DynamicActors(class'Actor', A) { // find my pawn and tell it if ( Pawn(A) != None && Pawn(A).PlayerReplicationInfo == self ) { Pawn(A).NotifyTeamChanged(); if ( PC.PlayerReplicationInfo != self ) break; } else if ( A.bNotifyLocalPlayerTeamReceived && PC.PlayerReplicationInfo == self ) A.NotifyLocalPlayerTeamReceived(); //if this is the local player's PRI, tell actors that want to know about it } } if ( !bRegisteredChatRoom && VoiceInfo != None && PlayerID != default.PlayerID && VoiceID != default.VoiceID ) { bRegisteredChatRoom = True; VoiceInfo.AddVoiceChatter(Self); } bNetNotify = NeedNetNotify(); } simulated function Destroyed() { local GameReplicationInfo GRI; if ( Level.GRI != None ) Level.GRI.RemovePRI(self); else { ForEach DynamicActors(class'GameReplicationInfo',GRI) { GRI.RemovePRI(self); break; } } if ( VoiceInfo == None ) foreach DynamicActors( class'VoiceChatReplicationInfo', VoiceInfo ) break; if ( VoiceInfo != None ) VoiceInfo.RemoveVoiceChatter(Self); Super.Destroyed(); } function SetCharacterVoice(string S) { local class NewVoiceType; if ( (Level.NetMode == NM_DedicatedServer) && (VoiceType != None) ) { VoiceTypeName = S; return; } if ( S == "" ) { VoiceTypeName = ""; return; } NewVoiceType = class(DynamicLoadObject(S,class'Class')); if ( NewVoiceType != None ) { VoiceType = NewVoiceType; VoiceTypeName = S; } } function SetCharacterName(string S) { CharacterName = S; } /* Reset() reset actor to initial state - used when restarting level without reloading. */ function Reset() { Super.Reset(); Score = 0; Deaths = 0; HasFlag = None; bReadyToPlay = false; NumLives = 0; bOutOfLives = false; } simulated function string GetHumanReadableName() { return PlayerName; } simulated function string GetLocationName() { local string VehicleString; local Vehicle V; if( ( PlayerVolume == None ) && ( PlayerZone == None ) ) { if ( (Owner != None) && Controller(Owner).IsInState('Dead') ) return StringDead; else return StringSpectating; } if ( Owner != None ) { if ( Vehicle(Controller(Owner).Pawn) != None ) VehicleString = Vehicle(Controller(Owner).Pawn).GetVehiclePositionString(); } else if ( Level.NetMode == NM_Client ) { if ( (CurrentVehicle != None) && (CurrentVehicle.PlayerReplicationInfo == self) ) VehicleString = CurrentVehicle.GetVehiclePositionString(); else if ( Level.TimeSeconds - Level.LastVehicleCheck > 1 ) { // vehicles are often bAlwaysRelevant, so may still be relevant ForEach DynamicActors(class'Vehicle', V) if ( V.PlayerReplicationInfo == self ) { VehicleString = V.GetVehiclePositionString(); CurrentVehicle = V; break; } if ( V == None ) Level.LastVehicleCheck = Level.TimeSeconds; } } if( ( PlayerVolume != None ) && ( PlayerVolume.LocationName != class'Volume'.Default.LocationName ) ) { if ( len(PlayerVolume.LocationName@VehicleString) > 32 ) return PlayerVolume.LocationName; return PlayerVolume.LocationName@VehicleString; } else if( PlayerZone != None && ( PlayerZone.LocationName != "" ) ) { if ( len(PlayerZone.LocationName@VehicleString) > 32 ) return PlayerZone.LocationName; return PlayerZone.LocationName@VehicleString; } else if ( VehicleString != "" ) return VehicleString; else if ( Level.Title != Level.Default.Title ) return Level.Title; else return StringUnknown; } simulated function material GetPortrait(); event UpdateCharacter(); function UpdatePlayerLocation() { local Volume V, Best; local Pawn P; local Controller C; C = Controller(Owner); if( C != None ) P = C.Pawn; if( P == None ) { PlayerVolume = None; PlayerZone = None; return; } if ( PlayerZone != P.Region.Zone ) PlayerZone = P.Region.Zone; foreach P.TouchingActors( class'Volume', V ) { if( V.LocationName == "") continue; if( (Best != None) && (V.LocationPriority <= Best.LocationPriority) ) continue; if( V.Encompasses(P) ) Best = V; } if ( PlayerVolume != Best ) PlayerVolume = Best; } /* DisplayDebug() list important controller attributes on canvas */ simulated function DisplayDebug(Canvas Canvas, out float YL, out float YPos) { if ( Team != None ) Canvas.DrawText(" PlayerName "$PlayerName$" Team "$Team.GetHumanReadableName() $"("$Team.TeamIndex$") has flag "$HasFlag); else Canvas.DrawText(" PlayerName "$PlayerName$" NO Team"); if ( !bBot ) { YPos += YL; Canvas.SetPos(4, YL); Canvas.DrawText(" bIsSpec:"$bIsSpectator@"OnlySpec:"$bOnlySpectator@"Waiting:"$bWaitingPlayer@"Ready:"$bReadyToPlay@"OutOfLives:"$bOutOfLives); } } event ClientNameChange() { local PlayerController PC; ForEach DynamicActors(class'PlayerController', PC) PC.ReceiveLocalizedMessage( class'GameMessage', 2, self ); } function Timer() { local Controller C; UpdatePlayerLocation(); SetTimer(1.5 + FRand(), true); if( FRand() < 0.65 ) return; if( !bBot ) { C = Controller(Owner); if ( !bReceivedPing ) Ping = Min(int(0.25 * float(C.ConsoleCommand("GETPING"))),255); } } function SetPlayerName(string S) { OldName = PlayerName; PlayerName = S; if ( PlayerController(Owner) != None ) PlayerController(Owner).PlayerOwnerName = S; } function SetWaitingPlayer(bool B) { bIsSpectator = B; bWaitingPlayer = B; } function SetChatPassword( string InPassword ) { if ( PrivateChatRoom != None ) PrivateChatRoom.SetChannelPassword(InPassword); } function SetVoiceMemberMask( int NewMask ) { VoiceMemberMask = NewMask; } simulated function string GetCallSign() { if ( TeamID > 14 ) return ""; return class'GameInfo'.default.CallSigns[TeamID]; } simulated event string GetNameCallSign() { if ( TeamID > 14 ) return PlayerName; return PlayerName$" ["$class'GameInfo'.default.CallSigns[TeamID]$"]"; } ssssX//============================================================================= // PlayerInput // Object within playercontroller that manages player input. // only spawned on client //============================================================================= class PlayerInput extends Object within PlayerController config(User) native transient; var globalconfig bool bInvertMouse; var bool bWasForward; // used for doubleclick move var bool bWasBack; var bool bWasLeft; var bool bWasRight; var bool bEdgeForward; var bool bEdgeBack; var bool bEdgeLeft; var bool bEdgeRight; var bool bAdjustSampling; // Mouse smoothing var globalconfig byte MouseSmoothingMode; var globalconfig float MouseSmoothingStrength; var globalconfig float MouseSensitivity; var globalconfig float MouseSamplingTime; var globalconfig float MouseAccelThreshold; var float SmoothedMouse[2], ZeroTime[2], SamplingTime[2], MaybeTime[2], OldSamples[4]; var int MouseSamples[2]; var float DoubleClickTimer; // max double click interval for double click move var globalconfig float DoubleClickTime; var globalconfig bool bEnableDodging; //============================================================================= // Input related functions. function bool InvertLook(); // Postprocess the player's input. event PlayerInput( float DeltaTime ) { local float FOVScale, MouseScale; // Ignore input if we're playing back a client-side demo. if( Outer.bDemoOwner && !Outer.default.bDemoOwner ) return; // Check for Double click move // flag transitions bEdgeForward = (bWasForward ^^ (aBaseY > 0)); bEdgeBack = (bWasBack ^^ (aBaseY < 0)); bEdgeLeft = (bWasLeft ^^ (aStrafe < 0)); bEdgeRight = (bWasRight ^^ (aStrafe > 0)); bWasForward = (aBaseY > 0); bWasBack = (aBaseY < 0); bWasLeft = (aStrafe < 0); bWasRight = (aStrafe > 0); // Smooth and amplify mouse movement FOVScale = DesiredFOV * 0.01111; // 0.01111 = 1/90 MouseScale = MouseSensitivity * FOVScale; aMouseX = SmoothMouse(aMouseX*MouseScale, DeltaTime,bXAxis,0); aMouseY = SmoothMouse(aMouseY*MouseScale, DeltaTime,bYAxis,1); aMouseX = AccelerateMouse(aMouseX); aMouseY = AccelerateMouse(aMouseY); // adjust keyboard and joystick movements aLookUp *= FOVScale; aTurn *= FOVScale; // Remap raw x-axis movement. if( bStrafe!=0 ) // strafe aStrafe += aBaseX * 7.5 + aMouseX; else // forward aTurn += aBaseX * FOVScale + aMouseX; aBaseX = 0; // Remap mouse y-axis movement. if( (bStrafe == 0) && (bAlwaysMouseLook || (bLook!=0)) ) { // Look up/down. if ( bInvertMouse ) aLookUp -= aMouseY; else aLookUp += aMouseY; } else // Move forward/backward. aForward += aMouseY; if ( bSnapLevel != 0 ) { bCenterView = true; bKeyboardLook = false; } else if (aLookUp != 0) { bCenterView = false; bKeyboardLook = true; } else if ( bSnapToLevel && !bAlwaysMouseLook ) { bCenterView = true; bKeyboardLook = false; } // Remap other y-axis movement. if ( bFreeLook != 0 ) { bKeyboardLook = true; aLookUp += 0.5 * aBaseY * FOVScale; } else aForward += aBaseY; aBaseY = 0; // Handle walking. HandleWalking(); } exec function SetSmoothingMode(byte B) { MouseSmoothingMode = B; // log("Smoothing mode "$MouseSmoothingMode); } exec function SetSmoothingStrength(float F) { MouseSmoothingStrength = FClamp(F,0,1); default.MouseSmoothingStrength = MouseSmoothingStrength; class'PlayerInput'.static.StaticSaveConfig(); } function float AccelerateMouse(float aMouse) { local float Accel; if ( abs(aMouse) == 0 ) return 0; Accel = MouseAccelThreshold * MouseSensitivity; if ( abs(aMouse) < Accel ) { if ( abs(aMouse) < 0.1 * Accel ) aMouse *= 0.1; else aMouse = aMouse * abs(aMouse)/Accel; } return aMouse; } function float SmoothMouse(float aMouse, float DeltaTime, out byte SampleCount, int Index) { local int i, sum; if ( MouseSmoothingMode == 0 ) return aMouse; if ( aMouse == 0 ) { ZeroTime[Index] += DeltaTime; if ( ZeroTime[Index] < MouseSamplingTime ) { SamplingTime[Index] += DeltaTime; MaybeTime[Index] += DeltaTime; aMouse = SmoothedMouse[Index]; } else { if ( bAdjustSampling && (MouseSamples[Index] > 9) ) { SamplingTime[Index] -= MaybeTime[Index]; MouseSamplingTime = 0.9 * MouseSamplingTime + 0.1 * SamplingTime[Index]/MouseSamples[Index]; } SamplingTime[Index] = 0; SmoothedMouse[Index] = 0; MouseSamples[Index] = 0; } } else { MaybeTime[Index] = 0; if ( SmoothedMouse[Index] != 0 ) { MouseSamples[Index] += SampleCount; if ( DeltaTime > MouseSamplingTime * (SampleCount + 1) ) SamplingTime[Index] += MouseSamplingTime * SampleCount; else { SamplingTime[Index] += DeltaTime; aMouse = aMouse * DeltaTime/(MouseSamplingTime * SampleCount); } } else SamplingTime[Index] = 0.5 * MouseSamplingTime; SmoothedMouse[Index] = aMouse/SampleCount; ZeroTime[Index] = 0; } SampleCount = 0; if ( MouseSmoothingMode > 1 ) { if ( aMouse == 0 ) { // stop in next tick for ( i=0; i<3; i++ ) { sum += (i+1) * 0.1; aMouse += sum * OldSamples[i]; OldSamples[i] = 0; } OldSamples[3] = 0; } else { aMouse = 0.4 * aMouse; OldSamples[3] = aMouse; for ( i=0; i<3; i++ ) { aMouse += (i+1) * 0.1 * OldSamples[i]; OldSamples[i] = OldSamples[i+1]; } } } return aMouse; } function UpdateSensitivity(float F) { MouseSensitivity = FMax(0,F); default.MouseSensitivity = MouseSensitivity; class'PlayerInput'.static.StaticSaveConfig(); } function UpdateAccel(float F) { MouseAccelThreshold = FMax(0,f); default.MouseAccelThreshold = MouseAccelThreshold; class'PlayerInput'.static.StaticSaveConfig(); } function UpdateSmoothing( int Mode ) { MouseSmoothingMode = Mode; default.MouseSmoothingMode = MouseSmoothingMode; class'PlayerInput'.static.StaticSaveConfig(); } function InvertMouse(optional string Invert) { if (Invert != "") bInvertMouse = bool(Invert); else bInvertMouse = !bInvertMouse; SaveConfig(); default.bInvertMouse = bInvertMouse; } function ChangeSnapView( bool B ) { bSnapToLevel = B; } // check for double click move function Actor.eDoubleClickDir CheckForDoubleClickMove(float DeltaTime) { local Actor.eDoubleClickDir DoubleClickMove, OldDoubleClick; if (!bEnableDodging) { DoubleClickMove = DCLICK_None; return DoubleClickMove; } if ( DoubleClickDir == DCLICK_Active ) DoubleClickMove = DCLICK_Active; else DoubleClickMove = DCLICK_None; if (DoubleClickTime > 0.0) { if ( DoubleClickDir == DCLICK_Active ) { if ( (Pawn != None) && (Pawn.Physics == PHYS_Walking) ) { DoubleClickTimer = 0; DoubleClickDir = DCLICK_Done; } } else if ( DoubleClickDir != DCLICK_Done ) { OldDoubleClick = DoubleClickDir; DoubleClickDir = DCLICK_None; if (bEdgeForward && bWasForward) DoubleClickDir = DCLICK_Forward; else if (bEdgeBack && bWasBack) DoubleClickDir = DCLICK_Back; else if (bEdgeLeft && bWasLeft) DoubleClickDir = DCLICK_Left; else if (bEdgeRight && bWasRight) DoubleClickDir = DCLICK_Right; if ( DoubleClickDir == DCLICK_None) DoubleClickDir = OldDoubleClick; else if ( DoubleClickDir != OldDoubleClick ) DoubleClickTimer = DoubleClickTime + 0.5 * DeltaTime; else DoubleClickMove = DoubleClickDir; } if (DoubleClickDir == DCLICK_Done) { DoubleClickTimer = FMin(DoubleClickTimer-DeltaTime,0); if (DoubleClickTimer < -0.35) { DoubleClickDir = DCLICK_None; DoubleClickTimer = DoubleClickTime; } } else if ((DoubleClickDir != DCLICK_None) && (DoubleClickDir != DCLICK_Active)) { DoubleClickTimer -= DeltaTime; if (DoubleClickTimer < 0) { DoubleClickDir = DCLICK_None; DoubleClickTimer = DoubleClickTime; } } } return DoubleClickMove; } sR//============================================================================= // PlayerController // // PlayerControllers are used by human players to control pawns. // // This is a built-in Unreal class and it shouldn't be modified. // for the change in Possess(). //============================================================================= class PlayerController extends Controller config(user) native nativereplication exportstructs DependsOn(Interactions); // Player info. var const player Player; // player input control var globalconfig bool bLookUpStairs; // look up/down stairs (player) var globalconfig bool bSnapToLevel; // Snap to level eyeheight when not mouselooking var globalconfig bool bAlwaysMouseLook; var globalconfig bool bKeyboardLook; // no snapping when true var bool bCenterView; // Player control flags var bool bBehindView; // Outside-the-player view. var bool bFrozen; // set when game ends or player dies to temporarily prevent player from restarting (until cleared by timer) var bool bPressedJump; var bool bDoubleJump; var bool bUpdatePosition; var bool bIsTyping; var bool bFixedCamera; // used to fix camera in position (to view animations) var bool bJumpStatus; // used in net games var bool bUpdating; var globalconfig bool bNeverSwitchOnPickup; // if true, don't automatically switch to picked up weapon var bool bHideSpectatorBeacons; var bool bZooming; var bool bHideVehicleNoEntryIndicator; var globalconfig bool bAlwaysLevel; var bool bSetTurnRot; var bool bCheatFlying; // instantly stop in flying mode var bool bFreeCamera; // free camera when in behindview mode (for checking out player models and animations) var bool bZeroRoll; var bool bCameraPositionLocked; var bool bViewBot; var bool UseFixedVisibility; var bool bFreeCam; // In FreeCam mode to adjust the cam rotator var bool bFreeCamZoom; // In zoom mode var bool bFreeCamSwivel; // In swivel mode var bool bBlockCloseCamera; var bool bValidBehindCamera; var bool bForcePrecache; var bool bClientDemo; var const bool bAllActorsRelevant; // used by UTTV. DO NOT SET THIS TRUE - it has a huge impact on network performance var bool bShortConnectTimeOut; // when true, reduces connect timeout to 15 seconds var bool bPendingDestroy; // when true, playercontroller is being destroyed var bool bEnableAmbientShake; var globalconfig bool bNoVoiceMessages; var globalconfig bool bNoTextToSpeechVoiceMessages; var globalconfig bool bNoVoiceTaunts; var globalconfig bool bNoAutoTaunts; var globalconfig bool bAutoTaunt; var globalconfig bool bNoMatureLanguage; var globalconfig bool bDynamicNetSpeed; var globalconfig bool bSmallWeapons; var bool bWeaponViewShake; var globalconfig bool bLandingShake; var globalconfig bool bAimingHelp; var(ForceFeedback) globalconfig bool bEnablePickupForceFeedback; var(ForceFeedback) globalconfig bool bEnableWeaponForceFeedback; var(ForceFeedback) globalconfig bool bEnableDamageForceFeedback; var(ForceFeedback) globalconfig bool bEnableGUIForceFeedback; var(ForceFeedback) bool bForceFeedbackSupported; // true if a device is detected var(VoiceChat) bool bVoiceChatEnabled; // Whether voice chat is enabled on this client var(VoiceChat) globalconfig bool bEnableInitialChatRoom; // Enables speaking on DefaultActiveChannel upon joining server var bool bViewingMatineeCinematic; var bool bCustomListener; var bool bAcuteHearing; // makes playercontroller hear much better (used to magnify hit sounds caused by player) var bool bMenuBeforeRespawn; //forces the midgame menu to pop up before player can click to respawn var bool bSkippedLastUpdate, bLastPressedJump; var globalconfig bool bEnableStatsTracking; var globalconfig bool bOnlySpeakTeamText; var bool bWasSpeedHack; var bool bIsSpaceFighter; // hack for spacefighter joystick controls var const bool bWasSaturated; // used by servers to identify saturated client connections var float FOVBias; // Voice Chat struct StoredChatPassword { var string ChatRoomName; var string ChatRoomPassword; }; // Contains a bit-mask of which channels to auto-join // 1 - Public, 2 - Local, 4 - Team var(VoiceChat) globalconfig byte AutoJoinMask; var input byte bStrafe, bSnapLevel, bLook, bFreeLook, bTurn180, bTurnToNearest, bXAxis, bYAxis; var EDoubleClickDir DoubleClickDir; // direction of movement key double click (for special moves) var globalconfig byte AnnouncerLevel; // 0=none, 1=no possession announcements, 2=all var globalconfig byte AnnouncerVolume; // 1 to 4 var globalconfig float TextToSpeechVoiceVolume; var float MaxResponseTime; // how long server will wait for client move update before setting position var float WaitDelay; // Delay time until can restart var pawn AcknowledgedPawn; // used in net games so client can acknowledge it possessed a pawn var input float aBaseX, aBaseY, aBaseZ, aMouseX, aMouseY, aForward, aTurn, aStrafe, aUp, aLookUp; // Vehicle Move Replication var float aLastForward, aLastStrafe, aLastUp, NumServerDrives, NumSkips; // Vehicle Check Radius var float VehicleCheckRadius; // Radius that is checked for nearby vehicles when pressing use var bool bSuccessfulUse; // gives PC a hint that UsedBy was successful // Camera info. var int ShowFlags; var int Misc1,Misc2; var int RendMap; var float OrthoZoom; // Orthogonal/map view zoom factor. var const actor ViewTarget; var const Controller RealViewTarget; var PlayerController DemoViewer; var float CameraDist; // multiplier for behindview camera dist var range CameraDistRange; var vector OldCameraLoc; // used in behindview calculations var rotator OldCameraRot; var transient array CameraEffects; // A stack of camera effects. var globalconfig float DesiredFOV; var globalconfig float DefaultFOV; var float ZoomLevel, DesiredZoomLevel; // Audio. var vector ListenerLocation; var rotator ListenerRotation; // Fixed visibility. var vector FixedLocation; var rotator FixedRotation; var matrix RenderWorldToCamera; // Screen flashes var vector FlashScale, FlashFog; var float ConstantGlowScale; var vector ConstantGlowFog; var globalconfig float ScreenFlashScaling; // Distance fog fading. var color LastDistanceFogColor; var float LastDistanceFogStart; var float LastDistanceFogEnd; var float CurrentDistanceFogEnd; var float TimeSinceLastFogChange; var int LastZone; // Remote Pawn ViewTargets var rotator TargetViewRotation; var rotator BlendedTargetViewRotation; var float TargetEyeHeight; var vector TargetWeaponViewOffset; var HUD myHUD; // heads up display info var float LastPlaySound; var float LastPlaySpeech; // Music info. var string Song; var EMusicTransition Transition; // Move buffering for network games. Clients save their un-acknowledged moves in order to replay them // when they get position updates from the server. var SavedMove SavedMoves; // buffered moves pending position updates var SavedMove FreeMoves; // freed moves, available for buffering var SavedMove PendingMove; var float CurrentTimeStamp,LastUpdateTime,ServerTimeStamp,TimeMargin, ClientUpdateTime; var float MaxTimeMargin; var globalconfig float TimeMarginSlack; // OBSOLETE var Weapon OldClientWeapon; var int WeaponUpdate; // Progess Indicator - used by the engine to provide status messages (HUD is responsible for displaying these). var string ProgressMessage[4]; var color ProgressColor[4]; var float ProgressTimeOut; // Localized strings var localized string QuickSaveString; var localized string NoPauseMessage; var localized string ViewingFrom; var localized string OwnCamera; // ReplicationInfo var GameReplicationInfo GameReplicationInfo; var VoiceChatReplicationInfo VoiceReplicationInfo; var VotingReplicationInfoBase VoteReplicationInfo; // Stats Logging var globalconfig string StatsUsername; var globalconfig string StatsPassword; var class LocalMessageClass; var(VoiceChat) class ChatRoomMessageClass; // view shaking (affects roll, and offsets camera position) var vector ShakeOffsetRate; var vector ShakeOffset; //current magnitude to offset camera from shake var vector ShakeOffsetTime; var vector ShakeOffsetMax; var vector ShakeRotRate; var vector ShakeRotMax; var rotator ShakeRot; var vector ShakeRotTime; var float AmbientShakeFalloffStartTime; var float AmbientShakeFalloffTime; // Time taken for shaking to stop after AmbientShakeFalloffStartTime has passed. var vector AmbientShakeOffsetMag; var float AmbientShakeOffsetFreq; var rotator AmbientShakeRotMag; var float AmbientShakeRotFreq; var Pawn TurnTarget; var config int EnemyTurnSpeed; var int GroundPitch; var rotator TurnRot180; var vector OldFloor; // used by PlayerSpider mode - floor for which old rotation was based; // Components ( inner classes ) var private transient CheatManager CheatManager; // Object within playercontroller that manages "cheat" commands var class CheatClass; // class of my CheatManager var private transient PlayerInput PlayerInput; // Object within playercontroller that manages player input. var config class InputClass; // class of my PlayerInput var private transient AdminBase AdminManager; var transient MaplistManagerBase MapHandler; // Used by AdminBase var string PlayerChatType; var PlayerChatManager ChatManager; // Manages all chat, speech, and voice messages sent to player var const vector FailedPathStart; // Camera control for debugging/tweaking // BehindView Camera Adjustments var rotator CameraDeltaRotation; // The rotator delta adjustment var float CameraDeltaRad; // The zoom delta adjustment var rotator CameraSwivel; // The swivel adjustment // For drawing player names struct PlayerNameInfo { var string mInfo; var color mColor; var float mXPos; var float mYPos; }; var(TeamBeacon) float TeamBeaconMaxDist; var(TeamBeacon) float TeamBeaconPlayerInfoMaxDist; var(TeamBeacon) Texture TeamBeaconTexture; var(TeamBeacon) Texture LinkBeaconTexture; var(TeamBeacon) Texture SpeakingBeaconTexture; var(TeamBeacon) Color TeamBeaconTeamColors[2]; var(TeamBeacon) Color TeamBeaconCustomColor; var private const array PlayerNameArray; // Demo recording view rotation var int DemoViewPitch; var int DemoViewYaw; var Security PlayerSecurity; // Used for Cheat Protection var float LoginDelay; var float NextLoginTime; var float ForcePrecacheTime; var float LastPingUpdate; var float ExactPing; var float OldPing; var float SpectateSpeed; var globalconfig float DynamicPingThreshold; var float NextSpeedChange; var float VoiceChangeLimit; var int ClientCap; var(Menu) config string MidGameMenuClass; // Menu that is shown when Escape is pressed var(Menu) config string DemoMenuClass; // Menu used for demos var(Menu) config string AdminMenuClass; // Menu that is shown when adminmenu command is used var(Menu) config string ChatPasswordMenuClass; // Menu that appears when attempting to join a chatroom that has a password var(VoiceChat) globalconfig array StoredChatPasswords; var VoiceChatRoom ActiveRoom; // The chatroom we're currently speaking to var(VoiceChat) globalconfig string LastActiveChannel; // Stores the currently active channel when switching maps var(VoiceChat) globalconfig string VoiceChatCodec; // Which voice chat codec to request in internet games (will only be used if it exists on server) var(VoiceChat) globalconfig string VoiceChatLANCodec; // Which voice chat codec to request in LAN games var(VoiceChat) globalconfig string ChatPassword; // Password for our personal chat room var(VoiceChat) globalconfig string DefaultActiveChannel; // Channel we initially want to make active // ClientAdjustPosition replication (event called at end of frame) struct ClientAdjustment { var float TimeStamp; var name newState; var EPhysics newPhysics; var vector NewLoc; var vector NewVel; var actor NewBase; var vector NewFloor; }; var ClientAdjustment PendingAdjustment; var AnnouncerQueueManager AnnouncerQueueManager; // Handling Announcer Queueing var AnnouncerVoice StatusAnnouncer; var AnnouncerVoice RewardAnnouncer; var float LastActiveTime; // used to kick idlers var Actor CalcViewActor; // optimize PlayerCalcView var vector CalcViewActorLocation; var vector CalcViewLocation; var rotator CalcViewRotation; var float LastPlayerCalcView; var float LastBroadcastTime; var string LastBroadcastString[4]; var float LastSpeedHackLog; var string PlayerOwnerName; // for savegames replication { // Things the server should send to the client. reliable if( bNetDirty && bNetOwner && Role==ROLE_Authority ) GameReplicationInfo, VoiceReplicationInfo, ChatManager, LoginDelay; unreliable if ( bNetOwner && Role==ROLE_Authority && (ViewTarget != Pawn) && (Pawn(ViewTarget) != None) ) TargetViewRotation, TargetEyeHeight; reliable if( bDemoRecording && Role==ROLE_Authority ) DemoViewPitch, DemoViewYaw; // Functions server can call. reliable if( Role==ROLE_Authority ) ClientSetHUD,ClientReliablePlaySound, FOV, StartZoom, ToggleZoom, StopZoom, EndZoom, ClientSetMusic, ClientRestart, ClientReset, ClientAdjustGlow, ClientSetBehindView, ClientSetFixedCamera, ClearProgressMessages, ProgressCommand, SetProgressMessage, SetProgressTime, GivePawn, ClientGotoState, ClientSetActiveRoom, ChatRoomMessage, ClientValidate, ClientSetWeaponViewShake, ClientSetViewTarget, ClientCapBandwidth, ClientOpenMenu, ClientCloseMenu, ClientReplaceMenu, ClientNetworkMessage, AdminReply; reliable if ( (Role == ROLE_Authority) ) ClientMessage, TeamMessage, ReceiveLocalizedMessage, QueueAnnouncement; unreliable if( Role==ROLE_Authority && !bDemoRecording ) ClientPlaySound, PlayAnnouncement, PlayRewardAnnouncement, PlayStatusAnnouncement; reliable if( Role==ROLE_Authority && !bDemoRecording ) ClientStopForceFeedback, ClientTravel, ClientSetClassicView; unreliable if( Role==ROLE_Authority ) SetFOVAngle, ClientDamageShake, ClientFlash,ClientUpdateFlagHolder, ClientAdjustPosition, ShortClientAdjustPosition, VeryShortClientAdjustPosition, LongClientAdjustPosition; unreliable if( (!bDemoRecording || bClientDemoRecording && bClientDemoNetFunc) && Role==ROLE_Authority ) ClientHearSound; reliable if( bClientDemoRecording && ROLE==ROLE_Authority ) DemoClientSetHUD; // Functions client can call. unreliable if( Role PlayerChatClass; super.PostBeginPlay(); MaxTimeMargin = Level.MaxTimeMargin; MaxResponseTime = Default.MaxResponseTime * Level.TimeDilation; if ( Level.NetMode == NM_Client ) SpawnDefaultHUD(); if (Level.LevelEnterText != "" ) ClientMessage(Level.LevelEnterText); FixFOV(); SetViewTarget(self); // MUST have a view target! LastActiveTime = Level.TimeSeconds; if ( Level.NetMode == NM_Standalone ) AddCheats(); bForcePrecache = (Role < ROLE_Authority); ForcePrecacheTime = Level.TimeSeconds + 1.2; if ( Level.Game != None ) MapHandler = Level.Game.MaplistHandler; if ( (PlayerChatType != "") && (Role == ROLE_Authority) ) { PlayerChatClass = class(DynamicLoadObject(PlayerChatType, class'Class')); if ( PlayerChatClass != None ) ChatManager = Spawn(PlayerChatClass, Self); } } simulated function bool BeyondViewDistance(vector OtherLocation, float CullDistance) { local float Dist; if ( ViewTarget == None ) return true; Dist = VSize(OtherLocation - ViewTarget.Location); if ( (CullDistance > 0) && (CullDistance < Dist * FOVBias) ) return true; return ( Region.Zone.bDistanceFog && (Dist > Region.Zone.DistanceFogEnd) ); } event KickWarning() { ReceiveLocalizedMessage( class'GameMessage', 15 ); } function ResetTimeMargin() { TimeMargin = -0.1; MaxTimeMargin = Level.MaxTimeMargin; } function ServerShortTimeout() { local Actor A; bShortConnectTimeOut = true; ResetTimeMargin(); // quick update of pickups and gameobjectives since this player is now relevant if ( Level.Game.NumPlayers < 8 ) { ForEach AllActors(class'Actor', A) if ( (A.NetUpdateFrequency < 1) && !A.bOnlyRelevantToOwner ) A.NetUpdateTime = FMin(A.NetUpdateTime, Level.TimeSeconds + 0.2 * FRand()); } else { ForEach AllActors(class'Actor', A) if ( (A.NetUpdateFrequency < 1) && !A.bOnlyRelevantToOwner ) A.NetUpdateTime = FMin(A.NetUpdateTime, Level.TimeSeconds + 0.5 * FRand()); } } function Actor GetPathTo(Actor Dest) { local int i; local Actor Best; local vector Dir; if ( Dest == None ) return Dest; if ( (Pawn.Physics != PHYS_Falling) && ((RouteGoal != Dest) || (Level.TimeSeconds - LastRouteFind > 1+FRand())) ) { MoveTarget = FindPathToward(Dest, false); if ( MoveTarget == None ) return Dest; } if ( RouteCache[0] == None ) return Dest; if ( RouteCache[1] == None ) return RouteCache[0]; Best = RouteCache[0]; Dir = Normal(RouteCache[1].Location - RouteCache[0].Location); // return furthest visible path in a relatively straight line from first for ( i=0; i<5; i++ ) { if ( (RouteCache[i] == None) || (VSize(Pawn.Location - RouteCache[i].Location) > 2000) ) break; if ( ((Normal(RouteCache[i].Location - RouteCache[0].Location) Dot Dir) > 0.7) && LineOfSightTo(RouteCache[i]) ) Best = RouteCache[i]; } return Best; } // This is called by the low level audio code whenever a stream is finished //!! Only for music started with PlayStream() simulated event StreamFinished(int StreamHandle, Interactions.EStreamFinishReason Reason) { local int i; if ( Player != None ) { for ( i = 0; i < Player.LocalInteractions.Length; i++ ) if ( Player.LocalInteractions[i] != None ) Player.LocalInteractions[i].StreamFinished( StreamHandle, Reason ); } } exec function KillAll(class aClass) { local Actor A; local Controller C; if (Role != ROLE_Authority) return; //notification if (CheatManager != None) CheatManager.ReportCheat("KillAll"); for (C = Level.ControllerList; C != None; C = C.NextController) if (PlayerController(C) != None) PlayerController(C).ClientMessage("Killed all "$string(aClass)); if ( ClassIsChildOf(aClass, class'AIController') ) { Level.Game.KillBots(Level.Game.NumBots); return; } 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; Level.Game.KillBots(Level.Game.NumBots); ForEach DynamicActors(class'Pawn', P) if ( ClassIsChildOf(P.Class, aClass) && !P.IsPlayerPawn() ) { if ( P.Controller != None ) P.Controller.Destroy(); P.Destroy(); } } exec function ToggleScreenShotMode() { if ( myHUD.bCrosshairShow ) { myHUD.bCrosshairShow = false; SetWeaponHand("Hidden"); myHUD.bHideHUD = true; TeamBeaconMaxDist = 0; bHideVehicleNoEntryIndicator = true; } else { // return to normal myHUD.bCrosshairShow = true; SetWeaponHand("Right"); myHUD.bHideHUD = false; TeamBeaconMaxDist = default.TeamBeaconMaxDist; bHideVehicleNoEntryIndicator = false; } } exec function SetSpectateSpeed(Float F) { SpectateSpeed = F; ServerSpectateSpeed(F); } function ClientSetWeaponViewShake(Bool B) { bWeaponViewShake = B; } function ClientSetClassicView() { Level.bClassicView = true; } function ServerSpectateSpeed(Float F) { SpectateSpeed = F; } function ServerGivePawn() { GivePawn(Pawn); } function ClientCapBandwidth(int Cap) { ClientCap = Cap; if ( (Player != None) && (Player.CurrentNetSpeed > Cap) ) SetNetSpeed(Cap); } function PendingStasis() { bStasis = true; Pawn = None; GotoState('Scripting'); } function AddCheats() { // Assuming that this never gets called for NM_Client if ( CheatManager == None && (Level.NetMode == NM_Standalone) ) CheatManager = new(self) CheatClass; } function MakeAdmin() { if ( AdminManager == None && Level != None && Level.Game != None && Level.Game.AccessControl != None) { if (Level.Game.AccessControl.AdminClass == None) Log("AdminClass is None"); else AdminManager = new(self) Level.Game.AccessControl.AdminClass; } } function HandlePickup(Pickup pick) { ReceiveLocalizedMessage(pick.MessageClass,,,,pick.class); } event ClientSetViewTarget( Actor a ) { local bool bNewViewTarget; if ( A == None ) { if ( ViewTarget != self ) SetLocation(CalcViewLocation); ServerVerifyViewTarget(); } else { bNewViewTarget = (ViewTarget != a); SetViewTarget( a ); if (bNewViewTarget) a.POVChanged(self, false); } } function ServerVerifyViewTarget() { if ( ViewTarget == self ) return; if ( ViewTarget == None ) return; ClientSetViewTarget(ViewTarget); } /* SpawnDefaultHUD() Spawn a HUD (make sure that PlayerController always has valid HUD, even if \ ClientSetHUD() hasn't been called\ */ function SpawnDefaultHUD() { myHUD = spawn(class'HUD',self); } /* Reset() reset actor to initial state - used when restarting level without reloading. */ function Reset() { local vehicle DrivenVehicle; DrivenVehicle = Vehicle(Pawn); if( DrivenVehicle != None ) DrivenVehicle.KDriverLeave(true); // Force the driver out of the car if ( Pawn != None ) PawnDied( Pawn ); super.Reset(); SetViewTarget( Self ); ClientSetViewTarget( self ); ClientSetFixedCamera( false ); bBehindView = false; WaitDelay = Level.TimeSeconds + 2; FixFOV(); if ( PlayerReplicationInfo.bOnlySpectator ) GotoState('Spectating'); else GotoState('PlayerWaiting'); } event ClientReset() { bBehindView = false; bFixedCamera = false; SetViewTarget( Self ); if ( PlayerReplicationInfo.bOnlySpectator ) GotoState('Spectating'); else GotoState('PlayerWaiting'); } function CleanOutSavedMoves() { local SavedMove Next; // clean out saved moves while ( SavedMoves != None ) { Next = SavedMoves.NextMove; SavedMoves.Destroy(); SavedMoves = Next; } if ( PendingMove != None ) { PendingMove.Destroy(); PendingMove = None; } } /* InitInputSystem() Spawn the appropriate class of PlayerInput Only called for playercontrollers that belong to local players */ event InitInputSystem() { PlayerInput = new(self) InputClass; } /* ClientGotoState() server uses this to force client into NewState */ function ClientGotoState(name NewState, name NewLabel) { GotoState(NewState,NewLabel); } function AskForPawn() { if ( IsInState('GameEnded') ) ClientGotoState('GameEnded', 'Begin'); else if ( IsInState('RoundEnded') ) ClientGotoState('RoundEnded', 'Begin'); else if ( Pawn != None ) GivePawn(Pawn); else { bFrozen = false; ServerRestartPlayer(); } } function GivePawn(Pawn NewPawn) { if ( NewPawn == None ) return; Pawn = NewPawn; NewPawn.Controller = self; ClientRestart(Pawn); } /* GetFacingDirection() returns direction faced relative to movement dir 0 = forward 16384 = right 32768 = back 49152 = left */ function int GetFacingDirection() { local vector X,Y,Z, Dir; GetAxes(Pawn.Rotation, X,Y,Z); Dir = Normal(Pawn.Acceleration); if ( Y Dot Dir > 0 ) return ( 49152 + 16384 * (X Dot Dir) ); else return ( 16384 - 16384 * (X Dot Dir) ); } // Possess a pawn function Possess(Pawn aPawn) { if ( PlayerReplicationInfo.bOnlySpectator ) return; ResetFOV(); aPawn.PossessedBy(self); Pawn = aPawn; Pawn.bStasis = false; ResetTimeMargin(); CleanOutSavedMoves(); // don't replay moves previous to possession if ( Vehicle(Pawn) != None && Vehicle(Pawn).Driver != None ) PlayerReplicationInfo.bIsFemale = Vehicle(Pawn).Driver.bIsFemale; else PlayerReplicationInfo.bIsFemale = Pawn.bIsFemale; ServerSetHandedness(Handedness); ServerSetAutoTaunt(bAutoTaunt); Restart(); } function AcknowledgePossession(Pawn P) { if ( Viewport(Player) != None ) { AcknowledgedPawn = P; if ( P != None ) P.SetBaseEyeHeight(); ServerAcknowledgePossession(P, Handedness, bAutoTaunt); } } function ServerAcknowledgePossession(Pawn P, float NewHand, bool bNewAutoTaunt) { ResetTimeMargin(); AcknowledgedPawn = P; ServerSetHandedness(NewHand); ServerSetAutoTaunt(bNewAutoTaunt); } // unpossessed a pawn (not because pawn was killed) function UnPossess() { if ( Pawn != None ) { SetLocation(Pawn.Location); Pawn.RemoteRole = ROLE_SimulatedProxy; Pawn.UnPossessed(); CleanOutSavedMoves(); // don't replay moves previous to unpossession if ( Viewtarget == Pawn ) SetViewTarget(self); } Pawn = None; GotoState('Spectating'); } function ViewNextBot() { if ( CheatManager != None ) CheatManager.ViewBot(); } // unpossessed a pawn (because pawn was killed) function PawnDied(Pawn P) { if ( P != Pawn ) return; EndZoom(); if ( Pawn != None ) Pawn.RemoteRole = ROLE_SimulatedProxy; if ( ViewTarget == Pawn ) bBehindView = true; Super.PawnDied(P); } simulated function ClientUpdateFlagHolder(PlayerReplicationInfo PRI, int i) { if ( (Role == ROLE_Authority) || (GameReplicationInfo == None) ) return; GameReplicationInfo.FlagHolder[i] = PRI; } simulated function ClientSetHUD(class newHUDClass, class newScoringClass ) { if ( myHUD != None ) myHUD.Destroy(); if (newHUDClass == None) myHUD = None; else { myHUD = spawn (newHUDClass, self); if (myHUD == None) log ("PlayerController::ClientSetHUD(): Could not spawn a HUD of class "$newHUDClass, 'Error'); else myHUD.SetScoreBoardClass( newScoringClass ); } if( Level.Song != "" && Level.Song != "None" ) ClientSetInitialMusic( Level.Song, MTRAN_Fade ); } // jdf --- // Server ignores this call, client plays effect simulated function ClientPlayForceFeedback( String EffectName ) { if (bForceFeedbackSupported && Viewport(Player) != None) PlayFeedbackEffect( EffectName ); } simulated function StopForceFeedback( optional String EffectName ) { if (bForceFeedbackSupported && Viewport(Player) != None) StopFeedbackEffect( EffectName ); } function ClientStopForceFeedback( optional String EffectName ) { if (bForceFeedbackSupported && Viewport(Player) != None) StopFeedbackEffect( EffectName ); } // --- jdf final function float UpdateFlashComponent(float current, float Step, float goal) { if ( goal > current ) return FMin(current + Step, goal); else return FMax(current - Step, goal); } function ViewFlash(float DeltaTime) { local vector goalFog; local float goalscale, delta, Step; local PhysicsVolume ViewVolume; delta = FMin(0.1, DeltaTime); goalScale = 1; // + ConstantGlowScale; goalFog = vect(0,0,0); // ConstantGlowFog; if ( Pawn != None ) { if ( bBehindView ) ViewVolume = Level.GetPhysicsVolume(CalcViewLocation); else ViewVolume = Pawn.HeadVolume; goalScale += ViewVolume.ViewFlash.X; goalFog += ViewVolume.ViewFog; } Step = 0.6 * delta * ScreenFlashScaling; FlashScale.X = UpdateFlashComponent(FlashScale.X,step,goalScale); FlashScale = FlashScale.X * vect(1,1,1); FlashFog.X = UpdateFlashComponent(FlashFog.X,step,goalFog.X); FlashFog.Y = UpdateFlashComponent(FlashFog.Y,step,goalFog.Y); FlashFog.Z = UpdateFlashComponent(FlashFog.Z,step,goalFog.Z); } simulated event ReceiveLocalizedMessage( class Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ) { // Wait for player to be up to date with replication when joining a server, before stacking up messages if ( Level.NetMode == NM_DedicatedServer || GameReplicationInfo == None ) return; Message.Static.ClientReceive( Self, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject ); if ( Message.static.IsConsoleMessage(Switch) && (Player != None) && (Player.Console != None) ) Player.Console.Message(Message.Static.GetString(Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject),0 ); } simulated event ChatRoomMessage( byte Result, int ChannelIndex, optional PlayerReplicationInfo RelatedPRI ) { local VoiceChatRoom VCR; local string str; if ( VoiceReplicationInfo != None && ChatRoomMessageClass != None ) { VCR = VoiceReplicationInfo.GetChannelAt(ChannelIndex); if ( VCR != None ) str = VCR.GetTitle(); if ( (str ~= "Team") || (str ~= "Public") || (str ~= "Local") ) return; ClientMessage( ChatRoomMessageClass.static.AssembleMessage(Result, str, RelatedPRI) ); } } event ClientMessage( coerce string S, optional Name Type ) { // Wait for player to be up to date with replication when joining a server, before stacking up messages if ( Level.NetMode == NM_DedicatedServer || GameReplicationInfo == None ) return; if (Type == '') Type = 'Event'; TeamMessage(PlayerReplicationInfo, S, Type); } function bool AllowTextToSpeech(PlayerReplicationInfo PRI, name Type) { if ( bNoTextToSpeechVoiceMessages || (PRI == None) ) return false; if ( Type == 'Say' ) { if ( PRI.bAdmin || ((GameReplicationInfo != None) && !GameReplicationInfo.bTeamGame) || (PRI == PlayerReplicationInfo) ) return true; if ( IsInState('GameEnded') || IsInState('RoundEnded') ) return true; return !bOnlySpeakTeamText; } else if ( Type == 'TeamSay' ) return true; return false; } event TeamMessage( PlayerReplicationInfo PRI, coerce string S, name Type ) { local string c; // Wait for player to be up to date with replication when joining a server, before stacking up messages if ( Level.NetMode == NM_DedicatedServer || GameReplicationInfo == None ) return; if( AllowTextToSpeech(PRI, Type) ) TextToSpeech( S, TextToSpeechVoiceVolume ); if ( Type == 'TeamSayQuiet' ) Type = 'TeamSay'; if ( myHUD != None ) myHUD.Message( PRI, c$S, Type ); if ( (Player != None) && (Player.Console != None) ) { if ( PRI!=None ) { if ( PRI.Team!=None && GameReplicationInfo.bTeamGame) { if (PRI.Team.TeamIndex==0) c = chr(27)$chr(200)$chr(1)$chr(1); else if (PRI.Team.TeamIndex==1) c = chr(27)$chr(125)$chr(200)$chr(253); } S = PRI.PlayerName$": "$S; } Player.Console.Chat( c$s, 6.0, PRI ); } } simulated function PlayBeepSound(); simulated function PrecacheAnnouncements() { if ( RewardAnnouncer != None ) RewardAnnouncer.PrecacheAnnouncements(true); if ( StatusAnnouncer != None ) StatusAnnouncer.PrecacheAnnouncements(false); } simulated function PlayStatusAnnouncement(name AName, byte AnnouncementLevel, optional bool bForce) { local float Atten; local sound ASound; // Wait for player to be up to date with replication when joining a server, before stacking up messages if ( Level.NetMode == NM_DedicatedServer || GameReplicationInfo == None ) return; if ( (AnnouncementLevel > AnnouncerLevel) || (StatusAnnouncer == None) ) return; if ( !bForce && (Level.TimeSeconds - LastPlaySound < 1) ) return; LastPlaySound = Level.TimeSeconds; // so voice messages won't overlap LastPlaySpeech = Level.TimeSeconds; // don't want chatter to overlap announcements Atten = 2.0 * FClamp(0.1 + float(AnnouncerVolume)*0.225,0.2,1.0); ASound = StatusAnnouncer.GetSound(AName); if ( ASound != None ) ClientPlaySound(ASound,true,Atten,SLOT_Talk); } simulated function PlayRewardAnnouncement(name AName, byte AnnouncementLevel, optional bool bForce) { local float Atten; local sound ASound; // Wait for player to be up to date with replication when joining a server, before stacking up messages if ( Level.NetMode == NM_DedicatedServer || GameReplicationInfo == None ) return; if ( (AnnouncementLevel > AnnouncerLevel) || (RewardAnnouncer == None) ) return; if ( !bForce && (Level.TimeSeconds - LastPlaySound < 1) ) return; LastPlaySound = Level.TimeSeconds; // so voice messages won't overlap LastPlaySpeech = Level.TimeSeconds; // don't want chatter to overlap announcements Atten = 2.0 * FClamp(0.1 + float(AnnouncerVolume)*0.225,0.2,1.0); ASound = RewardAnnouncer.GetSound(AName); if ( ASound != None ) ClientPlaySound(ASound,true,Atten,SLOT_Talk); } // PlayAnnouncement is OBSOLETE simulated function PlayAnnouncement(sound ASound, byte AnnouncementLevel, optional bool bForce) { local float Atten; if ( AnnouncementLevel > AnnouncerLevel ) return; if ( !bForce && (Level.TimeSeconds - LastPlaySound < 1) ) return; LastPlaySound = Level.TimeSeconds; // so voice messages won't overlap LastPlaySpeech = Level.TimeSeconds; // don't want chatter to overlap announcements Atten = 2.0 * FClamp(0.1 + float(AnnouncerVolume)*0.225,0.2,1.0); ClientPlaySound(ASound,true,Atten,SLOT_Talk); } // CustomizeAnnouncer is obsolete function Sound CustomizeAnnouncer(Sound AnnouncementSound) { return AnnouncementSound; } simulated function QueueAnnouncement( name ASoundName, byte AnnouncementLevel, optional AnnouncerQueueManager.EAPriority Priority, optional byte Switch ) { if ( AnnouncementLevel > AnnouncerLevel || Level.NetMode == NM_DedicatedServer || GameReplicationInfo == None ) return; if ( AnnouncerQueueManager == None ) { AnnouncerQueueManager = Spawn(class'AnnouncerQueueManager'); AnnouncerQueueManager.InitFor( Self ); } if ( AnnouncerQueueManager != None ) AnnouncerQueueManager.AddItemToQueue( ASoundName, Priority, Switch ); } function bool AllowVoiceMessage(name MessageType) { if ( Level.NetMode == NM_Standalone ) return true; if ( Level.TimeSeconds - OldMessageTime < 3 ) { if ( (MessageType == 'TAUNT') || (MessageType == 'AUTOTAUNT') ) return false; if ( Level.TimeSeconds - OldMessageTime < 1 ) return false; } if ( Level.TimeSeconds - OldMessageTime < 6 ) OldMessageTime = Level.TimeSeconds + 3; else OldMessageTime = Level.TimeSeconds; return true; } //Play a sound client side (so only client will hear it simulated function ClientPlaySound(sound ASound, optional bool bVolumeControl, optional float inAtten, optional ESoundSlot slot ) { local float atten; atten = 1.0; if( bVolumeControl ) atten = FClamp(inAtten,0,2); if ( ViewTarget != None ) ViewTarget.PlaySound(ASound, slot, atten,,,,false); } simulated function ClientReliablePlaySound(sound ASound, optional bool bVolumeControl ) { ClientPlaySound(ASound, bVolumeControl); } simulated event Destroyed() { local SavedMove Next; local Vehicle DrivenVehicle; local Pawn Driver; // cheatmanager, adminmanager, and playerinput cleaned up in C++ PostScriptDestroyed() if ( AdminManager != None ) AdminManager.DoLogout(); StopFeedbackEffect(); if ( Pawn != None ) { // If its a vehicle, just destroy the driver, otherwise do the normal. DrivenVehicle = Vehicle(Pawn); if( DrivenVehicle != None ) { Driver = DrivenVehicle.Driver; DrivenVehicle.KDriverLeave(true); // Force the driver out of the car if ( Driver != None ) { Driver.Health = 0; Driver.Died( self, class'Suicided', Driver.Location ); } } else { Pawn.Health = 0; Pawn.Died( self, class'Suicided', Pawn.Location ); } } if ( myHUD != None ) myHud.Destroy(); if ( AnnouncerQueueManager != None ) AnnouncerQueueManager.Destroy(); while ( FreeMoves != None ) { Next = FreeMoves.NextMove; FreeMoves.Destroy(); FreeMoves = Next; } while ( SavedMoves != None ) { Next = SavedMoves.NextMove; SavedMoves.Destroy(); SavedMoves = Next; } if( PlayerSecurity != None ) { PlayerSecurity.Destroy(); PlayerSecurity = None; } if ( ChatManager != None ) ChatManager.Destroy(); super.Destroyed(); } function ClientSetMusic( string NewSong, EMusicTransition NewTransition ) { local float FadeIn, FadeOut; switch (NewTransition) { case MTRAN_Segue: FadeIn = 7.0; FadeOut = 3.0; break; case MTRAN_Fade: FadeIn = 3.0; FadeOut = 3.0; break; case MTRAN_FastFade: FadeIn = 1.0; FadeOut = 1.0; break; case MTRAN_SlowFade: FadeIn = 5.0; FadeOut = 5.0; break; } StopAllMusic( FadeOut ); if ( NewSong != "" ) PlayMusic( NewSong, FadeIn ); Song = NewSong; Transition = NewTransition; if (Player!=None && Player.Console!=None) Player.Console.SetMusic(NewSong); } function ClientSetInitialMusic( string NewSong, EMusicTransition NewTransition ) { local string SongName; if ( Song != "" ) return; SongName = NewSong; if (Player!=None && Player.Console!=None) SongName = Player.Console.SetInitialMusic(NewSong); ClientSetMusic(SongName,NewTransition); } // ------------------------------------------------------------------------ // Zooming/FOV change functions function ToggleZoomWithMax(float MaxZoomLevel) { if ( DefaultFOV != DesiredFOV ) EndZoom(); else StartZoomWithMax(MaxZoomLevel); } function StartZoomWithMax(float MaxZoomLevel) { DesiredZoomLevel = MaxZoomLevel; myHUD.FadeZoom(); ZoomLevel = 0.0; bZooming = true; } function ToggleZoom() { ToggleZoomWithMax(0.9); } function StartZoom() { StartZoomWithMax(0.9); } function StopZoom() { bZooming = false; } function EndZoom() { if ( DesiredFOV != DefaultFOV ) myHUD.FadeZoom(); bZooming = false; DesiredFOV = DefaultFOV; } simulated function FixFOV() { FOVAngle = Default.DefaultFOV; DesiredFOV = Default.DefaultFOV; DefaultFOV = Default.DefaultFOV; } function SetFOV(float NewFOV) { DesiredFOV = NewFOV; FOVAngle = NewFOV; } function ResetFOV() { DesiredFOV = DefaultFOV; FOVAngle = DefaultFOV; } exec function FOV(float F) { if( (F >= 80.0) || (Level.Netmode==NM_Standalone) || PlayerReplicationInfo.bOnlySpectator ) { DefaultFOV = FClamp(F, 1, 170); DesiredFOV = DefaultFOV; SaveConfig(); } } exec function Mutate(string MutateString) { ServerMutate(MutateString); } function ServerMutate(string MutateString) { if( Level.NetMode == NM_Client ) return; Level.Game.BaseMutator.Mutate(MutateString, Self); } exec function SetSensitivity(float F) { PlayerInput.UpdateSensitivity(F); } exec function SetMouseSmoothing( int Mode ) { PlayerInput.UpdateSmoothing( Mode ); } exec function SetMouseAccel(float F) { PlayerInput.UpdateAccel(F); } exec function ForceReload() { if ( (Pawn != None) && (Pawn.Weapon != None) ) { //Pawn.Weapon.ForceReload(); //merge_hack } } // ------------------------------------------------------------------------ // Messaging functions function bool AllowTextMessage(string Msg) { local int i; if ( (Level.NetMode == NM_Standalone) || PlayerReplicationInfo.bAdmin ) return true; if ( ( Level.Pauser == none) && (Level.TimeSeconds - LastBroadcastTime < 2 ) ) return false; // lower frequency if same text if ( Level.TimeSeconds - LastBroadcastTime < 5 ) { Msg = Left(Msg,Clamp(len(Msg) - 4, 8, 64)); for ( i=0; i<4; i++ ) if ( LastBroadcastString[i] ~= Msg ) return false; } for ( i=3; i>0; i-- ) LastBroadcastString[i] = LastBroadcastString[i-1]; LastBroadcastTime = Level.TimeSeconds; return true; } // Send a message to all players. exec function Say( string Msg ) { Msg = Left(Msg,128); if ( AllowTextMessage(Msg) ) ServerSay(Msg); } function ServerSay( string Msg ) { local controller C; Msg = Level.Game.StripColor(Msg); // center print admin messages which start with # if (PlayerReplicationInfo.bAdmin && left(Msg,1) == "#" ) { Msg = right(Msg,len(Msg)-1); for( C=Level.ControllerList; C!=None; C=C.nextController ) if( C.IsA('PlayerController') ) { PlayerController(C).ClearProgressMessages(); PlayerController(C).SetProgressTime(6); PlayerController(C).SetProgressMessage(0, Msg, class'Canvas'.Static.MakeColor(255,255,255)); } return; } Level.Game.Broadcast(self, Msg, 'Say'); } exec function TeamSay( string Msg ) { Msg = Left(Msg,128); if ( AllowTextMessage(Msg) ) ServerTeamSay(Msg); } function ServerTeamSay( string Msg ) { LastActiveTime = Level.TimeSeconds; Msg = Level.Game.StripColor(Msg); if( !GameReplicationInfo.bTeamGame ) { Say( Msg ); return; } Level.Game.BroadcastTeam( self, Level.Game.ParseMessageString( Level.Game.BaseMutator , self, Msg ) , 'TeamSay'); } // ------------------------------------------------------------------------ function ServerSetAutoTaunt(bool Value) { bAutoTaunt = Value; } exec function SetAutoTaunt(bool Value) { class'PlayerController'.default.bAutoTaunt = Value; class'PlayerController'.static.StaticSaveConfig(); bAutoTaunt = Value; ServerSetAutoTaunt(Value); } // ------------------------------------------------------------------------ function ServerSetHandedness( float hand) { Handedness = hand; if ( (Pawn != None) && (Pawn.Weapon != None) ) Pawn.Weapon.SetHand(Handedness); } function SetHand(int IntValue) { Handedness = IntValue; SaveConfig(); if( (Pawn != None) && (Pawn.Weapon != None) ) Pawn.Weapon.SetHand(Handedness); ServerSetHandedness(Handedness); } exec function SetWeaponHand ( string S ) { if ( S ~= "Left" ) Handedness = -1; else if ( S~= "Right" ) Handedness = 1; else if ( S ~= "Center" ) Handedness = 0; else if ( S ~= "Hidden" ) Handedness = 2; SetHand(Handedness); } function bool IsDead() { return false; } exec function ShowGun () { if( Handedness == 2 ) Handedness = 1; else Handedness = 2; SetHand(Handedness); } event PreClientTravel() { log("PreClientTravel"); ClientStopForceFeedback(); // jdf } function ClientSetFixedCamera(bool B) { bFixedCamera = B; } function ClientSetBehindView(bool B) { local bool bWasBehindView; bWasBehindView = bBehindView; bBehindView = B; CameraDist = Default.CameraDist; if (bBehindView != bWasBehindView) ViewTarget.POVChanged(self, true); if (Vehicle(Pawn) != None) { Vehicle(Pawn).bDesiredBehindView = B; Pawn.SaveConfig(); } } function ClientVoiceMessage(PlayerReplicationInfo Sender, PlayerReplicationInfo Recipient, name messagetype, byte messageID) { local VoicePack V; if ( (Sender == None) || (Sender.voicetype == None) || (Player.Console == None) ) return; V = Spawn(Sender.voicetype, self); if ( V != None ) V.ClientInitialize(Sender, Recipient, messagetype, messageID); } /* ForceDeathUpdate() Make sure ClientAdjustPosition immediately informs client of pawn's death */ function ForceDeathUpdate() { LastUpdateTime = Level.TimeSeconds - 10; } /* RocketServerMove() compressed version of server move for PlayerRocketing state */ function RocketServerMove ( float TimeStamp, vector InAccel, vector ClientLoc, bool NewbDuck, byte ClientRoll, int View ) { ServerMove(TimeStamp,InAccel,ClientLoc,false,NewbDuck,false,false, DCLICK_NONE,ClientRoll,View); } /* DualRocketServerMove() compressed version of server move for PlayerRocketing state */ function DualRocketServerMove ( float TimeStamp0, vector InAccel0, bool NewbDuck0, byte ClientRoll0, int View0, float TimeStamp, vector InAccel, vector ClientLoc, bool NewbDuck, byte ClientRoll, int View ) { ServerMove(TimeStamp0,InAccel0,vect(0,0,0),false,NewbDuck0,false,false, DCLICK_NONE,ClientRoll0,View0); ServerMove(TimeStamp,InAccel,ClientLoc,false,NewbDuck,false,false, DCLICK_NONE,ClientRoll,View); } function SpaceFighterServerMove ( float TimeStamp, vector InAccel, vector ClientLoc, bool NewbDuck, int ViewPitch, int ViewYaw, int ViewRoll ) { local Rotator BackupView; BackupView.Pitch = ViewPitch; BackupView.Yaw = ViewYaw; BackupView.Roll = ViewRoll; SetRotation( BackupView ); if ( Pawn != None ) Pawn.SetRotation( BackupView ); Global.ServerMove(TimeStamp,InAccel,ClientLoc,false,NewbDuck,false,false, DCLICK_NONE,0,0); } function DualSpaceFighterServerMove ( float TimeStamp0, vector InAccel0, bool NewbDuck0, int ViewPitch0, int ViewYaw0, int ViewRoll0, float TimeStamp, vector InAccel, vector ClientLoc, bool NewbDuck, int ViewPitch, int ViewYaw, int ViewRoll ) { local Rotator BackupView; BackupView.Pitch = ViewPitch0; BackupView.Yaw = ViewYaw0; BackupView.Roll = ViewRoll0; SetRotation( BackupView ); if ( Pawn != None ) Pawn.SetRotation( BackupView ); Global.ServerMove(TimeStamp0,InAccel0,vect(0,0,0),false,NewbDuck0,false,false, DCLICK_NONE,0,0); BackupView.Pitch = ViewPitch; BackupView.Yaw = ViewYaw; BackupView.Roll = ViewRoll; SetRotation( BackupView ); if ( Pawn != None ) Pawn.SetRotation( BackupView ); Global.ServerMove(TimeStamp,InAccel,ClientLoc,false,NewbDuck,false,false, DCLICK_NONE,0,0); } /* TurretServerMove() compressed version of server move for PlayerTurreting state */ function TurretServerMove ( float TimeStamp, vector ClientLoc, bool NewbDuck, byte ClientRoll, int View ) { ServerMove(TimeStamp,Vect(0,0,0),ClientLoc,false,NewbDuck,false,false, DCLICK_NONE,ClientRoll,View); } /* DualTurretServerMove() compressed version of server move for PlayerTurreting state */ function DualTurretServerMove ( float TimeStamp0, bool NewbDuck0, byte ClientRoll0, int View0, float TimeStamp, vector ClientLoc, bool NewbDuck, byte ClientRoll, int View ) { ServerMove(TimeStamp0,Vect(0,0,0),vect(0,0,0),false,NewbDuck0,false,false, DCLICK_NONE,ClientRoll0,View0); ServerMove(TimeStamp,Vect(0,0,0),ClientLoc,false,NewbDuck,false,false, DCLICK_NONE,ClientRoll,View); } /* ShortServerMove() compressed version of server move for bandwidth saving */ function ShortServerMove ( float TimeStamp, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, byte ClientRoll, int View ) { ServerMove(TimeStamp,vect(0,0,0),ClientLoc,NewbRun,NewbDuck,NewbJumpStatus,false,DCLICK_None,ClientRoll,View); } /* DualServerMove() - replicated function sent by client to server - contains client movement and firing info for two moves */ function DualServerMove ( float TimeStamp0, vector InAccel0, byte PendingCompress, eDoubleClickDir DoubleClickMove0, int View0, float TimeStamp, vector InAccel, vector ClientLoc, eDoubleClickDir DoubleClickMove, byte ClientRoll, int View, optional byte OldTimeDelta, optional int OldAccel ) { local bool NewbRun0,NewbDuck0,NewbJumpStatus0,NewbDoubleJump0, NewbRun,NewbDuck,NewbJumpStatus,NewbDoubleJump; NewbRun0 = (PendingCompress & 1) != 0; NewbDuck0 = (PendingCompress & 2) != 0; NewbJumpStatus0 = (PendingCompress & 4) != 0; NewbDoubleJump0 = (PendingCompress & 8) != 0; NewbRun = (PendingCompress & 16) != 0; NewbDuck = (PendingCompress & 32) != 0; NewbJumpStatus = (PendingCompress & 64) != 0; NewbDoubleJump = (PendingCompress & 128) != 0; ServerMove(TimeStamp0,InAccel0,vect(0,0,0),NewbRun0,NewbDuck0,NewbJumpStatus0,NewbDoubleJump0,DoubleClickMove0, ClientRoll,View0); if ( ClientLoc == vect(0,0,0) ) ClientLoc = vect(0.1,0,0); ServerMove(TimeStamp,InAccel,ClientLoc,NewbRun,NewbDuck,NewbJumpStatus,NewbDoubleJump,DoubleClickMove,ClientRoll,View,OldTimeDelta,OldAccel); } /* ServerMove() - replicated function sent by client to server - contains client movement and firing info. */ function ServerMove ( float TimeStamp, vector InAccel, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, bool NewbDoubleJump, eDoubleClickDir DoubleClickMove, byte ClientRoll, int View, optional byte OldTimeDelta, optional int OldAccel ) { local float DeltaTime, clientErr, OldTimeStamp; local rotator DeltaRot, Rot, ViewRot; local vector Accel, LocDiff; local int maxPitch, ViewPitch, ViewYaw; local bool NewbPressedJump, OldbRun, OldbDoubleJump; local eDoubleClickDir OldDoubleClickMove; // If this move is outdated, discard it. if ( CurrentTimeStamp >= TimeStamp ) return; if ( AcknowledgedPawn != Pawn ) { OldTimeDelta = 0; InAccel = vect(0,0,0); GivePawn(Pawn); } // if OldTimeDelta corresponds to a lost packet, process it first if ( OldTimeDelta != 0 ) { OldTimeStamp = TimeStamp - float(OldTimeDelta)/500 - 0.001; if ( CurrentTimeStamp < OldTimeStamp - 0.001 ) { // split out components of lost move (approx) Accel.X = OldAccel >>> 23; if ( Accel.X > 127 ) Accel.X = -1 * (Accel.X - 128); Accel.Y = (OldAccel >>> 15) & 255; if ( Accel.Y > 127 ) Accel.Y = -1 * (Accel.Y - 128); Accel.Z = (OldAccel >>> 7) & 255; if ( Accel.Z > 127 ) Accel.Z = -1 * (Accel.Z - 128); Accel *= 20; OldbRun = ( (OldAccel & 64) != 0 ); OldbDoubleJump = ( (OldAccel & 32) != 0 ); NewbPressedJump = ( (OldAccel & 16) != 0 ); if ( NewbPressedJump ) bJumpStatus = NewbJumpStatus; switch (OldAccel & 7) { case 0: OldDoubleClickMove = DCLICK_None; break; case 1: OldDoubleClickMove = DCLICK_Left; break; case 2: OldDoubleClickMove = DCLICK_Right; break; case 3: OldDoubleClickMove = DCLICK_Forward; break; case 4: OldDoubleClickMove = DCLICK_Back; break; } //log("Recovered move from "$OldTimeStamp$" acceleration "$Accel$" from "$OldAccel); OldTimeStamp = FMin(OldTimeStamp, CurrentTimeStamp + MaxResponseTime); MoveAutonomous(OldTimeStamp - CurrentTimeStamp, OldbRun, (bDuck == 1), NewbPressedJump, OldbDoubleJump, OldDoubleClickMove, Accel, rot(0,0,0)); CurrentTimeStamp = OldTimeStamp; } } // View components ViewPitch = View/32768; ViewYaw = 2 * (View - 32768 * ViewPitch); ViewPitch *= 2; // Make acceleration. Accel = InAccel * 0.1; NewbPressedJump = (bJumpStatus != NewbJumpStatus); bJumpStatus = NewbJumpStatus; // Save move parameters. DeltaTime = FMin(MaxResponseTime,TimeStamp - CurrentTimeStamp); if ( Pawn == None ) { ResetTimeMargin(); } else if ( !CheckSpeedHack(DeltaTime) ) { bWasSpeedHack = true; DeltaTime = 0; Pawn.Velocity = vect(0,0,0); } else if ( bWasSpeedHack ) { // if have had a speedhack detection, then modify deltatime if getting too far ahead again if ( (TimeMargin > 0.5 * Level.MaxTimeMargin) && (Level.MaxTimeMargin > 0) ) DeltaTime *= 0.8; } CurrentTimeStamp = TimeStamp; ServerTimeStamp = Level.TimeSeconds; ViewRot.Pitch = ViewPitch; ViewRot.Yaw = ViewYaw; ViewRot.Roll = 0; if ( NewbPressedJump || (InAccel != vect(0,0,0)) ) LastActiveTime = Level.TimeSeconds; if ( Pawn == None || Pawn.bServerMoveSetPawnRot ) SetRotation(ViewRot); if ( AcknowledgedPawn != Pawn ) return; if ( (Pawn != None) && Pawn.bServerMoveSetPawnRot ) { Rot.Roll = 256 * ClientRoll; Rot.Yaw = ViewYaw; if ( (Pawn.Physics == PHYS_Swimming) || (Pawn.Physics == PHYS_Flying) ) maxPitch = 2; else maxPitch = 0; if ( (ViewPitch > maxPitch * RotationRate.Pitch) && (ViewPitch < 65536 - maxPitch * RotationRate.Pitch) ) { If (ViewPitch < 32768) Rot.Pitch = maxPitch * RotationRate.Pitch; else Rot.Pitch = 65536 - maxPitch * RotationRate.Pitch; } else Rot.Pitch = ViewPitch; DeltaRot = (Rotation - Rot); Pawn.SetRotation(Rot); } // Perform actual movement if ( (Level.Pauser == None) && (DeltaTime > 0) ) MoveAutonomous(DeltaTime, NewbRun, NewbDuck, NewbPressedJump, NewbDoubleJump, DoubleClickMove, Accel, DeltaRot); // Accumulate movement error. if ( ClientLoc == vect(0,0,0) ) return; // first part of double servermove else if ( Level.TimeSeconds - LastUpdateTime > 0.3 ) ClientErr = 10000; else if ( Level.TimeSeconds - LastUpdateTime > 180.0/Player.CurrentNetSpeed ) { if ( Pawn == None ) LocDiff = Location - ClientLoc; else LocDiff = Pawn.Location - ClientLoc; ClientErr = LocDiff Dot LocDiff; } // If client has accumulated a noticeable positional error, correct him. if ( ClientErr > 3 ) { if ( Pawn == None ) { PendingAdjustment.newPhysics = Physics; PendingAdjustment.NewLoc = Location; PendingAdjustment.NewVel = Velocity; } else { PendingAdjustment.newPhysics = Pawn.Physics; PendingAdjustment.NewVel = Pawn.Velocity; PendingAdjustment.NewBase = Pawn.Base; if ( (Mover(Pawn.Base) != None) || (Vehicle(Pawn.Base) != None) ) PendingAdjustment.NewLoc = Pawn.Location - Pawn.Base.Location; else PendingAdjustment.NewLoc = Pawn.Location; PendingAdjustment.NewFloor = Pawn.Floor; } //if ( (ClientErr != 10000) && (Pawn != None) ) // log(" Client Error at "$TimeStamp$" is "$ClientErr$" with acceleration "$Accel$" LocDiff "$LocDiff$" Physics "$Pawn.Physics); LastUpdateTime = Level.TimeSeconds; PendingAdjustment.TimeStamp = TimeStamp; PendingAdjustment.newState = GetStateName(); } //log("Server moved stamp "$TimeStamp$" location "$Pawn.Location$" Acceleration "$Pawn.Acceleration$" Velocity "$Pawn.Velocity); } /* Called on server at end of tick when PendingAdjustment has been set. Done this way to avoid ever sending more than one ClientAdjustment per server tick. */ event SendClientAdjustment() { if ( AcknowledgedPawn != Pawn ) { PendingAdjustment.TimeStamp = 0; return; } if ( (Pawn == None) || (Pawn.Physics != PHYS_Spider) ) { if ( PendingAdjustment.NewVel == vect(0,0,0) ) { ShortClientAdjustPosition ( PendingAdjustment.TimeStamp, PendingAdjustment.newState, PendingAdjustment.newPhysics, PendingAdjustment.NewLoc.X, PendingAdjustment.NewLoc.Y, PendingAdjustment.NewLoc.Z, PendingAdjustment.NewBase ); } else ClientAdjustPosition ( PendingAdjustment.TimeStamp, PendingAdjustment.newState, PendingAdjustment.newPhysics, PendingAdjustment.NewLoc.X, PendingAdjustment.NewLoc.Y, PendingAdjustment.NewLoc.Z, PendingAdjustment.NewVel.X, PendingAdjustment.NewVel.Y, PendingAdjustment.NewVel.Z, PendingAdjustment.NewBase ); } else LongClientAdjustPosition ( PendingAdjustment.TimeStamp, PendingAdjustment.newState, PendingAdjustment.newPhysics, PendingAdjustment.NewLoc.X, PendingAdjustment.NewLoc.Y, PendingAdjustment.NewLoc.Z, PendingAdjustment.NewVel.X, PendingAdjustment.NewVel.Y, PendingAdjustment.NewVel.Z, PendingAdjustment.NewBase, PendingAdjustment.NewFloor.X, PendingAdjustment.NewFloor.Y, PendingAdjustment.NewFloor.Z ); PendingAdjustment.TimeStamp = 0; } // Only executed on server function ServerDrive(float InForward, float InStrafe, float aUp, bool InJump, int View) { local rotator ViewRotation; // Added to handle setting of the correct ViewRotation on the server in network games --Dave@Psyonix ViewRotation.Pitch = View/32768; ViewRotation.Yaw = 2 * (View - 32768 * ViewRotation.Pitch); ViewRotation.Pitch *= 2; ViewRotation.Roll = 0; SetRotation(ViewRotation); ProcessDrive(InForward, InStrafe, aUp, InJump); } function ProcessDrive(float InForward, float InStrafe, float InUp, bool InJump) { ClientGotoState(GetStateName(), 'Begin'); } function ProcessMove ( float DeltaTime, vector newAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) { if ( (Pawn != None) && (Pawn.Acceleration != newAccel) ) Pawn.Acceleration = newAccel; } final function MoveAutonomous ( float DeltaTime, bool NewbRun, bool NewbDuck, bool NewbPressedJump, bool NewbDoubleJump, eDoubleClickDir DoubleClickMove, vector newAccel, rotator DeltaRot ) { if ( (Pawn != None) && Pawn.bHardAttach ) return; if ( NewbRun ) bRun = 1; else bRun = 0; if ( NewbDuck ) bDuck = 1; else bDuck = 0; bPressedJump = NewbPressedJump; bDoubleJump = NewbDoubleJump; HandleWalking(); ProcessMove(DeltaTime, newAccel, DoubleClickMove, DeltaRot); if ( Pawn != None ) Pawn.AutonomousPhysics(DeltaTime); else AutonomousPhysics(DeltaTime); bDoubleJump = false; //log("Role "$Role$" moveauto time "$100 * DeltaTime$" ("$Level.TimeDilation$")"); } /* VeryShortClientAdjustPosition bandwidth saving version, when velocity is zeroed, and pawn is walking */ function VeryShortClientAdjustPosition ( float TimeStamp, float NewLocX, float NewLocY, float NewLocZ, Actor NewBase ) { local vector Floor; if ( Pawn != None ) Floor = Pawn.Floor; LongClientAdjustPosition(TimeStamp,'PlayerWalking',PHYS_Walking,NewLocX,NewLocY,NewLocZ,0,0,0,NewBase,Floor.X,Floor.Y,Floor.Z); } /* ShortClientAdjustPosition bandwidth saving version, when velocity is zeroed */ function ShortClientAdjustPosition ( float TimeStamp, name newState, EPhysics newPhysics, float NewLocX, float NewLocY, float NewLocZ, Actor NewBase ) { local vector Floor; if ( Pawn != None ) Floor = Pawn.Floor; LongClientAdjustPosition(TimeStamp,newState,newPhysics,NewLocX,NewLocY,NewLocZ,0,0,0,NewBase,Floor.X,Floor.Y,Floor.Z); } /* ClientAdjustPosition - pass newloc and newvel in components so they don't get rounded */ function ClientAdjustPosition ( float TimeStamp, name newState, EPhysics newPhysics, float NewLocX, float NewLocY, float NewLocZ, float NewVelX, float NewVelY, float NewVelZ, Actor NewBase ) { local vector Floor; if ( Pawn != None ) Floor = Pawn.Floor; LongClientAdjustPosition(TimeStamp,newState,newPhysics,NewLocX,NewLocY,NewLocZ,NewVelX,NewVelY,NewVelZ,NewBase,Floor.X,Floor.Y,Floor.Z); } /* LongClientAdjustPosition long version, when care about pawn's floor normal */ function LongClientAdjustPosition ( float TimeStamp, name newState, EPhysics newPhysics, float NewLocX, float NewLocY, float NewLocZ, float NewVelX, float NewVelY, float NewVelZ, Actor NewBase, float NewFloorX, float NewFloorY, float NewFloorZ ) { local vector NewLocation, NewVelocity, NewFloor; local Actor MoveActor; local SavedMove CurrentMove; local float NewPing; // update ping if ( (PlayerReplicationInfo != None) && !bDemoOwner ) { NewPing = FMin(1.5, Level.TimeSeconds - TimeStamp); if ( ExactPing < 0.004 ) ExactPing = FMin(0.3,NewPing); else { if ( NewPing > 2 * ExactPing ) NewPing = FMin(NewPing, 3*ExactPing); ExactPing = FMin(0.99, 0.99 * ExactPing + 0.008 * NewPing); // placebo effect } PlayerReplicationInfo.Ping = Min(250.0 * ExactPing, 255); PlayerReplicationInfo.bReceivedPing = true; if ( Level.TimeSeconds - LastPingUpdate > 4 ) { if ( bDynamicNetSpeed && (OldPing > DynamicPingThreshold * 0.001) && (ExactPing > DynamicPingThreshold * 0.001) ) { if ( Level.MoveRepSize < 64 ) Level.MoveRepSize += 8; else if ( Player.CurrentNetSpeed >= 6000 ) SetNetSpeed(Player.CurrentNetSpeed - 1000); OldPing = 0; } else OldPing = ExactPing; LastPingUpdate = Level.TimeSeconds; ServerUpdatePing(1000 * ExactPing); } } if ( Pawn != None ) { if ( Pawn.bTearOff ) { Pawn = None; if ( !IsInState('GameEnded') && !IsInState('RoundEnded') && !IsInState('Dead') ) { GotoState('Dead'); } return; } MoveActor = Pawn; if ( (ViewTarget != Pawn) && ((ViewTarget == self) || ((Pawn(ViewTarget) != None) && (Pawn(ViewTarget).Health <= 0))) ) { bBehindView = false; SetViewTarget(Pawn); } } else { MoveActor = self; if( GetStateName() != newstate ) { if ( NewState == 'GameEnded' || NewState == 'RoundEnded' ) GotoState(NewState); else if ( IsInState('Dead') ) { if ( (NewState != 'PlayerWalking') && (NewState != 'PlayerSwimming') ) { GotoState(NewState); } return; } else if ( NewState == 'Dead' ) GotoState(NewState); } } if ( CurrentTimeStamp >= TimeStamp ) return; CurrentTimeStamp = TimeStamp; NewLocation.X = NewLocX; NewLocation.Y = NewLocY; NewLocation.Z = NewLocZ; NewVelocity.X = NewVelX; NewVelocity.Y = NewVelY; NewVelocity.Z = NewVelZ; // skip update if no error CurrentMove = SavedMoves; while ( CurrentMove != None ) { if ( CurrentMove.TimeStamp <= CurrentTimeStamp ) { SavedMoves = CurrentMove.NextMove; CurrentMove.NextMove = FreeMoves; FreeMoves = CurrentMove; if ( CurrentMove.TimeStamp == CurrentTimeStamp ) { FreeMoves.Clear(); if ( ((Mover(NewBase) != None) || (Vehicle(NewBase) != None)) && (NewBase == CurrentMove.EndBase) ) { if ( (GetStateName() == NewState) && IsInState('PlayerWalking') && ((MoveActor.Physics == PHYS_Walking) || (MoveActor.Physics == PHYS_Falling)) ) { if ( VSize(CurrentMove.SavedRelativeLocation - NewLocation) < 3 ) { CurrentMove = None; return; } else if ( (Vehicle(NewBase) != None) && (VSize(Velocity) < 3) && (VSize(NewVelocity) < 3) && (VSize(CurrentMove.SavedRelativeLocation - NewLocation) < 30) ) { CurrentMove = None; return; } } } else if ( (VSize(CurrentMove.SavedLocation - NewLocation) < 3) && (VSize(CurrentMove.SavedVelocity - NewVelocity) < 3) && (GetStateName() == NewState) && IsInState('PlayerWalking') && ((MoveActor.Physics == PHYS_Walking) || (MoveActor.Physics == PHYS_Falling)) ) { CurrentMove = None; return; } CurrentMove = None; } else { FreeMoves.Clear(); CurrentMove = SavedMoves; } } else CurrentMove = None; } if ( MoveActor.bHardAttach ) { if ( MoveActor.Base == None ) { if ( NewBase != None ) MoveActor.SetBase(NewBase); if ( MoveActor.Base == None ) MoveActor.bHardAttach = false; else return; } else return; } NewFloor.X = NewFloorX; NewFloor.Y = NewFloorY; NewFloor.Z = NewFloorZ; if ( (Mover(NewBase) != None) || (Vehicle(NewBase) != None) ) NewLocation += NewBase.Location; if ( !bDemoOwner ) { //if ( Pawn != None ) // log("Client "$Role$" adjust "$self$" stamp "$TimeStamp$" time "$Level.TimeSeconds$" location "$MoveActor.Location); MoveActor.bCanTeleport = false; if ( !MoveActor.SetLocation(NewLocation) && (Pawn(MoveActor) != None) && (MoveActor.CollisionHeight > Pawn(MoveActor).CrouchHeight) && !Pawn(MoveActor).bIsCrouched && (newPhysics == PHYS_Walking) && (MoveActor.Physics != PHYS_Karma) && (MoveActor.Physics != PHYS_KarmaRagDoll) ) { MoveActor.SetPhysics(newPhysics); Pawn(MoveActor).ForceCrouch(); MoveActor.SetLocation(NewLocation); } MoveActor.bCanTeleport = true; } // Hack. Don't let network change physics mode of karma stuff on the client. if( (MoveActor.Physics != newPhysics) && (MoveActor.Physics != PHYS_Karma) && (MoveActor.Physics != PHYS_KarmaRagDoll) && (newPhysics != PHYS_Karma) && (newPhysics != PHYS_KarmaRagDoll) ) { MoveActor.SetPhysics(newPhysics); } if ( MoveActor != self ) MoveActor.SetBase(NewBase, NewFloor); MoveActor.Velocity = NewVelocity; if( GetStateName() != newstate ) GotoState(newstate); bUpdatePosition = true; } function ServerUpdatePing(int NewPing) { PlayerReplicationInfo.Ping = Min(0.25 * NewPing, 250); PlayerReplicationInfo.bReceivedPing = true; } function ClientUpdatePosition() { local SavedMove CurrentMove; local int realbRun, realbDuck; local bool bRealJump; // Dont do any network position updates on things running PHYS_Karma if( Pawn != None && (Pawn.Physics == PHYS_Karma || Pawn.Physics == PHYS_KarmaRagDoll) ) return; bUpdatePosition = false; realbRun= bRun; realbDuck = bDuck; bRealJump = bPressedJump; CurrentMove = SavedMoves; bUpdating = true; while ( CurrentMove != None ) { if ( (PendingMove == CurrentMove) && (Pawn != None) ) PendingMove.SetInitialPosition(Pawn); if ( CurrentMove.TimeStamp <= CurrentTimeStamp ) { SavedMoves = CurrentMove.NextMove; CurrentMove.NextMove = FreeMoves; FreeMoves = CurrentMove; FreeMoves.Clear(); CurrentMove = SavedMoves; } else { MoveAutonomous(CurrentMove.Delta, CurrentMove.bRun, CurrentMove.bDuck, CurrentMove.bPressedJump, CurrentMove.bDoubleJump, CurrentMove.DoubleClickMove, CurrentMove.Acceleration, rot(0,0,0)); if ( Pawn != None ) { CurrentMove.SavedLocation = Pawn.Location; CurrentMove.SavedVelocity = Pawn.Velocity; CurrentMove.EndBase = Pawn.Base; if ( (CurrentMove.EndBase != None) && !CurrentMove.EndBase.bWorldGeometry ) CurrentMove.SavedRelativeLocation = Pawn.Location - CurrentMove.EndBase.Location; } CurrentMove = CurrentMove.NextMove; } } bUpdating = false; bDuck = realbDuck; bRun = realbRun; bPressedJump = bRealJump; } final function SavedMove GetFreeMove() { local SavedMove s, first; local int i; if ( FreeMoves == None ) { // don't allow more than 100 saved moves For ( s=SavedMoves; s!=None; s=s.NextMove ) { i++; if ( i > 100 ) { first = SavedMoves; SavedMoves = SavedMoves.NextMove; first.Clear(); first.NextMove = None; // clear out all the moves While ( SavedMoves != None ) { s = SavedMoves; SavedMoves = SavedMoves.NextMove; s.Clear(); s.NextMove = FreeMoves; FreeMoves = s; } return first; } } return Spawn(class'SavedMove'); } else { s = FreeMoves; FreeMoves = FreeMoves.NextMove; s.NextMove = None; return s; } } function int CompressAccel(int C) { if ( C >= 0 ) C = Min(C, 127); else C = Min(abs(C), 127) + 128; return C; } /* ======================================================================== Here's how player movement prediction, replication and correction works in network games: Every tick, the PlayerTick() function is called. It calls the PlayerMove() function (which is implemented in various states). PlayerMove() figures out the acceleration and rotation, and then calls ProcessMove() (for single player or listen servers), or ReplicateMove() (if its a network client). ReplicateMove() saves the move (in the PendingMove list), calls ProcessMove(), and then replicates the move to the server by calling the replicated function ServerMove() - passing the movement parameters, the client's resultant position, and a timestamp. ServerMove() is executed on the server. It decodes the movement parameters and causes the appropriate movement to occur. It then looks at the resulting position and if enough time has passed since the last response, or the position error is significant enough, the server calls ClientAdjustPosition(), a replicated function. ClientAdjustPosition() is executed on the client. The client sets its position to the servers version of position, and sets the bUpdatePosition flag to true. When PlayerTick() is called on the client again, if bUpdatePosition is true, the client will call ClientUpdatePosition() before calling PlayerMove(). ClientUpdatePosition() replays all the moves in the pending move list which occured after the timestamp of the move the server was adjusting. */ // // Replicate this client's desired movement to the server. // function ReplicateMove ( float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot ) { local SavedMove NewMove, OldMove, AlmostLastMove, LastMove; local byte ClientRoll; local float OldTimeDelta, NetMoveDelta; local int OldAccel; local vector BuildAccel, AccelNorm, MoveLoc, CompareAccel; local bool bPendingJumpStatus; MaxResponseTime = Default.MaxResponseTime * Level.TimeDilation; DeltaTime = FMin(DeltaTime, MaxResponseTime); // find the most recent move, and the most recent interesting move if ( SavedMoves != None ) { LastMove = SavedMoves; AlmostLastMove = LastMove; AccelNorm = Normal(NewAccel); while ( LastMove.NextMove != None ) { // find most recent interesting move to send redundantly if ( LastMove.IsJumpMove() ) { OldMove = LastMove; } else if ( (Pawn != None) && ((OldMove == None) || !OldMove.IsJumpMove()) ) { // see if acceleration direction changed if ( OldMove != None ) CompareAccel = Normal(OldMove.Acceleration); else CompareAccel = AccelNorm; if ( (LastMove.Acceleration != CompareAccel) && ((normal(LastMove.Acceleration) Dot CompareAccel) < 0.95) ) OldMove = LastMove; } AlmostLastMove = LastMove; LastMove = LastMove.NextMove; } if ( LastMove.IsJumpMove() ) { OldMove = LastMove; } else if ( (Pawn != None) && ((OldMove == None) || !OldMove.IsJumpMove()) ) { // see if acceleration direction changed if ( OldMove != None ) CompareAccel = Normal(OldMove.Acceleration); else CompareAccel = AccelNorm; if ( (LastMove.Acceleration != CompareAccel) && ((normal(LastMove.Acceleration) Dot CompareAccel) < 0.95) ) OldMove = LastMove; } } // Get a SavedMove actor to store the movement in. NewMove = GetFreeMove(); if ( NewMove == None ) return; NewMove.SetMoveFor(self, DeltaTime, NewAccel, DoubleClickMove); // Simulate the movement locally. bDoubleJump = false; ProcessMove(NewMove.Delta, NewMove.Acceleration, NewMove.DoubleClickMove, DeltaRot); // see if the two moves could be combined if ( (PendingMove != None) && (Pawn != None) && (Pawn.Physics == PHYS_Walking) && (NewMove.Delta + PendingMove.Delta < MaxResponseTime) && (NewAccel != vect(0,0,0)) && (PendingMove.SavedPhysics == PHYS_Walking) && !PendingMove.bPressedJump && !NewMove.bPressedJump && (PendingMove.bRun == NewMove.bRun) && (PendingMove.bDuck == NewMove.bDuck) && (PendingMove.bDoubleJump == NewMove.bDoubleJump) && (PendingMove.DoubleClickMove == DCLICK_None) && (NewMove.DoubleClickMove == DCLICK_None) && ((Normal(PendingMove.Acceleration) Dot Normal(NewAccel)) > 0.99) && (Level.TimeDilation >= 0.9) ) { Pawn.SetLocation(PendingMove.GetStartLocation()); Pawn.Velocity = PendingMove.StartVelocity; if ( PendingMove.StartBase != Pawn.Base); Pawn.SetBase(PendingMove.StartBase); Pawn.Floor = PendingMove.StartFloor; NewMove.Delta += PendingMove.Delta; NewMove.SetInitialPosition(Pawn); // remove pending move from move list if ( LastMove == PendingMove ) { if ( SavedMoves == PendingMove ) { SavedMoves.NextMove = FreeMoves; FreeMoves = SavedMoves; SavedMoves = None; } else { PendingMove.NextMove = FreeMoves; FreeMoves = PendingMove; if ( AlmostLastMove != None ) { AlmostLastMove.NextMove = None; LastMove = AlmostLastMove; } } FreeMoves.Clear(); } PendingMove = None; } if ( Pawn != None ) Pawn.AutonomousPhysics(NewMove.Delta); else AutonomousPhysics(DeltaTime); NewMove.PostUpdate(self); if ( SavedMoves == None ) SavedMoves = NewMove; else LastMove.NextMove = NewMove; if ( PendingMove == None ) { // Decide whether to hold off on move if ( (Player.CurrentNetSpeed > 10000) && (GameReplicationInfo != None) && (GameReplicationInfo.PRIArray.Length <= 10) ) NetMoveDelta = 0.011; else NetMoveDelta = FMax(0.0222,2 * Level.MoveRepSize/Player.CurrentNetSpeed); if ( (Level.TimeSeconds - ClientUpdateTime) * Level.TimeDilation * 0.91 < NetMoveDelta ) { PendingMove = NewMove; return; } } ClientUpdateTime = Level.TimeSeconds; // check if need to redundantly send previous move if ( OldMove != None ) { // old move important to replicate redundantly OldTimeDelta = FMin(255, (Level.TimeSeconds - OldMove.TimeStamp) * 500); BuildAccel = 0.05 * OldMove.Acceleration + vect(0.5, 0.5, 0.5); OldAccel = (CompressAccel(BuildAccel.X) << 23) + (CompressAccel(BuildAccel.Y) << 15) + (CompressAccel(BuildAccel.Z) << 7); if ( OldMove.bRun ) OldAccel += 64; if ( OldMove.bDoubleJump ) OldAccel += 32; if ( OldMove.bPressedJump ) OldAccel += 16; OldAccel += OldMove.DoubleClickMove; } // Send to the server ClientRoll = (Rotation.Roll >> 8) & 255; if ( PendingMove != None ) { if ( PendingMove.bPressedJump ) bJumpStatus = !bJumpStatus; bPendingJumpStatus = bJumpStatus; } if ( NewMove.bPressedJump ) bJumpStatus = !bJumpStatus; if ( Pawn == None ) MoveLoc = Location; else MoveLoc = Pawn.Location; CallServerMove ( NewMove.TimeStamp, NewMove.Acceleration * 10, MoveLoc, NewMove.bRun, NewMove.bDuck, bPendingJumpStatus, bJumpStatus, NewMove.bDoubleJump, NewMove.DoubleClickMove, ClientRoll, (32767 & (Rotation.Pitch/2)) * 32768 + (32767 & (Rotation.Yaw/2)), OldTimeDelta, OldAccel ); PendingMove = None; } function CallServerMove ( float TimeStamp, vector InAccel, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbPendingJumpStatus, bool NewbJumpStatus, bool NewbDoubleJump, eDoubleClickDir DoubleClickMove, byte ClientRoll, int View, optional byte OldTimeDelta, optional int OldAccel ) { local byte PendingCompress; local bool bCombine; if ( PendingMove != None ) { if ( PendingMove.bRun ) PendingCompress = 1; if ( PendingMove.bDuck ) PendingCompress += 2; if ( NewbPendingJumpStatus ) PendingCompress += 4; if ( PendingMove.bDoubleJump ) PendingCompress += 8; if ( NewbRun ) PendingCompress += 16; if ( NewbDuck ) PendingCompress += 32; if ( NewbJumpStatus ) PendingCompress += 64; if ( NewbDoubleJump ) PendingCompress += 128; // send two moves simultaneously if ( (InAccel == vect(0,0,0)) && (PendingMove.StartVelocity == vect(0,0,0)) && (DoubleClickMove == DCLICK_None) && (PendingMove.Acceleration == vect(0,0,0)) && (PendingMove.DoubleClickMove == DCLICK_None) && !PendingMove.bDoubleJump ) { if ( Pawn == None ) bCombine = (Velocity == vect(0,0,0)); else bCombine = (Pawn.Velocity == vect(0,0,0)); if ( bCombine ) { if ( OldTimeDelta == 0 ) { ShortServerMove ( TimeStamp, ClientLoc, NewbRun, NewbDuck, NewbJumpStatus, ClientRoll, View ); } else { ServerMove ( TimeStamp, InAccel, ClientLoc, NewbRun, NewbDuck, NewbJumpStatus, NewbDoubleJump, DoubleClickMove, ClientRoll, View, OldTimeDelta, OldAccel ); } return; } } if ( OldTimeDelta == 0 ) DualServerMove ( PendingMove.TimeStamp, PendingMove.Acceleration * 10, PendingCompress, PendingMove.DoubleClickMove, (32767 & (PendingMove.Rotation.Pitch/2)) * 32768 + (32767 & (PendingMove.Rotation.Yaw/2)), TimeStamp, InAccel, ClientLoc, DoubleClickMove, ClientRoll, View ); else DualServerMove ( PendingMove.TimeStamp, PendingMove.Acceleration * 10, PendingCompress, PendingMove.DoubleClickMove, (32767 & (PendingMove.Rotation.Pitch/2)) * 32768 + (32767 & (PendingMove.Rotation.Yaw/2)), TimeStamp, InAccel, ClientLoc, DoubleClickMove, ClientRoll, View, OldTimeDelta, OldAccel ); } else if ( OldTimeDelta != 0 ) { ServerMove ( TimeStamp, InAccel, ClientLoc, NewbRun, NewbDuck, NewbJumpStatus, NewbDoubleJump, DoubleClickMove, ClientRoll, View, OldTimeDelta, OldAccel ); } else if ( (InAccel == vect(0,0,0)) && (DoubleClickMove == DCLICK_None) && !NewbDoubleJump ) { ShortServerMove ( TimeStamp, ClientLoc, NewbRun, NewbDuck, NewbJumpStatus, ClientRoll, View ); } else ServerMove ( TimeStamp, InAccel, ClientLoc, NewbRun, NewbDuck, NewbJumpStatus, NewbDoubleJump, DoubleClickMove, ClientRoll, View ); } function HandleWalking() { if ( Pawn != None ) Pawn.SetWalking( (bRun != 0) && !Region.Zone.IsA('WarpZoneInfo') ); } function ServerRestartGame() { } function SetFOVAngle(float newFOV) { FOVAngle = newFOV; } exec function SetFlashScaling(float F) { ScreenFlashScaling = FClamp(F,0,1); } function ClientFlash( float scale, vector fog ) { FlashScale = (scale + (1 - ScreenFlashScaling) * (1 - Scale)) * vect(1,1,1); flashfog = ScreenFlashScaling * 0.001 * fog; } function ClientAdjustGlow( float scale, vector fog ) { ConstantGlowScale += scale; ConstantGlowFog += 0.001 * fog; } function DamageShake(int damage) //send type of damage too! { ClientDamageShake(damage); } // function ShakeView( float shaketime, float RollMag, vector OffsetMag, float RollRate, vector OffsetRate, float OffsetTime) private function ClientDamageShake(int damage) { // todo: add properties! ShakeView( Damage * vect(30,0,0), 120000 * vect(1,0,0), 0.15 + 0.005 * damage, damage * vect(0,0,0.03), vect(1,1,1), 0.2); } function WeaponShakeView(vector shRotMag, vector shRotRate, float shRotTime, vector shOffsetMag, vector shOffsetRate, float shOffsetTime) { if ( bWeaponViewShake ) ShakeView(shRotMag * (1.0 - ZoomLevel), shRotRate, shRotTime, shOffsetMag * (1.0 - ZoomLevel), shOffsetRate, shOffsetTime); } /* ShakeView() Call this function to shake the player's view shaketime = how long to roll view RollMag = how far to roll view as it shakes OffsetMag = max view offset RollRate = how fast to roll view OffsetRate = how fast to offset view OffsetTime = how long to offset view (number of shakes) */ function ShakeView(vector shRotMag, vector shRotRate, float shRotTime, vector shOffsetMag, vector shOffsetRate, float shOffsetTime) { if ( VSize(shRotMag) > VSize(ShakeRotMax) ) { ShakeRotMax = shRotMag; ShakeRotRate = shRotRate; ShakeRotTime = shRotTime * vect(1,1,1); } if ( VSize(shOffsetMag) > VSize(ShakeOffsetMax) ) { ShakeOffsetMax = shOffsetMag; ShakeOffsetRate = shOffsetRate; ShakeOffsetTime = shOffsetTime * vect(1,1,1); } } function StopViewShaking() { ShakeRotMax = vect(0,0,0); ShakeRotRate = vect(0,0,0); ShakeRotTime = vect(0,0,0); ShakeOffsetMax = vect(0,0,0); ShakeOffsetRate = vect(0,0,0); ShakeOffsetTime = vect(0,0,0); } //pass in FalloffStartTime = 0 for constant shaking event SetAmbientShake(float FalloffStartTime, float FalloffTime, vector OffsetMag, float OffsetFreq, rotator RotMag, float RotFreq) { bEnableAmbientShake = true; AmbientShakeFalloffStartTime = FalloffStartTime; AmbientShakeFalloffTime = FalloffTime; AmbientShakeOffsetMag = OffsetMag; AmbientShakeOffsetFreq = OffsetFreq; AmbientShakeRotMag = RotMag; AmbientShakeRotFreq = RotFreq; } event ShakeViewEvent(vector shRotMag, vector shRotRate, float shRotTime, vector shOffsetMag, vector shOffsetRate, float shOffsetTime) { ShakeView(shRotMag, shRotRate, shRotTime, shOffsetMag, shOffsetRate, shOffsetTime); } function damageAttitudeTo(pawn Other, float Damage) { if ( (Other != None) && (Other != Pawn) && (Damage > 0) ) Enemy = Other; } function Typing( bool bTyping ) { bIsTyping = bTyping; if ( (Pawn != None) && !Pawn.bTearOff ) Pawn.bIsTyping = bIsTyping; } //************************************************************************************* // Normal gameplay execs // Type the name of the exec function at the console to execute it exec function Jump( optional float F ) { if ( Level.Pauser == PlayerReplicationInfo ) SetPause(False); else bPressedJump = true; } // Send a voice message of a certain type to a certain player. exec function Speech( name Type, int Index, string Callsign ) { ServerSpeech(Type,Index,Callsign); } function ServerSpeech( name Type, int Index, string Callsign ) { // log("Type:"$Type@"Index:"$Index@"Callsign:"$Callsign); if(PlayerReplicationInfo.VoiceType != None) PlayerReplicationInfo.VoiceType.static.PlayerSpeech( Type, Index, Callsign, Self ); } exec function RestartLevel() { if( Level.Netmode==NM_Standalone ) ClientTravel( "?restart", TRAVEL_Relative, false ); } exec function LocalTravel( string URL ) { if( Level.Netmode==NM_Standalone ) ClientTravel( URL, TRAVEL_Relative, true ); } // ------------------------------------------------------------------------ // Loading and saving /* QuickSave() Save game to slot 9 */ exec function QuickSave() { if ( (Pawn != None) && (Pawn.Health > 0) && (Level.NetMode == NM_Standalone) ) { ClientMessage(QuickSaveString); ConsoleCommand("SaveGame 9"); } } /* QuickLoad() Load game from slot 9 */ exec function QuickLoad() { if ( Level.NetMode == NM_Standalone ) ClientTravel( "?load=9", TRAVEL_Absolute, false); } /* SetPause() Try to pause game; returns success indicator. Replicated to server in network games. */ function bool SetPause( BOOL bPause ) { bFire = 0; bAltFire = 0; return Level.Game.SetPause(bPause, self); } /* Pause() Command to try to pause the game. */ exec function Pause() { if ( bDemoOwner ) { if ( Level.Pauser == None ) Level.Pauser = PlayerReplicationInfo; else Level.Pauser = None; } else ServerPause(); } function ServerPause() { // Pause if not already if(Level.Pauser == None) SetPause(true); else SetPause(false); } exec function ShowMenu() { local bool bCloseHUDScreen; if ( MyHUD != None ) { bCloseHUDScreen = MyHUD.bShowScoreboard || MyHUD.bShowLocalStats; if ( MyHUD.bShowScoreboard ) MyHUD.bShowScoreboard = false; if ( MyHUD.bShowLocalStats ) MyHUD.bShowLocalStats = false; if ( bCloseHUDScreen ) return; } ShowMidGameMenu(true); } function ShowMidGameMenu(bool bPause) { // Pause if not already if(bPause && Level.Pauser == None) SetPause(true); StopForceFeedback(); // jdf - no way to pause feedback // Open menu if (bDemoOwner) ClientopenMenu(DemoMenuClass); else ClientOpenMenu(MidGameMenuClass); } // Activate specific inventory item exec function ActivateInventoryItem( class InvItem ) { local Powerups Inv; Inv = Powerups(Pawn.FindInventoryType(InvItem)); if ( Inv != None ) Inv.Activate(); } // ------------------------------------------------------------------------ // Weapon changing functions /* ThrowWeapon() Throw out current weapon, and switch to a new weapon */ exec function ThrowWeapon() { if ( (Pawn == None) || (Pawn.Weapon == None) ) return; ServerThrowWeapon(); } function ServerThrowWeapon() { local Vector TossVel; if (Pawn.CanThrowWeapon()) { TossVel = Vector(GetViewRotation()); TossVel = TossVel * ((Pawn.Velocity Dot TossVel) + 500) + Vect(0,0,250); Pawn.TossWeapon(TossVel); ClientSwitchToBestWeapon(); } } /* PrevWeapon() - switch to previous inventory group weapon */ exec function PrevWeapon() { if ( Level.Pauser != None ) return; if ( Pawn != None ) Pawn.PrevWeapon(); else if ( bBehindView ) CameraDist = FMax(CameraDistRange.Min, CameraDist - 1.0); } /* NextWeapon() - switch to next inventory group weapon */ exec function NextWeapon() { if ( Level.Pauser != None ) return; if ( Pawn != None ) Pawn.NextWeapon(); else if ( bBehindView ) CameraDist = FMin(CameraDistRange.Max, CameraDist + 1.0); } exec function PipedSwitchWeapon(byte F) { if ( (Pawn == None) || (Pawn.PendingWeapon != None) ) return; SwitchWeapon(F); } // The player wants to switch to weapon group number F. exec function SwitchWeapon(byte F) { if ( Pawn != None ) Pawn.SwitchWeapon(F); } exec function GetWeapon(class NewWeaponClass ) { local Inventory Inv; local int Count; if ( (Pawn == None) || (Pawn.Inventory == None) || (NewWeaponClass == None) ) return; if ( (Pawn.Weapon != None) && (Pawn.Weapon.Class == NewWeaponClass) && (Pawn.PendingWeapon == None) ) { Pawn.Weapon.Reselect(); return; } if ( Pawn.PendingWeapon != None && Pawn.PendingWeapon.bForceSwitch ) return; for ( Inv=Pawn.Inventory; Inv!=None; Inv=Inv.Inventory ) { if ( Inv.Class == NewWeaponClass ) { Pawn.PendingWeapon = Weapon(Inv); if ( !Pawn.PendingWeapon.HasAmmo() ) { ClientMessage( Pawn.PendingWeapon.ItemName$Pawn.PendingWeapon.MessageNoAmmo ); Pawn.PendingWeapon = None; return; } Pawn.Weapon.PutDown(); return; } Count++; if ( Count > 1000 ) return; } } // The player wants to select previous item exec function PrevItem() { local Inventory Inv; local Powerups LastItem; if ( (Level.Pauser!=None) || (Pawn == None) ) return; if (Pawn.SelectedItem==None) { Pawn.SelectedItem = Pawn.Inventory.SelectNext(); Return; } if (Pawn.SelectedItem.Inventory!=None) for( Inv=Pawn.SelectedItem.Inventory; Inv!=None; Inv=Inv.Inventory ) { if (Inv==None) Break; if ( Inv.IsA('Powerups') && Powerups(Inv).bActivatable) LastItem=Powerups(Inv); } for( Inv=Pawn.Inventory; Inv!=Pawn.SelectedItem; Inv=Inv.Inventory ) { if (Inv==None) Break; if ( Inv.IsA('Powerups') && Powerups(Inv).bActivatable) LastItem=Powerups(Inv); } if (LastItem!=None) Pawn.SelectedItem = LastItem; } // The player wants to active selected item exec function ActivateItem() { if( Level.Pauser!=None ) return; if ( (Pawn != None) && (Pawn.SelectedItem!=None) ) Pawn.SelectedItem.Activate(); } // The player wants to fire. exec function Fire( optional float F ) { if ( Level.NetMode == NM_StandAlone && bViewingMatineeCinematic ) { Level.Game.SceneAbort(); } if ( Level.Pauser == PlayerReplicationInfo ) { SetPause(false); return; } if( bDemoOwner || (Pawn == None) ) return; Pawn.Fire(F); } // The player wants to alternate-fire. exec function AltFire( optional float F ) { if ( Level.Pauser == PlayerReplicationInfo ) { SetPause(false); return; } if( bDemoOwner || (Pawn == None) ) return; Pawn.AltFire(F); } // The player wants to use something in the level. exec function Use() { ServerUse(); } function ServerUse() { local Actor A; local Vehicle DrivenVehicle, EntryVehicle, V; if ( Role < ROLE_Authority ) return; if ( Level.Pauser == PlayerReplicationInfo ) { SetPause(false); return; } if (Pawn == None || !Pawn.bCanUse) return; DrivenVehicle = Vehicle(Pawn); if( DrivenVehicle != None ) { DrivenVehicle.KDriverLeave(false); return; } // Check for nearby vehicles ForEach Pawn.VisibleCollidingActors(class'Vehicle', V, VehicleCheckRadius) { // Found a vehicle within radius EntryVehicle = V.FindEntryVehicle(Pawn); if (EntryVehicle != None && EntryVehicle.TryToDrive(Pawn)) return; } // Send the 'DoUse' event to each actor player is touching. ForEach Pawn.TouchingActors(class'Actor', A) A.UsedBy(Pawn); if ( Pawn.Base != None ) Pawn.Base.UsedBy( Pawn ); } exec function Suicide() { local float MinSuicideInterval; if ( Level.NetMode == NM_Standalone ) MinSuicideInterval = 1; else MinSuicideInterval = 10; if ( (Pawn != None) && (Level.TimeSeconds - Pawn.LastStartTime > MinSuicideInterval) ) Pawn.Suicide(); } exec function SetName( coerce string S) { ChangeName(S); UpdateURL("Name", S, true); SaveConfig(); } exec function SetVoice( coerce string S ) { if ( Level.NetMode == NM_StandAlone ) { if ( PlayerReplicationInfo != None ) PlayerReplicationInfo.SetCharacterVoice(S); } else ChangeVoiceType(S); UpdateURL("Voice", S, True); } function ChangeVoiceType(string NewVoiceType) { if ( VoiceChangeLimit > Level.TimeSeconds ) return; VoiceChangeLimit = Level.TimeSeconds + 10.0; // TODO - probably better to hook this up to the same limit system that playernames use if ( NewVoiceType != "" && PlayerReplicationInfo != None ) PlayerReplicationInfo.SetCharacterVoice(NewVoiceType); } function ChangeName( coerce string S ) { if ( Len(S) > 20 ) S = left(S,20); ReplaceText(S, " ", "_"); ReplaceText(S, "\"", ""); Level.Game.ChangeName( self, S, true ); } exec function SwitchTeam() { if ( (PlayerReplicationInfo.Team == None) || (PlayerReplicationInfo.Team.TeamIndex == 1) ) ServerChangeTeam(0); else ServerChangeTeam(1); } exec function ChangeTeam( int N ) { ServerChangeTeam(N); } function ServerChangeTeam( int N ) { local TeamInfo OldTeam; OldTeam = PlayerReplicationInfo.Team; Level.Game.ChangeTeam(self, N, true); if ( Level.Game.bTeamGame && (PlayerReplicationInfo.Team != OldTeam) ) { if ( (OldTeam != None) && (PlayerReplicationInfo.Team != None) && (PlayerReplicationInfo.Team.Size > OldTeam.Size) ) Adrenaline = 0; if ( Pawn != None ) Pawn.PlayerChangedTeam(); } } exec function SwitchLevel( string URL ) { if( Level.NetMode==NM_Standalone || Level.netMode==NM_ListenServer ) Level.ServerTravel( URL, false ); } event ProgressCommand(string Cmd, string Msg1, string Msg2) { local string c,v; log(Name$".ProgressCommand Cmd '"$Cmd$"' Msg1 '"$Msg1$"' Msg2 '"$Msg2$"'"); Divide(Cmd, ":", C, V); // Checking for bActive prevents multiple status message menus from being opened. However, this also // prevents status messages from appearing if another menu is open. // Instead, place checks for bActive in places where ProgressCommand is called, but we don't want to override other menus. if ( C~="menu" /*&& (!Player.GUIController.bActive)*/ ) ClientOpenMenu(v, false, Msg1, Msg2); } exec function ClearProgressMessages() { local int i; for (i=0; i ForcePrecacheTime ) { bForcePrecache = false; Level.FillPrecacheMaterialsArray( false ); Level.FillPrecacheStaticMeshesArray( false ); } } else if ( !bShortConnectTimeOut ) { bShortConnectTimeOut = true; ServerShortTimeout(); } if ( Pawn != AcknowledgedPawn ) { if ( Role < ROLE_Authority ) { // make sure old pawn controller is right if ( (AcknowledgedPawn != None) && (AcknowledgedPawn.Controller == self) ) AcknowledgedPawn.Controller = None; } AcknowledgePossession(Pawn); } PlayerInput.PlayerInput(DeltaTime); if ( bUpdatePosition ) ClientUpdatePosition(); if ( !IsSpectating() && Pawn != None ) Pawn.RawInput(DeltaTime, aBaseX, aBaseY, aBaseZ, aMouseX, aMouseY, aForward, aTurn, aStrafe, aUp, aLookUp); PlayerMove(DeltaTime); } function PlayerMove(float DeltaTime); // /* AdjustAim() Calls this version for player aiming help. Aimerror not used in this version. Only adjusts aiming at pawns */ function rotator AdjustAim(FireProperties FiredAmmunition, vector projStart, int aimerror) { local vector FireDir, AimSpot, HitNormal, HitLocation, OldAim, AimOffset; local actor BestTarget; local float bestAim, bestDist, projspeed; local actor HitActor; local bool bNoZAdjust, bLeading; local rotator AimRot; FireDir = vector(Rotation); if ( FiredAmmunition.bInstantHit ) HitActor = Trace(HitLocation, HitNormal, projStart + 10000 * FireDir, projStart, true); else HitActor = Trace(HitLocation, HitNormal, projStart + 4000 * FireDir, projStart, true); if ( (HitActor != None) && HitActor.bProjTarget ) { BestTarget = HitActor; bNoZAdjust = true; OldAim = HitLocation; BestDist = VSize(BestTarget.Location - Pawn.Location); } else { // adjust aim based on FOV bestAim = 0.90; if ( (Level.NetMode == NM_Standalone) && bAimingHelp ) { bestAim = 0.93; if ( FiredAmmunition.bInstantHit ) bestAim = 0.97; if ( FOVAngle < DefaultFOV - 8 ) bestAim = 0.99; } else if ( FiredAmmunition.bInstantHit ) bestAim = 1.0; BestTarget = PickTarget(bestAim, bestDist, FireDir, projStart, FiredAmmunition.MaxRange); if ( BestTarget == None ) { if (bBehindView) return Pawn.Rotation; else return Rotation; } OldAim = projStart + FireDir * bestDist; } InstantWarnTarget(BestTarget,FiredAmmunition,FireDir); ShotTarget = Pawn(BestTarget); if ( !bAimingHelp || (Level.NetMode != NM_Standalone) ) { if (bBehindView) return Pawn.Rotation; else return Rotation; } // aim at target - help with leading also if ( !FiredAmmunition.bInstantHit ) { projspeed = FiredAmmunition.ProjectileClass.default.speed; BestDist = vsize(BestTarget.Location + BestTarget.Velocity * FMin(1, 0.02 + BestDist/projSpeed) - projStart); bLeading = true; FireDir = BestTarget.Location + BestTarget.Velocity * FMin(1, 0.02 + BestDist/projSpeed) - projStart; AimSpot = projStart + bestDist * Normal(FireDir); // if splash damage weapon, try aiming at feet - trace down to find floor if ( FiredAmmunition.bTrySplash && ((BestTarget.Velocity != vect(0,0,0)) || (BestDist > 1500)) ) { HitActor = Trace(HitLocation, HitNormal, AimSpot - BestTarget.CollisionHeight * vect(0,0,2), AimSpot, false); if ( (HitActor != None) && FastTrace(HitLocation + vect(0,0,4),projstart) ) return rotator(HitLocation + vect(0,0,6) - projStart); } } else { FireDir = BestTarget.Location - projStart; AimSpot = projStart + bestDist * Normal(FireDir); } AimOffset = AimSpot - OldAim; // adjust Z of shooter if necessary if ( bNoZAdjust || (bLeading && (Abs(AimOffset.Z) < BestTarget.CollisionHeight)) ) AimSpot.Z = OldAim.Z; else if ( AimOffset.Z < 0 ) AimSpot.Z = BestTarget.Location.Z + 0.4 * BestTarget.CollisionHeight; else AimSpot.Z = BestTarget.Location.Z - 0.7 * BestTarget.CollisionHeight; if ( !bLeading ) { // if not leading, add slight random error ( significant at long distances ) if ( !bNoZAdjust ) { AimRot = rotator(AimSpot - projStart); if ( FOVAngle < DefaultFOV - 8 ) AimRot.Yaw = AimRot.Yaw + 200 - Rand(400); else AimRot.Yaw = AimRot.Yaw + 375 - Rand(750); return AimRot; } } else if ( !FastTrace(projStart + 0.9 * bestDist * Normal(FireDir), projStart) ) { FireDir = BestTarget.Location - projStart; AimSpot = projStart + bestDist * Normal(FireDir); } return rotator(AimSpot - projStart); } function bool NotifyLanded(vector HitNormal) { return bUpdating; } //============================================================================= // Player Control // Player view. // Compute the rendering viewpoint for the player. // function AdjustView(float DeltaTime ) { // teleporters affect your FOV, so adjust it back down if ( FOVAngle != DesiredFOV ) { if ( FOVAngle > DesiredFOV ) FOVAngle = FOVAngle - FMax(7, 0.9 * DeltaTime * (FOVAngle - DesiredFOV)); else FOVAngle = FOVAngle - FMin(-7, 0.9 * DeltaTime * (FOVAngle - DesiredFOV)); if ( Abs(FOVAngle - DesiredFOV) <= 10 ) FOVAngle = DesiredFOV; } // adjust FOV for weapon zooming if ( bZooming ) { ZoomLevel = FMin(ZoomLevel + DeltaTime, DesiredZoomLevel); DesiredFOV = FClamp(90.0 - (ZoomLevel * 88.0), 1, 170); } } function CalcBehindView(out vector CameraLocation, out rotator CameraRotation, float Dist) { local vector View,HitLocation,HitNormal; local float ViewDist,RealDist; local vector globalX,globalY,globalZ; local vector localX,localY,localZ; CameraRotation = Rotation; CameraRotation.Roll = 0; CameraLocation.Z += 12; // add view rotation offset to cameraview (amb) CameraRotation += CameraDeltaRotation; View = vect(1,0,0) >> CameraRotation; // add view radius offset to camera location and move viewpoint up from origin (amb) RealDist = Dist; Dist += CameraDeltaRad; if( Trace( HitLocation, HitNormal, CameraLocation - Dist * vector(CameraRotation), CameraLocation,false,vect(10,10,10) ) != None ) ViewDist = FMin( (CameraLocation - HitLocation) Dot View, Dist ); else ViewDist = Dist; if ( !bBlockCloseCamera || !bValidBehindCamera || (ViewDist > 10 + FMax(ViewTarget.CollisionRadius, ViewTarget.CollisionHeight)) ) { //Log("Update Cam "); bValidBehindCamera = true; OldCameraLoc = CameraLocation - ViewDist * View; OldCameraRot = CameraRotation; } else { //Log("Dont Update Cam "$bBlockCloseCamera@bValidBehindCamera@ViewDist); SetRotation(OldCameraRot); } CameraLocation = OldCameraLoc; CameraRotation = OldCameraRot; // add view swivel rotation to cameraview (amb) GetAxes(CameraSwivel,globalX,globalY,globalZ); localX = globalX >> CameraRotation; localY = globalY >> CameraRotation; localZ = globalZ >> CameraRotation; CameraRotation = OrthoRotation(localX,localY,localZ); } function CalcFirstPersonView( out vector CameraLocation, out rotator CameraRotation ) { local vector x, y, z, AmbShakeOffset; local rotator AmbShakeRot; local float FalloffScaling; GetAxes(Rotation, x, y, z); if(bEnableAmbientShake) { if (AmbientShakeFalloffStartTime > 0 && Level.TimeSeconds - AmbientShakeFalloffStartTime > AmbientShakeFalloffTime) bEnableAmbientShake = false; else { if (AmbientShakeFalloffStartTime > 0) { FalloffScaling = 1.0 - ((Level.TimeSeconds - AmbientShakeFalloffStartTime) / AmbientShakeFalloffTime); FalloffScaling = FClamp(FalloffScaling, 0.0, 1.0); } else FalloffScaling = 1.0; AmbShakeOffset = AmbientShakeOffsetMag * FalloffScaling * sin(Level.TimeSeconds * AmbientShakeOffsetFreq * 2 * Pi); AmbShakeRot = AmbientShakeRotMag * FalloffScaling * sin(Level.TimeSeconds * AmbientShakeRotFreq * 2 * Pi); } } // First-person view. CameraRotation = Normalize(Rotation + ShakeRot + AmbShakeRot); // amb CameraLocation = CameraLocation + Pawn.EyePosition() + Pawn.WalkBob + ShakeOffset.X * x + ShakeOffset.Y * y + ShakeOffset.Z * z + AmbShakeOffset; } event AddCameraEffect(CameraEffect NewEffect,optional bool RemoveExisting) { if(RemoveExisting) RemoveCameraEffect(NewEffect); CameraEffects.Length = CameraEffects.Length + 1; CameraEffects[CameraEffects.Length - 1] = NewEffect; } event RemoveCameraEffect(CameraEffect ExEffect) { local int EffectIndex; for(EffectIndex = 0;EffectIndex < CameraEffects.Length;EffectIndex++) if(CameraEffects[EffectIndex] == ExEffect) { CameraEffects.Remove(EffectIndex,1); return; } } exec function CreateCameraEffect(class EffectClass) { AddCameraEffect(new EffectClass); } simulated function rotator GetViewRotation() { if ( bBehindView && (Pawn != None) ) return Pawn.Rotation; return Rotation; } function CacheCalcView(actor ViewActor, vector CameraLocation, rotator CameraRotation) { CalcViewActor = ViewActor; if (ViewActor != None) CalcViewActorLocation = ViewActor.Location; CalcViewLocation = CameraLocation; CalcViewRotation = CameraRotation; LastPlayerCalcView = Level.TimeSeconds; } event PlayerCalcView(out actor ViewActor, out vector CameraLocation, out rotator CameraRotation ) { local Pawn PTarget; if ( LastPlayerCalcView == Level.TimeSeconds && CalcViewActor != None && CalcViewActor.Location == CalcViewActorLocation ) { ViewActor = CalcViewActor; CameraLocation = CalcViewLocation; CameraRotation = CalcViewRotation; return; } // If desired, call the pawn's own special callview if( Pawn != None && Pawn.bSpecialCalcView && (ViewTarget == Pawn) ) { // try the 'special' calcview. This may return false if its not applicable, and we do the usual. if ( Pawn.SpecialCalcView(ViewActor, CameraLocation, CameraRotation) ) { CacheCalcView(ViewActor,CameraLocation,CameraRotation); return; } } if ( (ViewTarget == None) || ViewTarget.bDeleteMe ) { if ( bViewBot && (CheatManager != None) ) CheatManager.ViewBot(); else if ( (Pawn != None) && !Pawn.bDeleteMe ) SetViewTarget(Pawn); else if ( RealViewTarget != None ) SetViewTarget(RealViewTarget); else SetViewTarget(self); } ViewActor = ViewTarget; CameraLocation = ViewTarget.Location; if ( ViewTarget == Pawn ) { if( bBehindView ) //up and behind CalcBehindView(CameraLocation, CameraRotation, CameraDist * Pawn.Default.CollisionRadius); else CalcFirstPersonView( CameraLocation, CameraRotation ); CacheCalcView(ViewActor,CameraLocation,CameraRotation); return; } if ( ViewTarget == self ) { if ( bCameraPositionLocked ) CameraRotation = CheatManager.LockedRotation; else CameraRotation = Rotation; CacheCalcView(ViewActor,CameraLocation,CameraRotation); return; } if ( ViewTarget.IsA('Projectile') ) { if ( Projectile(ViewTarget).bSpecialCalcView && Projectile(ViewTarget).SpecialCalcView(ViewActor, CameraLocation, CameraRotation, bBehindView) ) { CacheCalcView(ViewActor,CameraLocation,CameraRotation); return; } if ( !bBehindView ) { CameraLocation += (ViewTarget.CollisionHeight) * vect(0,0,1); CameraRotation = Rotation; CacheCalcView(ViewActor,CameraLocation,CameraRotation); return; } } CameraRotation = ViewTarget.Rotation; PTarget = Pawn(ViewTarget); if ( PTarget != None ) { if ( (Level.NetMode == NM_Client) || (bDemoOwner && (Level.NetMode != NM_Standalone)) ) { PTarget.SetViewRotation(TargetViewRotation); CameraRotation = BlendedTargetViewRotation; PTarget.EyeHeight = TargetEyeHeight; } else if ( PTarget.IsPlayerPawn() ) CameraRotation = PTarget.GetViewRotation(); if (PTarget.bSpecialCalcView && PTarget.SpectatorSpecialCalcView(self, ViewActor, CameraLocation, CameraRotation)) { CacheCalcView(ViewActor, CameraLocation, CameraRotation); return; } if ( !bBehindView ) CameraLocation += PTarget.EyePosition(); } if ( bBehindView ) { CameraLocation = CameraLocation + (ViewTarget.Default.CollisionHeight - ViewTarget.CollisionHeight) * vect(0,0,1); CalcBehindView(CameraLocation, CameraRotation, CameraDist * ViewTarget.Default.CollisionRadius); } CacheCalcView(ViewActor,CameraLocation,CameraRotation); } function int BlendRot(float DeltaTime, int BlendC, int NewC) { if ( Abs(BlendC - NewC) > 32767 ) { if ( BlendC > NewC ) NewC += 65536; else BlendC += 65536; } if ( Abs(BlendC - NewC) > 4096 ) BlendC = NewC; else BlendC = BlendC + (NewC - BlendC) * FMin(1,24 * DeltaTime); return (BlendC & 65535); } function CheckShake(out float MaxOffset, out float Offset, out float Rate, out float Time, float dt) { if ( abs(Offset) < abs(MaxOffset) ) return; Offset = MaxOffset; if ( Time > 1 ) { if ( Time * abs(MaxOffset/Rate) <= 1 ) MaxOffset = MaxOffset * (1/Time - 1); else MaxOffset *= -1; Time -= dt; Rate *= -1; } else { MaxOffset = 0; Offset = 0; Rate = 0; } } function UpdateShakeRotComponent(out float max, out int current, out float rate, out float time, float dt) { local float fCurrent; current = ((current & 65535) + rate * dt) & 65535; if ( current > 32768 ) current -= 65536; fCurrent = current; CheckShake(max, fCurrent, rate, time, dt); current = fCurrent; } function ViewShake(float DeltaTime) { if ( ShakeOffsetRate != vect(0,0,0) ) { // modify shake offset ShakeOffset.X += DeltaTime * ShakeOffsetRate.X; CheckShake(ShakeOffsetMax.X, ShakeOffset.X, ShakeOffsetRate.X, ShakeOffsetTime.X, DeltaTime); ShakeOffset.Y += DeltaTime * ShakeOffsetRate.Y; CheckShake(ShakeOffsetMax.Y, ShakeOffset.Y, ShakeOffsetRate.Y, ShakeOffsetTime.Y, DeltaTime); ShakeOffset.Z += DeltaTime * ShakeOffsetRate.Z; CheckShake(ShakeOffsetMax.Z, ShakeOffset.Z, ShakeOffsetRate.Z, ShakeOffsetTime.Z, DeltaTime); } if ( ShakeRotRate != vect(0,0,0) ) { UpdateShakeRotComponent(ShakeRotMax.X, ShakeRot.Pitch, ShakeRotRate.X, ShakeRotTime.X, DeltaTime); UpdateShakeRotComponent(ShakeRotMax.Y, ShakeRot.Yaw, ShakeRotRate.Y, ShakeRotTime.Y, DeltaTime); UpdateShakeRotComponent(ShakeRotMax.Z, ShakeRot.Roll, ShakeRotRate.Z, ShakeRotTime.Z, DeltaTime); } } function bool TurnTowardNearestEnemy(); function TurnAround() { if ( !bSetTurnRot ) { TurnRot180 = Rotation; TurnRot180.Yaw += 32768; bSetTurnRot = true; } DesiredRotation = TurnRot180; bRotateToDesired = ( DesiredRotation.Yaw != Rotation.Yaw ); } function UpdateRotation(float DeltaTime, float maxPitch) { local rotator newRotation, ViewRotation; if ( bInterpolating || ((Pawn != None) && Pawn.bInterpolating) ) { ViewShake(deltaTime); return; } // Added FreeCam control for better view control if (bFreeCam == True) { if (bFreeCamZoom == True) { CameraDeltaRad += DeltaTime * 0.25 * aLookUp; } else if (bFreeCamSwivel == True) { CameraSwivel.Yaw += 16.0 * DeltaTime * aTurn; CameraSwivel.Pitch += 16.0 * DeltaTime * aLookUp; } else { CameraDeltaRotation.Yaw += 32.0 * DeltaTime * aTurn; CameraDeltaRotation.Pitch += 32.0 * DeltaTime * aLookUp; } } else { ViewRotation = Rotation; if(Pawn != None && Pawn.Physics != PHYS_Flying) // mmmmm { // Ensure we are not setting the pawn to a rotation beyond its desired if( Pawn.DesiredRotation.Roll < 65535 && (ViewRotation.Roll < Pawn.DesiredRotation.Roll || ViewRotation.Roll > 0)) ViewRotation.Roll = 0; else if( Pawn.DesiredRotation.Roll > 0 && (ViewRotation.Roll > Pawn.DesiredRotation.Roll || ViewRotation.Roll < 65535)) ViewRotation.Roll = 0; } DesiredRotation = ViewRotation; //save old rotation if ( bTurnToNearest != 0 ) TurnTowardNearestEnemy(); else if ( bTurn180 != 0 ) TurnAround(); else { TurnTarget = None; bRotateToDesired = false; bSetTurnRot = false; ViewRotation.Yaw += 32.0 * DeltaTime * aTurn; ViewRotation.Pitch += 32.0 * DeltaTime * aLookUp; } if (Pawn != None) ViewRotation.Pitch = Pawn.LimitPitch(ViewRotation.Pitch); SetRotation(ViewRotation); ViewShake(deltaTime); ViewFlash(deltaTime); NewRotation = ViewRotation; //NewRotation.Roll = Rotation.Roll; if ( !bRotateToDesired && (Pawn != None) && (!bFreeCamera || !bBehindView) ) Pawn.FaceRotation(NewRotation, deltatime); } } function ClearDoubleClick() { if (PlayerInput != None) PlayerInput.DoubleClickTimer = 0.0; } simulated function bool DodgingIsEnabled() { if ( PlayerInput != None ) return PlayerInput.bEnableDodging; else if ( InputClass != None ) return InputClass.default.bEnableDodging; else return class'Engine.PlayerInput'.default.bEnableDodging; } simulated function SetDodging( bool Enabled ) { if( PlayerInput != None) PlayerInput.bEnableDodging = Enabled; InputClass.default.bEnableDodging = Enabled; InputClass.static.StaticSaveConfig(); } // Player movement. // Player Standing, walking, running, falling. state PlayerWalking { ignores SeePlayer, HearNoise, Bump; function bool NotifyPhysicsVolumeChange( PhysicsVolume NewVolume ) { if ( NewVolume.bWaterVolume ) GotoState(Pawn.WaterMovementState); return false; } function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) { local vector OldAccel; local bool OldCrouch; if ( Pawn == None ) return; OldAccel = Pawn.Acceleration; if ( Pawn.Acceleration != NewAccel ) Pawn.Acceleration = NewAccel; if ( bDoubleJump && (bUpdating || Pawn.CanDoubleJump()) ) Pawn.DoDoubleJump(bUpdating); else if ( bPressedJump ) Pawn.DoJump(bUpdating); Pawn.SetViewPitch(Rotation.Pitch); if ( Pawn.Physics != PHYS_Falling ) { OldCrouch = Pawn.bWantsToCrouch; if (bDuck == 0) Pawn.ShouldCrouch(false); else if ( Pawn.bCanCrouch ) Pawn.ShouldCrouch(true); } } function PlayerMove( float DeltaTime ) { local vector X,Y,Z, NewAccel; local eDoubleClickDir DoubleClickMove; local rotator OldRotation, ViewRotation; local bool bSaveJump; if( Pawn == None ) { GotoState('Dead'); // this was causing instant respawns in mp games return; } GetAxes(Pawn.Rotation,X,Y,Z); // Update acceleration. NewAccel = aForward*X + aStrafe*Y; NewAccel.Z = 0; if ( VSize(NewAccel) < 1.0 ) NewAccel = vect(0,0,0); DoubleClickMove = PlayerInput.CheckForDoubleClickMove(1.1*DeltaTime/Level.TimeDilation); GroundPitch = 0; ViewRotation = Rotation; if ( Pawn.Physics == PHYS_Walking ) { // tell pawn about any direction changes to give it a chance to play appropriate animation //if walking, look up/down stairs - unless player is rotating view if ( (bLook == 0) && (((Pawn.Acceleration != Vect(0,0,0)) && bSnapToLevel) || !bKeyboardLook) ) { if ( bLookUpStairs || bSnapToLevel ) { GroundPitch = FindStairRotation(deltaTime); ViewRotation.Pitch = GroundPitch; } else if ( bCenterView ) { ViewRotation.Pitch = ViewRotation.Pitch & 65535; if (ViewRotation.Pitch > 32768) ViewRotation.Pitch -= 65536; ViewRotation.Pitch = ViewRotation.Pitch * (1 - 12 * FMin(0.0833, deltaTime)); if ( (Abs(ViewRotation.Pitch) < 250) && (ViewRotation.Pitch < 100) ) ViewRotation.Pitch = -249; } } } else { if ( !bKeyboardLook && (bLook == 0) && bCenterView ) { ViewRotation.Pitch = ViewRotation.Pitch & 65535; if (ViewRotation.Pitch > 32768) ViewRotation.Pitch -= 65536; ViewRotation.Pitch = ViewRotation.Pitch * (1 - 12 * FMin(0.0833, deltaTime)); if ( (Abs(ViewRotation.Pitch) < 250) && (ViewRotation.Pitch < 100) ) ViewRotation.Pitch = -249; } } Pawn.CheckBob(DeltaTime, Y); // Update rotation. SetRotation(ViewRotation); OldRotation = Rotation; UpdateRotation(DeltaTime, 1); bDoubleJump = false; if ( bPressedJump && Pawn.CannotJumpNow() ) { bSaveJump = true; bPressedJump = false; } else bSaveJump = false; if ( Role < ROLE_Authority ) // then save this move and replicate it ReplicateMove(DeltaTime, NewAccel, DoubleClickMove, OldRotation - Rotation); else ProcessMove(DeltaTime, NewAccel, DoubleClickMove, OldRotation - Rotation); bPressedJump = bSaveJump; } function BeginState() { DoubleClickDir = DCLICK_None; bPressedJump = false; GroundPitch = 0; if ( Pawn != None ) { if ( Pawn.Mesh == None ) Pawn.SetMesh(); Pawn.ShouldCrouch(false); if (Pawn.Physics != PHYS_Falling && Pawn.Physics != PHYS_Karma) // FIXME HACK!!! Pawn.SetPhysics(PHYS_Walking); } } function EndState() { GroundPitch = 0; if ( Pawn != None && bDuck==0 ) Pawn.ShouldCrouch(false); } Begin: } // player is climbing ladder state PlayerClimbing { ignores SeePlayer, HearNoise, Bump; function bool NotifyPhysicsVolumeChange( PhysicsVolume NewVolume ) { if ( NewVolume.bWaterVolume ) GotoState(Pawn.WaterMovementState); else GotoState(Pawn.LandMovementState); return false; } function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) { local vector OldAccel; OldAccel = Pawn.Acceleration; if ( Pawn.Acceleration != NewAccel ) Pawn.Acceleration = NewAccel; if ( bPressedJump ) { Pawn.DoJump(bUpdating); if ( Pawn.Physics == PHYS_Falling ) GotoState('PlayerWalking'); } } function PlayerMove( float DeltaTime ) { local vector X,Y,Z, NewAccel; local eDoubleClickDir DoubleClickMove; local rotator OldRotation, ViewRotation; local bool bSaveJump; GetAxes(Rotation,X,Y,Z); // Update acceleration. if ( Pawn.OnLadder != None ) { NewAccel = aForward*Pawn.OnLadder.ClimbDir; if ( Pawn.OnLadder.bAllowLadderStrafing ) NewAccel += aStrafe*Y; } else NewAccel = aForward*X + aStrafe*Y; if ( VSize(NewAccel) < 1.0 ) NewAccel = vect(0,0,0); ViewRotation = Rotation; // Update rotation. SetRotation(ViewRotation); OldRotation = Rotation; UpdateRotation(DeltaTime, 1); if ( Role < ROLE_Authority ) // then save this move and replicate it ReplicateMove(DeltaTime, NewAccel, DoubleClickMove, OldRotation - Rotation); else ProcessMove(DeltaTime, NewAccel, DoubleClickMove, OldRotation - Rotation); bPressedJump = bSaveJump; } function BeginState() { Pawn.ShouldCrouch(false); bPressedJump = false; } function EndState() { if ( Pawn != None ) Pawn.ShouldCrouch(false); } } // Player movement. // Player Driving a Karma vehicle. state PlayerDriving { ignores SeePlayer, HearNoise, Bump; function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) { } // Set the throttle, steering etc. for the vehicle based on the input provided function ProcessDrive(float InForward, float InStrafe, float InUp, bool InJump) { local Vehicle CurrentVehicle; CurrentVehicle = Vehicle(Pawn); if(CurrentVehicle == None) return; //log("Forward:"@InForward@" Strafe:"@InStrafe@" Up:"@InUp); CurrentVehicle.Throttle = FClamp( InForward/5000.0, -1.0, 1.0 ); CurrentVehicle.Steering = FClamp( -InStrafe/5000.0, -1.0, 1.0 ); CurrentVehicle.Rise = FClamp( InUp/5000.0, -1.0, 1.0 ); } function PlayerMove( float DeltaTime ) { local Vehicle CurrentVehicle; local float NewPing; CurrentVehicle = Vehicle(Pawn); // update 'looking' rotation UpdateRotation(DeltaTime, 2); // TODO: Don't send things like aForward and aStrafe for gunners who don't need it // Only servers can actually do the driving logic. if (Role < ROLE_Authority ) { if ( (Level.TimeSeconds - LastPingUpdate > 4) && (PlayerReplicationInfo != None) && !bDemoOwner ) { LastPingUpdate = Level.TimeSeconds; NewPing = float(ConsoleCommand("GETPING")); if ( ExactPing < 0.006 ) ExactPing = FMin(0.1,0.001 * NewPing); else ExactPing = 0.99 * ExactPing + 0.0001 * NewPing; PlayerReplicationInfo.Ping = Min(250.0 * ExactPing, 255); PlayerReplicationInfo.bReceivedPing = true; OldPing = ExactPing; ServerUpdatePing(1000 * ExactPing); } if (!bSkippedLastUpdate && // in order to skip this update we must not have skipped the last one (Player.CurrentNetSpeed < 10000) && // and netspeed must be low (Level.TimeSeconds - ClientUpdateTime < 0.0222) && // and time since last update must be short bPressedJump == bLastPressedJump && // and update must not contain major changes aUp - aLastUp < 0.01 && // " aForward - aLastForward < 0.01 && // " aStrafe - aLastStrafe < 0.01 // " ) { // log("!bSkippedLastUpdate: "$!bSkippedLastUpdate); // log("(Player.CurrentNetSpeed < 10000): "$(Player.CurrentNetSpeed < 10000)); // log("(Level.TimeSeconds - ClientUpdateTime < 0.0222): "$(Level.TimeSeconds - ClientUpdateTime < 0.0222)$" - "$Level.TimeSeconds - ClientUpdateTime); // log("bPressedJump == bLastPressedJump: "$bPressedJump == bLastPressedJump); // log("aUp - aLastUp < 0.01: "$aUp - aLastUp < 0.01); // log("aForward - aLastForward < 0.01: "$aForward - aLastForward < 0.01); // log("aStrafe - aLastStrafe < 0.01: "$aStrafe - aLastStrafe < 0.01); bSkippedLastUpdate = True; return; } else { bSkippedLastUpdate = False; ClientUpdateTime = Level.TimeSeconds; // Save Move bLastPressedJump = bPressedJump; aLastUp = aUp; aLastForward = aForward; aLastStrafe = aStrafe; if (CurrentVehicle != None) { CurrentVehicle.Throttle = FClamp( aForward/5000.0, -1.0, 1.0 ); CurrentVehicle.Steering = FClamp( -aStrafe/5000.0, -1.0, 1.0 ); CurrentVehicle.Rise = FClamp( aUp/5000.0, -1.0, 1.0 ); } ServerDrive(aForward, aStrafe, aUp, bPressedJump, (32767 & (Rotation.Pitch/2)) * 32768 + (32767 & (Rotation.Yaw/2))); } } else ProcessDrive(aForward, aStrafe, aUp, bPressedJump); // If the vehicle is being controlled here - set replicated variables. if (CurrentVehicle != None) { if(bFire == 0 && CurrentVehicle.bWeaponIsFiring) CurrentVehicle.ClientVehicleCeaseFire(False); if(bAltFire == 0 && CurrentVehicle.bWeaponIsAltFiring) CurrentVehicle.ClientVehicleCeaseFire(True); } } function BeginState() { PlayerReplicationInfo.bReceivedPing = false; CleanOutSavedMoves(); } function EndState() { CleanOutSavedMoves(); } } // Player movement. // Player walking on walls state PlayerSpidering { ignores SeePlayer, HearNoise, Bump; event bool NotifyHitWall(vector HitNormal, actor HitActor) { Pawn.SetPhysics(PHYS_Spider); Pawn.SetBase(HitActor, HitNormal); return true; } // if spider mode, update rotation based on floor function UpdateRotation(float DeltaTime, float maxPitch) { local rotator ViewRotation; local vector MyFloor, CrossDir, FwdDir, OldFwdDir, OldX, RealFloor; if ( bInterpolating || Pawn.bInterpolating ) { ViewShake(deltaTime); return; } TurnTarget = None; bRotateToDesired = false; bSetTurnRot = false; if ( (Pawn.Base == None) || (Pawn.Floor == vect(0,0,0)) ) MyFloor = vect(0,0,1); else MyFloor = Pawn.Floor; if ( MyFloor != OldFloor ) { // smoothly change floor RealFloor = MyFloor; MyFloor = Normal(6*DeltaTime * MyFloor + (1 - 6*DeltaTime) * OldFloor); if ( (RealFloor Dot MyFloor) > 0.999 ) MyFloor = RealFloor; else { // translate view direction CrossDir = Normal(RealFloor Cross OldFloor); FwdDir = CrossDir Cross MyFloor; OldFwdDir = CrossDir Cross OldFloor; ViewX = MyFloor * (OldFloor Dot ViewX) + CrossDir * (CrossDir Dot ViewX) + FwdDir * (OldFwdDir Dot ViewX); ViewX = Normal(ViewX); ViewZ = MyFloor * (OldFloor Dot ViewZ) + CrossDir * (CrossDir Dot ViewZ) + FwdDir * (OldFwdDir Dot ViewZ); ViewZ = Normal(ViewZ); OldFloor = MyFloor; ViewY = Normal(MyFloor Cross ViewX); } } if ( (aTurn != 0) || (aLookUp != 0) ) { // adjust Yaw based on aTurn if ( aTurn != 0 ) ViewX = Normal(ViewX + 2 * ViewY * Sin(0.0005*DeltaTime*aTurn)); // adjust Pitch based on aLookUp if ( aLookUp != 0 ) { OldX = ViewX; ViewX = Normal(ViewX + 2 * ViewZ * Sin(0.0005*DeltaTime*aLookUp)); ViewZ = Normal(ViewX Cross ViewY); // bound max pitch if ( (ViewZ Dot MyFloor) < 0.707 ) { OldX = Normal(OldX - MyFloor * (MyFloor Dot OldX)); if ( (ViewX Dot MyFloor) > 0) ViewX = Normal(OldX + MyFloor); else ViewX = Normal(OldX - MyFloor); ViewZ = Normal(ViewX Cross ViewY); } } // calculate new Y axis ViewY = Normal(MyFloor Cross ViewX); } ViewRotation = OrthoRotation(ViewX,ViewY,ViewZ); SetRotation(ViewRotation); ViewShake(deltaTime); ViewFlash(deltaTime); Pawn.FaceRotation(ViewRotation, deltaTime ); } function bool NotifyLanded(vector HitNormal) { Pawn.SetPhysics(PHYS_Spider); return bUpdating; } function bool NotifyPhysicsVolumeChange( PhysicsVolume NewVolume ) { if ( NewVolume.bWaterVolume ) GotoState(Pawn.WaterMovementState); return false; } function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) { local vector OldAccel; OldAccel = Pawn.Acceleration; if ( Pawn.Acceleration != NewAccel ) Pawn.Acceleration = NewAccel; if ( bPressedJump ) Pawn.DoJump(bUpdating); } function PlayerMove( float DeltaTime ) { local vector NewAccel; local eDoubleClickDir DoubleClickMove; local rotator OldRotation, ViewRotation; local bool bSaveJump; GroundPitch = 0; ViewRotation = Rotation; Pawn.CheckBob(DeltaTime,vect(0,0,0)); // Update rotation. SetRotation(ViewRotation); OldRotation = Rotation; UpdateRotation(DeltaTime, 1); // Update acceleration. NewAccel = aForward*Normal(ViewX - OldFloor * (OldFloor Dot ViewX)) + aStrafe*ViewY; if ( VSize(NewAccel) < 1.0 ) NewAccel = vect(0,0,0); if ( bPressedJump && Pawn.CannotJumpNow() ) { bSaveJump = true; bPressedJump = false; } else bSaveJump = false; if ( Role < ROLE_Authority ) // then save this move and replicate it ReplicateMove(DeltaTime, NewAccel, DoubleClickMove, OldRotation - Rotation); else ProcessMove(DeltaTime, NewAccel, DoubleClickMove, OldRotation - Rotation); bPressedJump = bSaveJump; } function BeginState() { if ( Pawn.Mesh == None ) Pawn.SetMesh(); OldFloor = vect(0,0,1); GetAxes(Rotation,ViewX,ViewY,ViewZ); DoubleClickDir = DCLICK_None; Pawn.ShouldCrouch(false); bPressedJump = false; if (Pawn.Physics != PHYS_Falling) Pawn.SetPhysics(PHYS_Spider); GroundPitch = 0; Pawn.bCrawler = true; Pawn.SetCollisionSize(Pawn.Default.CollisionHeight,Pawn.Default.CollisionHeight); } function EndState() { GroundPitch = 0; if ( Pawn != None ) { Pawn.SetCollisionSize(Pawn.Default.CollisionRadius,Pawn.Default.CollisionHeight); Pawn.ShouldCrouch(false); Pawn.bCrawler = Pawn.Default.bCrawler; } } } // Player movement. // Player Swimming state PlayerSwimming { ignores SeePlayer, HearNoise, Bump; function bool WantsSmoothedView() { return ( !Pawn.bJustLanded ); } function bool NotifyLanded(vector HitNormal) { if ( Pawn.PhysicsVolume.bWaterVolume ) Pawn.SetPhysics(PHYS_Swimming); else GotoState(Pawn.LandMovementState); return bUpdating; } function bool NotifyPhysicsVolumeChange( PhysicsVolume NewVolume ) { local actor HitActor; local vector HitLocation, HitNormal, checkpoint; if ( !NewVolume.bWaterVolume ) { Pawn.SetPhysics(PHYS_Falling); if ( Pawn.Velocity.Z > 0 ) { if (Pawn.bUpAndOut && Pawn.CheckWaterJump(HitNormal)) //check for waterjump { Pawn.velocity.Z = FMax(Pawn.JumpZ,420) + 2 * Pawn.CollisionRadius; //set here so physics uses this for remainder of tick GotoState(Pawn.LandMovementState); } else if ( (Pawn.Velocity.Z > 160) || !Pawn.TouchingWaterVolume() ) GotoState(Pawn.LandMovementState); else //check if in deep water { checkpoint = Pawn.Location; checkpoint.Z -= (Pawn.CollisionHeight + 6.0); HitActor = Trace(HitLocation, HitNormal, checkpoint, Pawn.Location, false); if (HitActor != None) GotoState(Pawn.LandMovementState); else { Enable('Timer'); SetTimer(0.7,false); } } } } else { Disable('Timer'); Pawn.SetPhysics(PHYS_Swimming); } return false; } function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) { local vector X,Y,Z, OldAccel; local bool bUpAndOut; GetAxes(Rotation,X,Y,Z); OldAccel = Pawn.Acceleration; if ( Pawn.Acceleration != NewAccel ) Pawn.Acceleration = NewAccel; bUpAndOut = ((X Dot Pawn.Acceleration) > 0) && ((Pawn.Acceleration.Z > 0) || (Rotation.Pitch > 2048)); if ( Pawn.bUpAndOut != bUpAndOut ) Pawn.bUpAndOut = bUpAndOut; if ( !Pawn.PhysicsVolume.bWaterVolume ) //check for waterjump NotifyPhysicsVolumeChange(Pawn.PhysicsVolume); } function PlayerMove(float DeltaTime) { local rotator oldRotation; local vector X,Y,Z, NewAccel; GetAxes(Rotation,X,Y,Z); NewAccel = aForward*X + aStrafe*Y + aUp*vect(0,0,1); if ( VSize(NewAccel) < 1.0 ) NewAccel = vect(0,0,0); //add bobbing when swimming Pawn.CheckBob(DeltaTime, Y); // Update rotation. oldRotation = Rotation; UpdateRotation(DeltaTime, 2); if ( Role < ROLE_Authority ) // then save this move and replicate it ReplicateMove(DeltaTime, NewAccel, DCLICK_None, OldRotation - Rotation); else ProcessMove(DeltaTime, NewAccel, DCLICK_None, OldRotation - Rotation); bPressedJump = false; } function Timer() { if ( !Pawn.PhysicsVolume.bWaterVolume && (Role == ROLE_Authority) ) GotoState(Pawn.LandMovementState); Disable('Timer'); } function BeginState() { Disable('Timer'); Pawn.SetPhysics(PHYS_Swimming); } } state PlayerFlying { ignores SeePlayer, HearNoise, Bump; function PlayerMove(float DeltaTime) { local vector X,Y,Z; GetAxes(Rotation,X,Y,Z); Pawn.Acceleration = aForward*X + aStrafe*Y; if ( VSize(Pawn.Acceleration) < 1.0 ) Pawn.Acceleration = vect(0,0,0); if ( bCheatFlying && (Pawn.Acceleration == vect(0,0,0)) ) Pawn.Velocity = vect(0,0,0); // Update rotation. UpdateRotation(DeltaTime, 2); if ( Role < ROLE_Authority ) // then save this move and replicate it ReplicateMove(DeltaTime, Pawn.Acceleration, DCLICK_None, rot(0,0,0)); else ProcessMove(DeltaTime, Pawn.Acceleration, DCLICK_None, rot(0,0,0)); } function BeginState() { Pawn.SetPhysics(PHYS_Flying); } } state PlayerSpaceFlying { ignores SeePlayer, HearNoise, Bump; function CallServerMove ( float TimeStamp, vector InAccel, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, bool NewbPendingJumpStatus, bool NewbDoubleJump, eDoubleClickDir DoubleClickMove, byte ClientRoll, int View, optional byte OldTimeDelta, optional int OldAccel ) { local Rotator ViewRot; if ( Pawn == None ) ViewRot = Rotation; else ViewRot = Pawn.Rotation; if ( PendingMove != None ) { DualSpaceFighterServerMove ( PendingMove.TimeStamp, PendingMove.Acceleration * 10, PendingMove.bDuck, PendingMove.Rotation.Pitch, PendingMove.Rotation.Yaw, PendingMove.Rotation.Roll, TimeStamp, InAccel, ClientLoc, NewbDuck, ViewRot.Pitch, ViewRot.Yaw, ViewRot.Roll ); } else SpaceFighterServerMove ( TimeStamp, InAccel, ClientLoc, NewbDuck, ViewRot.Pitch, ViewRot.Yaw, ViewRot.Roll ); } /* ServerMove() - replicated function sent by client to server - contains client movement and firing info Passes acceleration in components so it doesn't get rounded. IGNORE VANILLA SERVER MOVES */ function ServerMove ( float TimeStamp, vector InAccel, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, bool NewbDoubleJump, eDoubleClickDir DoubleClickMove, byte ClientRoll, int View, optional byte OldTimeDelta, optional int OldAccel ) { // If this move is outdated, discard it. if ( CurrentTimeStamp >= TimeStamp ) return; if ( AcknowledgedPawn != Pawn ) { OldTimeDelta = 0; InAccel = vect(0,0,0); } else Pawn.AutonomousPhysics(TimeStamp - CurrentTimeStamp); CurrentTimeStamp = TimeStamp; ServerTimeStamp = Level.TimeSeconds; } function PlayerMove(float DeltaTime) { if ( Pawn == None ) { GotoState('dead'); return; } Pawn.UpdateRocketAcceleration(DeltaTime, aTurn, aLookUp); SetRotation( Pawn.Rotation ); ViewShake( DeltaTime ); ViewFlash( DeltaTime ); if ( Role < ROLE_Authority ) // then save this move and replicate it ReplicateMove(DeltaTime, Pawn.Acceleration, DCLICK_None, Pawn.Rotation ); else ProcessMove(DeltaTime, Pawn.Acceleration, DCLICK_None, rot(0,0,0)); } function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) { if ( Pawn == None ) return; if ( Pawn.Acceleration != NewAccel ) Pawn.Acceleration = NewAccel; if ( DeltaRot != rot(0,0,0) ) { if ( Pawn.Rotation != DeltaRot ) Pawn.SetRotation( DeltaRot ); if ( Rotation != DeltaRot ) SetRotation( DeltaRot ); } Pawn.Velocity = Pawn.Acceleration * Pawn.AirSpeed * 0.001; Pawn.ProcessMove(DeltaTime, NewAccel, DoubleClickMove, DeltaRot); } function BeginState() { if ( Pawn != None ) Pawn.SetPhysics( PHYS_Flying ); RotationRate.Pitch = 8192; // extending pitch limit bIsSpaceFighter = true; } function EndState() { RotationRate.Pitch = default.RotationRate.Pitch; // restoring pitch limit bIsSpaceFighter = false; } } state PlayerRocketing { ignores SeePlayer, HearNoise, Bump; function CallServerMove ( float TimeStamp, vector InAccel, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, bool NewbPendingJumpStatus, bool NewbDoubleJump, eDoubleClickDir DoubleClickMove, byte ClientRoll, int View, optional byte OldTimeDelta, optional int OldAccel ) { if ( PendingMove != None ) { DualRocketServerMove ( PendingMove.TimeStamp, PendingMove.Acceleration * 10, PendingMove.bDuck, ((PendingMove.Rotation.Roll >> 8) & 255), (32767 & (PendingMove.Rotation.Pitch/2)) * 32768 + (32767 & (PendingMove.Rotation.Yaw/2)), TimeStamp, InAccel, ClientLoc, NewbDuck, ClientRoll, View ); } else RocketServerMove ( TimeStamp, InAccel, ClientLoc, NewbDuck, ClientRoll, View ); } /* ServerMove() - replicated function sent by client to server - contains client movement and firing info Passes acceleration in components so it doesn't get rounded. IGNORE VANILLA SERVER MOVES */ function ServerMove ( float TimeStamp, vector InAccel, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, bool NewbDoubleJump, eDoubleClickDir DoubleClickMove, byte ClientRoll, int View, optional byte OldTimeDelta, optional int OldAccel ) { // If this move is outdated, discard it. if ( CurrentTimeStamp >= TimeStamp ) return; if ( !CheckSpeedHack(TimeStamp - CurrentTimeStamp) ) { if ( !bWasSpeedHack ) { if ( Level.TimeSeconds - LastSpeedHackLog > 20 ) { log("Possible speed hack by "$PlayerReplicationInfo.PlayerName); LastSpeedHackLog = Level.TimeSeconds; } ClientMessage( "Speed Hack Detected!",'CriticalEvent' ); } else bWasSpeedHack = true; } else { if ( AcknowledgedPawn != Pawn ) { OldTimeDelta = 0; InAccel = vect(0,0,0); } else Pawn.AutonomousPhysics(TimeStamp - CurrentTimeStamp); } CurrentTimeStamp = TimeStamp; ServerTimeStamp = Level.TimeSeconds; } function RocketServerMove ( float TimeStamp, vector InAccel, vector ClientLoc, bool NewbDuck, byte ClientRoll, int View ) { Global.ServerMove(TimeStamp,InAccel,ClientLoc,false,NewbDuck,false,false, DCLICK_NONE,ClientRoll,View); } function DualRocketServerMove ( float TimeStamp0, vector InAccel0, bool NewbDuck0, byte ClientRoll0, int View0, float TimeStamp, vector InAccel, vector ClientLoc, bool NewbDuck, byte ClientRoll, int View ) { Global.ServerMove(TimeStamp0,InAccel0,vect(0,0,0),false,NewbDuck0,false,false, DCLICK_NONE,ClientRoll0,View0); Global.ServerMove(TimeStamp,InAccel,ClientLoc,false,NewbDuck,false,false, DCLICK_NONE,ClientRoll,View); } function PlayerMove(float DeltaTime) { Pawn.UpdateRocketAcceleration(DeltaTime,aTurn,aLookUp); SetRotation(Pawn.Rotation); if ( Role < ROLE_Authority ) // then save this move and replicate it ReplicateMove(DeltaTime, Pawn.Acceleration, DCLICK_None, rot(0,0,0)); else ProcessMove(DeltaTime, Pawn.Acceleration, DCLICK_None, rot(0,0,0)); } function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) { if ( Pawn == None ) return; if ( Pawn.Acceleration != NewAccel ) Pawn.Acceleration = NewAccel; } function BeginState() { if ( Pawn != None ) Pawn.SetPhysics( PHYS_Flying ); RotationRate.Pitch = 8192; // extending pitch limit (limits network weapon aiming) } function EndState() { RotationRate.Pitch = default.RotationRate.Pitch; // restoring pitch limit } } state PlayerTurreting { ignores SeePlayer, HearNoise, Bump; function CallServerMove ( float TimeStamp, vector InAccel, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, bool NewbPendingJumpStatus, bool NewbDoubleJump, eDoubleClickDir DoubleClickMove, byte ClientRoll, int View, optional byte OldTimeDelta, optional int OldAccel ) { if ( PendingMove != None ) { DualTurretServerMove ( PendingMove.TimeStamp, PendingMove.bDuck, ((PendingMove.Rotation.Roll >> 8) & 255), (32767 & (PendingMove.Rotation.Pitch/2)) * 32768 + (32767 & (PendingMove.Rotation.Yaw/2)), TimeStamp, ClientLoc, NewbDuck, ClientRoll, View ); } else TurretServerMove ( TimeStamp, ClientLoc, NewbDuck, ClientRoll, View ); } /* ServerMove() - replicated function sent by client to server - contains client movement and firing info Passes acceleration in components so it doesn't get rounded. IGNORE VANILLA SERVER MOVES */ function ServerMove ( float TimeStamp, vector InAccel, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, bool NewbDoubleJump, eDoubleClickDir DoubleClickMove, byte ClientRoll, int View, optional byte OldTimeDelta, optional int OldAccel ) { // If this move is outdated, discard it. if ( CurrentTimeStamp >= TimeStamp ) return; if ( AcknowledgedPawn != Pawn ) { OldTimeDelta = 0; InAccel = vect(0,0,0); } if ( AcknowledgedPawn == Pawn && CurrentTimeStamp < TimeStamp ) Pawn.AutonomousPhysics(TimeStamp - CurrentTimeStamp); CurrentTimeStamp = TimeStamp; ServerTimeStamp = Level.TimeSeconds; } function TurretServerMove ( float TimeStamp, vector ClientLoc, bool NewbDuck, byte ClientRoll, int View ) { Global.ServerMove(TimeStamp,Vect(0,0,0),ClientLoc,false,NewbDuck,false,false, DCLICK_NONE,ClientRoll,View); } /* DualTurretServerMove() compressed version of server move for PlayerTurreting state */ function DualTurretServerMove ( float TimeStamp0, bool NewbDuck0, byte ClientRoll0, int View0, float TimeStamp, vector ClientLoc, bool NewbDuck, byte ClientRoll, int View ) { Global.ServerMove(TimeStamp0,Vect(0,0,0),vect(0,0,0),false,NewbDuck0,false,false, DCLICK_NONE,ClientRoll0,View0); Global.ServerMove(TimeStamp,Vect(0,0,0),ClientLoc,false,NewbDuck,false,false, DCLICK_NONE,ClientRoll,View); } function PlayerMove(float DeltaTime) { local Vehicle CurrentVehicle; if ( Pawn == None ) { GotoState('dead'); return; } Pawn.UpdateRocketAcceleration(DeltaTime, aTurn, aLookUp); if ( !bFreeCamera ) SetRotation( Pawn.Rotation ); ViewShake( deltaTime ); ViewFlash( deltaTime ); if ( Role < ROLE_Authority ) // then save this move and replicate it ReplicateMove(DeltaTime, Pawn.Acceleration, DCLICK_None, rot(0,0,0)); else ProcessMove(DeltaTime, Pawn.Acceleration, DCLICK_None, rot(0,0,0)); CurrentVehicle = Vehicle(Pawn); if ( CurrentVehicle != None ) { if ( bFire == 0 && CurrentVehicle.bWeaponIsFiring ) CurrentVehicle.ClientVehicleCeaseFire( false ); if ( bAltFire == 0 && CurrentVehicle.bWeaponIsAltFiring ) CurrentVehicle.ClientVehicleCeaseFire( true ); } } function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) { if ( Pawn == None ) return; Pawn.Acceleration = newAccel; } function BeginState() { if ( Pawn != None ) Pawn.SetPhysics( PHYS_Flying ); RotationRate.Pitch = 16384; // extending pitch limit (limits network weapon aiming) } function EndState() { RotationRate.Pitch = default.RotationRate.Pitch; // restoring pitch limit } Begin: } function bool IsSpectating() { return false; } state BaseSpectating { function bool IsSpectating() { return true; } function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot) { Acceleration = NewAccel; MoveSmooth(SpectateSpeed * Normal(Acceleration) * DeltaTime); } function PlayerMove(float DeltaTime) { local vector X,Y,Z; if ( (Pawn(ViewTarget) != None) && (Level.NetMode == NM_Client) ) { if ( Pawn(ViewTarget).bSimulateGravity ) TargetViewRotation.Roll = 0; BlendedTargetViewRotation.Pitch = BlendRot(DeltaTime, BlendedTargetViewRotation.Pitch, TargetViewRotation.Pitch & 65535); BlendedTargetViewRotation.Yaw = BlendRot(DeltaTime, BlendedTargetViewRotation.Yaw, TargetViewRotation.Yaw & 65535); BlendedTargetViewRotation.Roll = BlendRot(DeltaTime, BlendedTargetViewRotation.Roll, TargetViewRotation.Roll & 65535); } GetAxes(Rotation,X,Y,Z); Acceleration = 0.02 * (aForward*X + aStrafe*Y + aUp*vect(0,0,1)); UpdateRotation(DeltaTime, 1); if ( Role < ROLE_Authority ) // then save this move and replicate it ReplicateMove(DeltaTime, Acceleration, DCLICK_None, rot(0,0,0)); else ProcessMove(DeltaTime, Acceleration, DCLICK_None, rot(0,0,0)); } } state Scripting { // FIXME - IF HIT FIRE, AND NOT bInterpolating, Leave script exec function Fire( optional float F ) { } exec function AltFire( optional float F ) { Fire(F); } } function ServerViewNextPlayer() { local Controller C, Pick; local bool bFound, bRealSpec, bWasSpec; local TeamInfo RealTeam; bRealSpec = PlayerReplicationInfo.bOnlySpectator; bWasSpec = !bBehindView && (ViewTarget != Pawn) && (ViewTarget != self); PlayerReplicationInfo.bOnlySpectator = true; RealTeam = PlayerReplicationInfo.Team; // view next player for ( C=Level.ControllerList; C!=None; C=C.NextController ) { if ( bRealSpec && (C.PlayerReplicationInfo != None) ) // hack fix for invasion spectating PlayerReplicationInfo.Team = C.PlayerReplicationInfo.Team; if ( Level.Game.CanSpectate(self,bRealSpec,C) ) { if ( Pick == None ) Pick = C; if ( bFound ) { Pick = C; break; } else bFound = ( (RealViewTarget == C) || (ViewTarget == C) ); } } PlayerReplicationInfo.Team = RealTeam; SetViewTarget(Pick); ClientSetViewTarget(Pick); if ( (ViewTarget == self) || bWasSpec ) bBehindView = false; else bBehindView = true; //bChaseCam; ClientSetBehindView(bBehindView); PlayerReplicationInfo.bOnlySpectator = bRealSpec; } function ServerViewSelf() { SetLocation(ViewTarget.Location); ClientSetLocation(ViewTarget.Location, Rotation); bBehindView = false; SetViewTarget(self); ClientSetViewTarget(self); ClientMessage(OwnCamera, 'Event'); } function LoadPlayers() { local int i; if ( GameReplicationInfo == None ) return; for ( i=0; i 1.0) ) bFrozen = false; return; } ServerViewNextPlayer(); } // Return to spectator's own camera. exec function AltFire( optional float F ) { bBehindView = false; ServerViewSelf(); } function Timer() { bFrozen = false; } function BeginState() { if ( Pawn != None ) { SetLocation(Pawn.Location); UnPossess(); } bCollideWorld = true; CameraDist = Default.CameraDist; } function EndState() { PlayerReplicationInfo.bIsSpectator = false; bCollideWorld = false; } } state AttractMode extends Spectating { } auto state PlayerWaiting extends BaseSpectating { ignores SeePlayer, HearNoise, NotifyBump, TakeDamage, PhysicsVolumeChange, NextWeapon, PrevWeapon, SwitchToBestWeapon; exec function Jump( optional float F ) { } exec function Suicide() { } function ServerRestartPlayer() { if ( Level.TimeSeconds < WaitDelay ) return; if ( Level.NetMode == NM_Client ) return; if ( Level.Game.bWaitingToStartMatch ) PlayerReplicationInfo.bReadyToPlay = true; else Level.Game.RestartPlayer(self); } exec function Fire(optional float F) { LoadPlayers(); if ( !bForcePrecache && (Level.TimeSeconds > 0.2) ) ServerReStartPlayer(); } exec function AltFire(optional float F) { Fire(F); } function EndState() { if ( Pawn != None ) Pawn.SetMesh(); if ( PlayerReplicationInfo != None ) PlayerReplicationInfo.SetWaitingPlayer(false); bCollideWorld = false; } function BeginState() { CameraDist = Default.CameraDist; if ( PlayerReplicationInfo != None ) PlayerReplicationInfo.SetWaitingPlayer(true); bCollideWorld = true; } } state WaitingForPawn extends BaseSpectating { ignores SeePlayer, HearNoise, KilledBy, SwitchWeapon; exec function Fire( optional float F ) { AskForPawn(); } exec function AltFire( optional float F ) { } function LongClientAdjustPosition ( float TimeStamp, name newState, EPhysics newPhysics, float NewLocX, float NewLocY, float NewLocZ, float NewVelX, float NewVelY, float NewVelZ, Actor NewBase, float NewFloorX, float NewFloorY, float NewFloorZ ) { if ( newState == 'GameEnded' || newState == 'RoundEnded' ) GotoState(newState); } function PlayerTick(float DeltaTime) { Global.PlayerTick(DeltaTime); if ( Pawn != None ) { Pawn.Controller = self; Pawn.bUpdateEyeHeight = true; //log("Client restart in waitingforpawn"); ClientRestart(Pawn); } else if ( (TimerRate <= 0.0) || (TimerRate > 1.0) ) { SetTimer(0.2,true); AskForPawn(); } } function Timer() { AskForPawn(); } function BeginState() { SetTimer(0.2, true); AskForPawn(); } function EndState() { bBehindView = false; SetTimer(0.0, false); } } state GameEnded { ignores SeePlayer, HearNoise, KilledBy, NotifyBump, HitWall, NotifyHeadVolumeChange, NotifyPhysicsVolumeChange, Falling, TakeDamage, Suicide; function ServerReStartPlayer() { } function bool IsSpectating() { return true; } exec function Use() {} exec function SwitchWeapon(byte T) {} exec function ThrowWeapon() {} function Possess(Pawn aPawn) { Global.Possess(aPawn); if (Pawn != None) Pawn.TurnOff(); } function ServerReStartGame() { if ( Level.Game.PlayerCanRestartGame( Self ) ) Level.Game.RestartGame(); } exec function Fire( optional float F ) { if ( Role < ROLE_Authority) return; if ( !bFrozen ) ServerReStartGame(); else if ( TimerRate <= 0 ) SetTimer(1.5, false); } exec function AltFire( optional float F ) { Fire(F); } function PlayerMove(float DeltaTime) { local vector X,Y,Z; local Rotator ViewRotation; GetAxes(Rotation,X,Y,Z); // Update view rotation. if ( !bFixedCamera ) { ViewRotation = Rotation; ViewRotation.Yaw += 32.0 * DeltaTime * aTurn; ViewRotation.Pitch += 32.0 * DeltaTime * aLookUp; if (Pawn != None) ViewRotation.Pitch = Pawn.LimitPitch(ViewRotation.Pitch); SetRotation(ViewRotation); } else if ( ViewTarget != None ) SetRotation(ViewTarget.Rotation); ViewShake(DeltaTime); ViewFlash(DeltaTime); if ( Role < ROLE_Authority ) // then save this move and replicate it ReplicateMove(DeltaTime, vect(0,0,0), DCLICK_None, rot(0,0,0)); else ProcessMove(DeltaTime, vect(0,0,0), DCLICK_None, rot(0,0,0)); bPressedJump = false; } function ServerMove ( float TimeStamp, vector InAccel, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, bool NewbDoubleJump, eDoubleClickDir DoubleClickMove, byte ClientRoll, int View, optional byte OldTimeDelta, optional int OldAccel ) { Global.ServerMove(TimeStamp, InAccel, ClientLoc, NewbRun, NewbDuck, NewbJumpStatus,NewbDoubleJump, DoubleClickMove, ClientRoll, (32767 & (Rotation.Pitch/2)) * 32768 + (32767 & (Rotation.Yaw/2)) ); } function FindGoodView() { local vector cameraLoc; local rotator cameraRot, ViewRotation; local int tries, besttry; local float bestdist, newdist; local int startYaw; local actor ViewActor; ViewRotation = Rotation; ViewRotation.Pitch = 56000; tries = 0; besttry = 0; bestdist = 0.0; startYaw = ViewRotation.Yaw; for (tries=0; tries<16; tries++) { cameraLoc = ViewTarget.Location; SetRotation(ViewRotation); PlayerCalcView(ViewActor, cameraLoc, cameraRot); newdist = VSize(cameraLoc - ViewTarget.Location); if (newdist > bestdist) { bestdist = newdist; besttry = tries; } ViewRotation.Yaw += 4096; } ViewRotation.Yaw = startYaw + besttry * 4096; SetRotation(ViewRotation); } function Timer() { bFrozen = false; } function LongClientAdjustPosition ( float TimeStamp, name newState, EPhysics newPhysics, float NewLocX, float NewLocY, float NewLocZ, float NewVelX, float NewVelY, float NewVelZ, Actor NewBase, float NewFloorX, float NewFloorY, float NewFloorZ ) { } function BeginState() { local Pawn P; EndZoom(); StopForceFeedback(); CameraDist = Default.CameraDist; FOVAngle = DesiredFOV; bFire = 0; bAltFire = 0; if ( Pawn != None ) { if ( Vehicle(Pawn) != None ) Pawn.StopWeaponFiring(); Pawn.TurnOff(); Pawn.bSpecialHUD = false; Pawn.SimAnim.AnimRate = 0; if ( Pawn.Weapon != None ) { Pawn.Weapon.StopFire(0); Pawn.Weapon.StopFire(1); Pawn.Weapon.bEndOfRound = true; } } bFrozen = true; if ( !bFixedCamera ) { FindGoodView(); bBehindView = true; } SetTimer(5, false); ForEach DynamicActors(class'Pawn', P) { if ( P.Role == ROLE_Authority ) P.RemoteRole = ROLE_DumbProxy; P.TurnOff(); } } Begin: } state RoundEnded { ignores SeePlayer, HearNoise, KilledBy, NotifyBump, HitWall, NotifyHeadVolumeChange, NotifyPhysicsVolumeChange, Falling, TakeDamage, Suicide; function ServerReStartPlayer() { } function bool IsSpectating() { return true; } exec function Use() {} exec function SwitchWeapon(byte T) {} exec function ThrowWeapon() {} exec function Fire(optional float F) {} exec function AltFire(optional float F) {} function Possess(Pawn aPawn) { Global.Possess(aPawn); if (Pawn != None) Pawn.TurnOff(); } function PlayerMove(float DeltaTime) { local vector X,Y,Z; local Rotator ViewRotation; GetAxes(Rotation,X,Y,Z); // Update view rotation. if ( !bFixedCamera ) { ViewRotation = Rotation; ViewRotation.Yaw += 32.0 * DeltaTime * aTurn; ViewRotation.Pitch += 32.0 * DeltaTime * aLookUp; if (Pawn != None) ViewRotation.Pitch = Pawn.LimitPitch(ViewRotation.Pitch); SetRotation(ViewRotation); } else if ( ViewTarget != None ) SetRotation( ViewTarget.Rotation ); ViewShake( DeltaTime ); ViewFlash( DeltaTime ); if ( Role < ROLE_Authority ) // then save this move and replicate it ReplicateMove(DeltaTime, vect(0,0,0), DCLICK_None, rot(0,0,0)); else ProcessMove(DeltaTime, vect(0,0,0), DCLICK_None, rot(0,0,0)); bPressedJump = false; } function ServerMove ( float TimeStamp, vector InAccel, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, bool NewbDoubleJump, eDoubleClickDir DoubleClickMove, byte ClientRoll, int View, optional byte OldTimeDelta, optional int OldAccel ) { Global.ServerMove(TimeStamp, InAccel, ClientLoc, NewbRun, NewbDuck, NewbJumpStatus,NewbDoubleJump, DoubleClickMove, ClientRoll, (32767 & (Rotation.Pitch/2)) * 32768 + (32767 & (Rotation.Yaw/2)) ); } function FindGoodView() { local vector cameraLoc; local rotator cameraRot, ViewRotation; local int tries, besttry; local float bestdist, newdist; local int startYaw; local actor ViewActor; ViewRotation = Rotation; ViewRotation.Pitch = 56000; tries = 0; besttry = 0; bestdist = 0.0; startYaw = ViewRotation.Yaw; for (tries=0; tries<16; tries++) { cameraLoc = ViewTarget.Location; SetRotation(ViewRotation); PlayerCalcView(ViewActor, cameraLoc, cameraRot); newdist = VSize(cameraLoc - ViewTarget.Location); if ( newdist > bestdist ) { bestdist = newdist; besttry = tries; } ViewRotation.Yaw += 4096; } ViewRotation.Yaw = startYaw + besttry * 4096; SetRotation(ViewRotation); } function Timer() { bFrozen = false; } function LongClientAdjustPosition ( float TimeStamp, name newState, EPhysics newPhysics, float NewLocX, float NewLocY, float NewLocZ, float NewVelX, float NewVelY, float NewVelZ, Actor NewBase, float NewFloorX, float NewFloorY, float NewFloorZ ) { if ( newState == 'PlayerWaiting' ) GotoState( newState ); } function BeginState() { local Pawn P; EndZoom(); CameraDist = Default.CameraDist; FOVAngle = DesiredFOV; bFire = 0; bAltFire = 0; if ( Pawn != None ) { if ( Vehicle(Pawn) != None ) Pawn.StopWeaponFiring(); Pawn.TurnOff(); Pawn.bSpecialHUD = false; Pawn.SimAnim.AnimRate = 0; if ( Pawn.Weapon != None ) { Pawn.Weapon.StopFire(0); Pawn.Weapon.StopFire(1); Pawn.Weapon.bEndOfRound = true; } } bFrozen = true; bBehindView = true; if ( !bFixedCamera ) FindGoodView(); SetTimer(5, false); ForEach DynamicActors(class'Pawn', P) { if ( P.Role == ROLE_Authority ) P.RemoteRole = ROLE_DumbProxy; P.TurnOff(); } StopForceFeedback(); } function CalcBehindView(out vector CameraLocation, out rotator CameraRotation, float Dist) { local vector View; local float ViewDist,RealDist; local vector globalX,globalY,globalZ; local vector localX,localY,localZ; local vector HitLocation,HitNormal; local Actor HitActor; CameraRotation = Rotation; CameraRotation.Roll = 0; CameraLocation.Z += 12; // add view rotation offset to cameraview (amb) CameraRotation += CameraDeltaRotation; View = vect(1,0,0) >> CameraRotation; // add view radius offset to camera location and move viewpoint up from origin (amb) RealDist = Dist; Dist += CameraDeltaRad; HitActor = Trace( HitLocation, HitNormal, CameraLocation - Dist * vector(CameraRotation), CameraLocation,false,vect(10,10,10)); if ( HitActor != None && !HitActor.IsA('BlockingVolume') ) ViewDist = FMin( (CameraLocation - HitLocation) Dot View, Dist ); else ViewDist = Dist; if ( !bBlockCloseCamera || !bValidBehindCamera || (ViewDist > 10 + FMax(ViewTarget.CollisionRadius, ViewTarget.CollisionHeight)) ) { //Log("Update Cam "); bValidBehindCamera = true; OldCameraLoc = CameraLocation - ViewDist * View; OldCameraRot = CameraRotation; } else { //Log("Dont Update Cam "$bBlockCloseCamera@bValidBehindCamera@ViewDist); SetRotation(OldCameraRot); } CameraLocation = OldCameraLoc; CameraRotation = OldCameraRot; // add view swivel rotation to cameraview (amb) GetAxes(CameraSwivel,globalX,globalY,globalZ); localX = globalX >> CameraRotation; localY = globalY >> CameraRotation; localZ = globalZ >> CameraRotation; CameraRotation = OrthoRotation(localX,localY,localZ); } Begin: } state Dead { ignores SeePlayer, HearNoise, KilledBy, SwitchWeapon, NextWeapon, PrevWeapon; exec function ThrowWeapon() { //clientmessage("Throwweapon while dead, pawn "$Pawn$" health "$Pawn.health); } function bool IsDead() { return true; } function ServerReStartPlayer() { if ( !Level.Game.PlayerCanRestart( Self ) ) return; super.ServerRestartPlayer(); } exec function Fire( optional float F ) { if ( bFrozen ) { if ( (TimerRate <= 0.0) || (TimerRate > 1.0) ) bFrozen = false; return; } LoadPlayers(); if (bMenuBeforeRespawn) { bMenuBeforeRespawn = false; ShowMidGameMenu(false); } else ServerReStartPlayer(); } exec function AltFire( optional float F ) { Fire(F); } exec function Use() { if ( bFrozen ) { if ( (TimerRate <= 0.0) || (TimerRate > 1.0) ) bFrozen = false; return; } if ( Level.Game != None ) Level.Game.DeadUse(self); } function ServerMove ( float TimeStamp, vector Accel, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, bool NewbDoubleJump, eDoubleClickDir DoubleClickMove, byte ClientRoll, int View, optional byte OldTimeDelta, optional int OldAccel ) { Global.ServerMove( TimeStamp, Accel, ClientLoc, false, false, false, false, DoubleClickMove, ClientRoll, View); } function PlayerMove(float DeltaTime) { local vector X,Y,Z; local rotator ViewRotation; if ( !bFrozen ) { if ( bPressedJump ) { Fire(0); bPressedJump = false; } GetAxes(Rotation,X,Y,Z); // Update view rotation. ViewRotation = Rotation; ViewRotation.Yaw += 32.0 * DeltaTime * aTurn; ViewRotation.Pitch += 32.0 * DeltaTime * aLookUp; if (Pawn != None) ViewRotation.Pitch = Pawn.LimitPitch(ViewRotation.Pitch); SetRotation(ViewRotation); if ( Role < ROLE_Authority ) // then save this move and replicate it ReplicateMove(DeltaTime, vect(0,0,0), DCLICK_None, rot(0,0,0)); } else if ( (TimerRate <= 0.0) || (TimerRate > 1.0) ) bFrozen = false; ViewShake(DeltaTime); ViewFlash(DeltaTime); } function FindGoodView() { local vector cameraLoc; local rotator cameraRot, ViewRotation; local int tries, besttry; local float bestdist, newdist; local int startYaw; local actor ViewActor; ////log("Find good death scene view"); ViewRotation = Rotation; ViewRotation.Pitch = 56000; tries = 0; besttry = 0; bestdist = 0.0; startYaw = ViewRotation.Yaw; for (tries=0; tries<16; tries++) { cameraLoc = ViewTarget.Location; SetRotation(ViewRotation); PlayerCalcView(ViewActor, cameraLoc, cameraRot); newdist = VSize(cameraLoc - ViewTarget.Location); if (newdist > bestdist) { bestdist = newdist; besttry = tries; } ViewRotation.Yaw += 4096; } ViewRotation.Yaw = startYaw + besttry * 4096; SetRotation(ViewRotation); } function Timer() { if (!bFrozen) return; bFrozen = false; bPressedJump = false; } function BeginState() { local Actor A; if ( (Pawn != None) && ((Pawn.Controller == self) || (Pawn.Controller == None)) ) Pawn.Controller = None; EndZoom(); CameraDist = Default.CameraDist; FOVAngle = DesiredFOV; Pawn = None; Enemy = None; bBehindView = true; bFrozen = true; bJumpStatus = false; bPressedJump = false; bBlockCloseCamera = true; bValidBehindCamera = false; bFreeCamera = False; if ( Viewport(Player) != None ) ForEach DynamicActors(class'Actor',A) A.NotifyLocalPlayerDead(self); FindGoodView(); SetTimer(1.0, false); StopForceFeedback(); ClientPlayForceFeedback("Damage"); // jdf CleanOutSavedMoves(); } function EndState() { StopForceFeedback(); bBlockCloseCamera = false; CleanOutSavedMoves(); Velocity = vect(0,0,0); Acceleration = vect(0,0,0); if ( !PlayerReplicationInfo.bOutOfLives ) bBehindView = false; bPressedJump = false; if ( myHUD != None ) myHUD.bShowScoreBoard = false; StopViewShaking(); } Begin: Sleep(3.0); if ( myHUD != None ) myHUD.bShowScoreBoard = true; } //------------------------------------------------------------------------------ // Control options function ChangeStairLook( bool B ) { bLookUpStairs = B; if ( bLookUpStairs ) bAlwaysMouseLook = false; } function ChangeAlwaysMouseLook(Bool B) { bAlwaysMouseLook = B; if ( bAlwaysMouseLook ) bLookUpStairs = false; } singular event UnPressButtons() { bFire = 0; bAltFire = 0; bDuck = 0; bRun = 0; bVoiceTalk = 0; ResetInput(); } // Replace with good code event ClientOpenMenu (string Menu, optional bool bDisconnect,optional string Msg1, optional string Msg2) { // GUIController calls UnpressButtons() after it's been activated...once active, it swallows // all input events, preventing GameEngine from parsing script execs commands -- rjp if ( !Player.GUIController.OpenMenu(Menu, Msg1, Msg2) ) UnPressButtons(); if (bDisconnect) { // Use delayed console command, in case the menu that was opened had bDisconnectOnOpen=True -- rjp if ( Player.Console != None ) Player.Console.DelayedConsoleCommand("DISCONNECT"); else ConsoleCommand("Disconnect"); } } event ClientReplaceMenu(string Menu, optional bool bDisconnect,optional string Msg1, optional string Msg2) { if ( !Player.GUIController.bActive ) { if ( !Player.GUIController.ReplaceMenu(Menu,Msg1,Msg2) ) UnpressButtons(); } else Player.GUIController.ReplaceMenu(Menu,Msg1,Msg2); if (bDisconnect) { if ( Player.Console != None ) Player.Console.DelayedConsoleCommand("Disconnect"); else ConsoleCommand("Disconnect"); } } event ClientCloseMenu(optional bool bCloseAll, optional bool bCancel) { if (bCloseAll) Player.GUIController.CloseAll(bCancel,True); else Player.GUIController.CloseMenu(bCancel); } event ClientNetworkMessage(string ParamA, string ParamB) { ClientOpenMenu(Player.GUIController.NetworkMsgMenu, true, ParamA, ParamB); } simulated function bool IsMouseInverted() { return PlayerInput.bInvertMouse; } exec function InvertMouse(optional string Invert) { PlayerInput.InvertMouse(Invert); } exec function InvertLook() { local bool result; result = PlayerInput.InvertLook(); if (IsOnConsole()) { class'XBoxPlayerInput'.default.bInvertVLook = result; class'XBoxPlayerInput'.static.StaticSaveConfig(); } } function bool CanRestartPlayer() { return !PlayerReplicationInfo.bOnlySpectator; } ///////////////////////////////////////////////////////////////////////////// // Admin Handling : Was previously in Admin.uc // // // // Execute an administrative console command on the server. exec function Admin( string CommandLine ) { local string Result; if (AdminManager != None) { if ( Level.Game.AccessControl == None || !Level.Game.AccessControl.CanPerform(Self, "Xc") ) return; Result = ConsoleCommand( CommandLine ); if (Level.Game.AccessControl.bReplyToGUI) AdminReply(Result); else if( Result != "" ) ClientMessage( Result ); } } exec function AdminDebug( string CommandLine ) { if ( AdminManager != None ) { if ( Level.Game.AccessControl == None || !Level.Game.AccessControl.CanPerform(Self, "Xc") ) return; ConsoleCommand(CommandLine, True); } } exec function AdminLogin(string CmdLine) { if ( Level.TimeSeconds < NextLoginTime ) return; NextLoginTime = Level.TimeSeconds + LoginDelay; ServerAdminLogin(CmdLine); } function ServerAdminLogin( string CmdLine ) { local string uname, upass; if (AdminManager == None) { MakeAdmin(); if ( AdminManager != None ) { if ( !Divide(CmdLine, " ", uname, upass) ) upass = CmdLine; AdminManager.DoLogin(uname, upass); if ( !AdminManager.bAdmin ) AdminManager = None; else AddCheats(); } } } function AdminCommand( string CommandLine ) { if (Left(CommandLine, 11) ~= "AdminLogin ") { AdminLogin(Mid(CommandLine, 11)); ReportAdmin("adv="$Level.Game.AccessControl.IsA('AccessControlIni')); } else if (Left(CommandLine, 11) ~= "AdminLogout") { AdminLogout(); ReportAdmin(); } else if (Level.Game.AccessControl != None) { Level.Game.AccessControl.bReplyToGUI = true; Admin(CommandLine); Level.Game.AccessControl.bReplyToGUI = false; } } function ReportAdmin(optional string ReportText) { local string str; if (AdminManager != None && AdminManager.bAdmin) { if (Level.Game.AccessControl != None) { str = "name=" $ Level.Game.AccessControl.GetAdminName(Self); if ( ReportText != "" ) str $= ";" $ ReportText; } else { str = "name=Admin"; if ( ReportText != "" ) str $= ";" $ ReportText; } } else str = ReportText; AdminReply(str); } function AdminReply( string Reply ) { if (Player.GUIController != None) Player.GUIController.OnAdminReply(Reply); } exec function AdminLogout() { if (AdminManager != None) { AdminManager.DoLogout(); if (!AdminManager.bAdmin) AdminManager = None; } } exec function AdminGUI() { } ///////////////////////////////////////////////////////////////////////////// // // Demo Recording // // // Called on the client during client-side demo recording simulated event StartClientDemoRec() { // Here we replicate functions which the demo never saw. DemoClientSetHUD( MyHud.Class, MyHud.ScoreBoard.Class ); // tell server to replicate more stuff to me bClientDemo = true; ServerSetClientDemo(); } function ServerSetClientDemo() { bClientDemo = true; } // Called on the playback client during client-side demo playback simulated function DemoClientSetHUD(class newHUDClass, class newScoringClass ) { if( MyHUD == None ) ClientSetHUD( newHUDClass, newScoringClass ); } simulated function string GetCustomStatusAnnouncerClass() { return ""; } simulated function string GetCustomRewardAnnouncerClass() { return ""; } simulated function SetCustomStatusAnnouncerClass(string NewAnnouncerClass); simulated function SetCustomRewardAnnouncerClass(string NewAnnouncerClass); simulated function bool NeedNetNotify() { return false; } ///////////////////////////////////////////////////////////////////////////// // // Voice Recognition // // event VoiceCommand( string RecognizedString, string RawString ) { log(RecognizedString); TeamMessage( PlayerReplicationInfo, RawString, 'TeamSayQuiet' ); if ( RecognizedString != "" ) ServerVoiceCommand(RecognizedString); } exec function command(string RecognizedString) { Level.Game.ParseVoiceCommand( self, RecognizedString ); } function ServerVoiceCommand(string RecognizedString) { Level.Game.ParseVoiceCommand( self, RecognizedString ); } // ===================================================================================================================== // ===================================================================================================================== // Voice Chat // ===================================================================================================================== // ===================================================================================================================== // Join a voice chatroom by name exec function Join(string ChanName, string ChanPwd) { local int i, idx; local VoiceChatRoom VCR; if (VoiceReplicationInfo == None || !VoiceReplicationInfo.bEnableVoiceChat ) return; for (i = 0; i < StoredChatPasswords.Length; i++) { if (ChanName ~= StoredChatPasswords[i].ChatRoomName) { if ( ChanPwd == "" ) ChanPwd = StoredChatPasswords[i].ChatRoomPassword; else { StoredChatPasswords[i].ChatRoomPassword = ChanPwd; SaveConfig(); } break; } } if ( i == StoredChatPasswords.Length && ChanPwd != "" ) { StoredChatPasswords.Length = i + 1; StoredChatPasswords[i].ChatRoomName = ChanName; StoredChatPasswords[i].ChatRoomPassword = ChanPwd; SaveConfig(); } log("Join "$ChanName@"Password:"$ChanPwd@"PRI:"$PlayerReplicationInfo.PlayerName@"Team:"$PlayerReplicationInfo.Team,'VoiceChat'); if (PlayerReplicationInfo != None && PlayerReplicationInfo.Team != None) idx = PlayerReplicationInfo.Team.TeamIndex; VCR = VoiceReplicationInfo.GetChannel(ChanName, idx); if (VCR != None) { if (!VCR.IsMember(PlayerReplicationInfo)) ServerJoinVoiceChannel(VCR.ChannelIndex, ChanPwd); } else if ( ChatRoomMessageClass != None ) ClientMessage(ChatRoomMessageClass.static.AssembleMessage(0,ChanName)); } // Leave a voice chatroom by name exec function Leave(string ChannelTitle) { local VoiceChatRoom VCR; local int idx; if (VoiceReplicationInfo == None || !VoiceReplicationInfo.bEnableVoiceChat ) return; if (PlayerReplicationInfo != None && PlayerReplicationInfo.Team != None) idx = PlayerReplicationInfo.Team.TeamIndex; VCR = VoiceReplicationInfo.GetChannel(ChannelTitle, idx); if (VCR == None && ChatRoomMessageClass != None) { ClientMessage(ChatRoomMessageClass.static.AssembleMessage(0,ChannelTitle)); return; } if ( VCR == ActiveRoom ) ActiveRoom = None; ServerLeaveVoiceChannel(VCR.ChannelIndex); } // Set a voice chatroom to your active channel exec function Speak(string ChannelTitle) { local int idx; local VoiceChatRoom VCR; local string ChanPwd; if (VoiceReplicationInfo == None || !VoiceReplicationInfo.bEnableVoiceChat ) return; if (PlayerReplicationInfo != None && PlayerReplicationInfo.Team != None) idx = PlayerReplicationInfo.Team.TeamIndex; // Check that we are a member of this room VCR = VoiceReplicationInfo.GetChannel(ChannelTitle, idx); if (VCR == None && ChatRoomMessageClass != None) { ClientMessage(ChatRoomMessageClass.static.AssembleMessage(0,ChannelTitle)); return; } if (VCR.ChannelIndex >= 0) { ChanPwd = FindChannelPassword(ChannelTitle); ServerSpeak(VCR.ChannelIndex, ChanPwd); } else if ( ChatRoomMessageClass != None ) ClientMessage(ChatRoomMessageClass.static.AssembleMessage(0,ChannelTitle)); } // Set your active channel to the default channel exec function SpeakDefault() { local string str; str = GetDefaultActiveChannel(); if ( str != "" && (ActiveRoom == None || !(ActiveRoom.GetTitle() ~= str)) ) Speak(str); } // Set your active channel to the last active channel exec function SpeakLast() { if ( LastActiveChannel != "" && (ActiveRoom == None || !(ActiveRoom.GetTitle() ~= LastActiveChannel)) ) Speak(LastActiveChannel); } // Change the password for you personal chatroom exec function SetChatPassword(string NewPassword) { if (ChatPassword != NewPassword) { ChatPassword = NewPassword; SaveConfig(); ServerSetChatPassword(NewPassword); } } exec function EnableVoiceChat() { local bool bCurrent; bCurrent = bool(ConsoleCommand("get ini:Engine.Engine.AudioDevice UseVoIP")); ConsoleCommand("set ini:Engine.Engine.AudioDevice UseVoIP"@True); if ( VoiceReplicationInfo == None ) return; if ( !VoiceReplicationInfo.bEnableVoiceChat ) { ChatRoomMessage(15, -1); return; } ChangeVoiceChatMode( True ); InitializeVoiceChat(); // TODO What else needs to be done before a sound reboot? if (bCurrent == False) ConsoleCommand("SOUND_REBOOT"); } exec function DisableVoiceChat() { local bool bCurrent; bCurrent = bool(ConsoleCommand("get ini:Engine.Engine.AudioDevice UseVoIP")); ConsoleCommand("set ini:Engine.Engine.AudioDevice UseVoIP"@False); if (VoiceReplicationInfo == None || !VoiceReplicationInfo.bEnableVoiceChat ) return; ChangeVoiceChatMode( False ); // TODO What else needs to be done before a sound reboot? if (bCurrent == True) ConsoleCommand("SOUND_REBOOT"); } simulated function InitializeVoiceChat() { if ( bVoiceChatEnabled ) { InitPrivateChatRoom(); AutoJoinVoiceChat(); } } function InitPrivateChatRoom() { ServerChangeVoiceChatMode(True); if ( ChatPassword != "" ) ServerSetChatPassword(ChatPassword); } simulated function string GetDefaultActiveChannel() { local string DefaultChannel; if ( DefaultActiveChannel != "" ) DefaultChannel = DefaultActiveChannel; else if ( VoiceReplicationInfo != None ) DefaultChannel = VoiceReplicationInfo.GetDefaultChannel(); return DefaultChannel; } simulated function AutoJoinVoiceChat(); simulated function ChangeVoiceChatMode( bool bEnable ) { if (VoiceReplicationInfo == None) return; bVoiceChatEnabled = bEnable; if (Level.NetMode == NM_Client || Level.NetMode == NM_ListenServer) ServerChangeVoiceChatMode( bEnable ); } simulated function bool ChatBan(int PlayerID, byte Type) { log("ChatBan Role:"$GetEnum(enum'ENetRole', Role)@"ChatManager:"$ChatManager@"PlayerID:"$PlayerID@"Type:"$Type,'ChatManager'); if ( Level.NetMode == NM_StandAlone || Level.NetMode == NM_DedicatedServer ) return false; if ( ChatManager == None ) return false; if ( ChatManager.SetRestrictionID(PlayerID, Type) ) { ServerChatRestriction(PlayerID, Type); return true; } log(Name@"ChatBan not successful - could not find player with ID:"@PlayerID,'ChatManager'); return false; } simulated function SetChannelPassword(string ChannelName, string ChannelPassword) { local int i; if ( Level.NetMode == NM_DedicatedServer ) return; for ( i = 0; i < StoredChatPasswords.Length; i++ ) { if ( StoredChatPasswords[i].ChatRoomName ~= ChannelName ) break; } if ( i == StoredChatPasswords.Length ) StoredChatPasswords.Length = i + 1; StoredChatPasswords[i].ChatRoomName = ChannelName; StoredChatPasswords[i].ChatRoomPassword = ChannelPassword; SaveConfig(); } simulated function string FindChannelPassword(string ChannelName) { local int i; for ( i = 0; i < StoredChatPasswords.Length; i++ ) if ( StoredChatPasswords[i].ChatRoomName ~= ChannelName ) return StoredChatPasswords[i].ChatRoomPassword; return ""; } function VoiceChatRoom.EJoinChatResult ServerJoinVoiceChannel(int ChannelIndex, optional string ChannelPassword) { local VoiceChatRoom VCR; local VoiceChatRoom.EJoinChatResult Result; VCR = VoiceReplicationInfo.GetChannelAt(ChannelIndex); if (VoiceReplicationInfo == None || PlayerReplicationInfo == None || VCR == None || !VoiceReplicationInfo.bEnableVoiceChat) return JCR_Invalid; if ( VoiceReplicationInfo != None ) Result = VoiceReplicationInfo.JoinChannelAt(ChannelIndex, PlayerReplicationInfo, ChannelPassword); // Take the appropriate action depending on the result received from the VoiceReplicationInfo switch ( Result ) { case JCR_NeedPassword: ClientOpenMenu(ChatPasswordMenuClass, false, VCR.GetTitle(), "NEEDPW"); break; case JCR_WrongPassword: ClientOpenMenu(ChatPasswordMenuClass, False, VCR.GetTitle(), "WRONGPW"); break; case JCR_Success: Level.Game.ChangeVoiceChannel(PlayerReplicationInfo, ChannelIndex, -1); default: if ( ChannelIndex>VoiceReplicationInfo.GetPublicChannelCount(true) ) ChatRoomMessage(Result, ChannelIndex); } return Result; } function ServerLeaveVoiceChannel(int ChannelIndex) { local VoiceChatRoom VCR; if (VoiceReplicationInfo == None || PlayerReplicationInfo == None) return; if ( !VoiceReplicationInfo.bEnableVoiceChat ) { ChatRoomMessage(15, -1); return; } VCR = VoiceReplicationInfo.GetChannelAt(ChannelIndex); if (VCR != None && VCR.LeaveChannel(PlayerReplicationInfo)) { if (VCR == ActiveRoom) { ActiveRoom = None; if ( PlayerReplicationInfo != None ) PlayerReplicationInfo.ActiveChannel = -1; // not necessary as client will do this itself // ClientSetActiveRoom(-1); } Level.Game.ChangeVoiceChannel( PlayerReplicationInfo, -1, ChannelIndex ); if ( ChannelIndex>VoiceReplicationInfo.GetPublicChannelCount(true) ) ChatRoomMessage(8, ChannelIndex); } } function ServerSpeak(int ChannelIndex, optional string ChannelPassword) { local VoiceChatRoom VCR; local int Index; if (VoiceReplicationInfo == None) return; VCR = VoiceReplicationInfo.GetChannelAt(ChannelIndex); if ( VCR == None ) { if ( VoiceReplicationInfo.bEnableVoiceChat ) ChatRoomMessage(0, ChannelIndex); else ChatRoomMessage(15, ChannelIndex); return; } if ( !VCR.IsMember(PlayerReplicationInfo) ) { if ( ServerJoinVoiceChannel(ChannelIndex, ChannelPassword) != JCR_Success ) return; } Index = -1; if (ActiveRoom == VCR) { ChatRoomMessage(10, ChannelIndex); log(PlayerReplicationInfo.PlayerName@"no longer speaking on "$VCR.GetTitle(),'VoiceChat'); ActiveRoom = None; ClientSetActiveRoom(-1); } else { ActiveRoom = VCR; log(PlayerReplicationInfo.PlayerName@"speaking on"@VCR.GetTitle(),'VoiceChat'); ChatRoomMessage(9, ChannelIndex); ClientSetActiveRoom(VCR.ChannelIndex); Index = VCR.ChannelIndex; } if ( PlayerReplicationInfo != None ) PlayerReplicationinfo.ActiveChannel = Index; } function ServerSetChatPassword(string NewPassword) { ChatPassword = NewPassword; if (PlayerReplicationInfo != None) PlayerReplicationInfo.SetChatPassword(NewPassword); } function ServerChangeVoiceChatMode( bool bEnable ) { if (VoiceReplicationInfo == None) return; bVoiceChatEnabled = bEnable; if ( bVoiceChatEnabled ) { if ( VoiceReplicationInfo.bEnableVoiceChat ) VoiceReplicationInfo.AddVoiceChatter(PlayerReplicationInfo); else ChatRoomMessage(15, -1); } else VoiceReplicationInfo.RemoveVoiceChatter(PlayerReplicationInfo); } simulated function ClientSetActiveRoom(int ChannelIndex) { if ( VoiceReplicationInfo == None || !bVoiceChatEnabled ) return; if ( ActiveRoom != None ) LastActiveChannel = ActiveRoom.GetTitle(); else LastActiveChannel = ""; ActiveRoom = VoiceReplicationInfo.GetChannelAt(ChannelIndex); } // ===================================================================================================================== // ===================================================================================================================== // Chat Manager // ===================================================================================================================== // ===================================================================================================================== exec function ChatDebug() { ChatManager.ChatDebug(); ServerChatDebug(); } function ServerChatDebug(); function ServerRequestBanInfo(int PlayerID); function ServerChatRestriction(int PlayerID, byte Type) { local PlayerReplicationInfo PRI; local int i; log("ServerChatRestriction PlayerID:"$PlayerID@"Type:"$Type,'ChatManager'); if ( ChatManager == None || GameReplicationInfo == None) return; for ( i = 0; i < GameReplicationInfo.PRIArray.Length; i++ ) { log("ServerChatRestriction checking GRI.PRIArray["$i$"].PlayerID:"$GameReplicationInfo.PRIArray[i].PlayerID,'ChatManager'); if ( GameReplicationInfo.PRIArray[i] != None && GameReplicationInfo.PRIArray[i].PlayerID == PlayerID ) { PRI = GameReplicationInfo.PRIArray[i]; break; } } log("ServerChatRestriction PRI:"$PRI@"PRI.Owner"$PRI.Owner,'ChatManager'); if ( PRI == None || PlayerController(PRI.Owner) == None ) return; ChatManager.SetRestriction(PlayerController(GameReplicationInfo.PRIArray[i].Owner).GetPlayerIDHash(), Type); // If we added a ban for this player and this player is currently in our private chat room, remove the player if ( bool(Type & 8) && PlayerReplicationInfo != None && PlayerReplicationInfo.PrivateChatRoom != None && PlayerReplicationInfo.PrivateChatRoom.IsMember(PRI, True) ) { ChatRoomMessage(13, -1, PRI); PlayerReplicationInfo.PrivateChatRoom.RemoveMember(PRI); } } simulated event GainedChild( Actor Other ) { Super.GainedChild(Other); if ( VotingReplicationInfoBase(Other) != None ) VoteReplicationInfo = VotingReplicationInfoBase(Other); } simulated event LostChild(Actor Other) { Super.LostChild(Other); if ( VotingReplicationInfoBase(Other) != None ) VoteReplicationInfo = None; } exec function ShowVoteMenu() { if( Level.NetMode != NM_StandAlone && VoteReplicationInfo != none && VoteReplicationInfo.MapVoteEnabled() ) Player.GUIController.OpenMenu(Player.GUIController.GetPropertyText("MapVotingMenu")); } sJM-W#/dM-dd P GsaGU49:9:${$=m%qmm%\q% -}-qm-y$haY'9:9:$%Z%W&Z&W%W*&W*U%QU7MGwUM^*wUM`*UM`}WUMUU%U,wUZUWVUwV*w.V*.VuaUWUVVSUX GskL-V*P 9=L-P P  P GsYJ-l9:9:$9:9:$X%X7M9:XME9:YXYX;9:Y, Y$J-EY7MMJ- Gs{K-`!-u-K- Gsa|jR&S~|:1S||S-k'o%0o7r&or;q U|q ACCEPT-r'|q DENY-r(&S~U*SzUS|S-k-rw o&&zU|-k-rw oo@-k-Z%pppDenied connection for | with IP policy w r,o%o7w{owow;q U|q ACCEPT-r' |q DENY-r( S~U*bS_zUS|S-k-rw ozU|-k-rw oo-k-Z%pppDenied connection for | with Session IP policy w w&% GsVoT-x $ =9:w9:$ $E $r9:w9:$w* 9:!9:${w$9:w9:$pww$*-Q-Iw$R-U-Lw$z-V-Pw$-W-[w$9:w9:$wp9:w9:p{r?o w{9:w9:${{ox{33w${r9:w9:$9:w9:${o{9?%w${r  Gs\//============================================================================= // Player: Corresponds to a real player (a local camera or remote net player). // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class Player extends Object config(User) native noexport; //----------------------------------------------------------------------------- // Player properties. // Internal. var native const pointer vfOut; var native const pointer vfExec; // The actor this player controls. var transient const playercontroller Actor; var transient const playercontroller OldActor; var transient Console Console; // Window input variables var transient const bool bWindowsMouseAvailable; var bool bShowWindowsMouse; var transient const float WindowsMouseX; var transient const float WindowsMouseY; var transient int CurrentVoiceBandwidth; var const int CurrentNetSpeed; var globalconfig int ConfiguredInternetSpeed, ConfiguredLanSpeed; var byte SelectedCursor; var transient InteractionMaster InteractionMaster; // Callback to the IM var transient array LocalInteractions; // Holds a listing of all local Interactions var transient BaseGUIController GUIController; // Callback to the Menu Controller const IDC_ARROW=0; const IDC_SIZEALL=1; const IDC_SIZENESW=2; const IDC_SIZENS=3; const IDC_SIZENWSE=4; const IDC_SIZEWE=5; const IDC_WAIT=6; s slsd//============================================================================= // Pickup items. // // Pickup is the base class of actors that when touched by an appropriate pawn, // will create and place an Inventory actor in that pawn's inventory chain. Each // pickup class has an associated inventory class (its InventoryType). Pickups are // placed by level designers. Pickups can only interact with pawns when in their // default Pickup state. Pickups verify that they can give inventory to a pawn by // calling the GameInfo's PickupQuery() function. After a pickup spawns an inventory // item for a pawn, it then queries the GameInfo by calling the GameInfo's // ShouldRespawn() function about whether it should remain active, enter its Sleep // state and later become active again, or destroy itself. // // When navigation paths are built, each pickup has an InventorySpot (a subclass // of NavigationPoint) placed on it and associated with it // (the Pickup's MyMarker== the InventorySpot, // and the InventorySpot's markedItem == the pickup). // //============================================================================= class Pickup extends Actor abstract placeable native nativereplication; //----------------------------------------------------------------------------- // AI related info. var float MaxDesireability; // Maximum desireability this item will ever have. var InventorySpot MyMarker; var NavigationPoint PickupCache; // used for dropped pickups var() class InventoryType; var() bool bInstantRespawn; // Can be tagged so this item respawns instantly. var bool bOnlyReplicateHidden; // only replicate changes in bHidden (optimization for level pickups) var(Display) bool bAmbientGlow; // Whether to glow or not. var bool bDropped; var bool bPredictRespawns; // high skill bots may predict respawns for this item var() float RespawnTime; // Respawn after this time, 0 for instant. var float RespawnEffectTime; var() localized string PickupMessage; // Human readable description when picked up. var() sound PickupSound; var() string PickupForce; // jdf var() xPickUpBase PickUpBase; // Pick-up base which spawned this pickup. var Controller TeamOwner[4]; // AI controller currently going after this pickup (for team coordination) native final function AddToNavigation(); // cache dropped inventory in navigation network native final function RemoveFromNavigation(); static function StaticPrecache(LevelInfo L); function Destroyed() { if (MyMarker != None ) MyMarker.markedItem = None; if (Inventory != None ) Inventory.Destroy(); } simulated function String GetHumanReadableName() { if ( InventoryType == None ) return GetItemName(string(class)); if ( InventoryType.Default.ItemName == "" ) return GetItemName(string(InventoryType)); return InventoryType.Default.ItemName; } function bool IsSuperItem() { return (PickupBase != None) && PickupBase.bDelayedSpawn; } simulated static function UpdateHUD(HUD H) { H.LastPickupTime = H.Level.TimeSeconds; } /* Reset() reset actor to initial state - used when restarting level without reloading. */ function Reset() { if ( Inventory != None ) destroy(); else { if (myMarker != None && myMarker.bSuperPickup) GotoState('Sleeping', 'DelayedSpawn'); else GotoState('Pickup'); Super.Reset(); } } function RespawnEffect(); // Turns the pickup into a different type of pickup - specificly used by the WildcardCharger function Pickup Transmogrify(class NewClass) // de { local Pickup NewPickup; NewPickup = Spawn(NewClass); NewPickup.PickupBase = PickupBase; NewPickup.RespawnTime = RespawnTime; if (MyMarker != None ) { MyMarker.markedItem = NewPickup; NewPickup.MyMarker = MyMarker; MyMarker = None; } Destroy(); return NewPickup; } /* 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 0; } /* Pickups have 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. */ function float BotDesireability( pawn Bot ) { local Inventory AlreadyHas; local float desire; desire = MaxDesireability; if ( RespawnTime < 10 ) { AlreadyHas = Bot.FindInventoryType(InventoryType); if ( AlreadyHas != None ) { if ( Inventory != None ) { if( Inventory.Charge <= AlreadyHas.Charge ) return -1; } else if ( InventoryType.Default.Charge <= AlreadyHas.Charge ) return -1; } } return desire; } // Either give this inventory to player Other, or spawn a copy // and give it to the player Other, setting up original to be respawned. // function inventory SpawnCopy( pawn Other ) { local inventory Copy; if ( Inventory != None ) { Copy = Inventory; Inventory = None; } else Copy = spawn(InventoryType,Other,,,rot(0,0,0)); Copy.GiveTo( Other, self ); return Copy; } function StartSleeping() { if (bDropped) Destroy(); else GotoState('Sleeping'); } function AnnouncePickup( Pawn Receiver ) { Receiver.HandlePickup(self); PlaySound( PickupSound,SLOT_Interact ); } // // Set up respawn waiting if desired. // function SetRespawn() { if( Level.Game.ShouldRespawn(self) ) StartSleeping(); else Destroy(); } // HUD Messages static function string GetLocalString( optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2 ) { return Default.PickupMessage; } function InitDroppedPickupFor(Inventory Inv) { SetPhysics(PHYS_Falling); GotoState('FallingPickup'); Inventory = Inv; bAlwaysRelevant = false; bOnlyReplicateHidden = false; bUpdateSimulatedPosition = true; bDropped = true; LifeSpan = 16; bIgnoreEncroachers = false; // handles case of dropping stuff on lifts etc NetUpdateFrequency = 8; } function bool ReadyToPickup(float MaxWait) { return false; } event Landed(Vector HitNormal) { GotoState('Pickup','Begin'); } //============================================================================= // Pickup state: this inventory item is sitting on the ground. auto state Pickup { function bool ReadyToPickup(float MaxWait) { return true; } /* ValidTouch() Validate touch (if valid return true to let other pick me up and trigger event). */ function bool ValidTouch( actor Other ) { // make sure its a live player if ( (Pawn(Other) == None) || !Pawn(Other).bCanPickupInventory || (Pawn(Other).DrivenVehicle == None && Pawn(Other).Controller == None) ) return false; // make sure not touching through wall if ( !FastTrace(Other.Location, Location) ) return false; // make sure game will let player pick me up if( Level.Game.PickupQuery(Pawn(Other), self) ) { TriggerEvent(Event, self, Pawn(Other)); return true; } return false; } // When touched by an actor. function Touch( actor Other ) { local Inventory Copy; // If touched by a player pawn, let him pick this up. if( ValidTouch(Other) ) { Copy = SpawnCopy(Pawn(Other)); AnnouncePickup(Pawn(Other)); SetRespawn(); if ( Copy != None ) Copy.PickupFunction(Pawn(Other)); } } // Make sure no pawn already touching (while touch was disabled in sleep). function CheckTouching() { local Pawn P; ForEach TouchingActors(class'Pawn', P) Touch(P); } function Timer() { if ( bDropped ) GotoState('FadeOut'); } function BeginState() { UntriggerEvent(Event, self, None); if ( bDropped ) { AddToNavigation(); SetTimer(8, false); } } function EndState() { if ( bDropped ) RemoveFromNavigation(); } Begin: CheckTouching(); } state FallingPickup extends Pickup { function CheckTouching() { } function Timer() { GotoState('FadeOut'); } function BeginState() { SetTimer(8, false); } } State FadeOut extends Pickup { function Tick(float DeltaTime) { SetDrawScale(FMax(0.01, DrawScale - Default.DrawScale * DeltaTime)); } function BeginState() { RotationRate.Yaw=60000; SetPhysics(PHYS_Rotating); LifeSpan = 1.0; } function EndState() { LifeSpan = 0.0; SetDrawScale(Default.DrawScale); if ( Physics == PHYS_Rotating ) SetPhysics(PHYS_None); } } //============================================================================= // Sleeping state: Sitting hidden waiting to respawn. function float GetRespawnTime() { return RespawnTime; } State WaitingForMatch { ignores Touch; function MatchStarting() { GotoState( 'Sleeping', 'DelayedSpawn' ); } function BeginState() { NetUpdateTime = Level.TimeSeconds - 1; bHidden = true; } } State Sleeping { ignores Touch; function bool ReadyToPickup(float MaxWait) { return ( bPredictRespawns && (LatentFloat < MaxWait) ); } function StartSleeping() {} function BeginState() { local int i; NetUpdateTime = Level.TimeSeconds - 1; bHidden = true; for ( i=0; i<4; i++ ) TeamOwner[i] = None; } function EndState() { NetUpdateTime = Level.TimeSeconds - 1; bHidden = false; } DelayedSpawn: if ( Level.NetMode == NM_Standalone ) Sleep(FMin(30, Level.Game.GameDifficulty * 8)); else Sleep(30); Goto('Respawn'); Begin: Sleep( GetReSpawnTime() - RespawnEffectTime ); Respawn: RespawnEffect(); Sleep(RespawnEffectTime); if (PickUpBase != None) PickUpBase.TurnOn(); GotoState('Pickup'); } State Disabled { function bool ReadyToPickup(float MaxWait) { return false; } function Reset() {} function StartSleeping() {} simulated function BeginState() { MaxDesireability = 0; bHidden = true; ResetStaticFilterState(); SetCollision(false,false,false); } } s@//============================================================================= // PhysicsVolume: a bounding volume which affects actor physics // Each Actor is affected at any time by one PhysicsVolume // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class PhysicsVolume extends Volume native nativereplication; var() vector ZoneVelocity; var() vector Gravity; var vector BACKUP_Gravity; var() float GroundFriction; var() float TerminalVelocity; var() float DamagePerSec; var() class DamageType; var() int Priority; // determines which PhysicsVolume takes precedence if they overlap var() sound EntrySound; //only if waterzone var() sound ExitSound; // only if waterzone var() editinline I3DL2Listener VolumeEffect; var() class EntryActor; // e.g. a splash (only if water zone) var() class ExitActor; // e.g. a splash (only if water zone) var() class PawnEntryActor; // when pawn center enters volume var() float FluidFriction; var() vector ViewFlash, ViewFog; var() bool bPainCausing; // Zone causes pain. var bool BACKUP_bPainCausing; var() bool bDestructive; // Destroys most actors which enter it. var() bool bNoInventory; var() bool bMoveProjectiles;// this velocity zone should impart velocity to projectiles and effects var() bool bBounceVelocity; // this velocity zone should bounce actors that land in it var() bool bNeutralZone; // Players can't take damage in this zone. var() bool bWaterVolume; var() bool bNoDecals; var() bool bDamagesVehicles; // Distance Fog var(VolumeFog) bool bDistanceFog; // There is distance fog in this physicsvolume. var(VolumeFog) color DistanceFogColor; var(VolumeFog) float DistanceFogStart; var(VolumeFog) float DistanceFogEnd; // Karma var(Karma) float KExtraLinearDamping; // Extra damping applied to Karma actors in this volume. var(Karma) float KExtraAngularDamping; var(Karma) float KBuoyancy; // How buoyant Karma things are in this volume (if bWaterVolume true). Multiplied by Actors KarmaParams->KBuoyancy. var Info PainTimer; var PhysicsVolume NextPhysicsVolume; replication { // Things the server should send to the client. reliable if( bNetDirty && (Role==ROLE_Authority) ) Gravity; } simulated function PreBeginPlay() { if ( Base == None ) { RemoteRole = ROLE_None; bAlwaysRelevant = false; // true by default to put it in the networked list of static actors, turn back on if change gravity or base } super.PreBeginPlay(); } simulated function PostBeginPlay() { super.PostBeginPlay(); BACKUP_Gravity = Gravity; BACKUP_bPainCausing = bPainCausing; if( VolumeEffect == None && bWaterVolume ) VolumeEffect = new(Level.xLevel) class'EFFECT_WaterVolume'; } /* Reset() reset actor to initial state - used when restarting level without reloading. */ function Reset() { Gravity = BACKUP_Gravity; bPainCausing = BACKUP_bPainCausing; NetUpdateTime = Level.TimeSeconds - 1; } /* Called when an actor in this PhysicsVolume changes its physics mode */ event PhysicsChangedFor(Actor Other); event ActorEnteredVolume(Actor Other); event ActorLeavingVolume(Actor Other); simulated event PawnEnteredVolume(Pawn Other) { local vector HitLocation,HitNormal; local Actor SpawnedEntryActor; if ( bWaterVolume && (Level.TimeSeconds - Other.SplashTime > 0.3) && (PawnEntryActor != None) && !Level.bDropDetail && (Level.DetailMode != DM_Low) && EffectIsRelevant(Other.Location,false) ) { if ( !TraceThisActor(HitLocation, HitNormal, Other.Location - Other.CollisionHeight*vect(0,0,1), Other.Location + Other.CollisionHeight*vect(0,0,1)) ) { SpawnedEntryActor = Spawn(PawnEntryActor,Other,,HitLocation,rot(16384,0,0)); } } if ( (Role == ROLE_Authority) && Other.IsPlayerPawn() ) TriggerEvent(Event,self, Other); } event PawnLeavingVolume(Pawn Other) { if ( Other.IsPlayerPawn() ) UntriggerEvent(Event,self, Other); } function PlayerPawnDiedInVolume(Pawn Other) { UntriggerEvent(Event,self, Other); } singular event BaseChange() { if ( Base != None ) { bAlwaysRelevant = true; RemoteRole = ROLE_DumbProxy; } } /* TimerPop damage touched actors if pain causing. since PhysicsVolume is static, this function is actually called by a volumetimer */ function TimerPop(VolumeTimer T) { local actor A; local bool bFound; if ( T == PainTimer ) { if ( !bPainCausing ) { PainTimer.Destroy(); return; } ForEach TouchingActors(class'Actor', A) if ( A.bCanBeDamaged && !A.bStatic ) { CausePainTo(A); bFound = true; } if ( !bFound ) PainTimer.Destroy(); } } function Trigger( actor Other, pawn EventInstigator ) { local Pawn P; // turn zone damage on and off if (DamagePerSec != 0) { bPainCausing = !bPainCausing; if ( bPainCausing ) { if ( PainTimer == None ) PainTimer = spawn(class'VolumeTimer', self); ForEach TouchingActors(class'Pawn', P) CausePainTo(P); } } } simulated event touch(Actor Other) { local Pawn P; local bool bFoundPawn; Super.Touch(Other); if ( Other == None ) return; if ( (Other.Role == ROLE_Authority) || Other.bNetTemporary ) { if ( bNoInventory && (Pickup(Other) != None) && (Other.Owner == None) ) { Other.LifeSpan = 1.5; return; } if ( bMoveProjectiles && (ZoneVelocity != vect(0,0,0)) ) { if ( Other.Physics == PHYS_Projectile ) Other.Velocity += ZoneVelocity; else if ( (Other.Base == None) && Other.IsA('Emitter') && (Other.Physics == PHYS_None) ) { Other.SetPhysics(PHYS_Projectile); Other.Velocity += ZoneVelocity; } } if ( bPainCausing ) { if ( Other.bDestroyInPainVolume ) { Other.Destroy(); return; } if ( Other.bCanBeDamaged && !Other.bStatic ) { CausePainTo(Other); if ( Other == None ) return; if ( Role == ROLE_Authority ) { if ( PainTimer == None ) PainTimer = Spawn(class'VolumeTimer', self); else if ( Pawn(Other) != None ) { ForEach TouchingActors(class'Pawn', P) if ( (P != Other) && P.bCanBeDamaged ) { bFoundPawn = true; break; } if ( !bFoundPawn ) PainTimer.SetTimer(1.0,true); } } } } } if ( bWaterVolume && Other.CanSplash() ) PlayEntrySplash(Other); } simulated function PlayEntrySplash(Actor Other) { local vector StartLoc, Vel2D; if( EntrySound != None ) { Other.PlaySound(EntrySound, SLOT_Interact, Other.TransientSoundVolume); if ( Other.Instigator != None ) MakeNoise(1); } if( (EntryActor != None) && (Level.NetMode != NM_DedicatedServer) ) { StartLoc = Other.Location - Other.CollisionHeight*vect(0,0,0.8); if ( Other.CollisionRadius > 0 ) { Vel2D = Other.Velocity; Vel2D.Z = 0; if ( VSize(Vel2D) > 100 ) StartLoc = StartLoc + Normal(Vel2D) * CollisionRadius; } Spawn(EntryActor,,,StartLoc,rot(16384,0,0)); } } simulated event untouch(Actor Other) { if ( bWaterVolume && Other.CanSplash() ) PlayExitSplash(Other); } simulated function PlayExitSplash(Actor Other) { if( ExitSound != None ) Other.PlaySound(ExitSound, SLOT_Interact, Other.TransientSoundVolume); if( (ExitActor != None) && (Level.NetMode != NM_DedicatedServer) ) Spawn(ExitActor,,,Other.Location - Other.CollisionHeight*vect(0,0,0.8),rot(16384,0,0)); } function CausePainTo(Actor Other) { local float depth; local Pawn P; // FIXMEZONE figure out depth of actor, and base pain on that!!! depth = 1; P = Pawn(Other); if ( DamagePerSec > 0 ) { if ( Region.Zone.bSoftKillZ && (Other.Physics != PHYS_Walking) ) return; Other.TakeDamage(int(DamagePerSec * depth), None, Location, vect(0,0,0), DamageType); if ( (P != None) && (P.Controller != None) ) P.Controller.PawnIsInPain(self); } else { if ( (P != None) && (P.Health < P.HealthMax) ) P.Health = Min(P.HealthMax, P.Health - depth * DamagePerSec); } } s 32768sU^%l{ %D{ 7M:r{ M^%AM{ & { ppGameReplicationInfo::RemovePRI() pri=9V^% not found.!o Gs^pb[Ap%7pv %Xv 7MNwv M*D-pv Mv  Gssshd%]VW!y r9d%Password-ugd%9:9:$ -u w-H-`%SERVERFULLy {k{rk -uzry `%NEEDPWy `%WRONGPW{jE-O{%-E{z`b{%{&y `%SESSIONBAN{,y `%LOCALBAN Gssesb@ss_ //============================================================================= // Pawn, the base class of all actors that can be controlled by players or AI. // // Pawns are the physical representations of players and creatures in a level. // Pawns have a mesh, collision, and physics. Pawns can take damage, make sounds, // and hold weapons and other inventory. In short, they are responsible for all // physical interaction between the player or AI and the world. // // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class Pawn extends Actor abstract native placeable config(user) nativereplication exportstructs; #exec Texture Import File=Textures\Pawn.pcx Name=S_Pawn Mips=Off MASKED=1 //----------------------------------------------------------------------------- // Pawn variables. var Controller Controller; // cache net relevancy test var float NetRelevancyTime; var playerController LastRealViewer; var actor LastViewer; var const float LastLocTime; // used to force periodic location replication, even when pawn isn't moving // Physics related flags. var bool bJustLanded; // used by eyeheight adjustment var bool bLandRecovery; // used by eyeheight adjustment var bool bUpAndOut; // used by swimming var bool bIsWalking; // currently walking (can't jump, affects animations) var bool bWarping; // Set when travelling through warpzone (so shouldn't telefrag) var bool bWantsToCrouch; // if true crouched (physics will automatically reduce collision height to CrouchHeight) var const bool bIsCrouched; // set by physics to specify that pawn is currently crouched var const bool bTryToUncrouch; // when auto-crouch during movement, continually try to uncrouch var() bool bCanCrouch; // if true, this pawn is capable of crouching var bool bCrawler; // crawling - pitch and roll based on surface pawn is on var const bool bReducedSpeed; // used by movement natives var bool bJumpCapable; var bool bCanJump; // movement capabilities - used by AI var bool bCanWalk; var bool bCanSwim; var bool bCanFly; var bool bCanClimbLadders; var bool bCanStrafe; var bool bCanDoubleJump; var bool bCanWallDodge; var bool bAvoidLedges; // don't get too close to ledges var bool bStopAtLedges; // if bAvoidLedges and bStopAtLedges, Pawn doesn't try to walk along the edge at all var bool bNoJumpAdjust; // set to tell controller not to modify velocity of a jump/fall var bool bCountJumps; // if true, inventory wants message whenever this pawn jumps var const bool bSimulateGravity; // simulate gravity for this pawn on network clients when predicting position (true if pawn is walking or falling) var bool bUpdateEyeheight; // if true, UpdateEyeheight will get called every tick var bool bIgnoreForces; // if true, not affected by external forces var const bool bNoVelocityUpdate; // used by C++ physics var bool bCanWalkOffLedges; // Can still fall off ledges, even when walking (for Player Controlled pawns) var bool bSteadyFiring; // used for third person weapon anims/effects var bool bCanBeBaseForPawns; // all your 'base', are belong to us var bool bClientCollision; // used on clients when temporarily turning off collision var const bool bSimGravityDisabled; // used on network clients var bool bDirectHitWall; // always call pawn hitwall directly (no controller notifyhitwall) var bool bServerMoveSetPawnRot; var bool bFlyingKarma; // Tells AI that this vehicle can be flown like PHYS_Flying even though it has karma physics var bool bDrawCorona; var globalconfig bool bNoCoronas; // used by dead pawns (for bodies landing and changing collision box) var bool bThumped; var bool bInvulnerableBody; // AI related flags var bool bIsFemale; var bool bAutoActivate; // if true, automatically activate Powerups which have their bAutoActivate==true var bool bCanPickupInventory; // if true, will pickup inventory when touching pickup actors var bool bUpdatingDisplay; // to avoid infinite recursion through inventory setdisplay var bool bAmbientCreature; // AIs will ignore me var(AI) bool bLOSHearing; // can hear sounds from line-of-sight sources (which are close enough to hear) // bLOSHearing=true is like UT/Unreal hearing var(AI) bool bSameZoneHearing; // can hear any sound in same zone (if close enough to hear) var(AI) bool bAdjacentZoneHearing; // can hear any sound in adjacent zone (if close enough to hear) var(AI) bool bMuffledHearing; // can hear sounds through walls (but muffled - sound distance increased to double plus 4x the distance through walls var(AI) bool bAroundCornerHearing; // Hear sounds around one corner (slightly more expensive, and bLOSHearing must also be true) var(AI) bool bDontPossess; // if true, Pawn won't be possessed at game start var bool bAutoFire; // used for third person weapon anims/effects var bool bRollToDesired; // Update roll when turning to desired rotation (normally false) var bool bIgnorePlayFiring; // if true, ignore the next PlayFiring() call (used by AnimNotify_FireWeapon) var bool bStationary; // pawn can't move var bool bCachedRelevant; // network relevancy caching flag var bool bUseCompressedPosition; // use compressed position in networking - true unless want to replicate roll, or very high velocities var globalconfig bool bWeaponBob; var bool bHideRegularHUD; var bool bSpecialHUD; var bool bSpecialCrosshair; var bool bSpecialCalcView; // If true, the Controller controlling this pawn will call 'SpecialCalcView' to find camera pos. var bool bNoTeamBeacon; // never display team beacon for this pawn var bool bNoWeaponFiring; var bool bIsTyping; // play typing anim if idle var bool bScriptPostRender; // if true, PostRender2D() gets called instead of native team beacon drawing code var bool bCanUse; // can this pawn Use things? var bool bSuperSize; // hack for Leviathan var byte FlashCount; // used for third person weapon anims/effects // AI basics. var byte Visibility; //How visible is the pawn? 0=invisible, 128=normal, 255=highly visible var float DesiredSpeed; var float MaxDesiredSpeed; var(AI) name AIScriptTag; // tag of AIScript which should be associated with this pawn var(AI) float HearingThreshold; // max distance at which a makenoise(1.0) loudness sound can be heard var(AI) float Alertness; // -1 to 1 ->Used within specific states for varying reaction to stimuli var(AI) float SightRadius; // Maximum seeing distance. var(AI) float PeripheralVision; // Cosine of limits of peripheral vision. var() float SkillModifier; // skill modifier (same scale as game difficulty) var const float AvgPhysicsTime; // Physics updating time monitoring (for AI monitoring reaching destinations) var float MeleeRange; // Max range for melee attack (not including collision radii) var float NavigationPointRange; // extra slack to have "reached" a NavigationPoint var NavigationPoint Anchor; // current nearest path; var const NavigationPoint LastAnchor; // recent nearest path var float FindAnchorFailedTime; // last time a FindPath() attempt failed to find an anchor. var float LastValidAnchorTime; // last time a valid anchor was found var float DestinationOffset; // used to vary destination over NavigationPoints var float NextPathRadius; // radius of next path in route var vector SerpentineDir; // serpentine direction var float SerpentineDist; var float SerpentineTime; // how long to stay straight before strafing again var const float UncrouchTime; // when auto-crouch during movement, continually try to uncrouch once this decrements to zero var float SpawnTime; // Movement. var float GroundSpeed; // The maximum ground speed. var float WaterSpeed; // The maximum swimming speed. var float AirSpeed; // The maximum flying speed. var float LadderSpeed; // Ladder climbing speed var float AccelRate; // max acceleration rate var float JumpZ; // vertical acceleration w/ jump var float AirControl; // amount of AirControl available to the pawn var float WalkingPct; // pct. of running speed that walking speed is var float CrouchedPct; // pct. of running speed that crouched walking speed is var float MaxFallSpeed; // max speed pawn can land without taking damage (also limits what paths AI can use) var vector ConstantAcceleration; // acceleration added to pawn when falling var Vehicle DrivenVehicle; var vector ImpactVelocity; // velocity added while falling (bot tries to correct for it) var() int PitchUpLimit; var() int PitchDownLimit; // Player info. var string OwnerName; // Name of owning player (for save games, coop) var travel Weapon Weapon; // The pawn's current weapon. var Weapon PendingWeapon; // Will become weapon once current weapon is put down var travel Powerups SelectedItem; // currently selected inventory item var float BaseEyeHeight; // Base eye height above collision center. var float EyeHeight; // Current eye height, adjusted for bobbing and stairs. var vector Floor; // Normal of floor pawn is standing on (only used by PHYS_Spider and PHYS_Walking) var float SplashTime; // time of last splash var float CrouchHeight; // CollisionHeight when crouching var float CrouchRadius; // CollisionRadius when crouching var() float DrivingHeight; // CollisionHeight when driving a vehicle var() float DrivingRadius; // CollisionRadius when driving a vehicle var float OldZ; // Old Z Location - used for eyeheight smoothing var PhysicsVolume HeadVolume; // physics volume of head var float HealthMax; var float SuperHealthMax; var travel int Health; // Health: 100 = normal maximum var float BreathTime; // used for getting BreathTimer() messages (for no air, etc.) var float UnderWaterTime; // how much time pawn can go without air (in seconds) var float LastPainTime; // last time pawn played a takehit animation (updated in PlayHit()) var class ReducedDamageType; // which damagetype this creature is protected from (used by AI) var float HeadRadius; // Squared radius of the head of the pawn that is vulnerable to headshots var float HeadHeight; // Distance from base of neck to center of head - used for headshot calculation var float HeadScale; var bool bSetPCRotOnPossess; // Sound and noise management // remember location and position of last noises propagated var const vector noise1spot; var const float noise1time; var const pawn noise1other; var const float noise1loudness; var const vector noise2spot; var const float noise2time; var const pawn noise2other; var const float noise2loudness; var float LastPainSound; // view bob var globalconfig float Bob; var float LandBob, AppliedBob; var float bobtime; var vector WalkBob; var float SoundDampening; var float DamageScaling; var globalconfig float AmbientSoundScaling; var localized string MenuName; // Name used for this pawn type in menus (e.g. player selection) // shadow decal var Projector Shadow; // blood effect var class BloodEffect; var class LowGoreBlood; var class ControllerClass; // default class to use when pawn is controlled by AI (can be modified by an AIScript) var PlayerReplicationInfo PlayerReplicationInfo; var LadderVolume OnLadder; // ladder currently being climbed var name LandMovementState; // PlayerControllerState to use when moving on land or air var name WaterMovementState; // PlayerControllerState to use when moving in water var PlayerStart LastStartSpot; // used to avoid spawn camping var float LastStartTime; // Animation status var name AnimAction; // use for replicating anims // Animation updating by physics // Note that animation channels 2 through 11 are used for animation updating var vector TakeHitLocation; // location of last hit (for playing hit/death anims) var class HitDamageType; // damage type of last hit (for playing hit/death anims) var vector TearOffMomentum; // momentum to apply when torn off (bTearOff == true) var EPhysics OldPhysics; var bool bPhysicsAnimUpdate; var bool bWasCrouched; var bool bWasWalking; var bool bWasOnGround; var bool bInitializeAnimation; var bool bPlayedDeath; // jjs - physics based animation stuff var bool bIsIdle; // true when standing still on the ground, Physics can be used for determining other states var bool bWaitForAnim; // true if the pawn is playing an important non-looping animation (eg. landing/dodge) and doesn't feel like being interrupted var const bool bReverseRun; var bool bDoTorsoTwist; var const bool FootTurning; var const bool FootStill; var const byte ViewPitch; // jjs - something to replicate so we can see which way remote clients are looking var int SmoothViewPitch; var int SmoothViewYaw; var float OldRotYaw; // used for determining if pawn is turning var vector OldAcceleration; var name MovementAnims[4]; // Forward, Back, Left, Right var name TurnLeftAnim; var name TurnRightAnim; // turning anims when standing in place (scaled by turn speed) var(AnimTweaks) float BlendChangeTime; // time to blend between movement animations var float MovementBlendStartTime; // used for delaying the start of run blending var float ForwardStrafeBias; // bias of strafe blending in forward direction var float BackwardStrafeBias; // bias of strafe blending in backward direction var float DodgeSpeedFactor; // dodge speed moved here so animation knows the diff between a jump and a dodge var float DodgeSpeedZ; var const int OldAnimDir; var const Vector OldVelocity; var float IdleTime; var name SwimAnims[4]; // 0=forward, 1=backwards, 2=left, 3=right var name CrouchAnims[4]; var name WalkAnims[4]; var name AirAnims[4]; var name TakeoffAnims[4]; var name LandAnims[4]; var name DoubleJumpAnims[4]; var name DodgeAnims[4]; var name AirStillAnim; var name TakeoffStillAnim; var name CrouchTurnRightAnim; var name CrouchTurnLeftAnim; var name IdleCrouchAnim; var name IdleSwimAnim; var name IdleWeaponAnim; // WeaponAttachment code will set this one var name IdleRestAnim; var name IdleChatAnim; var array TauntAnims; // Array of names of taunt anim that can be played by this character. First 4 assumed to be orders. var localized string TauntAnimNames[16]; // Text description var const int FootRot; // torso twisting/looking stuff var const int TurnDir; var name RootBone; var name HeadBone; var name SpineBone1; var name SpineBone2; // xPawn replicated properties - moved here to take advantage of native replication var(Shield) transient float ShieldStrength; // current shielding (having been activated) struct HitFXData { var() Name Bone; var() class damtype; var() bool bSever; var() Rotator rotDir; }; var() HitFXData HitFx[8]; var transient int HitFxTicker; var transient CompressedPosition PawnPosition; var Controller DelayedDamageInstigatorController; var Controller LastHitBy; //give kill credit to this guy if hit momentum causes pawn to fall to his death var float MinFlySpeed; var float MaxRotation; // minimum dot product of movement direction and rotation vector, ignored if 0 replication { // Variables the server should send to the client. reliable if( bNetDirty && (Role==ROLE_Authority) ) bSimulateGravity, bIsCrouched, bIsWalking, PlayerReplicationInfo, AnimAction, HitDamageType, TakeHitLocation,HeadScale, bIsTyping, DrivenVehicle, bSpecialHUD; reliable if( bTearOff && bNetDirty && (Role==ROLE_Authority) ) TearOffMomentum; reliable if ( bNetDirty && !bNetOwner && (Role==ROLE_Authority) ) bSteadyFiring, ViewPitch; // - jjs reliable if( bNetDirty && bNetOwner && Role==ROLE_Authority ) Controller,SelectedItem, GroundSpeed, WaterSpeed, AirSpeed, AccelRate, JumpZ, AirControl, bCanWallDodge, PitchUpLimit, PitchDownLimit; reliable if( bNetDirty && Role==ROLE_Authority ) Health; reliable if ( bNetDirty && bNetInitial && Role==ROLE_Authority ) HealthMax; unreliable if ( !bNetOwner && Role==ROLE_Authority ) PawnPosition; // xPawn replicated properties - moved here to take advantage of native replication reliable if (Role==ROLE_Authority) ShieldStrength, HitFx, HitFxTicker; // replicated functions sent to server by owning client reliable if( Role 500 ) return None; } return Weapon; } simulated function SetBaseEyeheight() { if ( !bIsCrouched ) BaseEyeheight = Default.BaseEyeheight; else BaseEyeheight = FMin(0.8 * CrouchHeight, CrouchHeight - 10); Eyeheight = BaseEyeheight; } function Pawn GetAimTarget() { return self; } function DeactivateSpawnProtection() { SpawnTime = -100000; } function Actor GetPathTo(Actor Dest) { if ( PlayerController(Controller) == None ) return Dest; return PlayerController(Controller).GetPathTo(Dest); } function PlayerChangedTeam() { Died( None, class'DamageType', Location ); } /* Reset() reset actor to initial state - used when restarting level without reloading. */ function Reset() { if ( (Controller == None) || Controller.bIsPlayer ) { if ( Controller != None ) Controller.PawnDied(self); Destroy(); } else Super.Reset(); } function bool HasWeapon() { return (Weapon != None); } function ChooseFireAt( Actor A ) { Fire(0); } function bool StopWeaponFiring() { if (Weapon != None && Weapon.IsFiring()) { Weapon.ServerStopFire(0); Weapon.ServerStopFire(1); return true; } return false; } simulated function Fire( optional float F ) { if (Weapon != None) { Weapon.Fire(F); } } simulated function AltFire( optional float F ) { if( Weapon!=None ) Weapon.AltFire(F); } function bool RecommendLongRangedAttack() { if ( Weapon != None ) return Weapon.RecommendLongRangedAttack(); return false; } function bool CanAttack(Actor Other) { if ( Weapon == None ) return false; return Weapon.CanAttack(Other); } function bool TooCloseToAttack(Actor Other) { return false; } function float RefireRate() { if (Weapon != None) return Weapon.RefireRate(); return 0; } function bool IsFiring() { if (Weapon != None) return Weapon.IsFiring(); return false; } function bool FireOnRelease() { if (Weapon != None) return Weapon.FireOnRelease(); return false; } function bool NeedToTurn(vector targ) { local vector LookDir, AimDir; LookDir = Vector(Rotation); LookDir.Z = 0; LookDir = Normal(LookDir); AimDir = targ - Location; AimDir.Z = 0; AimDir = Normal(AimDir); return ((LookDir Dot AimDir) < 0.93); } function float ModifyThreat(float current, Pawn Threat) { return current; } function DrawHUD(Canvas Canvas); simulated function SpecialDrawCrosshair( Canvas C ); // If returns false, do normal calcview anyway function bool SpecialCalcView(out Actor ViewActor, out vector CameraLocation, out rotator CameraRotation); function bool SpectatorSpecialCalcView(PlayerController Viewer, out Actor ViewActor, out vector CameraLocation, out rotator CameraRotation); simulated function String GetHumanReadableName() { if ( PlayerReplicationInfo != None ) return PlayerReplicationInfo.PlayerName; return MenuName; } function PlayTeleportEffect(bool bOut, bool bSound) { MakeNoise(1.0); } function HoldFlag(Actor FlagActor); function DropFlag(); function bool PerformDodge(eDoubleClickDir DoubleClickMove, vector Dir, vector Cross); function NotifyTeamChanged(); /* PossessedBy() Pawn is possessed by Controller */ function PossessedBy(Controller C) { Controller = C; NetPriority = 3; NetUpdateFrequency = 100; NetUpdateTime = Level.TimeSeconds - 1; if ( C.PlayerReplicationInfo != None ) { PlayerReplicationInfo = C.PlayerReplicationInfo; OwnerName = PlayerReplicationInfo.PlayerName; } if ( C.IsA('PlayerController') ) { if ( bSetPCRotOnPossess ) C.SetRotation(Rotation); if ( Level.NetMode != NM_Standalone ) RemoteRole = ROLE_AutonomousProxy; BecomeViewTarget(); } else RemoteRole = Default.RemoteRole; SetOwner(Controller); // for network replication Eyeheight = BaseEyeHeight; ChangeAnimation(); } function UnPossessed() { NetUpdateTime = Level.TimeSeconds - 1; if ( DrivenVehicle != None ) NetUpdateFrequency = 5; PlayerReplicationInfo = None; SetOwner(None); Controller = None; } /* PointOfView() called by controller when possessing this pawn false = 1st person, true = 3rd person */ simulated function bool PointOfView() { return false; } function BecomeViewTarget() { bUpdateEyeHeight = true; } function DropToGround() { bCollideWorld = True; bInterpolating = false; if ( Health > 0 ) { SetCollision(true,true); SetPhysics(PHYS_Falling); AmbientSound = None; if ( IsHumanControlled() ) Controller.GotoState(LandMovementState); } } function bool CanGrabLadder() { return ( bCanClimbLadders && (Controller != None) && (Physics != PHYS_Ladder) && ((Physics != Phys_Falling) || (abs(Velocity.Z) <= JumpZ)) ); } event SetWalking(bool bNewIsWalking) { if ( bNewIsWalking != bIsWalking ) { bIsWalking = bNewIsWalking; ChangeAnimation(); } } simulated function bool CanSplash() { if ( (Level.TimeSeconds - SplashTime > 0.15) && ((Physics == PHYS_Falling) || (Physics == PHYS_Flying)) && (Abs(Velocity.Z) > 100) ) { SplashTime = Level.TimeSeconds; return true; } return false; } function EndClimbLadder(LadderVolume OldLadder) { if ( Controller != None ) Controller.EndClimbLadder(); if ( Physics == PHYS_Ladder ) SetPhysics(PHYS_Falling); } function ClimbLadder(LadderVolume L) { OnLadder = L; SetRotation(OnLadder.WallDir); SetPhysics(PHYS_Ladder); if ( IsHumanControlled() ) Controller.GotoState('PlayerClimbing'); } /* DisplayDebug() list important actor variable on canvas. Also show the pawn's controller and weapon info */ simulated function DisplayDebug(Canvas Canvas, out float YL, out float YPos) { local string T; Super.DisplayDebug(Canvas, YL, YPos); Canvas.SetDrawColor(255,255,255); Canvas.DrawText("Animation Action "$AnimAction$" Health "$Health); YPos += YL; Canvas.SetPos(4,YPos); Canvas.DrawText("Anchor "$Anchor$" Serpentine Dist "$SerpentineDist$" Time "$SerpentineTime); YPos += YL; Canvas.SetPos(4,YPos); T = "Floor "$Floor$" DesiredSpeed "$DesiredSpeed$" Crouched "$bIsCrouched$" Try to uncrouch "$UncrouchTime; if ( (OnLadder != None) || (Physics == PHYS_Ladder) ) T=T$" on ladder "$OnLadder; Canvas.DrawText(T); YPos += YL; Canvas.SetPos(4,YPos); Canvas.DrawText("EyeHeight "$Eyeheight$" BaseEyeHeight "$BaseEyeHeight$" Physics Anim "$bPhysicsAnimUpdate); YPos += YL; Canvas.SetPos(4,YPos); if ( Controller == None ) { Canvas.SetDrawColor(255,0,0); Canvas.DrawText("NO CONTROLLER"); YPos += YL; Canvas.SetPos(4,YPos); } else { if ( Controller.PlayerReplicationInfo != None ) { Canvas.SetDrawColor(255,0,0); Canvas.DrawText("Owned by "$Controller.PlayerReplicationInfo.PlayerName); YPos += YL; Canvas.SetPos(4,YPos); } Controller.DisplayDebug(Canvas,YL,YPos); } if ( Weapon == None ) { Canvas.SetDrawColor(0,255,0); Canvas.DrawText("NO WEAPON"); YPos += YL; Canvas.SetPos(4,YPos); } else Weapon.DisplayDebug(Canvas,YL,YPos); } // // Compute offset for drawing an inventory item. // simulated function vector CalcDrawOffset(inventory Inv) { local vector DrawOffset; if ( Controller == None ) return (Inv.PlayerViewOffset >> Rotation) + BaseEyeHeight * vect(0,0,1); DrawOffset = ((0.9/Weapon.DisplayFOV * 100 * ModifiedPlayerViewOffset(Inv)) >> GetViewRotation() ); if ( !IsLocallyControlled() ) DrawOffset.Z += BaseEyeHeight; else { DrawOffset.Z += EyeHeight; if( bWeaponBob ) DrawOffset += WeaponBob(Inv.BobDamping); DrawOffset += CameraShake(); } return DrawOffset; } simulated function vector CameraShake() { local vector x, y, z, shakevect; local PlayerController pc; pc = PlayerController(Controller); if (pc == None) return shakevect; GetAxes(pc.Rotation, x, y, z); shakevect = pc.ShakeOffset.X * x + pc.ShakeOffset.Y * y + pc.ShakeOffset.Z * z; return shakevect; } simulated function vector ModifiedPlayerViewOffset(inventory Inv) { return Inv.PlayerViewOffset; } simulated function vector WeaponBob(float BobDamping) { Local Vector WBob; WBob = BobDamping * WalkBob; WBob.Z = (0.45 + 0.55 * BobDamping) * WalkBob.Z; WBob.Z += LandBob; return WBob; } function CheckBob(float DeltaTime, vector Y) { local float Speed2D; if( !bWeaponBob || bJustLanded ) { BobTime = 0; WalkBob = Vect(0,0,0); return; } Bob = FClamp(Bob, -0.01, 0.01); if (Physics == PHYS_Walking ) { Speed2D = VSize(Velocity); if ( Speed2D < 10 ) BobTime += 0.2 * DeltaTime; else BobTime += DeltaTime * (0.3 + 0.7 * Speed2D/GroundSpeed); WalkBob = Y * Bob * Speed2D * sin(8 * BobTime); AppliedBob = AppliedBob * (1 - FMin(1, 16 * deltatime)); WalkBob.Z = AppliedBob; if ( Speed2D > 10 ) WalkBob.Z = WalkBob.Z + 0.75 * Bob * Speed2D * sin(16 * BobTime); } else if ( Physics == PHYS_Swimming ) { BobTime += DeltaTime; Speed2D = Sqrt(Velocity.X * Velocity.X + Velocity.Y * Velocity.Y); WalkBob = Y * Bob * 0.5 * Speed2D * sin(4.0 * BobTime); WalkBob.Z = Bob * 1.5 * Speed2D * sin(8.0 * BobTime); } else { BobTime = 0; WalkBob = WalkBob * (1 - FMin(1, 8 * deltatime)); } } //*************************************** // Vehicle driving // StartDriving() and StopDriving() also called on client // on transitions of bIsDriving setting simulated event StartDriving(Vehicle V) { DrivenVehicle = V; NetUpdateTime = Level.TimeSeconds - 1; AmbientSound = None; StopWeaponFiring(); DeactivateSpawnProtection(); // Move the driver into position, and attach to car. ShouldCrouch(false); bIgnoreForces = true; Velocity = vect(0,0,0); Acceleration = vect(0,0,0); bCanTeleport = false; if ( !V.bRemoteControlled || V.bHideRemoteDriver ) { SetCollision( False, False, False); bCollideWorld = false; V.AttachDriver( Self ); if ( V.bDrawDriverinTP ) CullDistance = 5000; else bHidden = true; } // set animation bPhysicsAnimUpdate = false; bWaitForAnim = false; if ( !V.bHideRemoteDriver && V.bDrawDriverinTP ) { if ( HasAnim(DrivenVehicle.DriveAnim) ) LoopAnim(DrivenVehicle.DriveAnim); else LoopAnim('Vehicle_Driving'); SetAnimFrame(0.5); SmoothViewYaw = Rotation.Yaw; SetTwistLook(0,0); } else if ( !V.bRemoteControlled ) { LoopAnim('Vehicle_Driving'); } } simulated event StopDriving(Vehicle V) { if ( (Role == ROLE_Authority) && (PlayerController(Controller) != None) ) V.PlayerStartTime = Level.TimeSeconds + 12; CullDistance = Default.CullDistance; NetUpdateTime = Level.TimeSeconds - 1; if (V != None && V.Weapon != None ) V.Weapon.ImmediateStopFire(); if ( Physics == PHYS_Karma ) return; DrivenVehicle = None; bIgnoreForces = false; bHardAttach = false; bWaitForAnim = false; bCanTeleport = true; bCollideWorld = true; PlayWaiting(); //PrePivot = vect(0,0,0); if ( V != None ) V.DetachDriver( Self ); bPhysicsAnimUpdate = Default.bPhysicsAnimUpdate; SetCollision(True, True); if ( (Role == ROLE_Authority) && (Health > 0) ) { if ( !V.bRemoteControlled || V.bHideRemoteDriver ) { Acceleration = vect(0, 0, 24000); if ( PhysicsVolume.bWaterVolume ) SetPhysics(PHYS_Swimming); else SetPhysics(PHYS_Falling); SetBase(None); bHidden = false; } } bOwnerNoSee = default.bOwnerNoSee; if ( Weapon != None ) { PendingWeapon = None; Weapon.BringUp(); } } simulated function bool FindValidTaunt( out name Sequence ) { return true; } // CheckTauntValid() is obsolete, use FindValidTaunt() simulated function bool CheckTauntValid( name Sequence ) { return FindValidTaunt(sequence); } //*************************************** // Interface to Pawn's Controller // return true if controlled by a Player (AI or human) simulated function bool IsPlayerPawn() { return ( (Controller != None) && Controller.bIsPlayer ); } // return true if was controlled by a Player (AI or human) simulated function bool WasPlayerPawn() { return false; } // return true if controlled by a real live human simulated function bool IsHumanControlled() { return ( PlayerController(Controller) != None ); } // return true if controlled by local (not network) player simulated function bool IsLocallyControlled() { if ( Level.NetMode == NM_Standalone ) return true; if ( Controller == None ) return false; if ( PlayerController(Controller) == None ) return true; return ( Viewport(PlayerController(Controller).Player) != None ); } // return true if viewing this pawn in first person pov. useful for determining what and where to spawn effects simulated function bool IsFirstPerson() { local PlayerController PC; PC = PlayerController(Controller); return ( PC != None && !PC.bBehindView && Viewport(PC.Player) != None ); } simulated function rotator GetViewRotation() { if ( Controller == None ) return Rotation; return Controller.GetViewRotation(); } simulated function SetViewRotation(rotator NewRotation ) { if ( Controller != None ) Controller.SetRotation(NewRotation); } final function bool InGodMode() { return ( (Controller != None) && Controller.bGodMode ); } function bool NearMoveTarget() { if ( (Controller == None) || (Controller.MoveTarget == None) ) return false; return ReachedDestination(Controller.MoveTarget); } simulated final function bool PressingFire() { return ( (Controller != None) && (Controller.bFire != 0) ); } simulated final function bool PressingAltFire() { return ( (Controller != None) && (Controller.bAltFire != 0) ); } function Actor GetMoveTarget() { if ( Controller == None ) return None; return Controller.MoveTarget; } function SetMoveTarget(Actor NewTarget ) { if ( Controller != None ) Controller.MoveTarget = NewTarget; } function bool LineOfSightTo(actor Other) { return ( (Controller != None) && Controller.LineOfSightTo(Other) ); } simulated final function rotator AdjustAim(FireProperties FiredAmmunition, vector projStart, int aimerror) { if ( Controller == None ) return Rotation; return Controller.AdjustAim(FiredAmmunition, projStart, aimerror); } function Actor ShootSpecial(Actor A) { if ( !Controller.bCanDoSpecial || (Weapon == None) ) return None; SetRotation(rotator(A.Location - Location)); Controller.Focus = A; Controller.FireWeaponAt(A); return A; } /* return a value (typically 0 to 1) adjusting pawn's perceived strength if under some special influence (like berserk) */ function float AdjustedStrength() { return 0; } function HandlePickup(Pickup pick) { MakeNoise(0.2); if ( Controller != None ) Controller.HandlePickup(pick); } function ReceiveLocalizedMessage( class Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ) { if ( PlayerController(Controller) != None ) PlayerController(Controller).ReceiveLocalizedMessage( Message, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject ); } event ClientMessage( coerce string S, optional Name Type ) { if ( PlayerController(Controller) != None ) PlayerController(Controller).ClientMessage( S, Type ); } function Trigger( actor Other, pawn EventInstigator ) { if ( Controller != None ) Controller.Trigger(Other, EventInstigator); } //*************************************** function bool CanTrigger(Trigger T) { return true; } function CreateInventory(string InventoryClassName) { } function GiveWeapon(string aClassName ) { local class WeaponClass; local Weapon NewWeapon; WeaponClass = class(DynamicLoadObject(aClassName, class'Class')); if( FindInventoryType(WeaponClass) != None ) return; newWeapon = Spawn(WeaponClass); if( newWeapon != None ) newWeapon.GiveTo(self); } function SetDisplayProperties(ERenderStyle NewStyle, Material NewTexture, bool bLighting ) { Style = NewStyle; Texture = NewTexture; bUnlit = bLighting; if ( Weapon != None ) Weapon.SetDisplayProperties(Style, Texture, bUnlit); if ( !bUpdatingDisplay && (Inventory != None) ) { bUpdatingDisplay = true; Inventory.SetOwnerDisplay(); } bUpdatingDisplay = false; } function SetDefaultDisplayProperties() { Style = Default.Style; texture = Default.Texture; bUnlit = Default.bUnlit; if ( Weapon != None ) Weapon.SetDefaultDisplayProperties(); if ( !bUpdatingDisplay && (Inventory != None) ) { bUpdatingDisplay = true; Inventory.SetOwnerDisplay(); } bUpdatingDisplay = false; } function FinishedInterpolation() { DropToGround(); } function JumpOutOfWater(vector jumpDir) { Falling(); Velocity = jumpDir * WaterSpeed; Acceleration = jumpDir * AccelRate; velocity.Z = FMax(380,JumpZ); //set here so physics uses this for remainder of tick bUpAndOut = true; } /* Modify velocity called by physics before applying new velocity for this tick. Velocity,Acceleration, etc. have been updated by the physics, but location hasn't */ simulated event ModifyVelocity(float DeltaTime, vector OldVelocity); event FellOutOfWorld(eKillZType KillType) { if ( Level.NetMode == NM_Client ) return; if ( (Controller != None) && Controller.AvoidCertainDeath() ) return; Health = -1; if( KillType == KILLZ_Lava) Died( None, class'FellLava', Location ); else if(KillType == KILLZ_Suicide) Died( None, class'Fell', Location ); else { if ( Physics != PHYS_Karma ) SetPhysics(PHYS_None); Died( None, class'Fell', Location ); } } /* ShouldCrouch() Controller is requesting that pawn crouch */ function ShouldCrouch(bool Crouch) { if ( bWantsToCrouch != Crouch ) bWantsToCrouch = Crouch; } // Stub events called when physics actually allows crouch to begin or end // use these for changing the animation (if script controlled) event EndCrouch(float HeightAdjust) { EyeHeight -= HeightAdjust; OldZ += HeightAdjust; BaseEyeHeight = Default.BaseEyeHeight; } event StartCrouch(float HeightAdjust) { EyeHeight += HeightAdjust; OldZ -= HeightAdjust; BaseEyeHeight = FMin(0.8 * CrouchHeight, CrouchHeight - 10); } function RestartPlayer(); function AddVelocity( vector NewVelocity) { if ( bIgnoreForces || (NewVelocity == vect(0,0,0)) ) return; if ( (Physics == PHYS_Falling) && (AIController(Controller) != None) ) ImpactVelocity += NewVelocity; if ( (Physics == PHYS_Walking) || (((Physics == PHYS_Ladder) || (Physics == PHYS_Spider)) && (NewVelocity.Z > Default.JumpZ)) ) SetPhysics(PHYS_Falling); if ( (Velocity.Z > 380) && (NewVelocity.Z > 0) ) NewVelocity.Z *= 0.5; Velocity += NewVelocity; } function KilledBy( pawn EventInstigator ) { local Controller Killer; Health = 0; if ( EventInstigator != None ) Killer = EventInstigator.Controller; Died( Killer, class'Suicided', Location ); } function TakeFallingDamage() { local float Shake, EffectiveSpeed; if (Velocity.Z < -0.5 * MaxFallSpeed) { if ( Role == ROLE_Authority ) { MakeNoise(1.0); if (Velocity.Z < -1 * MaxFallSpeed) { EffectiveSpeed = Velocity.Z; if ( TouchingWaterVolume() ) EffectiveSpeed = FMin(0, EffectiveSpeed + 100); if ( EffectiveSpeed < -1 * MaxFallSpeed ) TakeDamage(-100 * (EffectiveSpeed + MaxFallSpeed)/MaxFallSpeed, None, Location, vect(0,0,0), class'Fell'); } } if ( Controller != None ) { Shake = FMin(1, -1 * Velocity.Z/MaxFallSpeed); Controller.DamageShake(Shake); } } else if (Velocity.Z < -1.4 * JumpZ) MakeNoise(0.5); } function ClientReStart() { Velocity = vect(0,0,0); Acceleration = vect(0,0,0); BaseEyeHeight = Default.BaseEyeHeight; EyeHeight = BaseEyeHeight; PlayWaiting(); } function ClientSetLocation( vector NewLocation, rotator NewRotation ) { if ( Controller != None ) Controller.ClientSetLocation(NewLocation, NewRotation); } function ClientSetRotation( rotator NewRotation ) { if ( Controller != None ) Controller.ClientSetRotation(NewRotation); } simulated function FaceRotation( rotator NewRotation, float DeltaTime ) { if ( Physics == PHYS_Ladder ) SetRotation(OnLadder.Walldir); else { if ( (Physics == PHYS_Walking) || (Physics == PHYS_Falling) ) NewRotation.Pitch = 0; SetRotation(NewRotation); } } function int LimitPitch(int pitch) { pitch = pitch & 65535; if (pitch > PitchUpLimit && pitch < PitchDownLimit) { if (pitch - PitchUpLimit < PitchDownLimit - pitch) pitch = PitchUpLimit; else pitch = PitchDownLimit; } return pitch; } function ClientDying(class DamageType, vector HitLocation) { if ( Controller != None ) Controller.ClientDying(DamageType, HitLocation); } function DoComboName( string ComboClassName ); function bool InCurrentCombo() { return false; } //============================================================================= // UDamage stub. function EnableUDamage(float Amount); function DisableUDamage(); //============================================================================= // Shield stubs. function float GetShieldStrengthMax(); function float GetShieldStrength(); function bool AddShieldStrength(int Amount); function int CanUseShield(int Amount); //============================================================================= // Inventory related functions. // check before throwing simulated function bool CanThrowWeapon() { return ( (Weapon != None) && Weapon.CanThrow() && Level.Game.bAllowWeaponThrowing ); } // toss out a weapon function TossWeapon(Vector TossVel) { local Vector X,Y,Z; Weapon.Velocity = TossVel; GetAxes(Rotation,X,Y,Z); Weapon.DropFrom(Location + 0.8 * CollisionRadius * X - 0.5 * CollisionRadius * Y); } exec function SwitchToLastWeapon() { if ( (Weapon != None) && (Weapon.OldWeapon != None) && Weapon.OldWeapon.HasAmmo() ) { PendingWeapon = Weapon.OldWeapon; Weapon.PutDown(); } } /* PrevWeapon() - switch to previous inventory group weapon */ simulated function PrevWeapon() { if ( Level.Pauser != None ) return; if ( Weapon == None && Controller != None ) { Controller.SwitchToBestWeapon(); return; } if ( PendingWeapon != None ) { if ( PendingWeapon.bForceSwitch ) return; PendingWeapon = Inventory.PrevWeapon(None, PendingWeapon); } else PendingWeapon = Inventory.PrevWeapon(None, Weapon); if ( PendingWeapon != None ) Weapon.PutDown(); } /* NextWeapon() - switch to next inventory group weapon */ simulated function NextWeapon() { if ( Level.Pauser != None ) return; if ( Weapon == None && Controller != None ) { Controller.SwitchToBestWeapon(); return; } if ( PendingWeapon != None ) { if ( PendingWeapon.bForceSwitch ) return; PendingWeapon = Inventory.NextWeapon(None, PendingWeapon); } else PendingWeapon = Inventory.NextWeapon(None, Weapon); if ( PendingWeapon != None ) Weapon.PutDown(); } // The player wants to switch to weapon group number F. simulated function SwitchWeapon(byte F) { local weapon newWeapon; if ( (Level.Pauser!=None) || (Inventory == None) ) return; if ( (Weapon != None) && (Weapon.Inventory != None) ) newWeapon = Weapon.Inventory.WeaponChange(F, false); else newWeapon = None; if ( newWeapon == None ) newWeapon = Inventory.WeaponChange(F, true); if ( newWeapon == None ) { if ( F == 10 ) ServerNoTranslocator(); return; } if ( PendingWeapon != None && PendingWeapon.bForceSwitch ) return; if ( Weapon == None ) { PendingWeapon = newWeapon; ChangedWeapon(); } else if ( Weapon != newWeapon || PendingWeapon != None ) { PendingWeapon = newWeapon; Weapon.PutDown(); } else if ( Weapon == newWeapon ) Weapon.Reselect(); // sjs } function ServerNoTranslocator() { if ( Level.Game != None ) Level.Game.NoTranslocatorKeyPressed( PlayerController(Controller) ); } // The player/bot wants to select next item exec function NextItem() { if (SelectedItem==None) { SelectedItem = Inventory.SelectNext(); Return; } if (SelectedItem.Inventory!=None) SelectedItem = SelectedItem.Inventory.SelectNext(); else SelectedItem = Inventory.SelectNext(); if ( SelectedItem == None ) SelectedItem = Inventory.SelectNext(); } // FindInventoryType() // returns the inventory item of the requested class // if it exists in this pawn's inventory function Inventory FindInventoryType( class DesiredClass ) { local Inventory Inv; local int Count; for( Inv=Inventory; Inv!=None && Count < 1000; Inv=Inv.Inventory ) { if ( Inv.class == DesiredClass ) return Inv; Count++; } // Search for subclasses if exact class wasn't found Count = 0; for ( Inv = Inventory; Inv != None && Count < 1000; Inv = Inv.Inventory ) { if ( ClassIsChildOf(Inv.Class, DesiredClass) ) return Inv; Count++; } return None; } // Add Item to this pawn's inventory. // Returns true if successfully added, false if not. function bool AddInventory( inventory NewItem ) { // Skip if already in the inventory. local inventory Inv; local actor Last, Prev; local bool bAddedInOrder; Last = self; // The item should not have been destroyed if we get here. if (NewItem ==None ) log("tried to add none inventory to "$self); NewItem.SetOwner(Self); NewItem.NetUpdateTime = Level.TimeSeconds - 1; // order weapons based on priority if ( Weapon(NewItem) != None ) { Prev = self; for( Inv=Inventory; Inv!=None; Inv=Inv.Inventory ) { if ( (Inv.InventoryGroup == NewItem.InventoryGroup) && (Weapon(Inv) != None) ) { if( (Weapon(Inv).Priority < Weapon(NewItem).Priority) ) { bAddedInOrder = true; break; } } else if ( (Weapon(Prev) != None) && (Weapon(Prev).InventoryGroup == NewItem.InventoryGroup) ) { bAddedInOrder = true; break; } if ( !bAddedInOrder ) Prev = Inv; } if ( bAddedInOrder ) { NewItem.Inventory = Prev.Inventory; Prev.Inventory = NewItem; Prev.NetUpdateTime = Level.TimeSeconds - 1; } } if ( !bAddedInOrder ) { for( Inv=Inventory; Inv!=None; Inv=Inv.Inventory ) { if( Inv == NewItem ) return false; Last = Inv; } // Add to back of inventory chain (so minimizes net replication effect). NewItem.Inventory = None; Last.Inventory = NewItem; Last.NetUpdateTime = Level.TimeSeconds - 1; } if ( Controller != None ) Controller.NotifyAddInventory(NewItem); return true; } // Remove Item from this pawn's inventory, if it exists. function DeleteInventory( inventory Item ) { // If this item is in our inventory chain, unlink it. local actor Link; local int Count; if ( Item == Weapon ) Weapon = None; if ( Item == SelectedItem ) SelectedItem = None; for( Link = Self; Link!=None; Link=Link.Inventory ) { if( Link.Inventory == Item ) { Link.Inventory = Item.Inventory; Item.Inventory = None; Link.NetUpdateTime = Level.TimeSeconds - 1; Item.NetUpdateTime = Level.TimeSeconds - 1; break; } if ( Level.NetMode == NM_Client ) { Count++; if ( Count > 1000 ) break; } } Item.SetOwner(None); } // Just changed to pendingWeapon simulated function ChangedWeapon() { local Weapon OldWeapon; ServerChangedWeapon(Weapon, PendingWeapon); if (Role < ROLE_Authority) { OldWeapon = Weapon; Weapon = PendingWeapon; PendingWeapon = None; if ( Controller != None ) Controller.ChangedWeapon(); if (Weapon != None) Weapon.BringUp(OldWeapon); } } function name GetOffhandBoneFor(Inventory I) { return ''; } function name GetWeaponBoneFor(Inventory I) { return 'righthand'; } function ServerChangedWeapon(Weapon OldWeapon, Weapon NewWeapon) { Weapon = NewWeapon; if ( Controller != None ) Controller.ChangedWeapon(); PendingWeapon = None; if ( OldWeapon != None ) { OldWeapon.SetDefaultDisplayProperties(); OldWeapon.DetachFromPawn(self); OldWeapon.GotoState('Hidden'); OldWeapon.NetUpdateFrequency = 2; } if ( Weapon != None ) { Weapon.NetUpdateFrequency = 100; Weapon.AttachToPawn(self); Weapon.BringUp(OldWeapon); PlayWeaponSwitch(NewWeapon); } if ( Inventory != None ) Inventory.OwnerEvent('ChangedWeapon'); // tell inventory that weapon changed (in case any effect was being applied) } function bool IsHeadShot(vector loc, vector ray, float AdditionalScale) { local coords C; local vector HeadLoc, B, M, diff; local float t, DotMM, Distance; local int look; if (HeadBone == '') return False; // If we are a dedicated server estimate what animation is most likely playing on the client if (Level.NetMode == NM_DedicatedServer) { if (Physics == PHYS_Falling) PlayAnim(AirAnims[0], 1.0, 0.0); else if (Physics == PHYS_Walking) { if (bIsCrouched) PlayAnim(IdleCrouchAnim, 1.0, 0.0); else PlayAnim(IdleWeaponAnim, 1.0, 0.0); if ( bDoTorsoTwist ) { SmoothViewYaw = Rotation.Yaw; SmoothViewPitch = ViewPitch; look = (256 * ViewPitch) & 65535; if (look > 32768) look -= 65536; SetTwistLook(0, look); } } else if (Physics == PHYS_Swimming) PlayAnim(SwimAnims[0], 1.0, 0.0); SetAnimFrame(0.5); } C = GetBoneCoords(HeadBone); HeadLoc = C.Origin + (HeadHeight * HeadScale * AdditionalScale * C.XAxis); // Express snipe trace line in terms of B + tM B = loc; M = ray * (2.0 * CollisionHeight + 2.0 * CollisionRadius); // Find Point-Line Squared Distance diff = HeadLoc - B; t = M Dot diff; if (t > 0) { DotMM = M dot M; if (t < DotMM) { t = t / DotMM; diff = diff - (t * M); } else { t = 1; diff -= M; } } else t = 0; Distance = Sqrt(diff Dot diff); return (Distance < (HeadRadius * HeadScale * AdditionalScale)); } //============== // Encroachment event bool EncroachingOn( actor Other ) { if ( Other.bWorldGeometry || Other.bBlocksTeleport ) return true; if ( (Vehicle(Other) != None) && (Weapon != None) && Weapon.IsA('Translauncher') ) return true; if ( ((Controller == None) || !Controller.bIsPlayer || bWarping) && (Pawn(Other) != None) ) return true; return false; } event EncroachedBy( actor Other ) { // Allow encroachment by Vehicles so they can push the pawn out of the way if ( Pawn(Other) != None && Vehicle(Other) == None ) gibbedBy(Other); } function gibbedBy(actor Other) { if ( Role < ROLE_Authority ) return; if ( Pawn(Other) != None ) Died(Pawn(Other).Controller, class'DamTypeTelefragged', Location); else Died(None, class'Gibbed', Location); } //Base change - if new base is pawn or decoration, damage based on relative mass and old velocity // Also, non-players will jump off pawns immediately function JumpOffPawn() { Velocity += (100 + CollisionRadius) * VRand(); Velocity.Z = 200 + CollisionHeight; SetPhysics(PHYS_Falling); bNoJumpAdjust = true; if ( Controller != None ) Controller.SetFall(); } singular event BaseChange() { local float decorMass; if ( bInterpolating ) return; if ( (base == None) && (Physics == PHYS_None) ) SetPhysics(PHYS_Falling); // Pawns can only set base to non-pawns, or pawns which specifically allow it. // Otherwise we do some damage and jump off. else if ( Pawn(Base) != None && Base != DrivenVehicle ) { if ( !Pawn(Base).bCanBeBaseForPawns ) { Base.TakeDamage( (1-Velocity.Z/400)* Mass/Base.Mass, Self,Location,0.5 * Velocity , class'Crushed'); JumpOffPawn(); } } else if ( (Decoration(Base) != None) && (Velocity.Z < -400) ) { decorMass = FMax(Decoration(Base).Mass, 1); Base.TakeDamage((-2* Mass/decorMass * Velocity.Z/400), Self, Location, 0.5 * Velocity, class'Crushed'); } } event UpdateEyeHeight( float DeltaTime ) { local float smooth, MaxEyeHeight; local float OldEyeHeight; local Actor HitActor; local vector HitLocation,HitNormal; if ( Controller == None ) { EyeHeight = 0; return; } if ( bTearOff ) { EyeHeight = Default.BaseEyeheight; bUpdateEyeHeight = false; return; } HitActor = trace(HitLocation,HitNormal,Location + (CollisionHeight + MAXSTEPHEIGHT + 14) * vect(0,0,1), Location + CollisionHeight * vect(0,0,1),true); if ( HitActor == None ) MaxEyeHeight = CollisionHeight + MAXSTEPHEIGHT; else MaxEyeHeight = HitLocation.Z - Location.Z - 14; if ( abs(Location.Z - OldZ) > 15 ) { bJustLanded = false; bLandRecovery = false; } // smooth up/down stairs if ( !bJustLanded ) { smooth = FMin(0.9, 10.0 * DeltaTime/Level.TimeDilation); LandBob *= (1 - smooth); if( Controller.WantsSmoothedView() ) { OldEyeHeight = EyeHeight; EyeHeight = FClamp((EyeHeight - Location.Z + OldZ) * (1 - smooth) + BaseEyeHeight * smooth, -0.5 * CollisionHeight, MaxEyeheight); } else EyeHeight = FMin(EyeHeight * ( 1 - smooth) + BaseEyeHeight * smooth, MaxEyeHeight); } else if ( bLandRecovery ) { smooth = FMin(0.9, 10.0 * DeltaTime); OldEyeHeight = EyeHeight; EyeHeight = FMin(EyeHeight * ( 1 - 0.6*smooth) + BaseEyeHeight * 0.6*smooth, BaseEyeHeight); LandBob *= (1 - smooth); if ( Eyeheight >= BaseEyeheight - 1) { bJustLanded = false; bLandRecovery = false; Eyeheight = BaseEyeheight; } } else { smooth = FMin(0.65, 10.0 * DeltaTime); OldEyeHeight = EyeHeight; EyeHeight = FMin(EyeHeight * (1 - 1.5*smooth), MaxEyeHeight); LandBob += 0.03 * (OldEyeHeight - Eyeheight); if ( (Eyeheight < 0.25 * BaseEyeheight + 1) || (LandBob > 3) ) { bLandRecovery = true; Eyeheight = 0.25 * BaseEyeheight + 1; } } Controller.AdjustView(DeltaTime); } /* EyePosition() Called by PlayerController to determine camera position in first person view. Returns the offset from the Pawn's location at which to place the camera */ simulated function vector EyePosition() { return EyeHeight * vect(0,0,1) + WalkBob; } //============================================================================= simulated event Destroyed() { if ( Shadow != None ) Shadow.Destroy(); if ( Controller != None ) Controller.PawnDied(self); if ( Level.NetMode == NM_Client ) return; while ( Inventory != None ) Inventory.Destroy(); Weapon = None; Super.Destroyed(); } //============================================================================= // // Called immediately before gameplay begins. // event PreBeginPlay() { Super.PreBeginPlay(); Instigator = self; DesiredRotation = Rotation; if ( bDeleteMe ) return; if ( BaseEyeHeight == 0 ) BaseEyeHeight = 0.8 * CollisionHeight; EyeHeight = BaseEyeHeight; if ( menuname == "" ) menuname = GetItemName(string(class)); } event PostBeginPlay() { local AIScript A; Super.PostBeginPlay(); SplashTime = 0; SpawnTime = Level.TimeSeconds; EyeHeight = BaseEyeHeight; OldRotYaw = Rotation.Yaw; // automatically add controller to pawns which were placed in level // NOTE: pawns spawned during gameplay are not automatically possessed by a controller if ( Level.bStartup && (Health > 0) && !bDontPossess ) { // check if I have an AI Script if ( AIScriptTag != '' ) { ForEach AllActors(class'AIScript',A,AIScriptTag) break; // let the AIScript spawn and init my controller if ( A != None ) { A.SpawnControllerFor(self); if ( Controller != None ) return; } } if ( (ControllerClass != None) && (Controller == None) ) Controller = spawn(ControllerClass); if ( Controller != None ) { Controller.Possess(self); AIController(Controller).Skill += SkillModifier; } } } // called after PostBeginPlay on net client simulated event PostNetBeginPlay() { local playercontroller P; if ( Level.bDropDetail || (Level.DetailMode == DM_Low) ) MaxLights = Min(4,MaxLights); if ( Role == ROLE_Authority ) return; if ( (Controller != None) && (Controller.Pawn == None) ) { Controller.Pawn = self; if ( (PlayerController(Controller) != None) && (PlayerController(Controller).ViewTarget == Controller) ) PlayerController(Controller).SetViewTarget(self); } if ( Role == ROLE_AutonomousProxy ) bUpdateEyeHeight = true; if ( (PlayerReplicationInfo != None) && (PlayerReplicationInfo.Owner == None) ) { PlayerReplicationInfo.SetOwner(Controller); if ( left(PlayerReplicationInfo.PlayerName, 5) ~= "PRESS" ) { P = Level.GetLocalPlayerController(); if ( (P.PlayerReplicationInfo != None) && !(left(PlayerReplicationInfo.PlayerName, 5) ~= "PRESS") ) bScriptPostRender = true; } } PlayWaiting(); } simulated function SetMesh() { if (Mesh != None) return; LinkMesh( default.mesh ); } function Gasp(); function SetMovementPhysics(); function bool GiveHealth(int HealAmount, int HealMax) { if (Health < HealMax) { Health = Min(HealMax, Health + HealAmount); return true; } return false; } function bool HasUDamage() { return false; } function int ShieldAbsorb( int damage ) { return damage; } function TakeDamage(int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, class damageType) { local int actualDamage; local Controller Killer; if ( damagetype == None ) { if ( InstigatedBy != None ) warn("No damagetype for damage by "$instigatedby$" with weapon "$InstigatedBy.Weapon); DamageType = class'DamageType'; } if ( Role < ROLE_Authority ) { log(self$" client damage type "$damageType$" by "$instigatedBy); return; } if ( Health <= 0 ) return; if ((instigatedBy == None || instigatedBy.Controller == None) && DamageType.default.bDelayedDamage && DelayedDamageInstigatorController != None) instigatedBy = DelayedDamageInstigatorController.Pawn; if ( (Physics == PHYS_None) && (DrivenVehicle == None) ) SetMovementPhysics(); if (Physics == PHYS_Walking && damageType.default.bExtraMomentumZ) momentum.Z = FMax(momentum.Z, 0.4 * VSize(momentum)); if ( instigatedBy == self ) momentum *= 0.6; momentum = momentum/Mass; if (Weapon != None) Weapon.AdjustPlayerDamage( Damage, InstigatedBy, HitLocation, Momentum, DamageType ); if (DrivenVehicle != None) DrivenVehicle.AdjustDriverDamage( Damage, InstigatedBy, HitLocation, Momentum, DamageType ); if ( (InstigatedBy != None) && InstigatedBy.HasUDamage() ) Damage *= 2; actualDamage = Level.Game.ReduceDamage(Damage, self, instigatedBy, HitLocation, Momentum, DamageType); if( DamageType.default.bArmorStops && (actualDamage > 0) ) actualDamage = ShieldAbsorb(actualDamage); Health -= actualDamage; if ( HitLocation == vect(0,0,0) ) HitLocation = Location; PlayHit(actualDamage,InstigatedBy, hitLocation, damageType, Momentum); if ( Health <= 0 ) { // pawn died if ( DamageType.default.bCausedByWorld && (instigatedBy == None || instigatedBy == self) && LastHitBy != None ) Killer = LastHitBy; else if ( instigatedBy != None ) Killer = instigatedBy.GetKillerController(); if ( Killer == None && DamageType.Default.bDelayedDamage ) Killer = DelayedDamageInstigatorController; if ( bPhysicsAnimUpdate ) TearOffMomentum = momentum; Died(Killer, damageType, HitLocation); } else { AddVelocity( momentum ); if ( Controller != None ) Controller.NotifyTakeHit(instigatedBy, HitLocation, actualDamage, DamageType, Momentum); if ( instigatedBy != None && instigatedBy != self ) LastHitBy = instigatedBy.Controller; } MakeNoise(1.0); } function SetDelayedDamageInstigatorController(Controller C) { DelayedDamageInstigatorController = C; } simulated function int GetTeamNum() { if ( Controller != None ) return Controller.GetTeamNum(); if ( (DrivenVehicle != None) && (DrivenVehicle.Controller != None) ) return DrivenVehicle.Controller.GetTeamNum(); if ( (PlayerReplicationInfo == None) || (PlayerReplicationInfo.Team == None) ) return 255; return PlayerReplicationInfo.Team.TeamIndex; } function TeamInfo GetTeam() { if ( PlayerReplicationInfo != None ) return PlayerReplicationInfo.Team; if ( (DrivenVehicle != None) && (DrivenVehicle.PlayerReplicationInfo != None) ) return DrivenVehicle.PlayerReplicationInfo.Team; return None; } function Controller GetKillerController() { return Controller; } function Died(Controller Killer, class damageType, vector HitLocation) { local Vector TossVel; local Trigger T; local NavigationPoint N; if ( bDeleteMe || Level.bLevelChange || Level.Game == None ) return; // already destroyed, or level is being cleaned up if ( DamageType.default.bCausedByWorld && (Killer == None || Killer == Controller) && LastHitBy != None ) Killer = LastHitBy; // mutator hook to prevent deaths // WARNING - don't prevent bot suicides - they suicide when really needed if ( Level.Game.PreventDeath(self, Killer, damageType, HitLocation) ) { Health = max(Health, 1); //mutator should set this higher return; } Health = Min(0, Health); if ( Weapon != None && (DrivenVehicle == None || DrivenVehicle.bAllowWeaponToss) ) { if ( Controller != None ) Controller.LastPawnWeapon = Weapon.Class; Weapon.HolderDied(); TossVel = Vector(GetViewRotation()); TossVel = TossVel * ((Velocity Dot TossVel) + 500) + Vect(0,0,200); TossWeapon(TossVel); } if ( DrivenVehicle != None ) { Velocity = DrivenVehicle.Velocity; DrivenVehicle.DriverDied(); } if ( Controller != None ) { Controller.WasKilledBy(Killer); Level.Game.Killed(Killer, Controller, self, damageType); } else Level.Game.Killed(Killer, Controller(Owner), self, damageType); DrivenVehicle = None; if ( Killer != None ) TriggerEvent(Event, self, Killer.Pawn); else TriggerEvent(Event, self, None); // make sure to untrigger any triggers requiring player touch if ( IsPlayerPawn() || WasPlayerPawn() ) { PhysicsVolume.PlayerPawnDiedInVolume(self); ForEach TouchingActors(class'Trigger',T) T.PlayerToucherDied(self); // event for HoldObjectives //for ( N=Level.NavigationPointList; N!=None; N=N.NextNavigationPoint ) // if ( N.bStatic && N.bReceivePlayerToucherDiedNotify ) ForEach TouchingActors(class'NavigationPoint', N) if ( N.bReceivePlayerToucherDiedNotify ) N.PlayerToucherDied( Self ); } // remove powerup effects, etc. RemovePowerups(); Velocity.Z *= 1.3; if ( IsHumanControlled() ) PlayerController(Controller).ForceDeathUpdate(); if ( (DamageType != None) && DamageType.default.bAlwaysGibs ) ChunkUp( Rotation, DamageType.default.GibPerterbation ); else { NetUpdateFrequency = Default.NetUpdateFrequency; PlayDying(DamageType, HitLocation); if ( Level.Game.bGameEnded ) return; if ( !bPhysicsAnimUpdate && !IsLocallyControlled() ) ClientDying(DamageType, HitLocation); } } function RemovePowerups(); event Falling() { //SetPhysics(PHYS_Falling); //Note - physics changes type to PHYS_Falling by default if ( Controller != None ) Controller.SetFall(); } event HitWall(vector HitNormal, actor Wall); event Landed(vector HitNormal) { ImpactVelocity = vect(0,0,0); TakeFallingDamage(); if ( Health > 0 ) PlayLanded(Velocity.Z); if ( (Velocity.Z < -200) && (PlayerController(Controller) != None) ) { bJustLanded = PlayerController(Controller).bLandingShake; OldZ = Location.Z; } LastHitBy = None; } event HeadVolumeChange(PhysicsVolume newHeadVolume) { if ( (Level.NetMode == NM_Client) || (Controller == None) ) return; if ( HeadVolume.bWaterVolume ) { if (!newHeadVolume.bWaterVolume) { if ( Controller.bIsPlayer && (BreathTime > 0) && (BreathTime < 8) ) Gasp(); BreathTime = -1.0; } } else if ( newHeadVolume.bWaterVolume ) BreathTime = UnderWaterTime; } function bool TouchingWaterVolume() { local PhysicsVolume V; ForEach TouchingActors(class'PhysicsVolume',V) if ( V.bWaterVolume ) return true; return false; } //Pain timer just expired. //Check what zone I'm in (and which parts are) //based on that cause damage, and reset BreathTime function bool IsInPain() { local PhysicsVolume V; ForEach TouchingActors(class'PhysicsVolume',V) if ( V.bPainCausing && (V.DamageType != ReducedDamageType) && (V.DamagePerSec > 0) ) return true; return false; } event BreathTimer() { if ( (Health < 0) || (Level.NetMode == NM_Client) || (DrivenVehicle != None) ) return; TakeDrowningDamage(); if ( Health > 0 ) BreathTime = 2.0; } function TakeDrowningDamage(); function bool CheckWaterJump(out vector WallNormal) { local actor HitActor; local vector HitLocation, HitNormal, checkpoint, start, checkNorm; if ( AIController(Controller) != None ) { checkpoint = Acceleration; checkpoint.Z = 0.0; } if ( checkpoint == vect(0,0,0)) checkpoint = vector(Rotation); checkpoint.Z = 0.0; checkNorm = Normal(checkpoint); checkPoint = Location + 1.2 * CollisionRadius * checkNorm; HitActor = Trace(HitLocation, HitNormal, checkpoint, Location, true, GetCollisionExtent()); if ( (HitActor != None) && (Pawn(HitActor) == None) ) { WallNormal = -1 * HitNormal; start = Location; start.Z += 1.1 * MAXSTEPHEIGHT; checkPoint = start + 2 * CollisionRadius * checkNorm; HitActor = Trace(HitLocation, HitNormal, checkpoint, start, true); if ( (HitActor == None) || (HitNormal.Z > 0.7) ) return true; } return false; } function DoDoubleJump( bool bUpdating ); function bool CanDoubleJump(); function bool CanMultiJump(); function UpdateRocketAcceleration(float DeltaTime, float YawChange, float PitchChange); function ProcessMove(float DeltaTime, vector NewAccel, eDoubleClickDir DoubleClickMove, rotator DeltaRot); function bool Dodge(eDoubleClickDir DoubleClickMove) { return false; } //Player Jumped function bool DoJump( bool bUpdating ) { if ( !bIsCrouched && !bWantsToCrouch && ((Physics == PHYS_Walking) || (Physics == PHYS_Ladder) || (Physics == PHYS_Spider)) ) { if ( Role == ROLE_Authority ) { if ( (Level.Game != None) && (Level.Game.GameDifficulty > 2) ) MakeNoise(0.1 * Level.Game.GameDifficulty); if ( bCountJumps && (Inventory != None) ) Inventory.OwnerEvent('Jumped'); } if ( Physics == PHYS_Spider ) Velocity = JumpZ * Floor; else if ( Physics == PHYS_Ladder ) Velocity.Z = 0; else if ( bIsWalking ) Velocity.Z = Default.JumpZ; else Velocity.Z = JumpZ; if ( (Base != None) && !Base.bWorldGeometry ) Velocity.Z += Base.Velocity.Z; SetPhysics(PHYS_Falling); return true; } return false; } /* PlayMoverHitSound() Mover Hit me, play appropriate sound if any */ function PlayMoverHitSound(); function PlayDyingSound(); function PlayHit(float Damage, Pawn InstigatedBy, vector HitLocation, class damageType, vector Momentum) { local vector BloodOffset, Mo, HitNormal; local class DesiredEffect; local class DesiredEmitter; local PlayerController Hearer; if ( DamageType == None ) return; if ( (Damage <= 0) && ((Controller == None) || !Controller.bGodMode) ) return; if (Damage > DamageType.Default.DamageThreshold) //spawn some blood { HitNormal = Normal(HitLocation - Location); // Play any set effect if ( EffectIsRelevant(Location,true) ) { DesiredEffect = DamageType.static.GetPawnDamageEffect(HitLocation, Damage, Momentum, self, (Level.bDropDetail || Level.DetailMode == DM_Low)); if ( DesiredEffect != None ) { BloodOffset = 0.2 * CollisionRadius * HitNormal; BloodOffset.Z = BloodOffset.Z * 0.5; Mo = Momentum; if ( Mo.Z > 0 ) Mo.Z *= 0.5; spawn(DesiredEffect,self,,HitLocation + BloodOffset, rotator(Mo)); } // Spawn any preset emitter DesiredEmitter = DamageType.Static.GetPawnDamageEmitter(HitLocation, Damage, Momentum, self, (Level.bDropDetail || Level.DetailMode == DM_Low)); if (DesiredEmitter != None) spawn(DesiredEmitter,,,HitLocation+HitNormal, Rotator(HitNormal)); } } if ( Health <= 0 ) { if ( PhysicsVolume.bDestructive && (PhysicsVolume.ExitActor != None) ) Spawn(PhysicsVolume.ExitActor); return; } if ( Level.TimeSeconds - LastPainTime > 0.1 ) { if ( InstigatedBy != None && (DamageType != None) && DamageType.default.bDirectDamage ) Hearer = PlayerController(InstigatedBy.Controller); if ( Hearer != None ) Hearer.bAcuteHearing = true; PlayTakeHit(HitLocation,Damage,damageType); if ( Hearer != None ) Hearer.bAcuteHearing = false; LastPainTime = Level.TimeSeconds; } } /* Pawn was killed - detach any controller, and die */ // blow up into little pieces (implemented in subclass) simulated function ChunkUp( Rotator HitRotation, float ChunkPerterbation ) { if ( (Level.NetMode != NM_Client) && (Controller != None) ) { if ( Controller.bIsPlayer ) Controller.PawnDied(self); else Controller.Destroy(); } destroy(); } simulated function TurnOff() { SetCollision(true,false); AmbientSound = None; bNoWeaponFiring = true; Velocity = vect(0,0,0); SetPhysics(PHYS_None); bPhysicsAnimUpdate = false; bIsIdle = true; bWaitForAnim = false; StopAnimating(); bIgnoreForces = true; } /* IsInLoadout() return true if InventoryClass is part of required or optional equipment */ function bool IsInLoadout(class InventoryClass) { return true; } State Dying { ignores Trigger, Bump, HitWall, HeadVolumeChange, PhysicsVolumeChange, Falling, BreathTimer; event ChangeAnimation() {} event StopPlayFiring() {} function PlayFiring(float Rate, name FiringMode) {} function PlayWeaponSwitch(Weapon NewWeapon) {} function PlayTakeHit(vector HitLoc, int Damage, class damageType) {} simulated function PlayNextAnimation() {} function Died(Controller Killer, class damageType, vector HitLocation) { } event FellOutOfWorld(eKillZType KillType) { if(KillType == KILLZ_Lava || KillType == KILLZ_Suicide ) return; Destroy(); } function Timer() { if ( !PlayerCanSeeMe() ) Destroy(); else SetTimer(2.0, false); } function Landed(vector HitNormal) { local rotator finalRot; if( Velocity.Z < -500 ) TakeDamage( (1-Velocity.Z/30),Instigator,Location,vect(0,0,0) , class'Crushed'); finalRot = Rotation; finalRot.Roll = 0; finalRot.Pitch = 0; setRotation(finalRot); SetPhysics(PHYS_None); SetCollision(true, false); if ( !IsAnimating(0) ) LieStill(); } /* ReduceCylinder() made obsolete by ragdoll deaths */ function ReduceCylinder() { SetCollision(false,false); } function LandThump() { // animation notify - play sound if actually landed, and animation also shows it if ( Physics == PHYS_None) bThumped = true; } event AnimEnd(int Channel) { if ( Channel != 0 ) return; if ( Physics == PHYS_None ) LieStill(); else if ( PhysicsVolume.bWaterVolume ) { bThumped = true; LieStill(); } } function LieStill() { if ( !bThumped ) LandThump(); ReduceCylinder(); } singular function BaseChange() { if( base == None ) SetPhysics(PHYS_Falling); else if ( Pawn(base) != None ) // don't let corpse ride around on someone's head ChunkUp( Rotation, 1.0 ); } function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, class damageType) { SetPhysics(PHYS_Falling); if ( (Physics == PHYS_None) && (Momentum.Z < 0) ) Momentum.Z *= -1; Velocity += 3 * momentum/(Mass + 200); if ( bInvulnerableBody ) return; Damage *= DamageType.Default.GibModifier; Health -=Damage; if ( ((Damage > 30) || !IsAnimating()) && (Health < -80) ) ChunkUp( Rotation, DamageType.default.GibPerterbation ); } function BeginState() { local int i; //log(self$" dying"); if ( bTearOff && (Level.NetMode == NM_DedicatedServer) ) LifeSpan = 1.0; else SetTimer(12.0, false); SetPhysics(PHYS_Falling); bInvulnerableBody = true; if ( Controller != None ) { if ( Controller.bIsPlayer ) Controller.PawnDied(self); else Controller.Destroy(); } for (i = 0; i < Attached.length; i++) if (Attached[i] != None) Attached[i].PawnBaseDied(); } Begin: Sleep(0.2); bInvulnerableBody = false; PlayDyingSound(); } //============================================================================= // Animation interface for controllers simulated event SetAnimAction(name NewAction); /* PlayXXX() function called by controller to play transient animation actions */ simulated event PlayDying(class DamageType, vector HitLoc) { AmbientSound = None; GotoState('Dying'); if ( bPhysicsAnimUpdate ) { bReplicateMovement = false; bTearOff = true; Velocity += TearOffMomentum; SetPhysics(PHYS_Falling); } bPlayedDeath = true; } simulated function PlayFiring(optional float Rate, optional name FiringMode); function PlayWeaponSwitch(Weapon NewWeapon); simulated event StopPlayFiring() { bSteadyFiring = false; } function PlayTakeHit(vector HitLoc, int Damage, class damageType) { local Sound DesiredSound; if (Damage==0) return; // // Play a hit sound according to the DamageType DesiredSound = DamageType.Static.GetPawnDamageSound(); if (DesiredSound != None) PlayOwnedSound(DesiredSound,SLOT_Misc); } //============================================================================= // Pawn internal animation functions simulated event ChangeAnimation() { if ( (Controller != None) && Controller.bControlAnimations ) return; // player animation - set up new idle and moving animations PlayWaiting(); PlayMoving(); } simulated event AnimEnd(int Channel) { if ( Channel == 0 ) PlayWaiting(); } // Animation group checks (usually implemented in subclass) function bool CannotJumpNow() { return false; } simulated event PlayJump(); simulated event PlayFalling(); simulated function PlayMoving(); simulated function PlayWaiting(); function PlayLanded(float impactVel) { if ( !bPhysicsAnimUpdate ) PlayLandingAnimation(impactvel); } simulated event PlayLandingAnimation(float ImpactVel); function PlayVictoryAnimation(); function Vehicle GetVehicleBase() { return Vehicle(Base); } function int GetSpree() { return 0; } function IncrementSpree(); // Allows a pawn to process the raw input from the controller simulated function RawInput(float DeltaTime, float aBaseX, float aBaseY, float aBaseZ, float aMouseX, float aMouseY, float aForward, float aTurn, float aStrafe, float aUp, float aLookUp) { } function Suicide() { KilledBy(self); } // Cheats - invoked by CheatManager function bool CheatWalk() { UnderWaterTime = Default.UnderWaterTime; SetCollision(true, true , true); SetPhysics(PHYS_Walking); bCollideWorld = true; return true; } function bool CheatGhost() { UnderWaterTime = -1.0; SetCollision(false, false, false); bCollideWorld = false; return true; } function bool CheatFly() { UnderWaterTime = Default.UnderWaterTime; SetCollision(true, true , true); bCollideWorld = true; return true; } function float RangedAttackTime() { if ( Weapon != None ) return Weapon.RangedAttackTime(); return 0; } simulated function vector GetTargetLocation() { return Location; } sz&@5sG//============================================================================= // PathNode. //============================================================================= class PathNode extends NavigationPoint placeable native; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) sE class ParticleMaterial extends RenderedMaterial native noteditinlinenew; struct ParticleProjectorInfo { var bitmapmaterial BitmapMaterial; var matrix Matrix; var int Projected; var int BlendMode; }; var const int ParticleBlending; var const int BlendBetweenSubdivisions; var const int RenderTwoSided; var const int UseTFactor; var const bitmapmaterial BitmapMaterial; var const int AlphaTest; var const int AlphaRef; var const int ZTest; var const int ZWrite; var const int Wireframe; var transient bool AcceptsProjectors; var transient const int NumProjectors; var transient const ParticleProjectorInfo Projectors[8]; skcn"@* Gssesissnjm";z_N% Gsss{,@sszmh6{h z{,h Gsp@GsqGsrGssGsGsy,4sv@@5y,sp@@5sh//============================================================================= // ParticleEmitter: Base class for sub- emitters. // // make sure to keep structs in sync in UnParticleSystem.h //============================================================================= class ParticleEmitter extends Object abstract editinlinenew native; enum EBlendMode { BM_MODULATE, BM_MODULATE2X, BM_MODULATE4X, BM_ADD, BM_ADDSIGNED, BM_ADDSIGNED2X, BM_SUBTRACT, BM_ADDSMOOTH, BM_BLENDDIFFUSEALPHA, BM_BLENDTEXTUREALPHA, BM_BLENDFACTORALPHA, BM_BLENDTEXTUREALPHAPM, BM_BLENDCURRENTALPHA, BM_PREMODULATE, BM_MODULATEALPHA_ADDCOLOR, BM_MODULATEINVALPHA_ADDCOLOR, BM_MODULATEINVCOLOR_ADDALPHA, BM_HACK }; enum EParticleDrawStyle { PTDS_Regular, PTDS_AlphaBlend, PTDS_Modulated, PTDS_Translucent, PTDS_AlphaModulate_MightNotFogCorrectly, PTDS_Darken, PTDS_Brighten }; enum EParticleCoordinateSystem { PTCS_Independent, PTCS_Relative, PTCS_Absolute }; enum EParticleRotationSource { PTRS_None, PTRS_Actor, PTRS_Offset, PTRS_Normal }; enum EParticleVelocityDirection { PTVD_None, PTVD_StartPositionAndOwner, PTVD_OwnerAndStartPosition, PTVD_AddRadial }; enum EParticleStartLocationShape { PTLS_Box, PTLS_Sphere, PTLS_Polar, PTLS_All }; enum EParticleEffectAxis { PTEA_NegativeX, PTEA_PositiveZ }; enum EParticleCollisionSound { PTSC_None, PTSC_LinearGlobal, PTSC_LinearLocal, PTSC_Random }; enum EParticleMeshSpawning { PTMS_None, PTMS_Linear, PTMS_Random }; enum ESkelLocationUpdate { PTSU_None, PTSU_SpawnOffset, PTSU_Location }; struct ParticleTimeScale { var () float RelativeTime; // always in range [0..1] var () float RelativeSize; }; struct ParticleRevolutionScale { var () float RelativeTime; // always in range [0..1] var () vector RelativeRevolution; }; struct ParticleColorScale { var () float RelativeTime; // always in range [0..1] var () color Color; }; struct ParticleVelocityScale { var () float RelativeTime; // always in range [0..1] var () vector RelativeVelocity; }; struct Particle { var vector Location; var vector OldLocation; var vector Velocity; var vector StartSize; var vector SpinsPerSecond; var vector StartSpin; var vector RevolutionCenter; var vector RevolutionsPerSecond; var vector RevolutionsMultiplier; var vector Size; var vector StartLocation; var vector ColorMultiplier; var vector VelocityMultiplier; var vector OldMeshLocation; var color Color; var float Time; var float MaxLifetime; var float Mass; var int HitCount; var int Flags; var int Subdivision; var int BoneIndex; }; struct ParticleSound { var () sound Sound; var () range Radius; var () range Pitch; var () int Weight; var () range Volume; var () range Probability; }; // FLAGS var (Collision) bool UseCollision; var (Collision) bool UseCollisionPlanes; var (Collision) bool UseMaxCollisions; var (Collision) bool UseSpawnedVelocityScale; var (Color) bool UseColorScale; var (Fading) bool FadeOut; var (Fading) bool FadeIn; var (Force) bool UseActorForces; var (General) bool ResetAfterChange; var (Local) bool RespawnDeadParticles; var (Local) bool AutoDestroy; var (Local) bool AutoReset; var (Local) bool Disabled; var bool Backup_Disabled; // for resetting var (Local) bool DisableFogging; var (MeshSpawning) bool VelocityFromMesh; var (MeshSpawning) bool UniformMeshScale; var (MeshSpawning) bool UniformVelocityScale; var (MeshSpawning) bool UseColorFromMesh; var (MeshSpawning) bool SpawnOnlyInDirectionOfNormal; var (Rendering) bool AlphaTest; var (Rendering) bool AcceptsProjectors; var (Rendering) bool ZTest; var (Rendering) bool ZWrite; var (Revolution) bool UseRevolution; var (Revolution) bool UseRevolutionScale; var (Rotation) bool SpinParticles; var (Rotation) bool DampRotation; var (Size) bool UseSizeScale; var (Size) bool UseAbsoluteTimeForSizeScale; var (Size) bool UseRegularSizeScale; var (Size) bool UniformSize; var (Size) bool DetermineVelocityByLocationDifference; var (Size) bool ScaleSizeXByVelocity; var (Size) bool ScaleSizeYByVelocity; var (Size) bool ScaleSizeZByVelocity; var (Spawning) bool AutomaticInitialSpawning; var (Texture) bool BlendBetweenSubdivisions; var (Texture) bool UseSubdivisionScale; var (Texture) bool UseRandomSubdivision; var (Trigger) bool TriggerDisabled; var (Trigger) bool ResetOnTrigger; var (Velocity) bool UseVelocityScale; var (Velocity) bool AddVelocityFromOwner; var (Performance) float LowDetailFactor; var (Acceleration) vector Acceleration; var (Collision) vector ExtentMultiplier; var (Collision) rangevector DampingFactorRange; var (Collision) array CollisionPlanes; var (Collision) range MaxCollisions; var (Collision) int SpawnFromOtherEmitter; var (Collision) int SpawnAmount; var (Collision) rangevector SpawnedVelocityScaleRange; var (Color) array ColorScale; var (Color) float ColorScaleRepeats; var (Color) rangevector ColorMultiplierRange; var (Color) float Opacity; var (Fading) plane FadeOutFactor; var (Fading) float FadeOutStartTime; var (Fading) plane FadeInFactor; var (Fading) float FadeInEndTime; var (General) EParticleCoordinateSystem CoordinateSystem; var (General) const int MaxParticles; var (General) EParticleEffectAxis EffectAxis; var (Local) range AutoResetTimeRange; var (Local) string Name; var (Local) EDetailMode DetailMode; var (Location) vector StartLocationOffset; var (Location) rangevector StartLocationRange; var (Location) int AddLocationFromOtherEmitter; var (Location) EParticleStartLocationShape StartLocationShape; var (Location) range SphereRadiusRange; var (Location) rangevector StartLocationPolarRange; var (Mass) range StartMassRange; var (MeshSpawning) staticmesh MeshSpawningStaticMesh; var (MeshSpawning) EParticleMeshSpawning MeshSpawning; var (MeshSpawning) rangevector VelocityScaleRange; var (MeshSpawning) rangevector MeshScaleRange; var (MeshSpawning) vector MeshNormal; var (MeshSpawning) range MeshNormalThresholdRange; var (Rendering) int AlphaRef; var (Revolution) rangevector RevolutionCenterOffsetRange; var (Revolution) rangevector RevolutionsPerSecondRange; var (Revolution) array RevolutionScale; var (Revolution) float RevolutionScaleRepeats; var (Rotation) EParticleRotationSource UseRotationFrom; var (Rotation) rotator RotationOffset; var (Rotation) vector SpinCCWorCW; var (Rotation) rangevector SpinsPerSecondRange; var (Rotation) rangevector StartSpinRange; var (Rotation) rangevector RotationDampingFactorRange; var (Rotation) vector RotationNormal; var (Size) array SizeScale; var (Size) float SizeScaleRepeats; var (Size) rangevector StartSizeRange; var (Size) vector ScaleSizeByVelocityMultiplier; var (Size) float ScaleSizeByVelocityMax; var (SkeletalMesh) ESkelLocationUpdate UseSkeletalLocationAs; var (SkeletalMesh) actor SkeletalMeshActor; var (SkeletalMesh) vector SkeletalScale; var (SkeletalMesh) range RelativeBoneIndexRange; var (Sound) array Sounds; var (Sound) EParticleCollisionSound SpawningSound; var (Sound) range SpawningSoundIndex; var (Sound) range SpawningSoundProbability; var (Sound) EParticleCollisionSound CollisionSound; var (Sound) range CollisionSoundIndex; var (Sound) range CollisionSoundProbability; var (Spawning) float ParticlesPerSecond; var (Spawning) float InitialParticlesPerSecond; var (Texture) EParticleDrawStyle DrawStyle; var (Texture) texture Texture; var (Texture) int TextureUSubdivisions; var (Texture) int TextureVSubdivisions; var (Texture) array SubdivisionScale; var (Texture) int SubdivisionStart; var (Texture) int SubdivisionEnd; var (Tick) float SecondsBeforeInactive; var (Tick) float MinSquaredVelocity; var (Time) range InitialTimeRange; var (Time) range LifetimeRange; var (Time) range InitialDelayRange; var (Trigger) range SpawnOnTriggerRange; var (Trigger) float SpawnOnTriggerPPS; var (Velocity) rangevector StartVelocityRange; var (Velocity) range StartVelocityRadialRange; var (Velocity) vector MaxAbsVelocity; var (Velocity) rangevector VelocityLossRange; var (Velocity) bool RotateVelocityLossRange; var (Velocity) int AddVelocityFromOtherEmitter; var (Velocity) rangevector AddVelocityMultiplierRange; var (Velocity) EParticleVelocityDirection GetVelocityDirectionFrom; var (Velocity) array VelocityScale; var (Velocity) float VelocityScaleRepeats; var (Warmup) float WarmupTicksPerSecond; var (Warmup) float RelativeWarmupTime; var transient emitter Owner; var transient bool Initialized; var transient bool Inactive; var transient bool RealDisableFogging; var transient bool AllParticlesDead; var transient bool WarmedUp; var transient float InactiveTime; var transient array Particles; var transient int ParticleIndex; // index into circular list of particles var transient int ActiveParticles; // currently active particles var transient float PPSFraction; // used to keep track of fractional PPTick var transient box BoundingBox; var transient vector RealExtentMultiplier; var transient int OtherIndex; var transient float InitialDelay; var transient vector GlobalOffset; var transient float TimeTillReset; var transient int PS2Data; var transient int MaxActiveParticles; var transient int CurrentCollisionSoundIndex; var transient int CurrentSpawningSoundIndex; var transient int CurrentMeshSpawningIndex; var transient float MaxSizeScale; var transient int KillPending; var transient int DeferredParticles; var transient vector RealMeshNormal; var transient array MeshVertsAndNormals; var transient int CurrentSpawnOnTrigger; var transient int RenderableParticles; var transient rangevector RealVelocityLossRange; native function SpawnParticle( int Amount ); native function Trigger(); native function Reset(); sw _iFw ii3bsServerName]~9=,$Text60 'i3bsAdminName]~9=,$Text40 ''i4bsAdminEmail]~9=,$Text60 ''iQbsMessageOfTheDay]~$$Custom255;;GUI2K4.MOTDConfigPage '' G sn%ssEp%g/oe%9p%Passwordn%9p%AdminNamehn%e% Gst4sr%@sszssP-{b0-Y*9:_%-x'QQf9?%-x(@-J,f-pfz&T JI-G-F-{&T fC-B-A--Q-I`9?%-U-L`9?%-W-[A9?%-V-PA9?%-I`9?%-L`9?%-[A9?%-PA9?%|`w` #<^z&wi{&w\ Gswssl//============================================================================= // Palette: A 256-color Unreal palette. // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class Palette extends Object native noexport; var native const array Colors; s~^T ] ^9?/^9?%-@''^I^~&^q,d-@'IIp,?~&I G sh// // OpacityModfifer - used to override a shader's opacity channel (eg for shaders on terrain). // class OpacityModifier extends Modifier noteditinlinenew native; var Material Opacity; var bool bOverrideTexModifier; sC class ObjectPool extends Object; var Array Objects; // // AllocateObject // simulated function Object AllocateObject(class ObjectClass) { local Object Result; local int ObjectIndex; for(ObjectIndex = 0;ObjectIndex < Objects.Length;ObjectIndex++) { if(Objects[ObjectIndex].Class == ObjectClass) { Result = Objects[ObjectIndex]; Objects.Remove(ObjectIndex,1); break; } } if(Result == None) Result = new(Outer) ObjectClass; return Result; } // // FreeObject // simulated function FreeObject(Object Obj) { Objects.Length = Objects.Length + 1; Objects[Objects.Length - 1] = Obj; } // // Shrink // simulated function Shrink() { while(Objects.Length > 0) { //delete Objects[Objects.Length - 1]; Objects.Remove(Objects.Length - 1,1); }; } st%@ssPoj"rozoC 2jz%zz~z:稨pAdding Global Ban for: zo{oH-E7zzo{oH7rrpDENY;zbo.upAC_BanpXQoupAC_Kickedxzwo*oaoa'( GsIssz//============================================================================= // A sticky note. Level designers can place these in the level and then // view them as a batch in the error/warnings window. //============================================================================= class Note extends Actor placeable native; #exec Texture Import File=Textures\Note.pcx Name=S_Note Mips=Off MASKED=1 var() string Text; sKk//============================================================================= // NavigationPoint. // // NavigationPoints are organized into a network to provide AIControllers // the capability of determining paths to arbitrary destinations in a level // //============================================================================= class NavigationPoint extends Actor hidecategories(Lighting,LightColor,Karma,Force) native; #exec Texture Import File=Textures\S_Pickup.pcx Name=S_Pickup Mips=Off MASKED=1 #exec Texture Import File=Textures\SpwnAI.pcx Name=S_NavP Mips=Off MASKED=1 // not used currently #exec Texture Import File=Textures\SiteLite.pcx Name=S_Alarm Mips=Off MASKED=1 //------------------------------------------------------------------------------ // NavigationPoint variables var transient bool bEndPoint; // used by C++ navigation code var transient bool bTransientEndPoint; // set right before a path finding attempt, cleared afterward. var transient bool bHideEditorPaths; // don't show paths to this node in the editor var transient bool bCanReach; // used during paths review in editor var bool taken; // set when a creature is occupying this spot var() bool bBlocked; // this path is currently unuseable var() bool bPropagatesSound; // this navigation point can be used for sound propagation (around corners) var() bool bOneWayPath; // reachspecs from this path only in the direction the path is facing (180 degrees) var() bool bNeverUseStrafing; // shouldn't use bAdvancedTactics going to this point var() bool bAlwaysUseStrafing; // shouldn't use bAdvancedTactics going to this point var const bool bForceNoStrafing;// override any LD changes to bNeverUseStrafing var const bool bAutoBuilt; // placed during execution of "PATHS BUILD" var bool bSpecialMove; // if true, pawn will call SuggestMovePreparation() when moving toward this node var bool bNoAutoConnect; // don't connect this path to others except with special conditions (used by LiftCenter, for example) var const bool bNotBased; // used by path builder - if true, no error reported if node doesn't have a valid base var const bool bPathsChanged; // used for incremental path rebuilding in the editor var bool bDestinationOnly; // used by path building - means no automatically generated paths are sourced from this node var bool bSourceOnly; // used by path building - means this node is not the destination of any automatically generated path var bool bSpecialForced; // paths that are forced should call the SpecialCost() and SuggestMovePreparation() functions var bool bMustBeReachable; // used for PathReview code var bool bBlockable; // true if path can become blocked (used by pruning during path building) var bool bFlyingPreferred; // preferred by flying creatures var bool bMayCausePain; // set in C++ if in PhysicsVolume that may cause pain var bool bReceivePlayerToucherDiedNotify; var bool bAlreadyVisited; // internal use var() bool bVehicleDestination; // if true, forced paths to this node will have max width to accomodate vehicles var() bool bMakeSourceOnly; var() bool bNoSuperSize; // hack for Leviathans, which pretend to be smaller than they really are to use the path network - this forces them not to use a path var bool bForcedOnly; // only connect forced paths to this NavigationPoint var const array PathList; //index of reachspecs (used by C++ Navigation code) var() name ProscribedPaths[4]; // list of names of NavigationPoints which should never be connected from this path var() name ForcedPaths[4]; // list of names of NavigationPoints which should always be connected from this path var int visitedWeight; var const int bestPathWeight; var const NavigationPoint nextNavigationPoint; var const NavigationPoint nextOrdered; // for internal use during route searches var const NavigationPoint prevOrdered; // for internal use during route searches var const NavigationPoint previousPath; var int cost; // added cost to visit this pathnode var() int ExtraCost; // Extra weight added by level designer var transient int TransientCost; // added right before a path finding attempt, cleared afterward. var transient int FearCost; // extra weight diminishing over time (used for example, to mark path where bot died) var Pickup InventoryCache; // used to point to dropped weapons var float InventoryDist; var const float LastDetourWeight; var byte BaseVisible[2]; // used by some team game types- whether this point is visible from red base or defense points var float BaseDist[2]; // used by some team game types - distance to red base var vector MaxPathSize; function PostBeginPlay() { local int i; ExtraCost = Max(ExtraCost,0); for ( i=0; i DefaultWeapon; var string DefaultWeaponName; var bool bUserAdded; // mc - mutator was added by user (cmdline or mutator list) var bool bAddToServerPackages; // if true, the package this mutator is in will be added to serverpackages at load time var() cache string IconMaterialName; var() cache string ConfigMenuClassName; var() cache string GroupName; // Will only allow one mutator with this tag to be selected. /* rjp --- A note about mutators & the caching system: In order for your mutator to appear in the game's mutator lists, you must create a cache file which contains your mutator's important information. This can be done automatically using a commandlet. If you wish to ensure support for multiple languages in your mutator, you should always export localized strings to .int before exporting the mutator's cache information. This ensures that the caching system will recognize that your mutator has localized properties and will adjust your mutator's cache entry accordingly. To export localized properties, use the 'dumpint' commandlet: 'ucc dumpint ' - generates .int file containing all localized properties. To export cache entries, use the 'exportcache' commandlet: 'ucc exportcache ' - generates a .ucl file containing all required caching information. Ex: (ACoolMutator.u) ucc dumpint ACoolMutator.u - generates ACoolMutator.int ucc exportcache ACoolMutator.u - generates ACoolMutator.ucl file containing an entry for each mutator, gameinfo, weapon, and crosshair in the ACoolMutator package. Adding "Object=()" lines to your mutator's .int file is no longer necessary. If the caching system finds any Object=() entries in an .int file for your mutator, it will automatically create the necessary .ucl file the first time the game is started. -- rjp */ var() localized cache string FriendlyName; var() localized cache string Description; /* Don't call Actor PreBeginPlay() for Mutator */ event PreBeginPlay() { if ( !MutatorIsAllowed() ) Destroy(); else if (bAddToServerPackages) AddToPackageMap(); } function bool MutatorIsAllowed() { return !Level.IsDemoBuild() || Class==class'Mutator'; } function Destroyed() { local Mutator M; // remove from mutator list if ( Level.Game.BaseMutator == self ) Level.Game.BaseMutator = NextMutator; else { for ( M=Level.Game.BaseMutator; M!=None; M=M.NextMutator ) if ( M.NextMutator == self ) { M.NextMutator = NextMutator; break; } } Super.Destroyed(); } function Mutate(string MutateString, PlayerController Sender) { if ( NextMutator != None ) NextMutator.Mutate(MutateString, Sender); } function ModifyLogin(out string Portal, out string Options) { if ( NextMutator != None ) NextMutator.ModifyLogin(Portal, Options); } //Notification that a player is exiting function NotifyLogout(Controller Exiting) { if (NextMutator != None) NextMutator.NotifyLogout(Exiting); } /* called by GameInfo.RestartPlayer() change the players jumpz, etc. here */ function ModifyPlayer(Pawn Other) { if ( NextMutator != None ) NextMutator.ModifyPlayer(Other); } /* return what should replace the default weapon mutators further down the list override earlier mutators */ function Class GetDefaultWeapon() { local Class W; if ( NextMutator != None ) { W = NextMutator.GetDefaultWeapon(); if ( W == None ) W = MyDefaultWeapon(); } else W = MyDefaultWeapon(); return W; } /* GetInventoryClass() return an inventory class - either the class specified by InventoryClassName, or a replacement. Called when spawning initial inventory for player */ function Class GetInventoryClass(string InventoryClassName) { InventoryClassName = GetInventoryClassOverride(InventoryClassName); return class(DynamicLoadObject(InventoryClassName, class'Class')); } /* GetInventoryClassOverride() return the string passed in, or a replacement class name string. */ function string GetInventoryClassOverride(string InventoryClassName) { // here, in mutator subclass, change InventoryClassName if desired. For example: // if ( InventoryClassName == "Weapons.DorkyDefaultWeapon" // InventoryClassName = "ModWeapons.SuperDisintegrator" if ( NextMutator != None ) return NextMutator.GetInventoryClassOverride(InventoryClassName); return InventoryClassName; } function class MyDefaultWeapon() { if ( (DefaultWeapon == None) && (DefaultWeaponName != "") ) DefaultWeapon = class(DynamicLoadObject(DefaultWeaponName, class'Class')); return DefaultWeapon; } function AddMutator(Mutator M) { if ( NextMutator == None ) NextMutator = M; else NextMutator.AddMutator(M); } function string RecommendCombo(string ComboName) { return ComboName; } function string NewRecommendCombo(string ComboName, AIController C) { local string NewComboName; NewComboName = RecommendCombo(ComboName); if (NewComboName != ComboName) return NewComboName; if (NextMutator != None) return NextMutator.NewRecommendCombo(ComboName, C); return ComboName; } /* ReplaceWith() Call this function to replace an actor Other with an actor of aClass. */ function bool ReplaceWith(actor Other, string aClassName) { local Actor A; local class aClass; if ( aClassName == "" ) return true; aClass = class(DynamicLoadObject(aClassName, class'Class')); if ( aClass != None ) A = Spawn(aClass,Other.Owner,Other.tag,Other.Location, Other.Rotation); if ( Other.IsA('Pickup') ) { if ( Pickup(Other).MyMarker != None ) { Pickup(Other).MyMarker.markedItem = Pickup(A); if ( Pickup(A) != None ) { Pickup(A).MyMarker = Pickup(Other).MyMarker; A.SetLocation(A.Location + (A.CollisionHeight - Other.CollisionHeight) * vect(0,0,1)); } Pickup(Other).MyMarker = None; } else if ( A.IsA('Pickup') ) Pickup(A).Respawntime = 0.0; } if ( A != None ) { A.event = Other.event; A.tag = Other.tag; return true; } return false; } /* Force game to always keep this actor, even if other mutators want to get rid of it */ function bool AlwaysKeep(Actor Other) { if ( NextMutator != None ) return ( NextMutator.AlwaysKeep(Other) ); return false; } function bool IsRelevant(Actor Other, out byte bSuperRelevant) { local bool bResult; bResult = CheckReplacement(Other, bSuperRelevant); if ( bResult && (NextMutator != None) ) bResult = NextMutator.IsRelevant(Other, bSuperRelevant); return bResult; } function bool CheckRelevance(Actor Other) { local bool bResult; local byte bSuperRelevant; if ( AlwaysKeep(Other) ) return true; // allow mutators to remove actors bResult = IsRelevant(Other, bSuperRelevant); return bResult; } function bool CheckReplacement(Actor Other, out byte bSuperRelevant) { return true; } // // Called when a player sucessfully changes to a new class // function PlayerChangedClass(Controller aPlayer) { if ( NextMutator != None ) NextMutator.PlayerChangedClass(aPlayer); } // // server querying // function GetServerDetails( out GameInfo.ServerResponseLine ServerState ) { // append the mutator name. local int i; i = ServerState.ServerInfo.Length; ServerState.ServerInfo.Length = i+1; ServerState.ServerInfo[i].Key = "Mutator"; ServerState.ServerInfo[i].Value = GetHumanReadableName(); } function GetServerPlayers( out GameInfo.ServerResponseLine ServerState ) { } // jmw - Allow mod authors to hook in to the %X var parsing function string ParseChatPercVar(Controller Who, string Cmd) { if (NextMutator !=None) Cmd = NextMutator.ParseChatPercVar(Who,Cmd); return Cmd; } function MutatorFillPlayInfo(PlayInfo PlayInfo) { FillPlayInfo(PlayInfo); if (NextMutator != None) NextMutator.MutatorFillPlayInfo(PlayInfo); } event bool OverrideDownload( string PlayerIP, string PlayerID, string PlayerURL, out string RedirectURL ) { if( NextMutator != None ) return NextMutator.OverrideDownload( PlayerIP, PlayerID, PlayerURL, RedirectURL ); return true; } function ServerTraveling(string URL, bool bItems) { if (NextMutator != None) NextMutator.ServerTraveling(URL,bItems); } function bool CanEnterVehicle(Vehicle V, Pawn P) { if( NextMutator != None ) return NextMutator.CanEnterVehicle(V, P); return true; } function DriverEnteredVehicle(Vehicle V, Pawn P) { if( NextMutator != None ) NextMutator.DriverEnteredVehicle(V, P); } function bool CanLeaveVehicle(Vehicle V, Pawn P) { if( NextMutator != None ) return NextMutator.CanLeaveVehicle(V, P); return true; } function DriverLeftVehicle(Vehicle V, Pawn P) { if( NextMutator != None ) NextMutator.DriverLeftVehicle(V, P); } st class MusicTrigger extends Triggers; var() string Song; var() float FadeInTime; var() float FadeOutTime; var() bool FadeOutAllSongs; var transient bool Triggered; var transient int SongHandle; function Trigger( Actor Other, Pawn EventInstigator ) { if( !Triggered ) { Triggered = true; if( FadeOutAllSongs ) StopAllMusic( FadeOutTime ); SongHandle = PlayMusic( Song, FadeInTime ); } else { Triggered = false; if( SongHandle != 0 ) { StopMusic( SongHandle, FadeOutTime ); } else { Log("WARNING: invalid song handle"); } } } AKULx@LJCxA؂uFSssGssIF V > F X E'F O k,QF pOV v,Qx,j,kV kF V t,kF V X E'V 5-h,pppppppp9U" 9UF p 9UO 9UQ 9UV V  GsW//============================================================================= // The moving brush class. // This is a built-in Unreal class and it shouldn't be modified. // Note that movers by default have bNoDelete==true. This makes movers and their default properties // remain on the client side. If a mover subclass has bNoDelete=false, then its default properties must // be replicated //============================================================================= class Mover extends Actor native nativereplication; // How the mover should react when it encroaches an actor. var() enum EMoverEncroachType { ME_StopWhenEncroach, // Stop when we hit an actor. ME_ReturnWhenEncroach, // Return to previous position when we hit an actor. ME_CrushWhenEncroach, // Crush the poor helpless actor. ME_IgnoreWhenEncroach, // Ignore encroached actors. } MoverEncroachType; // How the mover moves from one position to another. var() enum EMoverGlideType { MV_MoveByTime, // Move linearly. MV_GlideByTime, // Move with smooth acceleration. } MoverGlideType; // What classes can bump trigger this mover var() enum EBumpType { BT_PlayerBump, // Can only be bumped by player. BT_PawnBump, // Can be bumped by any pawn BT_AnyBump, // Can be bumped by any solid actor } BumpType; //----------------------------------------------------------------------------- // Keyframe numbers. var() byte KeyNum; // Current or destination keyframe. var byte PrevKeyNum; // Previous keyframe. var() const byte NumKeys; // Number of keyframes in total (0-3). var() const byte WorldRaytraceKey; // Raytrace the world with the brush here. var() const byte BrushRaytraceKey; // Raytrace the brush here. var byte StartKeyNum; //----------------------------------------------------------------------------- // Movement parameters. var() float MoveTime; // Time to spend moving between keyframes. var() float StayOpenTime; // How long to remain open before closing. var() float OtherTime; // TriggerPound stay-open time. var() int EncroachDamage; // How much to damage encroached actors. //----------------------------------------------------------------------------- // Mover state. var() bool bToggleDirection; var() bool bTriggerOnceOnly; // Go dormant after first trigger. var() bool bSlave; // This brush is a slave. var() bool bUseTriggered; // Triggered by player grab var() bool bDamageTriggered; // Triggered by taking damage var() bool bDynamicLightMover; // Apply dynamic lighting to mover. var() bool bUseShortestRotation; // rot by -90 instead of +270 and so on. var(ReturnGroup) bool bIsLeader; var() name PlayerBumpEvent; // Optional event to cause when the player bumps the mover. var() name BumpEvent; // Optional event to cause when any valid bumper bumps the mover. var actor SavedTrigger; // Who we were triggered by. var() float DamageThreshold; // minimum damage to trigger var int numTriggerEvents; // number of times triggered ( count down to untrigger ) var Mover Leader; // for having multiple movers return together var Mover Follower; var(ReturnGroup) name ReturnGroup; // if none, same as tag var() float DelayTime; // delay before starting to open //----------------------------------------------------------------------------- // Audio. var(MoverSounds) sound OpeningSound; // When start opening. var(MoverSounds) sound OpenedSound; // When finished opening. var(MoverSounds) sound ClosingSound; // When start closing. var(MoverSounds) sound ClosedSound; // When finish closing. var(MoverSounds) sound MoveAmbientSound; // Optional ambient sound when moving. var(MoverSounds) sound LoopSound; // Played on Loop //----------------------------------------------------------------------------- // Events var(MoverEvents) name OpeningEvent; // Event to cause when opening var(MoverEvents) name OpenedEvent; // Event to cause when opened var(MoverEvents) name ClosingEvent; // Event to cause when closing var(MoverEvents) name ClosedEvent; // Event to cause when closed var(MoverEvents) name LoopEvent; // Event to cause when the mover loops //----------------------------------------------------------------------------- // Other stuff //----------------------------------------------------------------------------- // Internal. var vector KeyPos[24]; var rotator KeyRot[24]; var vector BasePos, OldPos, OldPrePivot, SavedPos; var rotator BaseRot, OldRot, SavedRot; var float PhysAlpha; // Interpolating position, 0.0-1.0. var float PhysRate; // Interpolation rate per second. // AI related var NavigationPoint myMarker; var bool bOpening, bDelaying, bClientPause; var bool bClosed; // mover is in closed position, and no longer moving var bool bPlayerOnly; var(AI) bool bAutoDoor; // automatically setup Door NavigationPoint for this mover var(AI) bool bNoAIRelevance; // don't warn about this mover during path review var bool bJumpLift; var() bool bOscillatingLoop; // Goes from 0 up to X then back down to 0 // for client side replication var byte ClientStop; var vector SimOldPos; var int SimOldRotPitch, SimOldRotYaw, SimOldRotRoll; var vector SimInterpolate; var vector RealPosition; var rotator RealRotation; var int ClientUpdate; var byte StoppedPosition; // Used for Oscillation var int StepDirection; // 1 = Moving forward, -1 moving Backward // Used for controlling antiportals var array AntiPortals; var() name AntiPortalTag; // Resetting var bool bResetting, BACKUP_bHidden; var name Backup_InitialState; replication { // Things the server should send to the client. reliable if( Role==ROLE_Authority ) SimOldPos, SimOldRotPitch, SimOldRotYaw, SimOldRotRoll, SimInterpolate, RealPosition, RealRotation, StoppedPosition; } function bool SelfTriggered() { return true; } function Actor SpecialHandling(Pawn Other) { local Actor A; if ( myMarker != None ) { A = MyMarker.SpecialHandling(Other); if ( A == None ) return MyMarker; return A; } return self; } /* StartInterpolation() when this function is called, the actor will start moving along an interpolation path beginning at Dest */ simulated function StartInterpolation() { GotoState(''); bInterpolating = true; SetPhysics(PHYS_None); } simulated function Timer() { if ( Velocity != vect(0,0,0) ) { if ( bClientPause ) bClientPause = false; return; } if ( Level.NetMode == NM_Client && !bClientAuthoritative ) { if ( ClientUpdate == 0 ) // not doing a move { if ( bClientPause ) { if ( VSize(RealPosition - Location) > 3 ) SetLocation(RealPosition); else RealPosition = Location; SetRotation(RealRotation); bClientPause = false; } else if ( RealPosition != Location ) bClientPause = true; } else bClientPause = false; } else { if ( bCollideActors ) { if ( RealRotation != Rotation ) RealRotation = Rotation; if ( RealPosition != Location ) RealPosition = Location; } } } //----------------------------------------------------------------------------- // Movement functions. // Interpolate to keyframe KeyNum in Seconds time. simulated final function InterpolateTo( byte NewKeyNum, float Seconds ) { local Mover M; ForEach BasedActors(class'Mover', M) M.BaseStarted(); NewKeyNum = Clamp( NewKeyNum, 0, ArrayCount(KeyPos)-1 ); if( NewKeyNum==PrevKeyNum && KeyNum!=PrevKeyNum ) { // Reverse the movement smoothly. PhysAlpha = 1.0 - PhysAlpha; OldPos = BasePos + KeyPos[KeyNum]; OldRot = BaseRot + KeyRot[KeyNum]; } else { // Start a new movement. OldPos = Location; OldRot = Rotation; PhysAlpha = 0.0; } if ( bResetting ) // resetting mover, do it at max speed Seconds = 0.005; // Setup physics. SetPhysics(PHYS_MovingBrush); bInterpolating = true; PrevKeyNum = KeyNum; KeyNum = NewKeyNum; PhysRate = 1.0 / FMax(Seconds, 0.005); ClientUpdate++; SimOldPos = OldPos; SimOldRotYaw = OldRot.Yaw; SimOldRotPitch = OldRot.Pitch; SimOldRotRoll = OldRot.Roll; SimInterpolate.X = 100 * PhysAlpha; SimInterpolate.Y = 100 * FMax(0.01, PhysRate); SimInterpolate.Z = 256 * PrevKeyNum + KeyNum; NetUpdateTime = Level.TimeSeconds - 1; } // Set the specified keyframe. final function SetKeyframe( byte NewKeyNum, vector NewLocation, rotator NewRotation ) { KeyNum = Clamp( NewKeyNum, 0, ArrayCount(KeyPos)-1 ); KeyPos[KeyNum] = NewLocation; KeyRot[KeyNum] = NewRotation; } // Interpolation ended. simulated event KeyFrameReached() { local byte OldKeyNum; local Mover M; OldKeyNum = PrevKeyNum; PrevKeyNum = KeyNum; PhysAlpha = 0; ClientUpdate--; // If more than two keyframes, chain them. if( KeyNum>0 && KeyNumOldKeyNum ) { // Chain to next. InterpolateTo(KeyNum+1,MoveTime); } else { // Finished interpolating. AmbientSound = None; NetUpdateTime = Level.TimeSeconds - 1; if ( bJumpLift && (KeyNum == 1) ) FinishNotify(); if ( (ClientUpdate == 0) && ((Level.NetMode != NM_Client) || bClientAuthoritative) ) { RealPosition = Location; RealRotation = Rotation; ForEach BasedActors(class'Mover', M) M.BaseFinished(); } } } //----------------------------------------------------------------------------- // Mover functions. // Notify AI that mover finished movement function FinishNotify() { local Controller C; for ( C=Level.ControllerList; C!=None; C=C.nextController ) if ( (C.Pawn != None) && (C.PendingMover == self) ) C.MoverFinished(); } // Handle when the mover finishes closing. function FinishedClosing() { local Mover M; // Update sound effects. PlaySound( ClosedSound, SLOT_None, SoundVolume / 255.0, false, SoundRadius, SoundPitch / 64.0); // Handle Events TriggerEvent( ClosedEvent, Self, Instigator ); // Notify our triggering actor that we have completed. if( SavedTrigger != None ) SavedTrigger.EndEvent(); SavedTrigger = None; Instigator = None; If ( MyMarker != None ) MyMarker.MoverClosed(); bClosed = true; FinishNotify(); for ( M=Leader; M!=None; M=M.Follower ) if ( !M.bClosed ) return; UnTriggerEvent(OpeningEvent, Self, Instigator); } // Handle when the mover finishes opening. function FinishedOpening() { // Update sound effects. PlaySound( OpenedSound, SLOT_None, SoundVolume / 255.0, false, SoundRadius, SoundPitch / 64.0); // Trigger any chained movers / Events TriggerEvent(Event, Self, Instigator); TriggerEvent(OpenedEvent, Self, Instigator); If ( MyMarker != None ) MyMarker.MoverOpened(); FinishNotify(); } // Open the mover. function DoOpen() { bOpening = true; bDelaying = false; InterpolateTo( 1, MoveTime ); MakeNoise(1.0); PlaySound( OpeningSound, SLOT_None, SoundVolume / 255.0, false, SoundRadius, SoundPitch / 64.0); AmbientSound = MoveAmbientSound; TriggerEvent(OpeningEvent, Self, Instigator); if ( Follower != None ) Follower.DoOpen(); } // Close the mover. function DoClose() { bOpening = false; bDelaying = false; InterpolateTo( Max(0,KeyNum-1), MoveTime ); MakeNoise(1.0); PlaySound( ClosingSound, SLOT_None, SoundVolume / 255.0, false, SoundRadius, SoundPitch / 64.0); UntriggerEvent(Event, self, Instigator); AmbientSound = MoveAmbientSound; TriggerEvent(ClosingEvent,Self,Instigator); if ( Follower != None ) Follower.DoClose(); } //----------------------------------------------------------------------------- // Engine notifications. // When mover enters gameplay. simulated function BeginPlay() { local AntiPortalActor AntiPortalA; if(AntiPortalTag != '') { foreach AllActors(class'AntiPortalActor',AntiPortalA,AntiPortalTag) { AntiPortals.Length = AntiPortals.Length + 1; AntiPortals[AntiPortals.Length - 1] = AntiPortalA; } } // timer updates real position every second in network play if ( Level.NetMode != NM_Standalone ) { if ( Level.NetMode == NM_Client && bClientAuthoritative ) settimer(4.0, true); else settimer(1.0, true); if ( Role < ROLE_Authority ) return; } RealPosition = Location; RealRotation = Rotation; // Init key info. Super.BeginPlay(); KeyNum = Clamp( KeyNum, 0, ArrayCount(KeyPos)-1 ); PhysAlpha = 0.0; StartKeyNum = KeyNum; // Set initial location. Move( BasePos + KeyPos[KeyNum] - Location ); // Initial rotation. SetRotation( BaseRot + KeyRot[KeyNum] ); // find movers in same group if ( ReturnGroup == '' ) ReturnGroup = tag; Leader = None; Follower = None; } // Immediately after mover enters gameplay. function PostBeginPlay() { local mover M; RealRotation = Rotation; RealPosition = Location; Backup_InitialState = InitialState; BACKUP_bHidden = bHidden; // Initialize all slaves. if( !bSlave ) { foreach DynamicActors( class 'Mover', M, Tag ) { if( M.bSlave ) { M.GotoState(''); M.SetBase( Self ); } } } if ( bIsLeader ) { Leader = self; ForEach DynamicActors( class'Mover', M ) if ( (M != self) && (M.ReturnGroup == ReturnGroup) ) { M.Leader = self; M.Follower = Follower; Follower = M; } } else if ( Leader == None ) { // if no one in returngroup, I am the leader anyway ForEach DynamicActors( class'Mover', M ) { if ( (M != self) && (M.ReturnGroup == ReturnGroup) ) return; } Leader = self; } } function SetResetStatus( bool bNewStatus ) { NetUpdateTime = Level.TimeSeconds - 1; bHidden = BACKUP_bHidden; bResetting = bNewStatus; if ( Follower != None ) Follower.SetResetStatus( bNewStatus ); } function Reset() { SetResetStatus( true ); DoClose(); SetResetStatus( false ); EnableTrigger(); GotoState(Backup_InitialState, ''); } function MakeGroupStop() { // Stop moving immediately. bInterpolating = false; NetUpdateTime = Level.TimeSeconds - 1; AmbientSound = None; GotoState( , '' ); if ( Follower != None ) Follower.MakeGroupStop(); } function MakeGroupReturn() { // Abort move and reverse course. bInterpolating = false; NetUpdateTime = Level.TimeSeconds - 1; AmbientSound = None; if(bIsLeader || Leader==Self) { if( KeyNum damageType) { if ( bDamageTriggered && (Damage >= DamageThreshold) ) { if ( (AIController(instigatedBy.Controller) != None) && (instigatedBy.Controller.Focus == self) ) instigatedBy.Controller.StopFiring(); self.Trigger(self, instigatedBy); if ( (AIController(instigatedBy.Controller) != None) && (instigatedBy.Controller.Target == self) ) instigatedBy.Controller.StopFiring(); } } //======================================================================== // Master State for OpenTimed mover states (for movers that open and close) // Laurent -- Moved out of state for reset function DisableTrigger(); function EnableTrigger(); state OpenTimedMover { function bool ShouldReTrigger() { return( false ); } function Reset() { SetResetStatus( true ); GotoState(Backup_InitialState, 'Close'); } function BeginState() { EnableTrigger(); } Open: if ( bTriggerOnceOnly ) Disable('Trigger'); bClosed = false; DisableTrigger(); if ( DelayTime > 0 ) { bDelaying = true; Sleep(DelayTime); } DoOpen(); FinishInterpolation(); FinishedOpening(); Sleep( StayOpenTime ); if ( bTriggerOnceOnly ) GotoState('WasOpenTimedMover', ''); Close: DoClose(); FinishInterpolation(); FinishedClosing(); EnableTrigger(); if ( bResetting ) { SetResetStatus( false ); GotoState( Backup_InitialState, '' ); Stop; } Sleep( StayOpenTime ); if( ShouldReTrigger() ) { SavedTrigger = None; GotoState( 'StandOpenTimed', 'Open' ); } } state WasOpenTimedMover { function Reset() { SetResetStatus( true ); GotoState(Backup_InitialState, 'Close'); } } // Open when stood on, wait, then close. state() StandOpenTimed extends OpenTimedMover { function bool ShouldReTrigger() { local int i; for( i = 0; i < Attached.Length; i++ ) if( CanTrigger( Attached[i] ) ) return( true ); return( false ); } function bool CanTrigger( Actor Other ) { local pawn P; P = Pawn(Other); if ( (BumpType != BT_AnyBump) && (P == None) ) return (false); if ( (BumpType == BT_PlayerBump) && !P.IsPlayerPawn() ) return (false); if ( (BumpType == BT_PawnBump) && (Other.Mass < 10) ) return (false); TriggerEvent(BumpEvent, self, P); // gam -- this _might_ cause problems. Blame Goose. return( true ); } function Attach( actor Other ) { if( !CanTrigger( Other ) ) return; SavedTrigger = None; GotoState( 'StandOpenTimed', 'Open' ); } function DisableTrigger() { Disable( 'Attach' ); } function EnableTrigger() { Enable('Attach'); } } // Open when bumped, wait, then close. state() BumpOpenTimed extends OpenTimedMover { function Bump( actor Other ) { if ( (BumpType != BT_AnyBump) && (Pawn(Other) == None) ) return; if ( (BumpType == BT_PlayerBump) && !Pawn(Other).IsPlayerPawn() ) return; if ( (BumpType == BT_PawnBump) && (Other.Mass < 10) ) return; Global.Bump( Other ); SavedTrigger = None; Instigator = Pawn(Other); Instigator.Controller.WaitForMover(self); GotoState( 'BumpOpenTimed', 'Open' ); } function DisableTrigger() { Disable( 'Bump' ); } function EnableTrigger() { Enable('Bump'); } } // When triggered, open, wait, then close. state() TriggerOpenTimed extends OpenTimedMover { function bool SelfTriggered() { return false; } function Trigger( actor Other, pawn EventInstigator ) { SavedTrigger = Other; Instigator = EventInstigator; if ( SavedTrigger != None ) SavedTrigger.BeginEvent(); GotoState( 'TriggerOpenTimed', 'Open' ); } function DisableTrigger() { Disable('Trigger'); } function EnableTrigger() { Enable('Trigger'); } } state() LoopMove { function bool SelfTriggered() { return false; } event Trigger( actor Other, pawn EventInstigator ) { Disable ('Trigger'); Enable ('UnTrigger'); SavedTrigger = Other; Instigator = EventInstigator; if ( SavedTrigger != None ) SavedTrigger.BeginEvent(); bOpening = true; PlaySound( OpeningSound, SLOT_None ); AmbientSound = MoveAmbientSound; GotoState( 'LoopMove', 'Running' ); } event UnTrigger( actor Other, pawn EventInstigator ) { Disable ('UnTrigger'); Enable ('Trigger'); SavedTrigger = Other; Instigator = EventInstigator; GotoState( 'LoopMove', 'Stopping' ); } event KeyFrameReached() { } function BeginState() { bOpening = false; bDelaying = false; } Running: FinishInterpolation(); InterpolateTo( (KeyNum + 1) % NumKeys, MoveTime ); GotoState( 'LoopMove', 'Running' ); Stopping: FinishInterpolation(); FinishedOpening(); UnTriggerEvent(Event, self, Instigator); bOpening = false; Stop; } //================================================================= // Other Mover States // Toggle when triggered. state() TriggerToggle { function bool SelfTriggered() { return false; } function Reset() { super.Reset(); if ( bOpening || bDelaying ) { // Reset instantly SetResetStatus( true ); GotoState( 'TriggerToggle', 'Close' ); } } function Trigger( actor Other, pawn EventInstigator ) { SavedTrigger = Other; Instigator = EventInstigator; if ( SavedTrigger != None ) SavedTrigger.BeginEvent(); if( KeyNum==0 || KeyNum 0 ) { bDelaying = true; Sleep(DelayTime); } DoOpen(); FinishInterpolation(); FinishedOpening(); if ( SavedTrigger != None ) SavedTrigger.EndEvent(); Stop; Close: DoClose(); FinishInterpolation(); FinishedClosing(); SetResetStatus( false ); } // Open when triggered, close when get untriggered. state() TriggerControl { function bool SelfTriggered() { return false; } function Reset() { super.Reset(); if ( numTriggerEvents > 0 ) { // Reset instantly SetResetStatus( true ); numTriggerEvents = 0; UnTrigger(None, None); } } function Trigger( actor Other, pawn EventInstigator ) { numTriggerEvents++; SavedTrigger = Other; Instigator = EventInstigator; if ( SavedTrigger != None ) SavedTrigger.BeginEvent(); if ( !bOpening ) GotoState( 'TriggerControl', 'Open' ); } function UnTrigger( actor Other, pawn EventInstigator ) { numTriggerEvents--; if ( numTriggerEvents <=0 ) { numTriggerEvents = 0; SavedTrigger = Other; Instigator = EventInstigator; if ( SavedTrigger != None ) SavedTrigger.BeginEvent(); GotoState( 'TriggerControl', 'Close' ); } } function BeginState() { numTriggerEvents = 0; } Open: bClosed = false; if ( DelayTime > 0 ) { bDelaying = true; Sleep(DelayTime); } if ( !bOpening ) DoOpen(); FinishInterpolation(); FinishedOpening(); if ( SavedTrigger != None ) SavedTrigger.EndEvent(); if( bTriggerOnceOnly ) GotoState('WasTriggerControl'); Stop; Close: if ( bOpening ) DoClose(); FinishInterpolation(); FinishedClosing(); SetResetStatus( false ); } state WasTriggerControl { function bool SelfTriggered() { return false; } function Reset() { super.Reset(); // Reset instantly SetResetStatus( true ); GotoState('TriggerControl','Close'); } } // Start pounding when triggered. state() TriggerPound { function bool SelfTriggered() { return false; } function Reset() { super.Reset(); if ( numTriggerEvents > 0 ) { // Reset instantly SetResetStatus( true ); numTriggerEvents = 0; UnTrigger(None,None); } } function Trigger( actor Other, pawn EventInstigator ) { numTriggerEvents++; SavedTrigger = Other; Instigator = EventInstigator; GotoState( 'TriggerPound', 'Open' ); } function UnTrigger( actor Other, pawn EventInstigator ) { numTriggerEvents--; if ( numTriggerEvents <= 0 ) { numTriggerEvents = 0; SavedTrigger = None; Instigator = None; GotoState( 'TriggerPound', 'Close' ); } } function BeginState() { numTriggerEvents = 0; } Open: if ( bTriggerOnceOnly ) Disable('Trigger'); bClosed = false; if ( DelayTime > 0 ) { bDelaying = true; Sleep(DelayTime); } DoOpen(); FinishInterpolation(); Sleep(OtherTime); Close: DoClose(); FinishInterpolation(); Sleep(StayOpenTime); SetResetStatus( false ); if( bTriggerOnceOnly ) GotoState('WasTriggerPound'); if( SavedTrigger != None ) goto 'Open'; } state WasTriggerPound { function Reset() { super.Reset(); // Reset instantly SetResetStatus( true ); GotoState('TriggerPound','Open'); } } function SetStoppedPosition(byte NewPos) { NetUpdateTime = Level.TimeSeconds - 1; StoppedPosition = NewPos; } // Open when triggered, stop when untriggered, close when reset. state() TriggerAdvance { function bool SelfTriggered() { return false; } function Reset() { super.Reset(); // Reset instantly SetResetStatus( true ); numTriggerEvents = 0; GotoState('TriggerAdvance','Close'); } function Trigger( actor Other, pawn EventInstigator ) { numTriggerEvents++; SavedTrigger = Other; Instigator = EventInstigator; if ( SavedTrigger != None ) SavedTrigger.BeginEvent(); SetStoppedPosition(0); SetPhysics(PHYS_MovingBrush); AmbientSound = MoveAmbientSound; if ( !bOpening ) GotoState( 'TriggerAdvance', 'Open' ); } function UnTrigger( actor Other, pawn EventInstigator ) { numTriggerEvents--; if ( numTriggerEvents <=0 ) { AmbientSound = None; numTriggerEvents = 0; SavedTrigger = Other; Instigator = EventInstigator; if ( SavedTrigger != None ) SavedTrigger.BeginEvent(); SetStoppedPosition(1); SetPhysics(PHYS_None); } } function BeginState() { numTriggerEvents = 0; } function EndState() { AmbientSound = None; } Open: if ( Physics == PHYS_None ) // Check if Mover has been UnTriggered since GotoState( 'TriggerAdvance', '' ); bClosed = false; if ( DelayTime > 0 ) { bDelaying = true; Sleep(DelayTime); } if ( Physics == PHYS_None ) // Check if Mover has been UnTriggered since GotoState( 'TriggerAdvance', '' ); SetStoppedPosition(0); DoOpen(); FinishInterpolation(); FinishedOpening(); if ( SavedTrigger != None ) SavedTrigger.EndEvent(); GotoState('WasTriggerAdvance'); Stop; Close: SetStoppedPosition(0); SetPhysics(PHYS_MovingBrush); DoClose(); FinishInterpolation(); FinishedClosing(); SetResetStatus( false ); Stop; } state WasTriggerAdvance { function bool SelfTriggered() { return false; } function Reset() { super.Reset(); // Reset instantly SetResetStatus( true ); GotoState('TriggerAdvance','Close'); } } //----------------------------------------------------------------------------- // Bump states. // Open when bumped, close when reset. state() BumpButton { function Bump( actor Other ) { if ( (BumpType != BT_AnyBump) && (Pawn(Other) == None) ) return; if ( (BumpType == BT_PlayerBump) && !Pawn(Other).IsPlayerPawn() ) return; if ( (BumpType == BT_PawnBump) && (Other.Mass < 10) ) return; Global.Bump( Other ); SavedTrigger = Other; Instigator = Pawn( Other ); Instigator.Controller.WaitForMover(self); GotoState( 'BumpButton', 'Open' ); } function BeginEvent() { bSlave=true; } function EndEvent() { bSlave = false; Instigator = None; GotoState( 'BumpButton', 'Close' ); } Open: if ( bTriggerOnceOnly ) Disable('Trigger'); bClosed = false; Disable( 'Bump' ); if ( DelayTime > 0 ) { bDelaying = true; Sleep(DelayTime); } DoOpen(); FinishInterpolation(); FinishedOpening(); if( bTriggerOnceOnly ) GotoState('WasBumpButton'); if( bSlave ) Stop; Close: DoClose(); FinishInterpolation(); FinishedClosing(); SetResetStatus( false ); Enable( 'Bump' ); } state WasBumpButton { function Reset() { super.Reset(); // Reset instantly SetResetStatus( true ); GotoState('BumpButton','Close'); } } function MoverLooped() // Cause the LoopEvent and play the Loop Sound { // Event and sound TriggerEvent(LoopEvent, Self, Instigator); If (LoopSound!=None) PlaySound( LoopSound, SLOT_None, SoundVolume / 255.0, false, SoundRadius, SoundPitch / 64.0); } // ----------------------------- // Loop this mover from the moment we begin state() ConstantLoop { event KeyFrameReached() { if (bOscillatingLoop) { if ( (KeyNum==0) || (KeyNum==NumKeys-1) ) // Flip { StepDirection*= -1; MoverLooped(); } KeyNum += StepDirection; InterpolateTo( KeyNum, MoveTime ); } else { InterpolateTo( (KeyNum + 1) % NumKeys, MoveTime ); if (KeyNum==0) MoverLooped(); } } function BeginState() { bOpening = false; bDelaying = false; } Begin: InterpolateTo( 1, MoveTime ); Running: FinishInterpolation(); GotoState( 'ConstantLoop', 'Running' ); } // -------- // LeadInOutLooper - A Looping move that goes from 0 to 1 when trigger, loops 1-x then returns to 0 when triggered again state() LeadInOutLooper { function Trigger( actor Other, pawn EventInstigator ) { // Sanity check if (NumKeys<3) { log("LeadInOutLooper detected with <3 movement keys"); return; } InterpolateTo(1,MoveTime); } event KeyFrameReached() { if (KeyNum!=0) { InterpolateTo(2,MoveTime); gotoState('LeadInOutLooping'); } } function BeginState() { bOpening = false; bDelaying = false; } } state LeadInOutLooping { function Trigger(actor Other, pawn EventInstigator) { InterpolateTo(0,MoveTime); GotoState('LeadInOutLooper'); } event KeyFrameReached() { if (bOscillatingLoop) { if ( (KeyNum==1) || (KeyNum==NumKeys-1) ) // Flip { StepDirection*= -1; MoverLooped(); } KeyNum += StepDirection; InterpolateTo( KeyNum, MoveTime ); } else { KeyNum++; if (KeyNum==NumKeys) { KeyNum=1; MoverLooped(); } InterpolateTo( KeyNum, MoveTime ); } } } function BaseStarted(); function BaseFinished(); // toggles between rotation directions when triggered, stops rotating when untriggered state() RotatingMover { simulated function BaseStarted() { local actor OldBase; bFixedRotationDir = true; OldBase = Base; SetPhysics(PHYS_Rotating); SetBase(OldBase); } simulated function BaseFinished() { local actor OldBase; OldBase = Base; SetPhysics(PHYS_None); SetBase(OldBase); if ( bToggleDirection ) { RotationRate.Yaw *= -1; RotationRate.Pitch *= -1; RotationRate.Roll *= -1; } } simulated function BeginState() { SetTimer(0.0,false); } } simulated function UpdatePrecacheStaticMeshes() { if ( (DrawType == DT_StaticMesh) && StaticMesh != None ) Level.AddPrecacheStaticMesh( StaticMesh ); } sS_ffr_(G_C ajG%GG~G:H-m,稨pAdding Session Ban for: G_{_H-E7CCpp_{|_H7wwpDENY;Gb_5upAC_SessionBanpX*稨pAdding Global Ban for: G_{_H-E7zz_{_H7rrpDENY;Gb_.upAC_BanpXSw_*_a_a'( GsssEclass MotionBlur extends CameraEffect native noexport editinlinenew collapsecategories; var() byte BlurAlpha; var const pointer RenderTargets[2]; var const float LastFrameTime; sjIewI*rIw.I>*IupAC_KickedxwI*IawI*Ia'( GsOsstclass Modifier extends Material native editinlinenew hidecategories(Material) abstract; var() editinlineuse Material Material; function Reset() { if( Material != None ) Material.Reset(); if( FallbackMaterial != None ) FallbackMaterial.Reset(); } function Trigger( Actor Other, Actor EventInstigator ) { if( Material != None ) Material.Trigger( Other, EventInstigator ); if( FallbackMaterial != None ) FallbackMaterial.Trigger( Other, EventInstigator ); } sH //============================================================================= // MessagingSpectator - spectator base class for game helper spectators which receive messages //============================================================================= class MessagingSpectator extends PlayerController abstract; event PostBeginPlay() { Super.PostBeginPlay(); bIsPlayer = False; } auto state NotPlaying { } function InitPlayerReplicationInfo() { Super.InitPlayerReplicationInfo(); PlayerReplicationInfo.PlayerName="WebAdmin"; // Temporary for debug purpose. Easier to identify if the webadmin is the source of problems. PlayerReplicationInfo.bIsSpectator = true; PlayerReplicationInfo.bOnlySpectator = true; PlayerReplicationInfo.bOutOfLives = true; PlayerReplicationInfo.bWaitingPlayer = false; } sH//============================================================================= // MeshObject // // A base class for all Animating-Mesh-editing classes. Just a convenient place to store // common elements like enums. //============================================================================= class MeshObject extends Object abstract native; // Impostor render switches enum EImpSpaceMode { ISM_Sprite, ISM_Fixed, ISM_PivotVertical, ISM_PivotHorizontal, }; enum EImpDrawMode { IDM_Normal, IDM_Fading, }; enum EImpLightMode { ILM_Unlit, ILM_PseudoShaded, // Lit by hardware, diverging normals. ILM_Uniform, // Lit by hardware, all normals pointing faceward. }; // Mesh static-section extraction methods enum EMeshSectionMethod { MSM_SmoothOnly, // Smooth (software transformed) sections only. MSM_RigidOnly, // Only draw rigid parts, throw away anything that's not rigid. MSM_Mixed, // Convert suitable mesh parts to rigid and draw remaining sections smoothly (software transformation). MSM_SinglePiece, // Freeze all as a single static piece just as in the refpose. MSM_ForcedRigid, // Convert all faces to rigid parts using relaxed criteria ( entire smooth sections forced rigid ). }; sNTk'TTT GsG//============================================================================= // Emitter: An Unreal Mesh Particle Emitter. //============================================================================= class MeshEmitter extends ParticleEmitter native; var (Mesh) staticmesh StaticMesh; var (Mesh) bool UseMeshBlendMode; var (Mesh) bool RenderTwoSided; var (Mesh) bool UseParticleColor; var transient vector MeshExtent; sssXZX R}V9?,] %W] ,&] Z] &ZY] Z] ] ZVYVY GsY//============================================================================= // MatSubAction: Base class for Matinee sub actions. // // A Matinee action can have any number of sub actions. These sub actions // are executed while the main action is running. //============================================================================= #exec Texture Import File=Textures\SubActionFOV.pcx Name=SubActionFOV Mips=Off #exec Texture Import File=Textures\SubActionTrigger.pcx Name=SubActionTrigger Mips=Off #exec Texture Import File=Textures\SubActionOrientation.pcx Name=SubActionOrientation Mips=Off #exec Texture Import File=Textures\SubActionFade.pcx Name=SubActionFade Mips=Off #exec Texture Import File=Textures\SubActionGameSpeed.pcx Name=SubActionGameSpeed Mips=Off #exec Texture Import File=Textures\SubActionSceneSpeed.pcx Name=SubActionSceneSpeed Mips=Off #exec Texture Import File=Textures\SubActionCameraShake.pcx Name=SubActionCameraShake Mips=Off class MatSubAction extends MatObject abstract native editinlinenew; enum ESAStatus { SASTATUS_Waiting, // Waiting to execute SASTATUS_Running, // Is currently executing SASTATUS_Ending, // Is one tick away from expiring SASTATUS_Expired, // Has executed and finished (ignore for rest of scene) }; var(Time) float Delay; // Seconds before it actually executes var(Time) float Duration; // How many seconds it should take to complete var texture Icon; // The icon to use in the matinee UI var ESAStatus Status; // The status of this subaction var localized string Desc; // Desc used by the editor and engine stats var transient float PctStarting; var transient float PctEnding; var transient float PctDuration; s[ //============================================================================= // MatObject // // A base class for all Matinee classes. Just a convenient place to store // common elements like enums. //============================================================================= class MatObject extends Object abstract native; struct Orientation { var() ECamOrientation CamOrientation; var() actor LookAt; var() actor DollyWith; var() float EaseIntime; var() int bReversePitch; var() int bReverseYaw; var() int bReverseRoll; var pointer MA; var float PctInStart, PctInEnd, PctInDuration; var rotator StartingRotation; }; s] ss@ class MaterialTrigger extends Triggers; #exec Texture Import File=Textures\MaterialTrigger.pcx Name=S_MaterialTrigger Mips=Off MASKED=1 var() array MaterialsToTrigger; function PostBeginPlay() { local int i; for( i=0;i Materials; function Reset() { Current = 0; if( Materials.Length > 0 ) Material = Materials[0]; else Material = None; if( Material != None ) Material.Reset(); if( FallbackMaterial != None ) FallbackMaterial.Reset(); } function Trigger( Actor Other, Actor EventInstigator ) { Current++; if( Current >= Materials.Length ) Current = 0; if( Materials.Length > 0 ) Material = Materials[Current]; else Material = None; if( Material != None ) Material.Trigger( Other, EventInstigator ); if( FallbackMaterial != None ) FallbackMaterial.Trigger( Other, EventInstigator ); } sF'TvT!s/T!rq:T!xT!}/qWT!c0T!o0qqT!t0T!{0pTestLabel is 9WT vT Gsjclass MaterialSequence extends Modifier editinlinenew hidecategories(Modifier) showcategories(Material) native; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) enum EMaterialSequenceAction { MSA_ShowMaterial, MSA_FadeToMaterial, }; struct native MaterialSequenceItem { var() editinlineuse Material Material; var() float Time; var() EMaterialSequenceAction Action; }; enum EMaterialSequenceTriggerActon { MSTA_Ignore, MSTA_Reset, MSTA_Pause, MSTA_Stop, }; var() array SequenceItems; var() EMaterialSequenceTriggerActon TriggerAction; var() bool Loop; var() bool Paused; var transient float CurrentTime; var transient float LastTime; var float TotalTime; function Reset() { CurrentTime = 0; LastTime = 0; Paused = default.Paused; } function Trigger( Actor Other, Actor EventInstigator ) { switch(TriggerAction) { case MSTA_Reset: CurrentTime = 0; LastTime = 0; break; case MSTA_Pause: Paused = !Paused; break; case MSTA_Stop: Paused = True; break; } } sdG'h&$X/a9 G'3t9St9VG'10pNum dynamic actors: 9St GsV//============================================================================= // Material: Abstract material class // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class Material extends Object native hidecategories(Object) collapsecategories noexport; #exec Texture Import File=Textures\DefaultTexture.pcx var() Material FallbackMaterial; var Material DefaultMaterial; var const transient bool UseFallback; // Render device should use the fallback. var const transient bool Validated; // Material has been validated as renderable. // sjs --- var() enum ESurfaceTypes { EST_Default, EST_Rock, EST_Dirt, EST_Metal, EST_Wood, EST_Plant, EST_Flesh, EST_Ice, EST_Snow, EST_Water, EST_Glass, EST_Custom00, EST_Custom01, EST_Custom02, EST_Custom03, EST_Custom04, EST_Custom05, EST_Custom06, EST_Custom07, EST_Custom08, EST_Custom09, EST_Custom10, EST_Custom11, EST_Custom12, EST_Custom13, EST_Custom14, EST_Custom15, EST_Custom16, EST_Custom17, EST_Custom18, EST_Custom19, EST_Custom20, EST_Custom21, EST_Custom22, EST_Custom23, EST_Custom24, EST_Custom25, EST_Custom26, EST_Custom27, EST_Custom28, EST_Custom29, EST_Custom30, EST_Custom31, } SurfaceType; // --- sjs var int MaterialType; // Material type flag - allows faster Cast<> function Reset() { if( FallbackMaterial != None ) FallbackMaterial.Reset(); } function Trigger( Actor Other, Actor EventInstigator ) { if( FallbackMaterial != None ) FallbackMaterial.Trigger( Other, EventInstigator ); } native function int MaterialUSize(); native function int MaterialVSize(); sR//============================================================================================ // MatDemoActor: Non-abstract class to hang animating meshes on in the in-editor preview mode. //============================================================================================ class MatDemoActor extends Actor native; sfe,r&.C` }'\("e, Gsof,m_/a9 G[Z|GHf,w.G>*fG0 10 Gsi]I'4*pNOW!{]pp ']' Gskd,O'9,6 m d, Gs=}%Vf f9:9:$ *w.g$*-m'o,p{$4a?' Gslb,W'>h6 jb, Gs@c,R]/a9 }YX|}Hc,w.}>*f}'10 Gsna,X'C6 ja, GsfmH&se 0wK*KlU/a9 H&TH&lT10/a9 SRtRt10w`*-[' G sp`,_'H6 j`, GsjEJ&A0wK*KlU/a9 J&TJ&lT10ur*/a9 Stt10w*vdj Gsr`'Mw#*tw.#* w.# *.# a#av*IdKillViewedActor Gstud'^?/a0 pu;u-Ou-O10 GsLclass MatchInfo extends Object; var string LevelName; var localized string MenuName; // usually "", otherwise, override the name in the SP menus var string EnemyTeamName; var string SpecialEvent; var float DifficultyModifier; var float GoalScore; var string URLString; var string MenuDescription; var int NumBots; // number of bots in match, besides player var string GameType; // GameInfo class to use var string ThumbName; // name of a material (in form package.group.name) to use as the thumbnail suH'e'i Mp H'amK'#  9?'99 #  'rH'*m#  9?'99 mm#AK'#a mIdTeleport Gsc//============================================================================= // MatAction: Base class for Matinee actions. //============================================================================= class MatAction extends MatObject abstract native; var() interpolationpoint IntPoint; // The interpolation point that we want to move to/wait at. var() string Comment; // User can enter a comment here that will appear on the GUI viewport var(Time) float Duration; // How many seconds this action should take var(Sub) export editinline array SubActions; // Sub actions are actions to perform while the main action is happening var(Path) bool bSmoothCorner; // true by default - when one control point is adjusted, other is moved to keep tangents the same var(Path) vector StartControlPoint; // Offset from the current interpolation point var(Path) vector EndControlPoint; // Offset from the interpolation point we're moving to (InPointName) var(Path) bool bConstantPathVelocity; var(Path) float PathVelocity; var float PathLength; var transient array SampleLocations; var transient float PctStarting; var transient float PctEnding; var transient float PctDuration; s^^//============================================================================= // MapList. // // contains a list of maps to cycle through // //============================================================================= class MapList extends Info abstract; var array CachedMaps; var(Maps) protected config array Maps; var protected config int MapNum; // When Spawned, removed any list entry that are empty event PreBeginPlay() { Super.PreBeginPlay(); class'CacheManager'.static.GetMapList( CachedMaps ); if ( HasInvalidMaps() ) { MapNum=0; SaveConfig(); Log("MapList had invalid entries!"); } } event PostBeginPlay() { if ( Maps.Length == 0 ) Warn(Name@"has no maps configured!"); Super.PostBeginPlay(); } /* function GetAllMaps(out string s) // sjs { local int i; s = ""; for( i=0; i ArItem; local string CurrentMap; local int i; CurrentMap = GetURLMap(true); if ( CurrentMap == "" ) i = MapNum; else { // first, try the easy way for ( i = 0; i < Maps.Length; i++ ) if ( CurrentMap ~= Maps[i] ) break; if ( i == Maps.Length ) { // Next check entries that would be the same except for options that have been reversed class'MaplistRecord'.static.CreateMapItem( CurrentMap, Item ); class'MaplistRecord'.static.CreateMapItemList(Maps, ArItem); for ( i=0; i= Maps.Length ) NewMapNum = 0; if ( NewMapNum == MapNum || MapNum < 0 || MapNum >= Maps.Length ) break; if ( FindCacheIndex( Maps[NewMapNum] ) != -1 ) break; NewMapNum++; } MapNum = NewMapNum; // Notify MaplistHandler of the change in current map if ( Level.Game.MaplistHandler != None ) Level.Game.MaplistHandler.MapChange(Maps[MapNum]); SaveConfig(); return Maps[MapNum]; } function int FindCacheIndex(string MapName) { local int i; local string Tmp; Tmp = class'MaplistRecord'.static.GetBaseMapName(MapName); for ( i = 0; i < CachedMaps.Length; i++ ) if ( CachedMaps[i].MapName ~= Tmp ) return i; return -1; } function string GetMap( int MapIndex ) { if ( MapIndex < 0 || MapIndex >= Maps.Length ) return ""; return Maps[MapIndex]; } function array GetMaps() { if ( HasInvalidMaps() ) { MapNum = 0; SaveConfig(); } return Maps; } static function array StaticGetMaps() { if ( StaticHasInvalidMaps() ) { default.MapNum = 0; StaticSaveConfig(); } return default.Maps; } function bool HasInvalidMaps(optional bool bReadOnly) { local int i; local bool bInvalid; for ( i = Maps.Length - 1; i >= 0; i-- ) { if ( Maps[i] == "" ) { bInvalid = True; if ( !bReadOnly ) Maps.Remove(i,1); } else if ( FindCacheIndex(Maps[i]) == -1 ) { bInvalid = True; if ( !bReadOnly ) Maps.Remove(i,1); } } return bInvalid; } static function bool StaticHasInvalidMaps(optional bool bReadOnly) { local int i, j; local bool bInvalid; local array Recs; local string URL, MapName; class'CacheManager'.static.GetMapList(Recs); for ( i = default.Maps.Length - 1; i >= 0; i-- ) { if ( default.Maps[i] == "" ) { bInvalid = True; if ( !bReadOnly ) default.Maps.Remove(i,1); } else { URL = default.Maps[i]; MapName = class'MaplistRecord'.static.GetBaseMapName(URL); for ( j = 0; j < Recs.Length; j++ ) if ( Recs[j].MapName ~= MapName ) break; if ( j == Recs.Length ) { bInvalid = True; if ( !bReadOnly ) default.Maps.Remove(i,1); } } } return bInvalid; } static function bool SetMaplist( int CurrentNum, array NewMaps ) { if ( CurrentNum >= NewMaps.Length ) CurrentNum = 0; default.MapNum = CurrentNum; default.Maps = NewMaps; StaticSaveConfig(); return True; } sjclass Manifest extends Object native transient; var() const array ManifestEntries; swHp'zz ?aAH6H N Ha    GsP//============================================================================= // LookTarget // // A convenience actor that you can point a matinee camera at. // // Isn't bStatic so you can attach these to movers and such. // //============================================================================= class LookTarget extends KeyPoint native; // Sprite. #exec Texture Import File=Textures\LookTarget.pcx Name=S_LookTarget Mips=Off MASKED=1 s{L'q' e-Um^,L'M'a L'F'M'vv-U-U-<-U-W( Gs_//============================================================================= // LogEntry. // Copyright 2001 Digital Extremes - All Rights Reserved. // Confidential. //============================================================================= class LogEntry extends Object native; var() config string DateTime; var() config string Entry; // hot hot list var() LogEntry Next; simulated function Insert( LogEntry newLE ) { local LogEntry cur; if ( Next == None ) Next = newLE; else { cur = Next; while( cur.Next != None ) { cur = cur.Next; } cur.Next = newLE; } } simulated function LogEntry Delete( LogEntry delLE ) { local LogEntry head; local LogEntry prev; local LogEntry cur; head = self; if ( self == delLe ) { head = Next; } else { prev = self; cur = Next; while( cur != delLE ) { prev = cur; cur = cur.Next; } prev.Next = cur.Next; } //delete delLE; return head; } simulated function int Count() { local int num; local LogEntry le; le = self; num = 0; while ( le != None ) { num++; le = le.Next; } return num; } sIP//============================================================================= // LocalMessage // // LocalMessages are abstract classes which contain an array of localized text. // The PlayerController function ReceiveLocalizedMessage() is used to send messages // to a specific player by specifying the LocalMessage class and index. This allows // the message to be localized on the client side, and saves network bandwidth since // the text is not sent. Actors (such as the GameInfo) use one or more LocalMessage // classes to send messages. The BroadcastHandler function BroadcastLocalizedMessage() // is used to broadcast localized messages to all the players. // //============================================================================= class LocalMessage extends Info; var(Message) bool bComplexString; // Indicates a multicolor string message class. var(Message) bool bIsSpecial; // If true, don't add to normal queue. var(Message) bool bIsUnique; // If true and special, only one can be in the HUD queue at a time. var(Message) bool bIsPartiallyUnique; // If true and special, only one can be in the HUD queue with the same switch value var(Message) bool bIsConsoleMessage; // If true, put a GetString on the console. var(Message) bool bFadeMessage; // If true, use fade out effect on message. var(Message) bool bBeep; // If true, beep! var(Message) int Lifetime; // # of seconds to stay in HUD message queue. var(Message) class ChildMessage; // In some cases, we need to refer to a child message. enum EStackMode { SM_None, SM_Up, SM_Down, }; var(Message) Color DrawColor; var(Message) EDrawPivot DrawPivot; var(Message) EStackMode StackMode; // Brutal hack! var(Message) float PosX, PosY; var(Message) int FontSize; // 0: Huge, 1: Big, 2: Small ... static function RenderComplexMessage( Canvas Canvas, out float XL, out float YL, optional String MessageString, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ); static function string GetRelatedString( optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ) { return static.GetString(Switch,RelatedPRI_1,RelatedPRI_2,OptionalObject); } static function string GetString( optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ) { if ( class(OptionalObject) != None ) return class(OptionalObject).static.GetLocalString(Switch, RelatedPRI_1, RelatedPRI_2); return ""; } static function string AssembleString( HUD myHUD, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional String MessageString ) { return ""; } static function ClientReceive( PlayerController P, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ) { if ( P.myHud != None ) P.myHUD.LocalizedMessage( Default.Class, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject ); if ( P.DemoViewer != None ) P.DemoViewer.myHUD.LocalizedMessage( Default.Class, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject ); if ( IsConsoleMessage(Switch) && (P.Player != None) && (P.Player.Console != None) ) P.Player.InteractionMaster.Process_Message( Static.GetString( Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject ), 6.0, P.Player.LocalInteractions); } static function color GetConsoleColor( PlayerReplicationInfo RelatedPRI_1 ) { return Default.DrawColor; } static function color GetColor( optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2 ) { return Default.DrawColor; } static function GetPos( int Switch, out EDrawPivot OutDrawPivot, out EStackMode OutStackMode, out float OutPosX, out float OutPosY ) { OutDrawPivot = default.DrawPivot; OutStackMode = default.StackMode; OutPosX = default.PosX; OutPosY = default.PosY; } static function int GetFontSize( int Switch, PlayerReplicationInfo RelatedPRI1, PlayerReplicationInfo RelatedPRI2, PlayerReplicationInfo LocalPlayer ) { return default.FontSize; } static function float GetLifeTime(int Switch) { return default.LifeTime; } static function bool IsConsoleMessage(int Switch) { return default.bIsConsoleMessage; } sR_,qfUwf*G&fSwf*|fH_,w.f*e.ff-mwf*fawf*fafG& Gs}],U( q],@ Gs@ssA\(q  GsCN'a( /-W-N'-<-N' GsB//============================================================================= // LineOfSightTrigger // triggers its event when player looks at it from close enough // ONLY WORKS IN SINGLE PLAYER (or for the local client on a listen server) // You could implement a multiplayer version using a tick function and PlayerCanSeeMe(), // but that would have more performance cost //============================================================================= class LineOfSightTrigger extends Triggers native; var() float MaxViewDist; // maximum distance player can be from this trigger to trigger it var float OldTickTime; var() bool bEnabled; var bool bTriggered; var() name SeenActorTag; // tag of actor which triggers this trigger when seen var actor SeenActor; var() int MaxViewAngle; // how directly a player must be looking at SeenActor center (in degrees) var float RequiredViewDir; // how directly player must be looking at SeenActor - 1.0 = straight on, 0.75 = barely on screen function PostBeginPlay() { Super.PostBeginPlay(); RequiredViewDir = cos(MaxViewAngle * PI/180); if ( SeenActorTag != '' ) ForEach AllActors(class'Actor',SeenActor,SeenActorTag) break; } event PlayerSeesMe(PlayerController P) { TriggerEvent(Event,self,P.Pawn); bTriggered = true; } function Trigger( actor Other, Pawn EventInstigator ) { bEnabled = true; } sD\,e(R3/\, GsBssFh(? Mp M#tIIdAmphibious GsHl(  Mp w*}q6You feel much lighter-O'q!DIdFly GsIn(b-O(_w*jrs GsJz( Mp w*Dr6You feel ethereal-O'q!DIdGhost GsKK P  Mp K pwK *Yw. K *. K ]sK K * yDIdAllAmmo Gsx//============================================================================= // The light class. //============================================================================= class Light extends Actor placeable native; #exec Texture Import File=Textures\S_Light.pcx Name=S_Light Mips=Off MASKED=1 var (Corona) float MinCoronaSize; var (Corona) float MaxCoronaSize; var (Corona) float CoronaRotation; var (Corona) float CoronaRotationOffset; var (Corona) bool UseOwnFinalBlend; sLO'}( Mp -^ -O'R-O'X$XXIdInvisible Gsl,//============================================================================= // LiftExit. //============================================================================= class LiftExit extends NavigationPoint placeable native; #exec Texture Import File=Textures\Lift_exit.pcx Name=S_LiftExit Mips=Off MASKED=1 var() name LiftTag; var Mover MyLift; var() byte SuggestedKeyFrame; // mover keyframe associated with this exit - optional var byte KeyFrame; var(LiftJump) bool bLiftJumpExit; var(LiftJump) bool bNoDoubleJump; function PostBeginPlay() { Super.PostBeginPlay(); if ( bLiftJumpExit && (MyLift != None) ) { if ( Level.Game.GameDifficulty < 4 ) ExtraCost = 10000000; MyLift.bJumpLift = true; } } function bool CanBeReachedFromLiftBy(Pawn Other) { local float RealJumpZ; if ( bLiftJumpExit ) { if ( (MyLift.Velocity.Z < 100) || (MyLift.KeyNum == 0) ) return false; RealJumpZ = Other.JumpZ; if ( !bNoDoubleJump ) Other.JumpZ = Other.JumpZ * 1.5; Other.JumpZ += MyLift.Velocity.Z; Other.bWantsToCrouch = false; Other.Controller.MoveTarget = self; Other.Controller.Destination = Location; Other.bNoJumpAdjust = true; Other.Velocity = SuggestFallVelocity(Location + vect(0,0,100), Other.Location, Other.JumpZ, Other.GroundSpeed); Other.Acceleration = vect(0,0,0); Other.SetPhysics(PHYS_Falling); Other.Controller.SetFall(); Other.DestinationOffset = CollisionRadius; Other.JumpZ = RealJumpZ; if ( !bNoDoubleJump ) Other.Controller.SetDoubleJump(); return true; } return ( (Location.Z < Other.Location.Z + Other.CollisionHeight) && Other.LineOfSightTo(self) ); } event bool SuggestMovePreparation(Pawn Other) { local Controller C; if ( (MyLift == 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 == MyLift) || ((LiftCenter(Other.Anchor) != None) && (LiftCenter(Other.Anchor).MyLift == MyLift) && (Other.ReachedDestination(Other.Anchor))) ) { // 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 Other.DesiredRotation = rotator(Location - Other.Location); Other.Controller.WaitForMover(MyLift); return true; } else { for ( C=Level.ControllerList; C!=None; C=C.nextController ) if ( (C.Pawn != None) && (C.PendingMover == MyLift) && C.SameTeamAs(Other.Controller) && C.Pawn.ReachedDestination(self) ) { Other.DesiredRotation = rotator(Location - Other.Location); Other.Controller.WaitForMover(MyLift); return true; } } return false; } sa(R Mp O-j-j(6God mode off -j'6God Mode onIdGod GsP[,C)D Mp  q[,bpbIdSloMo Gs]G~u W GsQZ,D)= Mp yZ,IdSetJumpZ GssesSY,J)!D Mp 6m {Y,IdSetGravity GsTssUP'M)( Mp M M P'XXP'IdSetSpeed Gs_///============================================================================= // LiftCenter. //============================================================================= class LiftCenter extends NavigationPoint placeable native; #exec Texture Import File=Textures\Lift_center.pcx Name=S_LiftCenter Mips=Off MASKED=1 var() name LiftTag; var mover MyLift; var() name LiftTrigger; var trigger RecommendedTrigger; var float MaxDist2D; var vector LiftOffset; // starting vector between MyLift location and LiftCenter location function PostBeginPlay() { if ( LiftTrigger != '' ) ForEach DynamicActors(class'Trigger', RecommendedTrigger, LiftTrigger ) break; Super.PostBeginPlay(); } /* 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 */ function Actor SpecialHandling(Pawn Other) { // if no lift, no special handling if ( MyLift == None ) return self; // check whether or not need to trigger the lift if ( !MyLift.IsInState('StandOpenTimed') ) { if ( MyLift.bClosed && (RecommendedTrigger != None) ) return RecommendedTrigger; } else if ( MyLift.BumpType == BT_PlayerBump && !Other.IsPlayerPawn() ) return None; return self; } /* Check if mover is positioned to allow Pawn to get on */ function 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 SetLocation(MyLift.Location + LiftOffset); SetBase(MyLift); // if mover is moving, wait if ( MyLift.bInterpolating || !ProceedWithMove(Other) ) { Other.Controller.WaitForMover(MyLift); return true; } return false; } function bool ProceedWithMove(Pawn Other) { local LiftExit Start; local float dist2D; local vector dir; // see if mover is at appropriate location/keyframe Start = LiftExit(Other.Anchor); if ( Other.Controller == None ) return false; else if ( (Start != None) && (Start.KeyFrame != 255) && Other.ReachedDestination(Start) ) { if ( MyLift.KeyNum == Start.KeyFrame ) return true; } else if ( (LiftExit(Other.Controller.MoveTarget) != None) && Other.ReachedDestination(self) ) return LiftExit(Other.Controller.MoveTarget).CanBeReachedFromLiftBy(Other); else { //check distance directly - make sure close dir = Location - Other.Location; dir.Z = 0; dist2d = vsize(dir); if ( (Location.Z - CollisionHeight < Other.Location.Z - Other.CollisionHeight + MAXSTEPHEIGHT) && (Location.Z - CollisionHeight > Other.Location.Z - Other.CollisionHeight - 1200) && ( dist2D < MaxDist2D) ) { return true; } } // if mover not operating, need to start it if ( MyLift.bClosed ) { Other.SetMoveTarget(SpecialHandling(Other)); return true; } return false; } sO //============================================================================= // LevelSummary contains the summary properties from the LevelInfo actor. // Designed for fast loading. //============================================================================= class LevelSummary extends Object native; var(LevelSummary) localized String Title; var(LevelSummary) localized String Description; var() localized string LevelEnterText; var(LevelSummary) String Author; var(LevelSummary) String DecoTextName; var(LevelSummary) int IdealPlayerCountMin; var(LevelSummary) int IdealPlayerCountMax; var(LevelSummary) bool HideFromMenus; var(SinglePlayer) int SinglePlayerTeamSize; var(LevelSummary) Material Screenshot; var(LevelSummary) string ExtraInfo; s}//============================================================================= // LevelInfo contains information about the current level. There should // be one per level and it should be actor 0. UnrealEd creates each level's // LevelInfo automatically so you should never have to place one // manually. // // The ZoneInfo properties in the LevelInfo are used to define // the properties of all zones which don't themselves have ZoneInfo. //============================================================================= class LevelInfo extends ZoneInfo native nativereplication notplaceable; // Textures. //#exec Texture Import File=Textures\WireframeTexture.tga // use white square instead #exec Texture Import File=Textures\WhiteSquareTexture.pcx #exec Texture Import File=Textures\S_Vertex.tga Name=LargeVertex //----------------------------------------------------------------------------- // Level time. // Time passage. var float TimeDilation; // Normally 1 - scales real time passage. // Current time. var float TimeSeconds; // Time in seconds since level began play. var transient int Year; // Year. var transient int Month; // Month. var transient int Day; // Day of month. var transient int DayOfWeek; // Day of week. var transient int Hour; // Hour. var transient int Minute; // Minute. var transient int Second; // Second. var transient int Millisecond; // Millisecond. var float PauseDelay; // time at which to start pause //----------------------------------------------------------------------------- // Level Summary Info var(LevelSummary) localized String Title; var(LevelSummary) String Author; var(LevelSummary) String Description; var(LevelSummary) Material Screenshot; var(LevelSummary) String DecoTextName; var(LevelSummary) int IdealPlayerCountMin; var(LevelSummary) int IdealPlayerCountMax; var(LevelSummary) string ExtraInfo; var(SinglePlayer) int SinglePlayerTeamSize; var(RadarMap) Material RadarMapImage; var(RadarMap) float CustomRadarRange; var() config enum EPhysicsDetailLevel { PDL_Low, PDL_Medium, PDL_High } PhysicsDetailLevel; var() config enum EMeshLODDetailLevel { MDL_Low, MDL_Medium, MDL_High, MDL_Ultra } MeshLODDetailLevel; // Karma - jag var(Karma) float KarmaTimeScale; // Karma physics timestep scaling. var(Karma) float RagdollTimeScale; // Ragdoll physics timestep scaling. This is applied on top of KarmaTimeScale. var(Karma) int MaxRagdolls; // Maximum number of simultaneous rag-dolls. var(Karma) float KarmaGravScale; // Allows you to make ragdolls use lower friction than normal. var(Karma) bool bKStaticFriction; // Better rag-doll/ground friction model, but more CPU. var() bool bKNoInit; // Start _NO_ Karma for this level. Only really for the Entry level. // jag var int LastTaunt[2]; // 'Global' last taunts used. var config float DecalStayScale; // affects decal stay time var() localized string LevelEnterText; // Message to tell players when they enter. var() string LocalizedPkg; // Package to look in for localizations. var PlayerReplicationInfo Pauser; // If paused, name of person pausing the game. var LevelSummary Summary; var string VisibleGroups; // List of the group names which were checked when the level was last saved //----------------------------------------------------------------------------- // Flags affecting the level. var(LevelSummary) bool HideFromMenus; var() bool bLonePlayer; // No multiplayer coordination, i.e. for entranceways. var bool bBegunPlay; // Whether gameplay has begun. var bool bPlayersOnly; // Only update players. var bool bFreezeKarma; // Stop all Karma physics from being evolved. var const EDetailMode DetailMode; // Client detail mode. var bool bDropDetail; // frame rate is below DesiredFrameRate, so drop high detail actors var bool bAggressiveLOD; // frame rate is well below DesiredFrameRate, so make LOD more aggressive var bool bStartup; // Starting gameplay. var config bool bLowSoundDetail; var bool bPathsRebuilt; // True if path network is valid var bool bHasPathNodes; var bool bLevelChange; var globalconfig bool bShouldPreload; // if true, preload all skins (initially set true if > 512 MB of system memory) var globalconfig bool bDesireSkinPreload; // user set property var globalconfig bool bKickLiveIdlers; // if true, even playercontrollers with pawns can be kicked for idling var bool bSkinsPreloaded; // set after skins are preloaded var bool bClassicView; // FOV at least 90, eyeheight up, small weapons OBSOLETE var(RadarMap) bool bShowRadarMap; var(RadarMap) bool bUseTerrainForRadarRange; var bool bIsSaveGame; // true while save game is being loaded (GameInfo bIsSaveGame stays true through entire game) var(SaveGames) bool bSupportSaveGames; // needs to be true to support savegames //----------------------------------------------------------------------------- // Renderer Management. var config bool bNeverPrecache; var() int LevelTextureLODBias; var float AnimMeshGlobalLOD; //State of the dDynamic LOD reduction for animating meshes. //----------------------------------------------------------------------------- // Legend - used for saving the viewport camera positions var() vector CameraLocationDynamic; var() vector CameraLocationTop; var() vector CameraLocationFront; var() vector CameraLocationSide; var() rotator CameraRotationDynamic; //----------------------------------------------------------------------------- // Audio properties. var(Audio) string Song; // Filename of the streaming song. var(Audio) float PlayerDoppler; // Player doppler shift, 0=none, 1=full. var(Audio) float MusicVolumeOverride; //----------------------------------------------------------------------------- // Miscellaneous information. var() float Brightness; var texture DefaultTexture; var texture WireframeTexture; var texture WhiteSquareTexture; var texture LargeVertex; var int HubStackLevel; var transient enum ELevelAction { LEVACT_None, LEVACT_Loading, LEVACT_Saving, LEVACT_Connecting, LEVACT_Precaching } LevelAction; var transient GameReplicationInfo GRI; //----------------------------------------------------------------------------- // Networking. var enum ENetMode { NM_Standalone, // Standalone game. NM_DedicatedServer, // Dedicated server, no local client. NM_ListenServer, // Listen server. NM_Client // Client only, no local server. } NetMode; var string ComputerName; // Machine's name according to the OS. var string EngineVersion; // Engine version. var string MinNetVersion; // Min engine version that is net compatible. //----------------------------------------------------------------------------- // Gameplay rules var() string DefaultGameType; var() string PreCacheGame; var GameInfo Game; var float DefaultGravity; var float LastVehicleCheck; var() float StallZ; //vehicles stall if they reach this //----------------------------------------------------------------------------- // Navigation point and Pawn lists (chained using nextNavigationPoint and nextPawn). var const NavigationPoint NavigationPointList; var const Controller ControllerList; var private PlayerController LocalPlayerController; // player who is client here //----------------------------------------------------------------------------- // Headlights var(Headlights) bool bUseHeadlights; var(Headlights) float HeadlightScaling; //----------------------------------------------------------------------------- // Server related. var string NextURL; var bool bNextItems; var float NextSwitchCountdown; //----------------------------------------------------------------------------- // Global object recycling pool. var transient ObjectPool ObjectPool; //----------------------------------------------------------------------------- // Additional resources to precache (e.g. Playerskins). var transient array PrecacheMaterials; var transient array PrecacheStaticMeshes; // common static mesh (for camouflage combo) var(Camouflage) StaticMesh IndoorCamouflageMesh; var(Camouflage) float IndoorMeshDrawscale; var(Camouflage) StaticMesh OutdoorCamouflageMesh; var(Camouflage) float OutdoorMeshDrawscale; // When kicking up dust in this level - what colour to use? var(DustColor) color DustColor; var(DustColor) color WaterDustColor; //----------------------------------------------------------------------------- // Replication/Networking var float MoveRepSize; var globalconfig float MaxClientFrameRate; // speed hack detection var globalconfig float MaxTimeMargin; var globalconfig float TimeMarginSlack; var globalconfig float MinTimeMargin; // these two properties are valid only during replication var const PlayerController ReplicationViewer; // during replication, set to the playercontroller to // which actors are currently being replicated var const Actor ReplicationViewTarget; // during replication, set to the viewtarget to // which actors are currently being replicated //----------------------------------------------------------------------------- // Functions. native simulated function DetailChange(EDetailMode NewDetailMode); native simulated function bool IsEntry(); native simulated function UpdateDistanceFogLOD(float LOD); native simulated function ForceLoadTexture(Texture Texture); native simulated function PhysicsVolume GetPhysicsVolume(vector Loc); // returns PhysicsVolume which encompasses Loc simulated function PostBeginPlay() { Super.PostBeginPlay(); DecalStayScale = Max(DecalStayScale,0); } simulated function class GetGameClass() { local class G; if(Level.Game != None) return Level.Game.Class; if (GRI != None && GRI.GameClass != "") G = class(DynamicLoadObject(GRI.GameClass,class'Class')); if(G != None) return G; if ( DefaultGameType != "" ) G = class(DynamicLoadObject(DefaultGameType,class'Class')); return G; } simulated event FillPrecacheMaterialsArray( bool FullPrecache ) { local Actor A; local class G; local bool bRealDesire; if ( NetMode == NM_DedicatedServer ) return; if ( !bSkinsPreloaded || FullPrecache ) { if ( Game != None ) G = Game.Class; else if ( (GRI != None) && (GRI.GameClass != "") ) G = class(DynamicLoadObject(GRI.GameClass,class'Class')); if ( G != None ) { G.Static.PreCacheGameTextures(self); bSkinsPreloaded = true; } if ( (G == None) && (DefaultGameType != "") ) G = class(DynamicLoadObject(DefaultGameType,class'Class')); if ( G == None ) G = class(DynamicLoadObject(PreCacheGame,class'Class')); if ( G != None ) { bRealDesire = bDesireSkinPreload; bDesireSkinPreload = false; G.Static.PreCacheGameTextures(self); bDesireSkinPreload = bRealDesire; } } ForEach AllActors(class'Actor',A) { if ( !A.bAlreadyPrecachedMaterials || FullPrecache ) { A.UpdatePrecacheMaterials(); A.bAlreadyPrecachedMaterials = true; } } } // OBSOLETE simulated function PrecacheAnnouncements(); simulated event FillPrecacheStaticMeshesArray( bool FullPrecache ) { local Actor A; local class G; if ( NetMode == NM_DedicatedServer ) return; if ( Game == None ) { if ( (GRI != None) && (GRI.GameClass != "") ) G = class(DynamicLoadObject(GRI.GameClass,class'Class')); if ( (G == None) && (DefaultGameType != "") ) G = class(DynamicLoadObject(DefaultGameType,class'Class')); if ( G == None ) G = class(DynamicLoadObject(PreCacheGame,class'Class')); if ( G != None ) G.Static.PreCacheGameStaticMeshes(self); } ForEach AllActors(class'Actor',A) if ( !A.bAlreadyPrecachedMeshes || FullPrecache ) { A.UpdatePrecacheStaticMeshes(); A.bAlreadyPrecachedMeshes = true; } } simulated function AddPrecacheMaterial(Material mat) { local int Index; if ( NetMode == NM_DedicatedServer ) return; if (mat == None) return; Index = Level.PrecacheMaterials.Length; PrecacheMaterials.Insert(Index, 1); PrecacheMaterials[Index] = mat; } simulated function AddPrecacheStaticMesh(StaticMesh stat) { local int Index; if ( NetMode == NM_DedicatedServer ) return; if (stat == None) return; Index = Level.PrecacheStaticMeshes.Length; PrecacheStaticMeshes.Insert(Index, 1); PrecacheStaticMeshes[Index] = stat; } // // Return the URL of this level on the local machine. // native simulated function string GetLocalURL(); // // Demo build flag // native simulated static final function bool IsDemoBuild(); // True if this is a demo build. // software rendering flag native simulated static final function bool IsSoftwareRendering(); // // Return the URL of this level, which may possibly // exist on a remote machine. // native simulated function string GetAddressURL(); // // Returns whether we are currently in the process of connecting to a URL // native simulated function bool IsPendingConnection(); // // Jump the server to a new level. // event ServerTravel( string URL, bool bItems ) { if ( InStr(url,"%")>=0 ) { log("URL Contains illegal character '%'."); return; } if (InStr(url,":")>=0 || InStr(url,"/")>=0 || InStr(url,"\\")>=0) { log("URL blocked"); return; } if( NextURL=="" ) { bLevelChange = true; bNextItems = bItems; NextURL = URL; if( Game!=None ) Game.ProcessServerTravel( URL, bItems ); else NextSwitchCountdown = 0; } } // // ensure the DefaultPhysicsVolume class is loaded. // function ThisIsNeverExecuted() { local DefaultPhysicsVolume P; P = None; } /* Reset() reset actor to initial state - used when restarting level without reloading. */ function Reset() { DefaultGravity = Default.DefaultGravity; // perform garbage collection of objects (not done during gameplay) ConsoleCommand("OBJ GARBAGE"); Super.Reset(); } //----------------------------------------------------------------------------- // Network replication. replication { reliable if( bNetDirty && Role==ROLE_Authority ) Pauser, TimeDilation, DefaultGravity; reliable if( bNetInitial && Role==ROLE_Authority ) RagdollTimeScale, KarmaTimeScale, KarmaGravScale; } // // PreBeginPlay // simulated event PreBeginPlay() { // Create the object pool. Super.PreBeginPlay(); ObjectPool = new(xLevel) class'ObjectPool'; } simulated function PlayerController GetLocalPlayerController() { local PlayerController PC; if ( Level.NetMode == NM_DedicatedServer ) return None; if ( LocalPlayerController != None ) return LocalPlayerController; ForEach DynamicActors(class'PlayerController', PC) { if ( Viewport(PC.Player) != None ) { LocalPlayerController = PC; break; } } return LocalPlayerController; } sjVd"** GsI6/*============================================================================= // LadderVolumes, when touched, cause ladder supporting actors to use Phys_Ladder. // note that underwater ladders won't be waterzones (no breathing problems) ============================================================================= */ class LadderVolume extends PhysicsVolume native; var() name ClimbingAnimation, TopAnimation; // name of animation to play when climbing this ladder 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; simulated function 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) ) { for ( C=Level.ControllerList; C!=None; C=C.NextController ) 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); } sW])05 Mp \ IdKillPawns Gs_W,^)=SW, wS*/a9 VrVSwVw * \dV10 GsssPvclass LadderInfo extends Object abstract; /* * LadderInfo contains all the information needed to determine * the contents of each step in the single-player ladder, and * to determine what match is next in each ladder. * * author: polge * last edit: capps */ var() editinline array DMMatches; var() editinline array TDMMatches; var() editinline array DOMMatches; var() editinline array CTFMatches; var() editinline array BRMatches; var() editinline array ChampionshipMatches; const DMLadderIndex = 0; const TDMLadderIndex = 1; const DOMLadderIndex = 2; const CTFLadderIndex = 3; const BRLadderIndex = 4; const ChampionshipLadderIndex = 5; var int OpenNextLadderAtRung[5]; static function string UpdateLadders(GameProfile G, int CurrentLadder) { local string SpecialEvent; if ( G.LadderRung[CurrentLadder] > G.CurrentMenuRung ) { // they've chosen to play a match they've completed previously return ""; } // updates ladder rungs appropriately switch( CurrentLadder ) { case DMLadderIndex: /*if ( Default.OpenNextLadderAtRung[CurrentLadder] == G.LadderRung[CurrentLadder] ) { G.LadderRung[TDMLadderIndex] = 0; SpecialEvent = "TDM OPENED"; } else if ( G.LadderRung[CurrentLadder] >= Default.DMMatches.Length ) { G.LadderRung[CurrentLadder] = Default.DMMatches.Length; SpecialEvent = "DM COMPLETE"; } else */ SpecialEvent = Default.DMMatches[G.LadderRung[CurrentLadder]].SpecialEvent; break; case TDMLadderIndex: /*if ( G.LadderRung[CurrentLadder] >= Default.TDMMatches.Length ) { G.LadderRung[CurrentLadder] = Default.TDMMatches.Length; SpecialEvent = "TDM COMPLETE"; } else if ( Default.OpenNextLadderAtRung[CurrentLadder] == G.LadderRung[CurrentLadder] ) { G.LadderRung[DOMLadderIndex] = 0; SpecialEvent = "DOM OPENED"; } else */ SpecialEvent = Default.TDMMatches[G.LadderRung[CurrentLadder]].SpecialEvent; break; case DOMLadderIndex: /*if ( G.LadderRung[CurrentLadder] >= Default.DOMMatches.Length ) { G.LadderRung[CurrentLadder] = Default.DOMMatches.Length; SpecialEvent = "DOM COMPLETE"; } else if ( Default.OpenNextLadderAtRung[CurrentLadder] == G.LadderRung[CurrentLadder] ) { G.LadderRung[CTFLadderIndex] = 0; SpecialEvent = "CTF OPENED"; } else */ SpecialEvent = Default.DOMMatches[G.LadderRung[CurrentLadder]].SpecialEvent; break; case CTFLadderIndex: /*if ( G.LadderRung[CurrentLadder] >= Default.CTFMatches.Length ) { G.LadderRung[CurrentLadder] = Default.CTFMatches.Length; SpecialEvent = "CTF COMPLETE"; } else if ( Default.OpenNextLadderAtRung[CurrentLadder] == G.LadderRung[CurrentLadder] ) { G.LadderRung[BRLadderIndex] = 0; SpecialEvent = "BR OPENED"; } else */ SpecialEvent = Default.CTFMatches[G.LadderRung[CurrentLadder]].SpecialEvent; break; case BRLadderIndex: /*if ( G.LadderRung[CurrentLadder] >= Default.BRMatches.Length ) { G.LadderRung[CurrentLadder] = Default.BRMatches.Length; SpecialEvent = "BR COMPLETE"; } else */ SpecialEvent = Default.BRMatches[G.LadderRung[CurrentLadder]].SpecialEvent; break; case ChampionshipLadderIndex: /* if ( G.LadderRung[CurrentLadder] >= Default.ChampionshipMatches.Length ) { G.LadderRung[CurrentLadder] = Default.ChampionshipMatches.Length; SpecialEvent = "CHAMPIONSHIP COMPLETE"; } else */ SpecialEvent = Default.ChampionshipMatches[G.LadderRung[CurrentLadder]].SpecialEvent; break; } // open new ladder if appropriate if ( InStr (SpecialEvent, "OPENED") >= 0 ) { if ( Left (SpecialEvent, 3) == "TDM" ) { G.LadderRung[TDMLadderIndex] = 0; } else if ( Left (SpecialEvent, 3) == "CTF" ) { G.LadderRung[CTFLadderIndex] = 0; } else if ( Left (SpecialEvent, 3) == "DOM" ) { G.LadderRung[DOMLadderIndex] = 0; } else if ( Left (SpecialEvent, 2) == "BR" ) { G.LadderRung[BRLadderIndex] = 0; } } G.LadderRung[CurrentLadder] += 1; // check if championship ladder should be opened if ( (G.LadderRung[5] == -1) && (G.LadderRung[0] >= Default.DMMatches.Length) && (G.LadderRung[1] >= Default.TDMMatches.Length) && (G.LadderRung[2] >= Default.DOMMatches.Length) && (G.LadderRung[3] >= Default.CTFMatches.Length) && (G.LadderRung[4] >= Default.BRMatches.Length) ) { G.LadderRung[5] = 0; SpecialEvent = "CHAMPIONSHIP OPENED"; } return SpecialEvent; } // robust checks are in LadderInfo, returns none if not found static function MatchInfo GetMatchInfo(int ladder, int rung) { local array matcharray; if (rung < 0) { return none; } switch (ladder) { case DMLadderIndex: matcharray = Default.DMMatches; break; case TDMLadderIndex: matcharray = Default.TDMMatches; break; case DOMLadderIndex: matcharray = Default.DOMMatches; break; case CTFLadderIndex: matcharray = Default.CTFMatches; break; case BRLadderIndex: matcharray = Default.BRMatches; break; case ChampionshipLadderIndex: matcharray = Default.ChampionshipMatches; break; } if ( matcharray.Length <= 0 ) { return none; } if ( rung >= matcharray.Length ) { return matcharray[matcharray.Length-1]; } return matcharray[rung]; } static function MatchInfo GetCurrentMatchInfo(GameProfile G) { return GetMatchInfo (G.CurrentLadder, G.CurrentMenuRung); } static function string MakeURLFor(GameProfile G) { local MatchInfo M; local string URL; M = GetCurrentMatchInfo(G); if ( M == none ) { Log("SINGLEPLAYER LadderInfo::MakeURLFor MatchInfo invalid."); return ""; } G.EnemyTeam = M.EnemyTeamName; G.Difficulty = G.BaseDifficulty + M.DifficultyModifier; URL = M.LevelName$"?Name="$G.PlayerName$"?Character="$G.PlayerCharacter$"?SaveGame="$G.PackageName$M.URLString; if ( M.GoalScore != 0 ) URL = URL$"?GoalScore="$M.GoalScore; if ( M.NumBots > 0 ) URL = URL$"?NumBots="$M.NumBots; if ( M.GameType != "" ) URL = URL$"?Game="$M.GameType; URL = URL$"?Team=1"; // always blue team return URL; } // Used in menus: this is the gametype info for the next match //FIXME!! Useless and unfortunate code, must use localization mechanism //@@ LOCALIZE ME static function string GetMatchDescription (GameProfile G){ local string retval; switch (G.CurrentLadder) { case DMLadderIndex: retval = "Deathmatch"; break; case TDMLadderIndex: retval = "Team Deathmatch"; break; case DOMLadderIndex: retval = "Domination"; break; case CTFLadderIndex: retval = "Capture the Flag"; break; case BRLadderIndex: retval = "Bombing Run"; break; case ChampionshipLadderIndex: retval = "Championship Match"; break; } return retval; } // handy helper function to convert numbers to lengths static function int LengthOfLadder(int ladder) { switch (ladder) { case DMLadderIndex: return Default.DMMatches.Length; case TDMLadderIndex: return Default.TDMMatches.Length; case DOMLadderIndex: return Default.DOMMatches.Length; case CTFLadderIndex: return Default.CTFMatches.Length; case BRLadderIndex: return Default.BRMatches.Length; case ChampionshipLadderIndex: return Default.ChampionshipMatches.Length; default: return -1; } } sH/*============================================================================= // 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 ============================================================================= */ class Ladder extends SmallNavigationPoint placeable native; #exec Texture Import File=Textures\Ladder.pcx Name=S_Ladder Mips=Off MASKED=1 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; } s`Q'f)R Mp pFabricate Q'bQ' wb*|w*c  c  ab c9?,H99 #?9?,IdSummon Gsk //============================================================================= // KVehicle spawner location. //============================================================================= class KVehicleFactory extends SVehicleFactory placeable; #exec Texture Import File=Textures\S_KVehFact.pcx Name=S_KVehFact Mips=Off MASKED=1 var() class KVehicleClass; event Trigger( Actor Other, Pawn EventInstigator ) { local KVehicle CreatedVehicle; if ( VehicleCount >= MaxVehicleCount ) return; if ( KVehicleClass != None ) { CreatedVehicle = Spawn(KVehicleClass, , , Location, Rotation); if ( CreatedVehicle != None ) { VehicleCount++; CreatedVehicle.ParentFactory = Self; } } } sst// Generic 'Karma Vehicle' base class that can be controlled by a Pawn. class KVehicle extends Vehicle native abstract; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // Effect spawned when vehicle is destroyed var (KVehicle) class DestroyEffectClass; // Simple 'driving-in-rings' logic. var (KVehicle) bool bAutoDrive; // The factory that created this vehicle. //var KVehicleFactory ParentFactory; // Weapon system var bool bVehicleIsFiring, bVehicleIsAltFiring; const FilterFrames = 5; var vector CameraHistory[FilterFrames]; var int NextHistorySlot; var bool bHistoryWarmup; // Useful function for plotting data to real-time graph on screen. native final function GraphData(string DataName, float DataValue); function TakeDamage(int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, class damageType) { Super.TakeDamage(Damage,instigatedBy,HitLocation,Momentum,DamageType); } // You got some new info from the server (ie. VehicleState has some new info). event VehicleStateReceived(); // Called when a parameter of the overall articulated actor has changed (like PostEditChange) // The script must then call KUpdateConstraintParams or Actor Karma mutators as appropriate. simulated event KVehicleUpdateParams(); // The pawn Driver has tried to take control of this vehicle function bool TryToDrive(Pawn P) { if ( P.bIsCrouched || (P.Controller == None) || (Driver != None) || !P.Controller.bIsPlayer ) return false; if ( !P.IsHumanControlled() || !P.Controller.IsInState('PlayerDriving') ) { KDriverEnter(P); return true; } return false; } // Events called on driver entering/leaving vehicle simulated function ClientKDriverEnter(PlayerController pc) { pc.myHUD.bCrosshairShow = false; pc.myHUD.bShowWeaponInfo = false; pc.myHUD.bShowPoints = false; pc.bBehindView = true; pc.bFreeCamera = true; pc.SetRotation(rotator( vect(-1, 0, 0) >> Rotation )); } function KDriverEnter(Pawn P) { local PlayerController PC; local Controller C; // Set pawns current controller to control the vehicle pawn instead Driver = P; // Move the driver into position, and attach to car. Driver.SetCollision(false, false); Driver.bCollideWorld = false; Driver.bPhysicsAnimUpdate = false; Driver.Velocity = vect(0,0,0); Driver.SetPhysics(PHYS_None); Driver.SetBase(self); // Disconnect PlayerController from Driver and connect to KVehicle. C = P.Controller; p.Controller.Unpossess(); Driver.SetOwner(C); // This keeps the driver relevant. C.Possess(self); PC = PlayerController(C); if ( PC != None ) { PC.ClientSetViewTarget(self); // Set playercontroller to view the vehicle // Change controller state to driver PC.GotoState('PlayerDriving'); ClientKDriverEnter(PC); } } simulated function ClientKDriverLeave(PlayerController pc) { pc.bBehindView = false; pc.bFreeCamera = false; // This removes any 'roll' from the look direction. //exitLookDir = Vector(pc.Rotation); //pc.SetRotation(Rotator(exitLookDir)); pc.myHUD.bCrosshairShow = pc.myHUD.default.bCrosshairShow; pc.myHUD.bShowWeaponInfo = pc.myHUD.default.bShowWeaponInfo; pc.myHUD.bShowPoints = pc.myHUD.default.bShowPoints; // Reset the view-smoothing NextHistorySlot = 0; bHistoryWarmup = true; } // Called from the PlayerController when player wants to get out. function bool KDriverLeave(bool bForceLeave) { local PlayerController pc; local int i; local bool havePlaced; local vector HitLocation, HitNormal, tryPlace; // Do nothing if we're not being driven if(Driver == None) return false; // Before we can exit, we need to find a place to put the driver. // Iterate over array of possible exit locations. if (!bRemoteControlled) { Driver.bCollideWorld = true; Driver.SetCollision(true, true); havePlaced = false; for(i=0; i < ExitPositions.Length && havePlaced == false; i++) { //Log("Trying Exit:"$i); tryPlace = Location + (ExitPositions[i] >> Rotation); // First, do a line check (stops us passing through things on exit). if( Trace(HitLocation, HitNormal, tryPlace, Location, false) != None ) continue; // Then see if we can place the player there. if( !Driver.SetLocation(tryPlace) ) continue; havePlaced = true; } // If we could not find a place to put the driver, leave driver inside as before. if(!havePlaced && !bForceLeave) { Log("Could not place driver."); Driver.bCollideWorld = false; Driver.SetCollision(false, false); return false; } } pc = PlayerController(Controller); ClientKDriverLeave(pc); // Reconnect PlayerController to Driver. pc.Unpossess(); pc.Possess(Driver); pc.ClientSetViewTarget(Driver); // Set playercontroller to view the persone that got out Controller = None; Driver.PlayWaiting(); Driver.bPhysicsAnimUpdate = Driver.Default.bPhysicsAnimUpdate; // Do stuff on client //pc.ClientSetBehindView(false); //pc.ClientSetFixedCamera(true); if (!bRemoteControlled) { Driver.Acceleration = vect(0, 0, 24000); Driver.SetPhysics(PHYS_Falling); Driver.SetBase(None); } // Car now has no driver Driver = None; // Put brakes on before you get out :) Throttle=0; Steering=0; // Stop firing when you get out! bVehicleIsFiring = false; bVehicleIsAltFiring = false; return true; } // Special calc-view for vehicles simulated function bool SpecialCalcView(out actor ViewActor, out vector CameraLocation, out rotator CameraRotation ) { local vector CamLookAt, HitLocation, HitNormal; local PlayerController pc; local int i, averageOver; pc = PlayerController(Controller); // Only do this mode we have a playercontroller viewing this vehicle if(pc == None || pc.ViewTarget != self) return false; ViewActor = self; CamLookAt = Location + (vect(-100, 0, 100) >> Rotation); ////////////////////////////////////////////////////// // Smooth lookat position over a few frames. CameraHistory[NextHistorySlot] = CamLookAt; NextHistorySlot++; if(bHistoryWarmup) averageOver = NextHistorySlot; else averageOver = FilterFrames; CamLookAt = vect(0, 0, 0); for(i=0; i> CameraRotation); if( Trace( HitLocation, HitNormal, CameraLocation, CamLookAt, false, vect(10, 10, 10) ) != None ) { CameraLocation = HitLocation; } return true; } simulated function Destroyed() { // If there was a driver in the vehicle, destroy him too if ( Driver != None ) Driver.Destroy(); // Trigger any effects for destruction if(DestroyEffectClass != None) spawn(DestroyEffectClass, , , Location, Rotation); Super.Destroyed(); } simulated event Tick(float deltaSeconds) { } // Includes properties from KActor sy&class KTire extends KActor native abstract; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) var KCarWheelJoint WheelJoint; // joint holding this wheel to chassis etc. // TYRE MODEL // FRICTION var float RollFriction; // friction coeff. in tyre direction var float LateralFriction; // friction coeff. in sideways direction // SLIP // slip = min(maxSlip, minSlip + (slipRate * angular vel)) var float RollSlip; // max first-order (force ~ vel) slip in tyre direction var float LateralSlip; // max first-order (force ~ vel) slip in sideways direction var float MinSlip; // minimum slip (both directions) var float SlipRate; // amount of extra slip per unit velocity // NORMAL var float Softness; // 'softness' in the normal dir var float Adhesion; // 'stickyness' in the normal dir var float Restitution; // 'bouncyness' in the normal dir // Other Output information var const bool bTireOnGround; // If this tire is currently in contact with something. var const float GroundSlipVel; // relative tangential velocity of wheel against ground (0 for static, >0 for slipping) // could use this to trigger squeeling noises/smoke var const vector GroundSlipVec; // full vector version of above (ie GroundSlipVel is magnitude of this vector). var const float SpinSpeed; // current speed (65535 = 1 rev/sec) of this wheel spinning about its axis var const material GroundMaterial; // material that tyre is touching var const ESurfaceTypes GroundSurfaceType; // surface type that the tyre is touching // This is filled in by VehicleStateReceived in KVehicle. var KRigidBodyState ReceiveState; var bool bReceiveStateNew; // This even is for updating the state (position, velocity etc.) of the tire's karma // body when we get new information from the network. event bool KUpdateState(out KRigidBodyState newState) { if(!bReceiveStateNew) return false; newState = ReceiveState; bReceiveStateNew = false; return true; //return false; } // By default, nothing happens if you shoot a tire function TakeDamage(int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, class damageType) { } sdh)cV Mp -B(-B(IdPlayersOnly GscV,m)zr V,-T,' Gska {k GspU,@kU, Gsiq)]=w* g  Z g   GslS,^ -<(-Q(Vw*vjv-S,6p!~{ GsssmQ,v) >zUwwz*`z-X|zHQ,wzzSwz*6FzH!~vz- Repulsors; // default is sphere with mass 1 and radius 1 s{fJ*1+ Mp 19:9:$ n P w*fwf*w. f*. fJ*ffnIdLoaded GsBn BC- Mp b9:9:$r*w.e* bXWeapons.AssaultRiflebXWeapons.RocketLauncherbXWeapons.ShockRiflebXWeapons.ShieldGunbXWeapons.LinkGunbXWeapons.SniperRiflebXWeapons.FlakCannonbXWeapons.MiniGunbXWeapons.TransLauncherbXWeapons.PainterbXWeapons.BioRiflebXWeapons.Redeemer$bUTClassic.ClassicSniperRifle$bOnslaught.ONSGrenadeLauncherbOnslaught.ONSAVRiLbOnslaught.ONSMineLayer bOnslaughtFull.ONSPainterIdAllWeapons GsCO*^,1 Mp G9:9:$r* IdSkipMatchwU*UZ GsDT'S*l2 Mp G9:9:$r* TT'% IdJumpMatchwU*U"WT' Gsk!//============================================================================= // KarmaActor. // Just a handy class to derive off to make physics objects. //============================================================================= class KActor extends Actor native placeable; // (cpptext) // (cpptext) // (cpptext) // (cpptext) var (Karma) bool bKTakeShot; // Ragdoll impact sounds. var() array ImpactSounds; var() float ImpactVolume; var() class ImpactEffect; var() bool bOrientImpactEffect; var() float ImpactInterval; var transient float LastImpactTime; // Default behaviour when shot is to apply an impulse and kick the KActor. function TakeDamage(int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, class damageType) { local vector ApplyImpulse; //Log("TakeDamage: "$self); if(bKTakeShot && damageType.default.KDamageImpulse > 0) { if(VSize(momentum) < 0.001) { // DEBUG //Log("Zero momentum to KActor.TakeDamage"); // END DEBUG return; } ApplyImpulse = Normal(momentum) * damageType.default.KDamageImpulse; KAddImpulse(ApplyImpulse, hitlocation); } } // Default behaviour when triggered is to wake up the physics. function Trigger( actor Other, pawn EventInstigator ) { KWake(); } // event KImpact(actor other, vector pos, vector impactVel, vector impactNorm) { local int numSounds, soundNum; // If its time for another impact. if(Level.TimeSeconds > LastImpactTime + ImpactInterval) { // If we have some sounds, play a random one. numSounds = ImpactSounds.Length; if(numSounds > 0) { soundNum = Rand(numSounds); //Log("Play Sound:"$soundNum); PlaySound(ImpactSounds[soundNum], SLOT_Ambient, ImpactVolume); } // If we have an effect class (and its relevant), spawn it. if( (ImpactEffect != None) && EffectIsRelevant(pos, false) ) { if(bOrientImpactEffect) spawn(ImpactEffect, self, , pos, rotator(impactVel)); else spawn(ImpactEffect, self, , pos); } LastImpactTime = Level.TimeSeconds; } } sV//============================= // Jumppad - bounces players/bots up // not directly placeable. Make a subclass with appropriate sound effect etc. // class JumpPad extends NavigationPoint native; var vector JumpVelocity, BACKUP_JumpVelocity; var Actor JumpTarget; var() float JumpZModifier; // for tweaking Jump, if needed var() sound JumpSound; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) function PostBeginPlay() { local NavigationPoint N; super.PostBeginPlay(); ForEach AllActors(class'NavigationPoint', N) if ( (N != self) && NearSpot(N.Location) ) N.ExtraCost += 1000; if ( JumpVelocity != JumpVelocity ) { log(self$" has illegal jump velocity "$JumpVelocity); JumpVelocity = vect(0,0,0); } BACKUP_JumpVelocity = JumpVelocity; } /* Reset() reset actor to initial state - used when restarting level without reloading. */ function Reset() { JumpVelocity = BACKUP_JumpVelocity; } event Touch(Actor Other) { if ( (Pawn(Other) == None) || (Other.Physics == PHYS_None) || (Vehicle(Other) != None) ) return; PendingTouch = Other.PendingTouch; Other.PendingTouch = self; } event PostTouch(Actor Other) { local Pawn P; P = Pawn(Other); if ( (P == None) || (P.Physics == PHYS_None) || (Vehicle(Other) != None) || (P.DrivenVehicle != None) ) return; if ( AIController(P.Controller) != None ) { P.Controller.Movetarget = JumpTarget; P.Controller.Focus = JumpTarget; if ( P.Physics != PHYS_Flying ) P.Controller.MoveTimer = 2.0; P.DestinationOffset = JumpTarget.CollisionRadius; } if ( P.Physics == PHYS_Walking ) P.SetPhysics(PHYS_Falling); P.Velocity = JumpVelocity; P.Acceleration = vect(0,0,0); if ( JumpSound != None ) P.PlaySound(JumpSound); } ssesXN&B|SetAdminFromURL calledoM MURL::Admin9=,o-j 'M oD_j N&M&D [o_ DWN&AM& GsFL,N(L,F GU@$   " "" "Gd"s@sp //============================================================================= // JumpDest. // specifies positions that can be reached with greater than normal jump // forced paths will check for greater than normal jump capability // NOTE these have NO relation to JumpPads //============================================================================= class JumpDest extends NavigationPoint native; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) var bool bOptionalJumpDest; var() bool bForceDoubleJump; // hack for map fixing var int NumUpstreamPaths; var ReachSpec UpstreamPaths[8]; var vector NeededJump[8]; var float CalculatedGravityZ[8]; function int GetPathIndex(ReachSpec Path) { local int i; if ( Path == None ) return 0; for ( i=0; i<4; i++ ) if ( UpstreamPaths[i] == Path ) return i; return 0; } event int SpecialCost(Pawn Other, ReachSpec Path) { local int Num; if ( Other.Physics == PHYS_Flying ) return 100; if ( Vehicle(Other) != None ) return 10000000; Num = GetPathIndex(Path); if ( Abs(Other.JumpZ/Other.PhysicsVolume.Gravity.Z) >= Abs(NeededJump[Num].Z/CalculatedGravityZ[Num]) ) return 100; return 10000000; } function DoJump(Pawn Other) { Other.bWantsToCrouch = false; Other.Controller.MoveTarget = self; Other.Controller.Destination = Location; Other.bNoJumpAdjust = true; if ( bForceDoubleJump ) Other.Velocity = Other.Controller.EAdjustJump(0,Other.Default.GroundSpeed); else Other.Velocity = Other.Controller.EAdjustJump(0,Other.GroundSpeed); Other.Acceleration = vect(0,0,0); Other.SetPhysics(PHYS_Falling); Other.Controller.SetFall(); Other.DestinationOffset = CollisionRadius; } event bool SuggestMovePreparation(Pawn Other) { local int Num; if ( Other.Controller == None ) return false; Num = GetPathIndex(Other.Controller.CurrentPath); if ( Abs(Other.JumpZ/Other.PhysicsVolume.Gravity.Z) < Abs(NeededJump[Num].Z/CalculatedGravityZ[Num]) ) return false; DoJump(Other); return false; } sp//============================================================================= // InventorySpot. //============================================================================= class InventorySpot extends SmallNavigationPoint native; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) var Pickup markedItem; var xPickupBase myPickupBase; var bool bSuperPickup; // set in xPickupBase PostBeginPlay() /* GetMoveTargetFor() Possibly return pickup rather than self as movetarget */ function Actor GetMoveTargetFor(AIController B, float MaxWait) { if ( (markedItem != None) && markedItem.ReadyToPickup(MaxWait) && (B.Desireability(markedItem) > 0) ) return markedItem; return self; } /* 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) */ event float DetourWeight(Pawn Other,float PathWeight) { if ( (markedItem != None) && markedItem.ReadyToPickup(0) ) return markedItem.DetourWeight(Other,PathWeight); } sUclass InventoryAttachment extends Actor native nativereplication; // (cpptext) // (cpptext) // (cpptext) // (cpptext) var bool bFastAttachmentReplication; // only replicates the subset of actor properties needed by basic attachments whose // common properties don't vary from their defaults var int inventoryattachment_dummy; // packing for hammer. disregard. --ryan. function InitFor(Inventory I) { Instigator = I.Instigator; } sn//============================================================================= // 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 // replace themselves with an actor of their Pickup class. // //============================================================================= class Inventory extends Actor abstract native nativereplication; #exec Texture Import File=Textures\Inventry.pcx Name=S_Inventory Mips=Off MASKED=1 //----------------------------------------------------------------------------- var byte InventoryGroup; // The weapon/inventory set, 0-9. var byte GroupOffset; // position within inventory group. (used by prevweapon and nextweapon) var bool bDisplayableInv; // Item displayed in HUD. var bool bTossedOut; // true if weapon/inventory was tossed out (so players can't cheat w/ weaponstay) var cache class PickupClass; // what class of pickup is associated with this inventory item var() travel int Charge; // Charge (for example, armor remaining if an armor) //----------------------------------------------------------------------------- // Rendering information. // Player view rendering info. var vector PlayerViewOffset; // Offset from view center. var(FirstPerson) rotator PlayerViewPivot; // additive rotation offset for tweaks var() bool bDrawingFirstPerson; var() float BobDamping; // how much to damp view bob // 3rd person mesh. var actor ThirdPersonActor; var cache class AttachmentClass; // HUD graphics var() Material IconMaterial; var() IntBox IconCoords; var() localized cache String ItemName; // Network replication. replication { // Things the server should send to the client. reliable if( bNetOwner && bNetDirty && (Role==ROLE_Authority) ) Charge,ThirdPersonActor; } function AttachToPawn(Pawn P) { local name BoneName; Instigator = P; if ( ThirdPersonActor == None ) { ThirdPersonActor = Spawn(AttachmentClass,Owner); InventoryAttachment(ThirdPersonActor).InitFor(self); } else ThirdPersonActor.NetUpdateTime = Level.TimeSeconds - 1; BoneName = P.GetWeaponBoneFor(self); if ( BoneName == '' ) { ThirdPersonActor.SetLocation(P.Location); ThirdPersonActor.SetBase(P); } else P.AttachToBone(ThirdPersonActor,BoneName); } /* UpdateRelative() For tweaking weapon positioning. Pass in a new relativerotation, and use the weapon editactor properties sheet to modify the relativelocation */ exec function updaterelative(int pitch, int yaw, int roll) { local rotator NewRot; NewRot.Pitch = pitch; NewRot.Yaw = yaw; NewRot.Roll = roll; ThirdPersonActor.SetRelativeLocation(ThirdPersonActor.Default.RelativeLocation); ThirdPersonActor.SetRelativeRotation(NewRot); } function DetachFromPawn(Pawn P) { if ( ThirdPersonActor != None ) { ThirdPersonActor.Destroy(); ThirdPersonActor = None; } } /* RenderOverlays() - Draw first person view of inventory Most Inventory actors are never rendered. The common exception is Weapon actors. Inventory actors may be rendered in the first person view of the player holding them using the RenderOverlays() function. */ simulated event RenderOverlays( canvas Canvas ) { if ( (Instigator == None) || (Instigator.Controller == None)) return; SetLocation( Instigator.Location + Instigator.CalcDrawOffset(self) ); SetRotation( Instigator.GetViewRotation() ); Canvas.DrawActor(self, false); } simulated function String GetHumanReadableName() { if ( ItemName == "" ) ItemName = GetItemName(string(Class)); return ItemName; } function PickupFunction(Pawn Other); //============================================================================= // AI inventory functions. simulated function Weapon RecommendWeapon( out float rating ) { if ( inventory != None ) return inventory.RecommendWeapon(rating); else { rating = -1; return None; } } //============================================================================= // Inventory travelling across servers. // // Called after a travelling inventory item has been accepted into a level. // event TravelPreAccept() { Super.TravelPreAccept(); GiveTo( Pawn(Owner) ); } function TravelPostAccept() { Super.TravelPostAccept(); PickupFunction(Pawn(Owner)); } //============================================================================= // General inventory functions. // // Called by engine when destroyed. // function Destroyed() { // Remove from owner's inventory. if( Pawn(Owner)!=None ) Pawn(Owner).DeleteInventory( Self ); if ( ThirdPersonActor != None ) ThirdPersonActor.Destroy(); } // // Give this inventory item to a pawn. // function GiveTo( pawn Other, optional Pickup Pickup ) { Instigator = Other; if ( Other.AddInventory( Self ) ) GotoState(''); else Destroy(); } // // Function which lets existing items in a pawn's inventory // prevent the pawn from picking something up. Return true to abort pickup // or if item handles pickup, otherwise keep going through inventory list. // function bool HandlePickupQuery( pickup Item ) { if ( Item.InventoryType == Class ) return true; if ( Inventory == None ) return false; return Inventory.HandlePickupQuery(Item); } // // Select first activatable powerup. // function Powerups SelectNext() { if ( Inventory != None ) return Inventory.SelectNext(); else return None; } // // Toss this item out. // function DropFrom(vector StartLocation) { local Pickup P; if ( Instigator != None ) { DetachFromPawn(Instigator); Instigator.DeleteInventory(self); } SetDefaultDisplayProperties(); Instigator = None; StopAnimating(); GotoState(''); P = spawn(PickupClass,,,StartLocation); if ( P == None ) { destroy(); return; } P.InitDroppedPickupFor(self); P.Velocity = Velocity; Velocity = vect(0,0,0); } //============================================================================= // Using. function Use( float Value ); //============================================================================= // Weapon functions. // Find a weapon in inventory that has an Inventory Group matching F. simulated function Weapon WeaponChange( byte F, bool bSilent ) { if( Inventory == None) return None; else return Inventory.WeaponChange( F, bSilent ); } // Find the previous weapon (using the Inventory group) simulated function Weapon PrevWeapon(Weapon CurrentChoice, Weapon CurrentWeapon) { if ( Inventory == None ) return CurrentChoice; else return Inventory.PrevWeapon(CurrentChoice,CurrentWeapon); } // Find the next weapon (using the Inventory group) simulated function Weapon NextWeapon(Weapon CurrentChoice, Weapon CurrentWeapon) { if ( Inventory == None ) return CurrentChoice; else return Inventory.NextWeapon(CurrentChoice,CurrentWeapon); } //============================================================================= // Armor functions. // // Return the best armor to use. // function armor PrioritizeArmor( int Damage, class DamageType, vector HitLocation ) { local Armor FirstArmor; if ( Inventory != None ) FirstArmor = Inventory.PrioritizeArmor(Damage, DamageType, HitLocation); else FirstArmor = None; return FirstArmor; } // // Used to inform inventory when owner event occurs (for example jumping or weapon change) // function OwnerEvent(name EventName) { if( Inventory != None ) Inventory.OwnerEvent(EventName); } // used to ask inventory if it needs to affect its owners display properties function SetOwnerDisplay() { if( Inventory != None ) Inventory.SetOwnerDisplay(); } static function string StaticItemName() { return Default.ItemName; } sQ//============================================================================= // InterpolationPoint. // Used as destinations to move the camera to in Matinee scenes. //============================================================================= class InterpolationPoint extends Keypoint native; #exec Texture Import File=Textures\InterpolationPoint.pcx Name=S_Interp Mips=Off MASKED=1 sB//============================================================================= // InternetInfo: Parent class for Internet connection classes //============================================================================= class InternetInfo extends Info native transient; // gam --- function int GetBeaconCount() { return (0); } // --- gam function string GetBeaconAddress( int i ); function string GetBeaconText( int i ); szN// ==================================================================== // Class: Engine.Interactions // // This is an abstract class for the interaction sub-system. This new // sub-system is responsible for tunneling input and Pre/Post rendering // time to individual viewports and interactions. // // (c) 2001, Epic Games, Inc. All Rights Reserved // ==================================================================== class Interactions extends Object abstract native; //----------------------------------------------------------------------------- // Input. // Input system states. enum EInputAction { IST_None, // Not performing special input processing. IST_Press, // Handling a keypress or button press. IST_Hold, // Handling holding a key or button. IST_Release, // Handling a key or button release. IST_Axis, // Handling analog axis movement. }; // Input keys. enum EInputKey { /*00*/ IK_None ,IK_LeftMouse ,IK_RightMouse ,IK_Cancel , /*04*/ IK_MiddleMouse ,IK_Unknown05 ,IK_Unknown06 ,IK_Unknown07 , /*08*/ IK_Backspace ,IK_Tab ,IK_Unknown0A ,IK_Unknown0B , /*0C*/ IK_Unknown0C ,IK_Enter ,IK_Unknown0E ,IK_Unknown0F , /*10*/ IK_Shift ,IK_Ctrl ,IK_Alt ,IK_Pause , /*14*/ IK_CapsLock ,IK_Unknown15 ,IK_Unknown16 ,IK_Unknown17 , /*18*/ IK_Unknown18 ,IK_Unknown19 ,IK_Unknown1A ,IK_Escape , /*1C*/ IK_Unknown1C ,IK_Unknown1D ,IK_Unknown1E ,IK_Unknown1F , /*20*/ IK_Space ,IK_PageUp ,IK_PageDown ,IK_End , /*24*/ IK_Home ,IK_Left ,IK_Up ,IK_Right , /*28*/ IK_Down ,IK_Select ,IK_Print ,IK_Execute , /*2C*/ IK_PrintScrn ,IK_Insert ,IK_Delete ,IK_Help , /*30*/ IK_0 ,IK_1 ,IK_2 ,IK_3 , /*34*/ IK_4 ,IK_5 ,IK_6 ,IK_7 , /*38*/ IK_8 ,IK_9 ,IK_Unknown3A ,IK_Unknown3B , /*3C*/ IK_Unknown3C ,IK_Unknown3D ,IK_Unknown3E ,IK_Unknown3F , /*40*/ IK_Unknown40 ,IK_A ,IK_B ,IK_C , /*44*/ IK_D ,IK_E ,IK_F ,IK_G , /*48*/ IK_H ,IK_I ,IK_J ,IK_K , /*4C*/ IK_L ,IK_M ,IK_N ,IK_O , /*50*/ IK_P ,IK_Q ,IK_R ,IK_S , /*54*/ IK_T ,IK_U ,IK_V ,IK_W , /*58*/ IK_X ,IK_Y ,IK_Z ,IK_Unknown5B , /*5C*/ IK_Unknown5C ,IK_Unknown5D ,IK_Unknown5E ,IK_Unknown5F , /*60*/ IK_NumPad0 ,IK_NumPad1 ,IK_NumPad2 ,IK_NumPad3 , /*64*/ IK_NumPad4 ,IK_NumPad5 ,IK_NumPad6 ,IK_NumPad7 , /*68*/ IK_NumPad8 ,IK_NumPad9 ,IK_GreyStar ,IK_GreyPlus , /*6C*/ IK_Separator ,IK_GreyMinus ,IK_NumPadPeriod,IK_GreySlash , /*70*/ IK_F1 ,IK_F2 ,IK_F3 ,IK_F4 , /*74*/ IK_F5 ,IK_F6 ,IK_F7 ,IK_F8 , /*78*/ IK_F9 ,IK_F10 ,IK_F11 ,IK_F12 , /*7C*/ IK_F13 ,IK_F14 ,IK_F15 ,IK_F16 , /*80*/ IK_F17 ,IK_F18 ,IK_F19 ,IK_F20 , /*84*/ IK_F21 ,IK_F22 ,IK_F23 ,IK_F24 , /*88*/ IK_Unknown88 ,IK_Unknown89 ,IK_Unknown8A ,IK_Unknown8B , /*8C*/ IK_Unknown8C ,IK_Unknown8D ,IK_Unknown8E ,IK_Unknown8F , /*90*/ IK_NumLock ,IK_ScrollLock ,IK_Unknown92 ,IK_Unknown93 , /*94*/ IK_Unknown94 ,IK_Unknown95 ,IK_Unknown96 ,IK_Unknown97 , /*98*/ IK_Unknown98 ,IK_Unknown99 ,IK_Unknown9A ,IK_Unknown9B , /*9C*/ IK_Unknown9C ,IK_Unknown9D ,IK_Unknown9E ,IK_Unknown9F , /*A0*/ IK_LShift ,IK_RShift ,IK_LControl ,IK_RControl , /*A4*/ IK_UnknownA4 ,IK_UnknownA5 ,IK_UnknownA6 ,IK_UnknownA7 , /*A8*/ IK_UnknownA8 ,IK_UnknownA9 ,IK_UnknownAA ,IK_UnknownAB , /*AC*/ IK_UnknownAC ,IK_UnknownAD ,IK_UnknownAE ,IK_UnknownAF , /*B0*/ IK_UnknownB0 ,IK_UnknownB1 ,IK_UnknownB2 ,IK_UnknownB3 , /*B4*/ IK_UnknownB4 ,IK_UnknownB5 ,IK_UnknownB6 ,IK_UnknownB7 , /*B8*/ IK_UnknownB8 ,IK_Unicode ,IK_Semicolon ,IK_Equals , /*BC*/ IK_Comma ,IK_Minus ,IK_Period ,IK_Slash , /*C0*/ IK_Tilde ,IK_Mouse4 ,IK_Mouse5 ,IK_Mouse6 , /*C4*/ IK_Mouse7 ,IK_Mouse8 ,IK_UnknownC6 ,IK_UnknownC7 , /*C8*/ IK_Joy1 ,IK_Joy2 ,IK_Joy3 ,IK_Joy4 , /*CC*/ IK_Joy5 ,IK_Joy6 ,IK_Joy7 ,IK_Joy8 , /*D0*/ IK_Joy9 ,IK_Joy10 ,IK_Joy11 ,IK_Joy12 , /*D4*/ IK_Joy13 ,IK_Joy14 ,IK_Joy15 ,IK_Joy16 , /*D8*/ IK_UnknownD8 ,IK_UnknownD9 ,IK_UnknownDA ,IK_LeftBracket , /*DC*/ IK_Backslash ,IK_RightBracket,IK_SingleQuote ,IK_UnknownDF , /*E0*/ IK_UnknownE0 ,IK_UnknownE1 ,IK_UnknownE2 ,IK_UnknownE3 , /*E4*/ IK_MouseX ,IK_MouseY ,IK_MouseZ ,IK_MouseW , /*E8*/ IK_JoyU ,IK_JoyV ,IK_JoySlider1 ,IK_JoySlider2 , /*EC*/ IK_MouseWheelUp ,IK_MouseWheelDown,IK_Unknown10E,UK_Unknown10F , /*F0*/ IK_JoyX ,IK_JoyY ,IK_JoyZ ,IK_JoyR , /*F4*/ IK_UnknownF4 ,IK_UnknownF5 ,IK_Attn ,IK_CrSel , /*F8*/ IK_ExSel ,IK_ErEof ,IK_Play ,IK_Zoom , /*FC*/ IK_NoName ,IK_PA1 ,IK_OEMClear }; enum EStreamFinishReason { STREAMFINISH_EOF, STREAMFINISH_Error }; static function string GetFriendlyName( EInputKey iKey ) { return Mid( GetEnum(enum'EInputKey', iKey), 3 ); } sJ// ==================================================================== // Class: Engine.InteractionMaster // // The InteractionMaster controls the entire interaction system. It's // job is to take input and Pre/PostRender call and route them to individual // Interactions and/or viewports. // // The stubs here in script are for just the GlobalInteracations as those // are the only Interactions the IM routes directly too. A new stub is // created in order to limit the number of C++ -> Uscript switches. // // (c) 2001, Epic Games, Inc. All Rights Reserved // ==================================================================== class InteractionMaster extends Interactions transient Native; var transient Client Client; var transient const Interaction BaseMenu; // Holds a pointer to the base menu system var transient const Interaction Console; // Holds the special Interaction that acts as the console var transient array GlobalInteractions; // Holds a listing of all global Interactions var transient bool bRequireRawJoystick; native function Travel(string URL); // Setup a travel to a new map // ==================================================================== // Control functions // ==================================================================== event Interaction AddInteraction(string InteractionName, optional Player AttachTo) // Adds an Interaction { local Interaction NewInteraction; local class NewInteractionClass; NewInteractionClass = class(DynamicLoadObject(InteractionName, class'Class')); if (NewInteractionClass!=None) { NewInteraction = new NewInteractionClass; if (NewInteraction != None) { // Place the Interaction in the proper array if (AttachTo != None) // Handle location Interactions { AttachTo.LocalInteractions.Length = AttachTo.LocalInteractions.Length + 1; AttachTo.LocalInteractions[AttachTo.LocalInteractions.Length-1] = NewInteraction; NewInteraction.ViewportOwner = AttachTo; } else // Handle Global Interactions { GlobalInteractions.Length = GlobalInteractions.Length + 1; GlobalInteractions[GlobalInteractions.Length-1] = NewInteraction; } // Initialize the Interaction NewInteraction.Initialize(); NewInteraction.Master = Self; return NewInteraction; } else Log("Could not create interaction ["$InteractionName$"]",'IMaster'); } else Log("Could not load interaction ["$InteractionName$"]",'IMaster'); return none; } // AddInteraction event RemoveInteraction(interaction RemoveMe) // Removes a Interaction { local int Index; // Grab the array to work with if (RemoveMe.ViewportOwner != None) { for (Index = 0; Index < RemoveMe.ViewPortOwner.LocalInteractions.Length; Index++) { if ( RemoveMe.ViewPortOwner.LocalInteractions[Index] == RemoveMe ) { RemoveMe.ViewPortOwner.LocalInteractions.Remove(Index,1); return; } } } else { for (Index = 0; Index < GlobalInteractions.Length; Index++) { if ( GlobalInteractions[Index] == RemoveMe ) { GlobalInteractions.Remove(Index,1); return; } } } // Find the Interaction to delete Log("Could not remove interaction ["$RemoveMe$"] (Not Found)", 'IMaster'); } // RemoveInteraction // ==================================================================== // SetFocusTo - This function will cause a window to adjust it's position // in it's array so that it processes input first and displays last. // ==================================================================== event SetFocusTo(Interaction Inter, optional Player ViewportOwner) { local array InteractionArray; local Interaction temp; local int i,iIndex; if (ViewportOwner != none) InteractionArray = ViewportOwner.LocalInteractions; else InteractionArray = GlobalInteractions; if (InteractionArray.Length == 0) { Log("Attempt to SetFocus on an empty Array.",'IMaster'); return; } // Search for the Interaction iIndex = -1; for ( i=0; i InteractionArray, out EInputKey Key, optional string Unicode ) // Process a single key press { local int Index; // Chain through the Interactions for ( Index=0; Index InteractionArray, out EInputKey Key, out EInputAction Action, FLOAT Delta ) // Process the range of input events { local int Index; // Chain through the Interactions for ( Index=0; Index InteractionArray, canvas Canvas ) { local int index; // Chain through the Interactions for ( Index=InteractionArray.Length; Index>0; Index--) // Give each Interaction PreRender time { if ( (InteractionArray[Index-1].bVisible ) && (!InteractionArray[Index-1].bNativeEvents) ) InteractionArray[Index-1].PreRender(canvas); } } // Process_PreRender event Process_PostRender( array InteractionArray, canvas Canvas ) { local int index; // Chain through the Interactions for ( Index=InteractionArray.Length; Index>0; Index--) // Give each Interaction PreRender time { if ( (InteractionArray[Index-1].bVisible ) && (!InteractionArray[Index-1].bNativeEvents) ) InteractionArray[Index-1].PostRender(canvas); } } // Process_PostRender // ==================================================================== // Tick - Interactions can request access to be ticked. // ==================================================================== event Process_Tick( array InteractionArray, float DeltaTime ) { local int Index; // Chain through the Interactions for ( Index=0; Index InteractionArray) { local int Index; // Chain through the Interactions for ( Index=0; Index InteractionArray) { local int Index; for (Index=0;Index Overlays; /* Draw3DLine() draw line in world space. Should be used when engine calls RenderWorldOverlays() event. */ native final function Draw3DLine(vector Start, vector End, color LineColor); native final function DrawCanvasLine(float X1, float Y1, float X2, float Y2, color LineColor); native static final function StaticDrawCanvasLine( Canvas C, float X1, float Y1, float X2, float Y2, color LineColor ); delegate OnPostRender(HUD Sender, Canvas C); // Called when PostRender is finished delegate OnBuildMOTD(HUD Sender); // Called when building the message of the day function DrawCustomBeacon(Canvas C, Pawn P, float ScreenLocX, float ScreenLocY) { local texture BeaconTex; local float XL,YL; BeaconTex = PlayerOwner.TeamBeaconTexture; if ( (BeaconTex == None) || (P.PlayerReplicationInfo == None) ) return; if ( P.PlayerReplicationInfo.Team != None ) C.DrawColor = class'PlayerController'.Default.TeamBeaconTeamColors[P.PlayerReplicationInfo.Team.TeamIndex]; else C.DrawColor = class'PlayerController'.Default.TeamBeaconTeamColors[0]; C.StrLen(P.PlayerReplicationInfo.PlayerName, XL, YL); C.SetPos(ScreenLocX - 0.5*XL , ScreenLocY - 0.125 * BeaconTex.VSize - YL); C.DrawText(P.PlayerReplicationInfo.PlayerName,true); C.SetPos(ScreenLocX - 0.125 * BeaconTex.USize, ScreenLocY - 0.125 * BeaconTex.VSize); C.DrawTile(BeaconTex, 0.25 * BeaconTex.USize, 0.25 * BeaconTex.VSize, 0.0, 0.0, BeaconTex.USize, BeaconTex.VSize); } simulated function BuildMOTD() { local int i; local array InMOTD; if (!bBuiltMOTD) OnBuildMOTD(self); if (bBuiltMOTD || PlayerOwner==None || PlayerOwner.GameReplicationInfo==None) return; bBuiltMOTD = true; PlayerOwner.SetProgressTime(6); Split(PlayerOwner.GameReplicationInfo.MessageOfTheDay, "|", InMOTD); for ( i = 0; i < InMOTD.Length && i < ArrayCount(MOTD); i++ ) MOTD[i] = InMOTD[i]; } simulated event PostBeginPlay() { Super.PostBeginPlay(); LinkActors (); CreateKeyMenus(); ForEach AllActors(class'SceneSubTitles', SubTitles) break; } /* Reset() reset actor to initial state - used when restarting level without reloading. */ function Reset() { bShowVoteMenu = false; bShowScoreboard = false; Super.Reset(); } simulated function CreateKeyMenus(); simulated event Destroyed() { if( ScoreBoard != None ) { ScoreBoard.Destroy(); ScoreBoard = None; } if( VoteMenu != None ) { VoteMenu.Destroy(); VoteMenu = None; } Super.Destroyed(); } //============================================================================= // Execs /* toggles displaying scoreboard */ exec function ShowScores() { bShowScoreboard = !bShowScoreboard; } exec function ShowStats() { bShowLocalStats = !bShowLocalStats; } exec function NextStats() { if ( LocalStatsScreen != None ) LocalStatsScreen.NextStats(); } /* toggles displaying properties of player's current viewtarget */ exec function ShowDebug() { bShowDebugInfo = !bShowDebugInfo; } simulated event WorldSpaceOverlays() { if ( bShowDebugInfo && Pawn(PlayerOwner.ViewTarget) != None ) DrawRoute(); } function CheckCountdown(GameReplicationInfo GRI); event ConnectFailure(string FailCode, string URL) { PlayerOwner.ReceiveLocalizedMessage(class'FailedConnect', class'FailedConnect'.Static.GetFailSwitch(FailCode)); } function GetLocalStatsScreen(); simulated event PostRender( canvas Canvas ) { local float XPos, YPos; local plane OldModulate,OM; local color OldColor; local int i; BuildMOTD(); OldModulate = Canvas.ColorModulate; OldColor = Canvas.DrawColor; Canvas.ColorModulate.X = 1; Canvas.ColorModulate.Y = 1; Canvas.ColorModulate.Z = 1; Canvas.ColorModulate.W = HudOpacity/255; LinkActors(); ResScaleX = Canvas.SizeX / 640.0; ResScaleY = Canvas.SizeY / 480.0; CheckCountDown(PlayerOwner.GameReplicationInfo); if ( PawnOwner != None ) { if ( !PlayerOwner.bBehindView ) { if ( PlayerOwner.bDemoOwner || ((Level.NetMode == NM_Client) && (PlayerOwner.Pawn != PawnOwner)) ) PawnOwner.GetDemoRecordingWeapon(); else CanvasDrawActors( Canvas, false ); } else CanvasDrawActors( Canvas, false ); } if ( PawnOwner != None && PawnOwner.bSpecialHUD ) PawnOwner.DrawHud(Canvas); if ( bShowDebugInfo ) { Canvas.Font = GetConsoleFont(Canvas); Canvas.Style = ERenderStyle.STY_Alpha; Canvas.DrawColor = ConsoleColor; PlayerOwner.ViewTarget.DisplayDebug(Canvas, XPos, YPos); if (PlayerOwner.ViewTarget != PlayerOwner && (Pawn(PlayerOwner.ViewTarget) == None || Pawn(PlayerOwner.ViewTarget).Controller == None)) { YPos += XPos * 2; Canvas.SetPos(4, YPos); Canvas.DrawText("----- VIEWER INFO -----"); YPos += XPos; Canvas.SetPos(4, YPos); PlayerOwner.DisplayDebug(Canvas, XPos, YPos); } } else if( !bHideHud ) { if ( bShowLocalStats ) { if ( LocalStatsScreen == None ) GetLocalStatsScreen(); if ( LocalStatsScreen != None ) { OM = Canvas.ColorModulate; Canvas.ColorModulate = OldModulate; LocalStatsScreen.DrawScoreboard(Canvas); DisplayMessages(Canvas); Canvas.ColorModulate = OM; } } else if (bShowScoreBoard) { if (ScoreBoard != None) { OM = Canvas.ColorModulate; Canvas.ColorModulate = OldModulate; ScoreBoard.DrawScoreboard(Canvas); if ( Scoreboard.bDisplayMessages ) DisplayMessages(Canvas); Canvas.ColorModulate = OM; } } else { if ( (PlayerOwner == None) || (PawnOwner == None) || (PawnOwnerPRI == None) || (PlayerOwner.IsSpectating() && PlayerOwner.bBehindView) ) DrawSpectatingHud(Canvas); else if( !PawnOwner.bHideRegularHUD ) DrawHud(Canvas); for (i = 0; i < Overlays.length; i++) Overlays[i].Render(Canvas); if (!DrawLevelAction (Canvas)) { if (PlayerOwner!=None) { if (PlayerOwner.ProgressTimeOut > Level.TimeSeconds) { DisplayProgressMessages (Canvas); } else if (MOTDState==1) MOTDState=2; } } if (bShowBadConnectionAlert) DisplayBadConnectionAlert (Canvas); DisplayMessages(Canvas); } if( bShowVoteMenu && VoteMenu!=None ) VoteMenu.RenderOverlays(Canvas); } else if ( PawnOwner != None ) DrawInstructionGfx(Canvas); PlayerOwner.RenderOverlays(Canvas); if (PlayerOwner.bViewingMatineeCinematic) DrawCinematicHUD(Canvas); if ((PlayerConsole != None) && PlayerConsole.bTyping) DrawTypingPrompt(Canvas, PlayerConsole.TypedStr, PlayerConsole.TypedStrPos); Canvas.ColorModulate=OldModulate; Canvas.DrawColor = OldColor; OnPostRender(Self, Canvas); } // called when viewing a Matinee cinematic simulated function DrawCinematicHUD( Canvas C ) { local int i; if (!bHideHUD && !bShowLocalStats && !bShowScoreBoard) return; //already rendered any overlays for (i = 0; i < Overlays.length; i++) Overlays[i].Render(C); } simulated function DrawInstructionGfx( Canvas C ); simulated function SetInstructionText( string text ); simulated function SetInstructionKeyText( string text ); /* Specific function to use Canvas.DrawActor() Clear Z-Buffer once, prior to rendering all actors */ function CanvasDrawActors( Canvas C, bool bClearedZBuffer ) { if ( !PlayerOwner.bBehindView && PawnOwner.Weapon != None ) { if ( !bClearedZBuffer) C.DrawActor(None, false, true); // Clear the z-buffer here PawnOwner.Weapon.RenderOverlays( C ); } } simulated function DrawRoute() { local int i; local Controller C; local vector Start, End, RealStart;; local bool bPath; C = Pawn(PlayerOwner.ViewTarget).Controller; if ( C == None ) return; if ( C.CurrentPath != None ) Start = C.CurrentPath.Start.Location; else Start = PlayerOwner.ViewTarget.Location; RealStart = Start; if ( C.bAdjusting ) { Draw3DLine(C.Pawn.Location, C.AdjustLoc, class'Canvas'.Static.MakeColor(255,0,255)); Start = C.AdjustLoc; } // show where pawn is going if ( (C == PlayerOwner) || (C.MoveTarget == C.RouteCache[0]) && (C.MoveTarget != None) ) { if ( (C == PlayerOwner) && (C.Destination != vect(0,0,0)) ) { if ( C.PointReachable(C.Destination) ) { Draw3DLine(C.Pawn.Location, C.Destination, class'Canvas'.Static.MakeColor(255,255,255)); return; } C.FindPathTo(C.Destination); } for ( i=0; i<16; i++ ) { if ( C.RouteCache[i] == None ) break; bPath = true; Draw3DLine(Start,C.RouteCache[i].Location,class'Canvas'.Static.MakeColor(0,255,0)); Start = C.RouteCache[i].Location; } if ( bPath ) Draw3DLine(RealStart,C.Destination,class'Canvas'.Static.MakeColor(255,255,255)); } else if ( PlayerOwner.ViewTarget.Velocity != vect(0,0,0) ) Draw3DLine(RealStart,C.Destination,class'Canvas'.Static.MakeColor(255,255,255)); if ( C == PlayerOwner ) return; // show where pawn is looking if ( C.Focus != None ) End = C.Focus.Location; else End = C.FocalPoint; Draw3DLine(PlayerOwner.ViewTarget.Location + Pawn(PlayerOwner.ViewTarget).BaseEyeHeight * vect(0,0,1),End,class'Canvas'.Static.MakeColor(255,0,0)); } simulated function DisplayProgressMessages (Canvas C) { local int i, LineCount; local GameReplicationInfo GRI; local float FontDX, FontDY; local float X, Y; local int Alpha; local float TimeLeft; TimeLeft = PlayerOwner.ProgressTimeOut - Level.TimeSeconds; if( TimeLeft >= ProgressFadeTime ) Alpha = 255; else Alpha = (255 * TimeLeft) / ProgressFadeTime; GRI = PlayerOwner.GameReplicationInfo; LineCount = 0; for (i = 0; i < ArrayCount (PlayerOwner.ProgressMessage); i++) { if (PlayerOwner.ProgressMessage[i] == "") continue; LineCount++; } if (bBuiltMOTD && MOTDState<2) { if (MOTD[0] != "") LineCount++; if (MOTD[1] != "") LineCount++; if (MOTD[2] != "") LineCount++; if (MOTD[3] != "") LineCount++; } C.Font = LoadProgressFont(); C.Style = ERenderStyle.STY_Alpha; C.TextSize ("A", FontDX, FontDY); X = (0.5 * HudCanvasScale * C.SizeX) + (((1.0 - HudCanvasScale) / 2.0) * C.SizeX); Y = (0.5 * HudCanvasScale * C.SizeY) + (((1.0 - HudCanvasScale) / 2.0) * C.SizeY); Y -= FontDY * (float (LineCount) / 2.0); for (i = 0; i < ArrayCount (PlayerOwner.ProgressMessage); i++) { if (PlayerOwner.ProgressMessage[i] == "") continue; C.DrawColor = PlayerOwner.ProgressColor[i]; C.DrawColor.A = Alpha; C.TextSize (PlayerOwner.ProgressMessage[i], FontDX, FontDY); C.SetPos (X - (FontDX / 2.0), Y); C.DrawText (PlayerOwner.ProgressMessage[i]); Y += FontDY; } if( (GRI != None) && (Level.NetMode != NM_StandAlone) && (MOTDState<2) ) { MOTDState=1; C.DrawColor = MOTDColor; C.DrawColor.A = Alpha; for (i=0;i<4;i++) { C.TextSize (MOTD[i], FontDX, FontDY); C.SetPos (X - (FontDX / 2.0), Y); C.DrawText (MOTD[i]); Y += FontDY; } } } function DrawHud (Canvas C); function DrawSpectatingHud (Canvas C); function bool DrawLevelAction (Canvas C); /* DisplayBadConnectionAlert() Warn user that net connection is bad */ function DisplayBadConnectionAlert (Canvas C); function bool IsInCinematic(); simulated function LocalizedMessage( class Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject, optional string CriticalString ); simulated function DrawTypingPrompt (Canvas C, String Text, optional int Pos) { local float XPos, YPos; local float XL, YL; C.Font = GetConsoleFont(C); C.Style = ERenderStyle.STY_Alpha; C.DrawColor = ConsoleColor; C.TextSize ("A", XL, YL); XPos = (ConsoleMessagePosX * HudCanvasScale * C.SizeX) + (((1.0 - HudCanvasScale) * 0.5) * C.SizeX); YPos = (ConsoleMessagePosY * HudCanvasScale * C.SizeY) + (((1.0 - HudCanvasScale) * 0.5) * C.SizeY) - YL; C.SetPos (XPos, YPos); //C.DrawTextClipped ("(>"@Left(Text, Pos)$"_"$Right(Text, Len(Text) - Pos), false); C.DrawTextClipped("(>"@Left(Text, Pos)$chr(4)$Eval(Pos < Len(Text), Mid(Text, Pos), "_"), true); } simulated function SetScoreBoardClass (class ScoreBoardClass) { if (ScoreBoard != None ) ScoreBoard.Destroy(); if (ScoreBoardClass == None) ScoreBoard = None; else { ScoreBoard = Spawn (ScoreBoardClass, Owner); if (ScoreBoard == None) log ("Hud::SetScoreBoard(): Could not spawn a scoreboard of class "$ScoreBoardClass, 'Error'); } } exec function ShowHud() { bHideHud = !bHideHud; SaveConfig(); } simulated function LinkActors() { PlayerOwner = PlayerController (Owner); if (PlayerOwner == None) { PlayerConsole = None; PawnOwner = None; PawnOwnerPRI = None; return; } if (PlayerOwner.Player != None) PlayerConsole = PlayerOwner.Player.Console; else PlayerConsole = None; if ( (Pawn(PlayerOwner.ViewTarget) != None) && (Pawn(PlayerOwner.ViewTarget).Health > 0) ) PawnOwner = Pawn(PlayerOwner.ViewTarget); else if (PlayerOwner.Pawn != None ) PawnOwner = PlayerOwner.Pawn; else PawnOwner = None; if ( (PawnOwner != None) && (PawnOwner.PlayerReplicationInfo != None) ) PawnOwnerPRI = PawnOwner.PlayerReplicationInfo; else PawnOwnerPRI = PlayerOwner.PlayerReplicationInfo; } simulated function Message( PlayerReplicationInfo PRI, coerce string Msg, name MsgType ) { if ( bMessageBeep ) PlayerOwner.PlayBeepSound(); if ( (MsgType == 'Say') || (MsgType == 'TeamSay') ) Msg = PRI.PlayerName$": "$Msg; AddTextMessage(Msg,class'LocalMessage',PRI); } function DisplayPortrait(PlayerReplicationInfo PRI); function DisplayMessages(Canvas C) { local int i, j, XPos, YPos,MessageCount; local float XL, YL; for( i = 0; i < ConsoleMessageCount; i++ ) { if ( TextMessages[i].Text == "" ) break; else if( TextMessages[i].MessageLife < Level.TimeSeconds ) { TextMessages[i].Text = ""; if( i < ConsoleMessageCount - 1 ) { for( j=i; j MessageClass, PlayerReplicationInfo PRI) { local int i; if( bMessageBeep && MessageClass.Default.bBeep ) PlayerOwner.PlayBeepSound(); for( i=0; i= 512 ) FontSize++; if ( C.ClipX >= 640 ) FontSize++; if ( C.ClipX >= 800 ) FontSize++; if ( C.ClipX >= 1024 ) FontSize++; if ( C.ClipX >= 1280 ) FontSize++; if ( C.ClipX >= 1600 ) FontSize++; return LoadFont(Clamp( 8-FontSize, 0, 8)); } static function Font GetMediumFontFor(Canvas Canvas) { local int i; for ( i=0; i<8; i++ ) { if ( Default.FontScreenWidthMedium[i] <= Canvas.ClipX ) return LoadFontStatic(i); } return LoadFontStatic(8); } function Font GetMediumFont( float Size ) { local int i; for ( i=0; i<8; i++ ) { if ( Default.FontScreenWidthMedium[i] <= Size ) return LoadFontStatic(i); } return LoadFontStatic(8); } static function Font LargerFontThan(Font aFont) { local int i; for ( i=0; i<7; i++ ) if ( LoadFontStatic(i) == aFont ) return LoadFontStatic(Max(0,i-4)); return LoadFontStatic(5); } simulated function font LoadProgressFont() { if( ProgressFontFont == None ) { ProgressFontFont = Font(DynamicLoadObject(ProgressFontName, class'Font')); if( ProgressFontFont == None ) { Log("Warning: "$Self$" Couldn't dynamically load font "$ProgressFontName); ProgressFontFont = Font'DefaultFont'; } } return ProgressFontFont; } event AnnouncementPlayed( Name AnnouncerSound, byte Switch ); simulated function DrawTargeting( Canvas C ); function DisplayHit(vector HitDir, int Damage, class damageType) { if ( (PawnOwner != None) && (PawnOwner.ShieldStrength > 0) ) PlayerOwner.ClientFlash(0.5,vect(700,700,0)); else if ( Damage > 1 ) PlayerOwner.ClientFlash(DamageType.Default.FlashScale,DamageType.Default.FlashFog); } simulated function AddHudOverlay(HudOverlay Overlay) { local int i; for (i = 0; i < Overlays.Length; i++) if (Overlays[i] == Overlay) return; Overlays[Overlays.length] = Overlay; Overlay.SetOwner(self); } simulated function RemoveHudOverlay(HudOverlay Overlay) { local int i; for (i = 0; i < Overlays.length; i++) if (Overlays[i] == Overlay) { Overlays.Remove(i, 1); Overlay.SetOwner(None); return; } } s0class Gibbed extends DamageType abstract; s@sslIan IHlogged out.FnIIHgave up administrator abilities. Gs@ssH// ==================================================================== // Class: Engine.GameStats // Parent: Engine.Info // // the GameStats object is used to send individual stat events to the // stats server. Each game should spawn a GameStats object if it // wishes to have stat logging. // // ==================================================================== class GameStats extends Info Native Config; var FileLog TempLog; var GameReplicationInfo GRI; var bool bShowBots; var string Tab; /** create local stat logs */ var globalconfig bool bLocalLog; /** filename to use, check GetLogFilename() for replacements */ var globalconfig string LogFileName; native final function string GetStatsIdentifier( Controller C ); native final function string GetMapFileName(); // Returns the name of the current map ///////////////////////////////////// // GameStats interface function Init() { if (bLocalLog) { TempLog = spawn(class 'FileLog'); if (TempLog != None) { TempLog.OpenLog(GetLogFilename()); } else { Warn("Could not create output file"); } } } function Shutdown() { if (TempLog!=None) TempLog.Destroy(); } function Logf(string LogString) { if (TempLog!=None) TempLog.Logf(LogString); } ///////////////////////////////////// // Internals event PostBeginPlay() { Super.PostBeginPlay(); Tab = Chr(9); Init(); } event Destroyed() { Shutdown(); Super.Destroyed(); } function string TimeStamp() { local string seconds; seconds = string(Level.TimeSeconds); // Remove the centiseconds if( InStr(seconds,".") != -1 ) seconds = Left( seconds, InStr(seconds,".") ); return seconds; } function string Header() { return TimeStamp()$Tab; } function String FullTimeDate() // Date/Time in MYSQL format { return Level.Year$"-"$Level.Month$"-"$Level.Day$" "$Level.Hour$":"$Level.Minute$":"$Level.Second; } function String TimeZone() // Timezone (offset) of game server's local time to GTM, e.g. -4 or +5 { return "0"; // FIXME Jack - currently pretending GMT } function String MapName() { local string mapname; mapname = GetMapFileName(); // Remove the file name extention .ut2 if( InStr(mapname,".ut2") != -1 ) mapname = Left( mapname, InStr(mapname,".ut2") ); ReplaceText(mapname, tab, "_"); return mapname; } // Stat Logging functions function NewGame() { local string out, tmp; local string ngTitle, ngAuthor, ngGameGameName; local int i; local mutator MyMutie; local GameRules MyRules; ngTitle = Level.Title; // Making local copies ngAuthor = Level.Author; ngGameGameName = Level.Game.GameName; ReplaceText(ngTitle, tab, "_"); // Replacing tabs with _ ReplaceText(ngAuthor, tab, "_"); ReplaceText(ngGameGameName, tab, "_"); GRI = Level.Game.GameReplicationInfo; out = Header()$"NG"$Tab; // "NewGame" out $= FullTimeDate()$Tab; // Game server's local time out $= TimeZone()$Tab; // Game server's time zone (offset to GMT) out $= MapName()$Tab; // Map file name without map extention .ut2 out $= ngTitle$Tab; out $= ngAuthor$Tab; out $= Level.Game.Class$Tab; out $= ngGameGameName; tmp = ""; i = 0; foreach AllActors(class'Mutator',MyMutie) { if (tmp != "") tmp $= "|" $ MyMutie.Class; else tmp $= MyMutie.Class; i++; } foreach AllActors(class'GameRules',MyRules) { if (tmp!="") tmp $= "|"$MyRules.Class; else tmp $= MyRules.Class; i++; } if (i>0) { ReplaceText(tmp, tab, "_"); out $= Tab $ "Mutators=" $ tmp; } Logf(out); } function ServerInfo() { local string out, flags; local string siServerName, siAdminName, siAdminEmail; local GameInfo.ServerResponseLine ServerState; local int i; siServerName = GRI.ServerName; // Making local copies siAdminName = GRI.AdminName; siAdminEmail = GRI.AdminEmail; ReplaceText(siServerName, tab, "_"); ReplaceText(siAdminName, tab, "_"); ReplaceText(siAdminEmail, tab, "_"); out = Header() $ "SI" $ Tab; // "SeverInfo" out $= siServerName $ Tab; // Server name out $= TimeZone()$Tab; // Timezone out $= siAdminName$Tab; // Admin name out $= siAdminEmail$Tab; // Admin email out $= Tab; // IP:port (filled in by Master Server) flags = ""; // Server flag / key combos Level.Game.GetServerDetails( ServerState ); for( i=0;i PRIs; local PlayerReplicationInfo PRI,t; out = Header()$"EG"$Tab$Reason; // "EndGame" // Quick cascade sort. for (i=0;i PRI.Deaths) ) { t = PRIs[j]; PRIs[j] = PRI; PRI = t; } } PRIs[j] = PRI; } } // Minimal scoreboard, shows Playernumbers in order of Score for (i=0;i Damage) { local string out; if ( Victim.bBot || Victim.bOnlySpectator || ((Killer != None) && Killer.bBot) ) return; out = Header()$Killtype$Tab; // KillerNumber and KillerDamagetype if (Killer!=None) { out $= Controller(Killer.Owner).PlayerNum$Tab; // KillerWeapon no longer used, using damagetype out $= GetItemName(string(Damage))$Tab; } else out $= "-1"$Tab$GetItemName(string(Damage))$Tab; // No PlayerNum -> -1, Environment "deaths" // VictimNumber and VictimWeapon out $= Controller(Victim.Owner).PlayerNum$Tab$GetItemName(string(Controller(Victim.Owner).GetLastWeapon())); // Type killers tracked as player event (redundant Typing, removed from kill line) if ( PlayerController(Victim.Owner)!= None && PlayerController(Victim.Owner).bIsTyping) { if ( PlayerController(Killer.Owner) != PlayerController(Victim.Owner) ) SpecialEvent(Killer, "type_kill"); // Killer killed typing victim } Logf(out); } // Special Events are everything else regarding the player function SpecialEvent(PlayerReplicationInfo Who, string Desc) { local string out; if (Who != None) { if ( Who.bBot || Who.bOnlySpectator ) // Avoid spectator suicide on console "type_kill" return; out = string(Controller(Who.Owner).PlayerNum); } else out = "-1"; Logf( Header()$"P"$Tab$out$Tab$Desc ); //"PSpecial" } // Special events regarding the game function GameEvent(string GEvent, string Desc, PlayerReplicationInfo Who) { local string out, geDesc; if (Who != None) { if ( Who.bBot || Who.bOnlySpectator ) // Specator could cause NameChange, TeamChange! No longer. return; out = string(Controller(Who.Owner).PlayerNum); } else out = "-1"; geDesc = Desc; ReplaceText(geDesc, tab, "_"); // geDesc, can be the nickname! Logf( Header()$"G"$Tab$GEvent$Tab$out$Tab$geDesc ); //"GSpecial" } /** return the filename to use for the log file. The following formatting rules are accepted: %P server port %Y year %M month %D day %H hour %I minute %S second %W day of the week */ function string GetLogFilename() { local string result; result = LogFileName; ReplaceText(result, "%P", string(Level.Game.GetServerPort())); ReplaceText(result, "%N", Level.Game.GameReplicationInfo.ServerName); ReplaceText(result, "%Y", Right("0000"$string(Level.Year), 4)); ReplaceText(result, "%M", Right("00"$string(Level.Month), 2)); ReplaceText(result, "%D", Right("00"$string(Level.Day), 2)); ReplaceText(result, "%H", Right("00"$string(Level.Hour), 2)); ReplaceText(result, "%I", Right("00"$string(Level.Minute), 2)); ReplaceText(result, "%W", Right("0"$string(Level.DayOfWeek), 1)); ReplaceText(result, "%S", Right("00"$string(Level.Second), 2)); return result; } sr;//============================================================================= // GameRules. // // The GameRules class handles game rule modifications for the GameInfo such as scoring, // finding player starts, and damage modification. // //============================================================================= class GameRules extends Info; var GameRules NextGameRules; function AddGameRules(GameRules GR) { if ( NextGameRules == None ) NextGameRules = GR; else NextGameRules.AddGameRules(GR); } /* Override GameInfo FindPlayerStart() - called by GameInfo.FindPlayerStart() if a NavigationPoint is returned, it will be used as the playerstart */ function NavigationPoint FindPlayerStart( Controller Player, optional byte InTeam, optional string incomingName ) { if ( NextGameRules != None ) return NextGameRules.FindPlayerStart(Player,InTeam,incomingName); return None; } /* return string containing game rules information */ function string GetRules() { local string ResultSet; if ( NextGameRules == None ) ResultSet = ResultSet$NextGameRules.GetRules(); return ResultSet; } // // server querying // append the mutator name- only used if mutator adds me and deletes itself. function GetServerDetails( out GameInfo.ServerResponseLine ServerState ); // // Restart the game. // function bool HandleRestartGame() { if ( (NextGameRules != None) && NextGameRules.HandleRestartGame() ) return true; return false; } /* CheckEndGame() Allows modification of game ending conditions. Return false to prevent game from ending */ function bool CheckEndGame(PlayerReplicationInfo Winner, string Reason) { if ( NextGameRules != None ) return NextGameRules.CheckEndGame(Winner,Reason); return true; } /* CheckScore() see if this score means the game ends return true to override gameinfo checkscore, or if game was ended (with a call to Level.Game.EndGame() ) */ function bool CheckScore(PlayerReplicationInfo Scorer) { if ( NextGameRules != None ) return NextGameRules.CheckScore(Scorer); return false; } /* OverridePickupQuery() when pawn wants to pickup something, gamerules given a chance to modify it. If this function returns true, bAllowPickup will determine if the object can be picked up. */ function bool OverridePickupQuery(Pawn Other, Pickup item, out byte bAllowPickup) { if ( (NextGameRules != None) && NextGameRules.OverridePickupQuery(Other, item, bAllowPickup) ) return true; return false; } function bool PreventDeath(Pawn Killed, Controller Killer, class damageType, vector HitLocation) { if ( (NextGameRules != None) && NextGameRules.PreventDeath(Killed,Killer, damageType,HitLocation) ) return true; return false; } function bool PreventSever(Pawn Killed, Name boneName, int Damage, class DamageType) { if ( (NextGameRules != None) && NextGameRules.PreventSever(Killed, boneName, Damage, DamageType) ) return true; return false; } function ScoreObjective(PlayerReplicationInfo Scorer, Int Score) { if ( NextGameRules != None ) NextGameRules.ScoreObjective(Scorer,Score); } function ScoreKill(Controller Killer, Controller Killed) { if ( NextGameRules != None ) NextGameRules.ScoreKill(Killer,Killed); } function bool CriticalPlayer(Controller Other) { if ( (NextGameRules != None) && (NextGameRules.CriticalPlayer(Other)) ) return true; return false; } function int NetDamage( int OriginalDamage, int Damage, pawn injured, pawn instigatedBy, vector HitLocation, out vector Momentum, class DamageType ) { if ( NextGameRules != None ) return NextGameRules.NetDamage( OriginalDamage,Damage,injured,instigatedBy,HitLocation,Momentum,DamageType ); return Damage; } sbsscssdssessf@ssg@ssh@ss@ssP E,w*2 )E,)D,)C, Gs~o{MrG * rA *Gw$*.$a!OQMl,w$*w.e.$*~.e.$gd9:9:$wt*rtT~tgd"H9?&/a9 e[a`r[T~[gdt[a10r[*H"wG *{G f Kf}G f~, G fG f~fwA *{A I'M}A I'~, A I'A I'~{{~~{~~~i, GspK_h KHlogged in as Administrator.JnKKHlogged in as a server administrator. GsssjB,c3b )B,)A, Gs~@sssQ&b^ <7Q&-Z Q&-Z ('( Gsn@,e4 %)@,)|+){+)z+)y+)x+)w+ Gsssu}+[TB 4/h~++}+-Z ''( GswGK  GstV"O "h_N%D( Gskz|"f GsDS^j9D ;r_*_i2 : =rM *M i2 2-\&M "M MAdmin9=,^_j Wh^[M mAdmin_ ^WAdminG Gs@ssqv+|*5E )v+)u+)t+)s+ Gsssvx# Gs{k+%K.$/wK*E KJrE *G *A * wA 6aE  hA 6aE  h/E a3 Kzf1w@*I@I1 sE @10"wG @G @ Gsf|[&RN"j}w`*[&fappppppp PlayerName H Team `|(9S`}) has flag 9V^[&(app PlayerName H NO Teamg-m@[&)@[&appppp bIsSpec:9T-iOnlySpec:9T-jWaiting:9T-WReady:9T-}%OutOfLives:9T-~% Gsyr+@+6 %)r+)q+)p+)o+)m+)l+)k+ Gs@ssss}_&F'_$,/a9 _&(_&F a,10 GsaAa&4g%yka?'!ff&? v-ma&.$v-TV9=9D>9La&VGETPING, Gsn+@ssC@ssD@ss~i+A+7 )i+)h+ Gs@ssB`+uv&Br%HH`+?w.$*.$``+ GsFg+d8u )g+)f+)e+ Gsr@sssg&sJ@sKsId+f91 /)d+)c+)b+)a+)_+)^+)]+)[+)U+ Gssg&sL@@sNss\+sO@sPsHe&x~Y'-i-e&-W-e& GsssSsesB@ssMT+X:q )T+ GsssWS+F+; )S+)R+ GsY\@ ?r$*$-@.$S a l$ 6l%/$ a3 ruu s$99lu Ffff?.$ pua0 -j&'10-j&a GslssZO+H+=; )O+)N+)L+)K+ GsaP+H\r!Zwj*3j-mj-j g9S.j$wdg-1kQ+kQ_`pppppppdGQP+QgQk Gs`D L% Gsssg{JJZw{*3{-m{-j w9S.{$wdw-1`pppppdPQwQM+ Gs]J+K+> )J+)I+)H+)G+)E+ Gs_dE Gsess@sscjE GsiF+Z)Iw -mw -jwv*v-m }ppdF+Qwv*aB}p9S.v$wQaB}p.9Vn&QaB}ppp-1Q.9Vn&QaB}pp9S.w $wQ.9V.w $v_w.w $*.w $-Pw.v$.w $Jvtype_kill`} GsbA+L+?")A+)~*)}*)|* GskB+v! oB`pppppppdTQ9SB+Q9UC+QD+ Gslssnq&Vd(q&-mq&-j `pppppppdSQ9S.q&$wQ9U*Q@+ Gs@sshz*V@n )z*)x* Gsq&L n(&-m&-j r&pppdDQ9S.&$w`r& G_$*FH*   " " " " Gd"s@ile???/'ix63??33'djȮiN??>3' \ҎeV????\xd'zK???d6i???Oűű?i̖??űűz̡?ōxշB}+d衖6}gzz'}w}#ig'ugE d}nud }iڊiugYgiiz}u}gidu}u \dz}} iir}u}i͈y}; qxҮu;z}; x򱩱Hz#E  iE x}}u*nxĪx xzzrii}z smw*T+A)w*)v*)u*)t* Gs}yMI(y-my-j YppppdCQ9S.y$wQaBYK*.y$`Y Gstfs@sssffsssps*[+BP)s*)r*)q*)p*)o* G$syfszfs{fsA@ssqm*k+Hs)m*)l*)k* Gs~n*C8EpppdEGQn*z%yz7OMKzOMoK-jK-m7I7I&C%^C7I&TCI}K}NCI}K}%CIdKdJ'CICIKKJ'CCIKz'z%z7IaBEpQ9S.zI$wz`E GsCNE`pdSG GssO(s|j*l+I)j*)i*)h*)g* GsBssDLsK\ijO`iOZcOXjQ_iQ_cQ_\ppdSIQaB\pjQaB\pQQaB\piQaB\pcQaB\Q` giK%{K76OiaB`ppp\6vK6Oi\6SK6OiK`Q_aB\``\ GsFLs@f*o+J$)f*)e*)d* GsGLsHLsJLsEc*u+K )c*)b*)a*)`*)_*)^* Gs\LsNeO}, rd~e^(fLdQ_eQ_fQ_OpeppdNGQaBepQQaBepQQaBep@QaBepdQaBepeQaBep9VQaBeflw%/a0 *w{laBlp|9VwaBl9Vww10/a0 It#{laBlp|9VtaBl9Vtw10dw%lQ_aBeppQMutators=l`e GsYLsf @ssRM@hYf N*=~f .ut2f f ~f .ut2f Q_f  Gs@ssu#QzP P U'U'V'V'W'W'X'X'PPUUww{{X X BBY'Y'-H,(-G,(I,?Z'Z' Gscx//============================================================================= // GameReplicationInfo. //============================================================================= class GameReplicationInfo extends ReplicationInfo native nativereplication exportstructs; var string GameName; // Assigned by GameInfo. var string GameClass; // Assigned by GameInfo. var bool bTeamGame; // Assigned by GameInfo. var bool bStopCountDown; var bool bMatchHasBegun; var bool bTeamSymbolsUpdated; var bool bNoTeamSkins; var bool bForceTeamSkins; var bool bForceNoPlayerLights; var bool bAllowPlayerLights; var bool bFastWeaponSwitching; var bool bNoTeamChanges; var int RemainingTime, ElapsedTime, RemainingMinute; var float SecondCount; var int GoalScore; var int TimeLimit; var int MaxLives; var int MinNetPlayers; var float WeaponBerserk; var TeamInfo Teams[2]; var() globalconfig string ServerName; // Name of the server, i.e.: Bob's Server. var() globalconfig string ShortName; // Abbreviated name of server, i.e.: B's Serv (stupid example) var() globalconfig string AdminName; // Name of the server admin. var() globalconfig string AdminEmail; // Email address of the server admin. var() globalconfig int ServerRegion; // Region of the game server. var() globalconfig string MessageOfTheDay; var() deprecated string MOTDLine1, MOTDLine2, MOTDLine3, MOTDLine4; var Actor Winner; // set by gameinfo when game ends var VoiceChatReplicationInfo VoiceReplicationInfo; var() texture TeamSymbols[2]; var() array PRIArray; // mc - localized PlayInfo descriptions & extra info const PROPNUM = 4; var localized string GRIPropsDisplayText[PROPNUM]; var localized string GRIPropDescText[PROPNUM]; var vector FlagPos; // replicated 2D position of one object var EFlagState FlagState[2]; var PlayerReplicationInfo FlagHolder[2]; // hack to work around flag holder replication FIXME remove when break net compatibility var PlayerReplicationInfo FlagTarget; // used by Bombing Run (targeted player) // stats var int MatchID; var int BotDifficulty; // for bPlayersVsBots replication { reliable if ( bNetDirty && (Role == ROLE_Authority) ) bStopCountDown, Winner, Teams, FlagPos, FlagState, bMatchHasBegun, MatchID, FlagTarget; reliable if ( !bNetInitial && bNetDirty && (Role == ROLE_Authority) ) RemainingMinute; reliable if ( bNetInitial && (Role==ROLE_Authority) ) GameName, GameClass, bTeamGame, bNoTeamSkins, bForceTeamSkins, bForceNoPlayerLights, WeaponBerserk, bAllowPlayerLights, bFastWeaponSwitching, RemainingTime, ElapsedTime, MessageOfTheDay, ServerName, ShortName, AdminName, AdminEmail, ServerRegion, GoalScore, MaxLives, TimeLimit, TeamSymbols, VoiceReplicationInfo, MinNetPlayers, bNoTeamChanges,BotDifficulty; } simulated function PostNetBeginPlay() { local PlayerReplicationInfo PRI; Level.GRI = self; if ( VoiceReplicationInfo == None ) foreach DynamicActors(class'VoiceChatReplicationInfo', VoiceReplicationInfo) break; ForEach DynamicActors(class'PlayerReplicationInfo',PRI) AddPRI(PRI); if ( Level.NetMode == NM_Client ) TeamSymbolNotify(); } simulated function TeamSymbolNotify() { local Actor A; if ( TeamSymbols[0] == None ) return; bTeamSymbolsUpdated = true; ForEach AllActors(class'Actor', A) A.SetGRI(self); } simulated function UpdatePrecacheMaterials() { Level.AddPrecacheMaterial(TeamSymbols[0]); Level.AddPrecacheMaterial(TeamSymbols[1]); } simulated function PostBeginPlay() { super.PostBeginPlay(); MessageOfTheDay = repl(MessageOfTheDay, chr(160),' '); if( Level.NetMode == NM_Client ) { // clear variables so we don't display our own values if the server has them left blank ServerName = ""; AdminName = ""; AdminEmail = ""; MessageOfTheDay = ""; } SecondCount = Level.TimeSeconds; SetTimer(Level.TimeDilation, true); } /* Reset() reset actor to initial state - used when restarting level without reloading. */ function Reset() { Super.Reset(); Winner = None; } simulated function Timer() { local int i; local PlayerReplicationInfo OldHolder[2]; local Controller C; if ( Level.NetMode == NM_Client ) { ElapsedTime++; if ( RemainingMinute != 0 ) { RemainingTime = RemainingMinute; RemainingMinute = 0; } if ( (RemainingTime > 0) && !bStopCountDown ) RemainingTime--; if ( !bTeamSymbolsUpdated ) TeamSymbolNotify(); SetTimer(Level.TimeDilation, true); } else if ( Level.NetMode != NM_Standalone ) { OldHolder[0] = FlagHolder[0]; OldHolder[1] = FlagHolder[1]; FlagHolder[0] = None; FlagHolder[1] = None; for ( i=0; i= 32 ) NewVoiceID = 0; PRI.VoiceID = NewVoiceID; } PRIArray[PRIArray.Length] = PRI; } simulated function RemovePRI(PlayerReplicationInfo PRI) { local int i; for (i=0; i pris) { local int i; local int num; pris.Remove(0, pris.Length); for (i=0; i PlayerTeam; // Player team members var int PlayerLineup[4]; // Lineup for current match. Stores index into PlayerTeam array. const LINEUP_SIZE = 4; var string EnemyTeam; // Opponent team name for pending/current match var string TeamName; // Player team name var string TeamSymbolName; // name of team symbol var() float BaseDifficulty; // configured at start of single player var() float Difficulty; var int SalaryCap; // allowable salary cap for team roster // stored here, but also passed separately on URL var string PlayerName; var string PlayerCharacter; // player's stats - individual experience var() int Kills; var() int Goals; var() int Deaths; var() int Wins; var() int Matches; // Ladders: -1 = Locked var int LadderRung[6]; const NUM_LADDERS = 6; var string SpecialEvent; var string GameLadderName; var class GameLadder; // current match var int CurrentLadder; var transient int CurrentMenuRung; // set by menu system, used for starting a match, in LadderInfo. if -1, use next match in order var transient Object NextMatchObject; // Used by GUI SP Pages for holding the Button for Next Match var transient Object ChampBorderObject; // Used by GUI SP Pages for holding the border for Championship. // Sad hack, but easiest way to communicate GUI objects between Ladder and Qual tabs var bool bInLadderGame; // Used to see if we should return to the SP menu after the match has finished, // also used to check if we should use the LoadingClass vignette var bool bWonMatch; // constructor: set up the GameLadder function Initialize(GameInfo currentGame, string pn) { local Controller C; if (GameLadder == none) { GameLadder = class(DynamicLoadObject(GameLadderName, class'Class')); } PackageName=pn; PlayerName=pn; // set character, player in current game for ( C=currentGame.Level.ControllerList; C!=None; C=C.NextController ) { if ( PlayerController(C) != None ) { currentGame.ChangeName (PlayerController(C), PlayerName, false); break; } } NextMatchObject=None; ChampBorderObject=None; } // skip this rung of the ladder without saving function CheatSkipMatch(GameInfo CurrentGame) { SpecialEvent = GameLadder.static.UpdateLadders(self,CurrentLadder); // updates LadderRungs appropriately ContinueSinglePlayerGame(CurrentGame.Level); } // skip directly to a certain ladder/rung // takes a single number (54) and splits into ladder 5, match 4 function CheatJumpMatch(GameInfo currentGame, int param) { local Controller C; local int newladder, newrung; newladder = param/10; newrung = param-(newladder*10); if (newladder < 0 || newladder >= NUM_LADDERS || newrung < 0) return; bInLadderGame=true; CurrentLadder = newladder; LadderRung[CurrentLadder] = newrung; CurrentMenuRung=newrung; // open game for ( C=currentGame.Level.ControllerList; C!=None; C=C.NextController ) { if ( PlayerController(C) != None ) { PlayerController(C).ConsoleCommand("START"@GameLadder.static.MakeURLFor(self)); break; } } } // robust checks are in LadderInfo, returns none if not found function MatchInfo GetMatchInfo(int ladder, int rung) { if ( GameLadder != none ) { return GameLadder.static.GetMatchInfo(ladder,rung); } else { return none; } } // After a game is completed, this function should be called to // record the player's statistics and update the ladder. // Currently called from Deathmatch 'MatchOver' state function RegisterGame(GameInfo currentGame, PlayerReplicationInfo PRI) { Log("SINGLEPLAYER GameProfile::RegisterGame for profile"@self.packagename); Kills += PRI.Kills; Goals += PRI.GoalsScored; Deaths += PRI.Deaths; Matches++; if ( bWonMatch ) { //Log("SINGLEPLAYER GameProfile::RegisterGame player won the match."); SpecialEvent = GameLadder.static.UpdateLadders(self,CurrentLadder); // updates LadderRungs appropriately Wins++; } bWonMatch = false; } // Send the player to the next match in the given ladder function StartNewMatch(int PickedLadder, LevelInfo CurrentLevel) { local Controller C; bWonMatch = false; bInLadderGame=true; CurrentLadder = PickedLadder; CurrentLevel.Game.SavePackage(PackageName); // open game for ( C=currentLevel.ControllerList; C!=None; C=C.NextController ) { if ( PlayerController(C) != None ) { PlayerController(C).ConsoleCommand("START"@GameLadder.static.MakeURLFor(self)); break; } } } // Handy helper function to find the player's first unfinished ladder // If no ladders are unfinished, return 0 for DM ladder function int FindFirstUnfinishedLadder() { local int i; for (i=0; i<6; i++) { // 6 is magic from number of ladders, declared above if (LadderRung[i] < GameLadder.static.LengthOfLadder(i)) { return i; } } return 0; } // override in subclasses! function ContinueSinglePlayerGame(LevelInfo level, optional bool bReplace) { Level.Game.SavePackage(PackageName); // the direct call to startnewmatch is to avoid using a game-specific menu system StartNewMatch(FindFirstUnfinishedLadder(), level); } // Used in menus: this is the gametype info for the next match function string GetMatchDescription() { return GameLadder.static.GetMatchDescription(self); } // accessor function static int GetNumPositions() { return NUM_POSITIONS; } // return number of teammates needed for currently selected match // assumes player team always gets an odd player function int GetNumTeammatesForMatch() { local MatchInfo M; M = GameLadder.static.GetCurrentMatchInfo(self); if ( M.GameType ~= "xGame.xDeathmatch" || M.GameType ~= "xGame.BossDM" ) return 0; else return M.NumBots / 2; } function static string TextPositionDescription(int posnval) { local string retval; if (posnval < 0 || posnval > NUM_POSITIONS) // magic number based on team size of 7 return "Error"; switch (posnval) { case EPlayerPos.POS_Auto: retval = default.PositionName[0]; break; case EPlayerPos.POS_Defense: retval = default.PositionName[1]; break; case EPlayerPos.POS_Offense: retval = default.PositionName[2]; break; case EPlayerPos.POS_Roam: retval = default.PositionName[3]; break; /* case EPlayerPos.POS_Captain: retval = "CAPTAIN"; break;*/ case EPlayerPos.POS_Supporting: retval = default.PositionName[4]; break; } return retval; } function static EPlayerPos EnumPositionDescription(string posnval) { local EPlayerPos retval; if (posnval == default.PositionName[0]) { retval = EPlayerPos.POS_Auto; } else if (posnval == default.PositionName[1]) { retval = EPlayerPos.POS_Defense; } else if (posnval == default.PositionName[2]) { retval = EPlayerPos.POS_Offense; } else if (posnval == default.PositionName[3]) { retval = EPlayerPos.POS_Roam; } else if (posnval == default.PositionName[4]) { retval = EPlayerPos.POS_Supporting; } else retval = EPlayerPos.POS_Auto; return retval; } function string GetPositionDescription(int playernum) { if (playernum < 0 || playernum >= TEAM_SIZE) return "Error"; return TextPositionDescription(PlayerPositions[playernum]); } // takes a lineup position (1-4) and sets that player's game position function SetPosition (int lineupnum, string posn) { if ((lineupnum >= 0) && (lineupnum < 4)) PlayerPositions[PlayerLineup[lineupnum]] = EnumPositionDescription(posn); } // called when adjusting the lineup // takes lineup position (1-4) and team position (1-7) and makes it all work function SetLineup (int lineuppos, int teampos) { local int oldlineuppos, oldteammate, i; // check bounds if ( lineuppos < 0 || lineuppos > LINEUP_SIZE ) return; if ( teampos < 0 || teampos >= TEAM_SIZE ) return; if ( PlayerLineup[lineuppos] == teampos ) // no-op return; // check to see if player 'teampos' was already in the lineup oldlineuppos=-1; for ( i=0; i= 0 ) { oldteammate = PlayerLineup[lineuppos]; } PlayerLineup[lineuppos] = teampos; if ( oldlineuppos >= 0 ) { PlayerLineup[oldlineuppos] = oldteammate; } } // add teammate to the next available position on the team // return false if not added because already on team or no room // assumes it's a legal player record function bool AddTeammate(string botname) { local int i; if ( botname == "" ) { return false; } for ( i=0; i= PlayerTeam.Length || PlayerTeam[i] == "" ) { Playerteam[i] = botname; return true; } if ( PlayerTeam[i] ~= botname ) { // already on team return false; } } return false; // never found space } // remove teammate from the team // return false if not removed because not on team function bool ReleaseTeammate(string botname) { local int i, j; if ( botname == "" ) { return false; } for ( i=0; i ServerInfo; var() array PlayerInfo; }; //----------------------------------------------------------------------------- // Variables. var bool bRestartLevel; // Level should be restarted when player dies var bool bPauseable; // Whether the game is pauseable. var config bool bWeaponStay; // Whether or not weapons stay when picked up. var bool bCanChangeSkin; // Allow player to change skins in game. var cache bool bTeamGame; // This is a team game. var bool bGameEnded; // set when game ends var bool bOverTime; var localized bool bAlternateMode; var bool bCanViewOthers; var bool bDelayedStart; var bool bWaitingToStartMatch; var globalconfig bool bChangeLevels; var bool bAlreadyChanged; var bool bLoggingGame; // Does this gametype log? var globalconfig bool bEnableStatLogging; // If True, games will log var config bool bAllowWeaponThrowing; var globalconfig bool bAllowBehindView; var globalconfig bool bAdminCanPause; var bool bGameRestarted; var globalconfig bool bWeaponShouldViewShake; var bool bModViewShake; // for mutators to turn off weaponviewshake var bool bForceClassicView; // OBSOLETE var globalconfig bool bLowGore; // OBSOLETE - use GoreLevel instead; var bool bWelcomePending; var bool bAttractCam; var bool bMustJoinBeforeStart; // players can only spectate if they join after the game starts var bool bTestMode; var bool bAllowVehicles; //are vehicles allowed in this gametype? var bool bAllowMPGameSpeed; var bool bIsSaveGame; // stays true during entire game (unlike LevelInfo property) var bool bLiberalVehiclePaths; var globalconfig bool bLargeGameVOIP; var globalconfig int GoreLevel; var globalconfig float GameDifficulty; var float AutoAim; // OBSOLETE How much autoaiming to do (1 = none, 0 = always). // (cosine of max error to correct) var globalconfig float GameSpeed; // Scale applied to game rate. var float StartTime; var string DefaultPlayerClassName; // user interface var string ScoreBoardType; // Type of class to use for scoreboards. (gam) var string BotMenuType; // Type of bot menu to display. -NOT USED- var cache string RulesMenuType; // Type of rules menu to display. var string SettingsMenuType; // Type of settings menu to display. -NOT USED- var string GameUMenuType; // Type of Game dropdown to display. (Used as map menu in Onslaught) var string MultiplayerUMenuType; // Type of Multiplayer dropdown to display. -NOT USED- var string GameOptionsMenuType; // Type of options dropdown to display. -NOT USED- var cache string HUDSettingsMenu; // Optional GUI page for configuring HUD options specific to this gametype var string HUDType; // HUD class this game uses. var cache string MapListType; // Maplist this game uses. var cache string MapPrefix; // Prefix characters for names of maps for this game type. var string BeaconName; // Identifying string used for finding LAN servers. var localized string GoreLevelText[3]; var() int ResetCountDown; var() config int ResetTimeDelay; // time (seconds) before restarting teams var globalconfig int MaxSpectators; // Maximum number of spectators. var int NumSpectators; // Current number of spectators. var globalconfig int MaxPlayers; var int NumPlayers; // number of human players var int NumBots; // number of non-human players (AI controlled but participating as a player) var int CurrentID; var localized string DefaultPlayerName; var float FearCostFallOff; // how fast the FearCost in NavigationPoints falls off 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; var name OtherMesgGroup; //------------------------------------- // GameInfo components var string MutatorClass; var Mutator BaseMutator; // linked list of Mutators (for modifying actors as they enter the game) var() globalconfig string AccessControlClass; var AccessControl AccessControl; // AccessControl controls whether players can enter and/or become admins var GameRules GameRulesModifiers; // linked list of modifier classes which affect game rules var() string BroadcastHandlerClass; var() class BroadcastClass; var BroadcastHandler BroadcastHandler; // handles message (text and localized) broadcasts var class PlayerControllerClass; // type of player controller to spawn for players logging in var string PlayerControllerClassName; // ReplicationInfo var() class GameReplicationInfoClass; var GameReplicationInfo GameReplicationInfo; // Voice chat var() class VoiceReplicationInfoClass; var VoiceChatReplicationInfo VoiceReplicationInfo; // Maplist management var globalconfig string MaplistHandlerType; var class MaplistHandlerClass; var transient MaplistManagerBase MaplistHandler; // Stats - jmw var GameStats GameStats; // Holds the GameStats actor var globalconfig string GameStatsClass; // Type of GameStats actor to spawn // Server demo recording - rjp var transient string DemoCommand; // set in InitGame to value of ?DemoRec= // only checked in GameInfo.PostBeginPlay() // Cheat Protection var globalconfig string SecurityClass; // Cache-related information var() cache localized string GameName; var() cache localized string Description; var() cache string ScreenShotName; var() cache String DecoTextName; // deprecated ? var() cache String Acronym; // voting handler var globalconfig string VotingHandlerType; var class VotingHandlerClass; var transient VotingHandler VotingHandler; // persistant game data management var() transient GameProfile CurrentGameProfile; var() private const transient Manifest SaveGameManifest; // localized PlayInfo descriptions & extra info const GIPROPNUM = 15; var localized string GIPropsDisplayText[GIPROPNUM]; var localized string GIPropDescText[GIPROPNUM]; var localized string GIPropsExtras[2]; var Vehicle VehicleList; var string CallSigns[15]; var globalconfig string ServerSkillLevel; // The Server Skill Level ( 0 - 2, Beginner - Advanced ) var globalconfig float MaxIdleTime; // maximum time players are allowed to idle before being kicked //Loading screen hints var localized string NoBindString; var color BindColor; native final function Manifest GetSavedGames(); native final function Object CreateDataObject ( class objClass, string objName, string packageName ); native final function bool DeleteDataObject ( class objClass, string objName, string packageName ); native final function Object LoadDataObject ( class objClass, string objName, string packageName ); native final iterator function AllDataObjects ( class objClass, out Object obj, string packageName ); native final function bool SavePackage ( string packageName ); native final function bool DeletePackage ( string packageName ); native final static function LoadMapList(string MapPrefix, out array Maps); //------------------------------------------------------------------------------ // Engine notifications. function PreBeginPlay() { StartTime = 0; GameReplicationInfo = Spawn(GameReplicationInfoClass); Level.GRI = GameReplicationInfo; InitGameReplicationInfo(); InitVoiceReplicationInfo(); // Create stat logging actor. InitLogging(); } function Destroyed() { CurrentGameProfile = None; Super.Destroyed(); } function UpdatePrecacheMaterials() { PrecacheGameTextures(Level); } function UpdatePrecacheStaticMeshes() { PrecacheGameStaticMeshes(Level); } static function PrecacheGameTextures(LevelInfo myLevel); static function PrecacheGameStaticMeshes(LevelInfo myLevel); static function PrecacheGameAnnouncements(AnnouncerVoice V, bool bRewardSounds); function string FindPlayerByID( int PlayerID ) { local PlayerReplicationInfo PRI; PRI = GameReplicationInfo.FindPlayerByID(PlayerID); if ( PRI != None ) return PRI.PlayerName; return ""; } function ChangeMap(int ContextID) // sjs { local MapList MyList; local class ML; local string MapString; ML = class(DynamicLoadObject(MapListType, class'Class')); MyList = spawn(ML); MapString = MyList.GetMap(ContextID); MyList.Destroy(); if( MapString == "" ) return; Level.ServerTravel(MapString, false); } static function bool UseLowGore() { return ( Default.bAlternateMode || Default.bLowGore || (Default.GoreLevel < 2) ); } static function bool NoBlood() { return ( Default.GoreLevel == 0 ); } function PostBeginPlay() { if ( MaxIdleTime > 0 ) MaxIdleTime = FMax(MaxIdleTime, 30); if (GameStats!=None) { GameStats.NewGame(); GameStats.ServerInfo(); } // Do not start any demo recordings until everything has been initialized if ( DemoCommand != "" ) ConsoleCommand("demorec"@DemoCommand, True); } /* Reset() reset actor to initial state - used when restarting level without reloading. */ function Reset() { Super.Reset(); bGameEnded = false; bOverTime = false; bWaitingToStartMatch = true; InitGameReplicationInfo(); InitVoiceReplicationInfo(); } /* InitLogging() Set up statistics logging */ function InitLogging() { local class MyGameStatsClass; if ( !bEnableStatLogging || !bLoggingGame || (Level.NetMode == NM_Standalone) || (Level.NetMode == NM_ListenServer) ) return; MyGameStatsClass=class(DynamicLoadObject(GameStatsClass,class'class')); if (MyGameStatsClass!=None) { GameStats = spawn(MyGameStatsClass); if (GameStats==None) log("Could to create Stats Object"); } else log("Error loading GameStats ["$GameStatsClass$"]"); } function Timer() { local NavigationPoint N; local int i; // If we are a server, broadcast a welcome message. if( bWelcomePending ) { bWelcomePending = false; if ( Level.NetMode != NM_Standalone ) { for ( i=0; i 0) && (Level.TimeSeconds - LastActiveTime > Level.Game.MaxIdleTime) ) KickIdler(self); */ event KickIdler(PlayerController PC) { log("Kicking idle player "$PC.PlayerReplicationInfo.PlayerName); AccessControl.DefaultKickReason = AccessControl.IdleKickReason; AccessControl.KickPlayer(PC); AccessControl.DefaultKickReason = AccessControl.Default.DefaultKickReason; } //------------------------------------------------------------------------------ // Replication function InitGameReplicationInfo() { GameReplicationInfo.bTeamGame = bTeamGame; GameReplicationInfo.GameName = GameName; GameReplicationInfo.GameClass = string(Class); GameReplicationInfo.MaxLives = MaxLives; } function InitVoiceReplicationInfo() { log(Name@"VoiceReplicationInfo created:"@VoiceReplicationInfo,'VoiceChat'); } function InitMaplistHandler(); native function string GetNetworkNumber(); //------------------------------------------------------------------------------ // Server/Game Querying. function GetServerInfo( out ServerResponseLine ServerState ) { local int RealSkillLevel; ServerState.ServerName = StripColor(GameReplicationInfo.ServerName); ServerState.MapName = Left(string(Level), InStr(string(Level), ".")); ServerState.GameType = Mid( string(Class), InStr(string(Class), ".")+1); ServerState.CurrentPlayers = GetNumPlayers(); ServerState.MaxPlayers = MaxPlayers; ServerState.IP = ""; // filled in at the other end. ServerState.Port = GetServerPort(); // rjp -- // Valid values are 0, 1, 2 // empty string will NOT be considered as 0 in the database, so we need to do some fiddling here // to make sure that servers that do not set a default value for ServerSkillLevel still report a skill level RealSkillLevel = Clamp( int(ServerSkillLevel), 0, 2 ); ServerState.SkillLevel = string(RealSkillLevel); ServerState.ServerInfo.Length = 0; ServerState.PlayerInfo.Length = 0; } function int GetNumPlayers() { return NumPlayers; } function GetServerDetails( out ServerResponseLine ServerState ) { local Mutator M; local GameRules G; local int i, Len, NumMutators; local string MutatorName; local bool bFound; AddServerDetail( ServerState, "ServerMode", Eval(Level.NetMode == NM_ListenServer, "non-dedicated", "dedicated") ); AddServerDetail( ServerState, "AdminName", GameReplicationInfo.AdminName ); AddServerDetail( ServerState, "AdminEmail", GameReplicationInfo.AdminEmail ); AddServerDetail( ServerState, "ServerVersion", Level.EngineVersion ); if ( AccessControl != None && AccessControl.RequiresPassword() ) AddServerDetail( ServerState, "GamePassword", "True" ); AddServerDetail( ServerState, "GameStats", GameStats != None ); if ( AllowGameSpeedChange() && (GameSpeed != 1.0) ) AddServerDetail( ServerState, "GameSpeed", int(GameSpeed*100)/100.0 ); AddServerDetail( ServerState, "MaxSpectators", MaxSpectators ); // voting if( VotingHandler != None ) VotingHandler.GetServerDetails(ServerState); // Ask the mutators if they have anything to add. for (M = BaseMutator; M != None; M = M.NextMutator) { M.GetServerDetails(ServerState); NumMutators++; } // Ask the gamerules if they have anything to add. for ( G=GameRulesModifiers; G!=None; G=G.NextGameRules ) G.GetServerDetails(ServerState); // make sure all the mutators were really added for ( i=0; i 1 ) { // something is missing for (M = BaseMutator.NextMutator; M != None; M = M.NextMutator) { MutatorName = M.GetHumanReadableName(); for ( i=0; i=0); return int(Mid(S,i+1)); } function bool SetPause( BOOL bPause, PlayerController P ) { if( bPauseable || (bAdminCanPause && (P.IsA('Admin') || P.PlayerReplicationInfo.bAdmin)) || Level.Netmode==NM_Standalone ) { if( bPause ) Level.Pauser=P.PlayerReplicationInfo; else Level.Pauser=None; return True; } else return False; } //------------------------------------------------------------------------------ // Game parameters. function bool AllowGameSpeedChange() { if ( Level.NetMode == NM_Standalone ) return true; else return bAllowMPGameSpeed; } // // Set gameplay speed. // function SetGameSpeed( Float T ) { local float OldSpeed; if ( !AllowGameSpeedChange() ) { Level.TimeDilation = 1.1; GameSpeed = 1.0; Default.GameSpeed = GameSpeed; } else { OldSpeed = GameSpeed; GameSpeed = FMax(T, 0.1); Level.TimeDilation = 1.1 * GameSpeed; if ( GameSpeed != OldSpeed ) { Default.GameSpeed = GameSpeed; class'GameInfo'.static.StaticSaveConfig(); } } SetTimer(Level.TimeDilation, true); } // // Called after setting low or high detail mode. // event DetailChange() { local actor A; local zoneinfo Z; if( Level.DetailMode == DM_Low ) { foreach DynamicActors(class'Actor', A) { if( (A.bHighDetail || A.bSuperHighDetail) && !A.bGameRelevant ) A.Destroy(); } } else if( Level.DetailMode == DM_High ) { foreach DynamicActors(class'Actor', A) { if( A.bSuperHighDetail && !A.bGameRelevant ) A.Destroy(); } } foreach AllActors(class'ZoneInfo', Z) Z.LinkToSkybox(); } //------------------------------------------------------------------------------ // 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; } /* 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 Error ) { local string InOpt, LeftOpt; local int pos; local class ACClass; local class GRClass; local bool bIsTutorial; InOpt = ParseOption( Options, "SaveGame"); if (InOpt != "" && CurrentGameProfile == none) { CurrentGameProfile = LoadDataObject(class'GameProfile', "GameProfile", InOpt); if ( CurrentGameProfile != none ) CurrentGameProfile.Initialize(self, InOpt); else { Log("SINGLEPLAYER GameInfo::InitGame failed to find GameProfile"@InOpt); } if ( !CurrentGameProfile.bInLadderGame ) { CurrentGameProfile = None; } } if ( (CurrentGameProfile == None) && (Left(string(level),3) ~= "TUT") ) bIsTutorial = true; MaxPlayers = Clamp(GetIntOption( Options, "MaxPlayers", MaxPlayers ),0,32); MaxSpectators = Clamp(GetIntOption( Options, "MaxSpectators", MaxSpectators ),0,32); GameDifficulty = FMax(0,GetIntOption(Options, "Difficulty", GameDifficulty)); if ( (CurrentGameProfile != None) || bIsTutorial ) { if (CurrentGameProfile != None) GameDifficulty = CurrentGameProfile.Difficulty; SetGameSpeed(1.0); } AddMutator(MutatorClass); BroadcastClass = class(DynamicLoadObject(BroadcastHandlerClass,Class'Class')); default.BroadcastClass = BroadcastClass; // rjp -- for PlayInfo BroadcastHandler = spawn(BroadcastClass); InOpt = ParseOption( Options, "AccessControl"); if( InOpt != "" ) ACClass = class(DynamicLoadObject(InOpt, class'Class')); if ( ACClass == None ) { ACClass = class(DynamicLoadObject(AccessControlClass, class'Class')); if (ACClass == None) ACClass = class'Engine.AccessControl'; } LeftOpt = ParseOption( Options, "AdminName" ); InOpt = ParseOption( Options, "AdminPassword"); if( LeftOpt!="" && InOpt!="" ) ACClass.default.bDontAddDefaultAdmin = true; // Only spawn access control if we are a server if (Level.NetMode == NM_ListenServer || Level.NetMode == NM_DedicatedServer ) { AccessControl = Spawn(ACClass); if (AccessControl != None && LeftOpt!="" && InOpt!="" ) AccessControl.SetAdminFromURL(LeftOpt, InOpt); } SetGameSpeed(1.0); InOpt = ParseOption( Options, "GameRules"); if ( InOpt != "" ) { log("Game Rules"@InOpt); while ( InOpt != "" ) { pos = InStr(InOpt,","); if ( pos > 0 ) { LeftOpt = Left(InOpt, pos); InOpt = Right(InOpt, Len(InOpt) - pos - 1); } else { LeftOpt = InOpt; InOpt = ""; } log("Add game rules "$LeftOpt); GRClass = class(DynamicLoadObject(LeftOpt, class'Class')); if ( GRClass != None ) { if ( GameRulesModifiers == None ) GameRulesModifiers = Spawn(GRClass); else GameRulesModifiers.AddGameRules(Spawn(GRClass)); } } } 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); } } if ( (CurrentGameProfile == None) && !bIsTutorial ) { InOpt = ParseOption( Options, "GameSpeed"); if( InOpt != "" ) { log("GameSpeed"@InOpt); SetGameSpeed(float(InOpt)); } } InOpt = ParseOption( Options, "GamePassword"); if( InOpt != "" && AccessControl != None) { AccessControl.SetGamePassWord(InOpt); log( "GamePassword" @ InOpt ); } InOpt = ParseOption( Options,"AllowThrowing"); if ( InOpt != "" ) bAllowWeaponThrowing = bool(InOpt); InOpt = ParseOption( Options,"AllowBehindview"); if ( InOpt != "" ) bAllowBehindview = bool(InOpt); InOpt = ParseOption(Options, "GameStats"); if ( InOpt != "") bEnableStatLogging = bool(InOpt); log("GameInfo::InitGame : bEnableStatLogging"@bEnableStatLogging); if( HasOption(Options, "DemoRec") ) DemoCommand = ParseOption(Options, "DemoRec"); if ( HasOption(Options, "AttractCam") ) bAttractCam = true; // Voting handler requires maplist manager to be configured InitMaplistHandler(); InOpt = ParseOption( Options, "VotingHandler"); if( InOpt != "" ) VotingHandlerClass = class(DynamicLoadObject(InOpt, class'Class')); if( VotingHandlerClass == None ) { if( VotingHandlerType != "" ) VotingHandlerClass = class(DynamicLoadObject(VotingHandlerType, class'Class')); else VotingHandlerClass = class(DynamicLoadObject("Engine.VotingHandler", class'Class')); } class'Engine.GameInfo'.default.VotingHandlerClass = VotingHandlerClass; if( (Level.NetMode != NM_StandAlone) && (VotingHandlerClass != None) && VotingHandlerClass.Static.IsEnabled() ) { VotingHandler = Spawn(VotingHandlerClass); if(VotingHandler == none) log("WARNING: Failed to spawn VotingHandler"); } bTestMode = HasOption(Options, "CheckErrors"); } function AddMutator(string mutname, optional bool bUserAdded) { local class mutClass; local Mutator mut; if ( !Static.AllowMutator(MutName) ) return; mutClass = class(DynamicLoadObject(mutname, class'Class')); if (mutClass == None) return; if ( (mutClass.Default.GroupName != "") && (BaseMutator != None) ) { // make sure no mutators with same groupname for ( mut=BaseMutator; mut!=None; mut=mut.NextMutator ) if ( mut.GroupName == mutClass.Default.GroupName ) { 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); } function AddGameModifier( GameRules NewRule ) { if ( NewRule == None ) return; if ( GameRulesModifiers != None ) GameRulesModifiers.AddGameRules(NewRule); else GameRulesModifiers = NewRule; } // // Return beacon text for serverbeacon. // event string GetBeaconText() { return Level.ComputerName $ " " $ Left(Level.Title,24) $ "\\t" $ BeaconName $ "\\t" $ GetNumPlayers() $ "/" $ MaxPlayers; } /* ProcessServerTravel() Optional handling of ServerTravel for network games. */ function ProcessServerTravel( string URL, bool bItems ) { local playercontroller P, LocalPlayer; // Pass it along BaseMutator.ServerTraveling(URL,bItems); EndLogging("mapchange"); // Notify clients we're switching level and give them time to receive. // We call PreClientTravel directly on any local PlayerPawns (ie listen server) log("ProcessServerTravel:"@URL); foreach DynamicActors( class'PlayerController', P ) if( NetConnection( P.Player)!=None ) P.ClientTravel( Eval( Instr(URL,"?") > 0, Left(URL,Instr(URL,"?")), URL), TRAVEL_Relative, bItems ); else { LocalPlayer = P; P.PreClientTravel(); } if ( (Level.NetMode == NM_ListenServer) && (LocalPlayer != None) ) Level.NextURL = Level.NextURL $"?Team="$LocalPlayer.GetDefaultURL("Team") $"?Name="$LocalPlayer.GetDefaultURL("Name") $"?Class="$LocalPlayer.GetDefaultURL("Class") $"?Character="$LocalPlayer.GetDefaultURL("Character"); // Switch immediately if not networking. if( Level.NetMode!=NM_DedicatedServer && Level.NetMode!=NM_ListenServer ) Level.NextSwitchCountdown = 0.0; } // // Accept or reject a player on the server. // Fails login if you set the Error to a non-empty string. // event PreLogin ( string Options, string Address, string PlayerID, out string Error, out string FailCode ) { local bool bSpectator; bSpectator = ( ParseOption( Options, "SpectatorOnly" ) ~= "1" ); if (AccessControl != None) AccessControl.PreLogin(Options, Address, PlayerID,Error, FailCode, bSpectator); } function int GetIntOption( string Options, string ParseString, int CurrentValue) { local string InOpt; InOpt = ParseOption( Options, ParseString ); if ( InOpt != "" ) return int(InOpt); return CurrentValue; } function bool BecomeSpectator(PlayerController P) { if ( (P.PlayerReplicationInfo == None) || !GameReplicationInfo.bMatchHasBegun || (NumSpectators >= MaxSpectators) || P.IsInState('GameEnded') || P.IsInState('RoundEnded') ) { P.ReceiveLocalizedMessage(GameMessageClass, 12); return false; } P.PlayerReplicationInfo.bOnlySpectator = true; NumSpectators++; NumPlayers--; return true; } function bool AllowBecomeActivePlayer(PlayerController P) { if ( (P.PlayerReplicationInfo == None) || !GameReplicationInfo.bMatchHasBegun || bMustJoinBeforeStart || (NumPlayers >= MaxPlayers) || (MaxLives > 0) || P.IsInState('GameEnded') || P.IsInState('RoundEnded') ) { P.ReceiveLocalizedMessage(GameMessageClass, 13); return false; } return true; } function bool AtCapacity(bool bSpectator) { if ( Level.NetMode == NM_Standalone ) return false; if ( bSpectator ) return ( (NumSpectators >= MaxSpectators) && ((Level.NetMode != NM_ListenServer) || (NumPlayers > 0)) ); else return ( (MaxPlayers>0) && (NumPlayers>=MaxPlayers) ); } function InitSavedLevel() { if ( Level.GRI == None ) Level.GRI = GameReplicationInfo; if ( Level.ObjectPool == None ) Level.ObjectPool = new(xLevel) class'ObjectPool'; } // // 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. // event PlayerController Login ( string Portal, string Options, out string Error ) { local NavigationPoint StartSpot; local PlayerController NewPlayer, TestPlayer; local string InName, InAdminName, InPassword, InChecksum, InCharacter,InSex; local byte InTeam; local bool bSpectator, bAdmin; local class MySecurityClass; local pawn TestPawn; Options = StripColor(Options); // Strip out color Codes BaseMutator.ModifyLogin(Portal, Options); // Get URL options. InName = Left(ParseOption ( Options, "Name"), 20); InTeam = GetIntOption( Options, "Team", 255 ); // default to "no team" InAdminName= ParseOption ( Options, "AdminName"); InPassword = ParseOption ( Options, "Password" ); InChecksum = ParseOption ( Options, "Checksum" ); if ( HasOption(Options, "Load") ) { log("Loading Savegame"); InitSavedLevel(); bIsSaveGame = true; // Try to match up to existing unoccupied player in level, // for savegames - also needed coop level switching. ForEach DynamicActors(class'PlayerController', TestPlayer ) { if ( (TestPlayer.Player==None) && (TestPlayer.PlayerOwnerName~=InName) ) { TestPawn = TestPlayer.Pawn; if ( TestPawn != None ) TestPawn.SetRotation(TestPawn.Controller.Rotation); log("FOUND "$TestPlayer@TestPlayer.PlayerReplicationInfo.PlayerName); return TestPlayer; } } } bSpectator = ( ParseOption( Options, "SpectatorOnly" ) ~= "1" ); if (AccessControl != None) bAdmin = AccessControl.CheckOptionsAdmin(Options); // Make sure there is capacity except for admins. (This might have changed since the PreLogin call). if ( !bAdmin && AtCapacity(bSpectator) ) { Error = GameMessageClass.Default.MaxedOutMessage; 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) InTeam = PickTeam(InTeam,None); // Find a start spot. StartSpot = FindPlayerStart( None, InTeam, Portal ); if( StartSpot == None ) { Error = GameMessageClass.Default.FailedPlaceMessage; return None; } if ( PlayerControllerClass == None ) PlayerControllerClass = class(DynamicLoadObject(PlayerControllerClassName, class'Class')); NewPlayer = spawn(PlayerControllerClass,,,StartSpot.Location,StartSpot.Rotation); // Handle spawn failure. if( NewPlayer == None ) { log("Couldn't spawn player controller of class "$PlayerControllerClass); Error = GameMessageClass.Default.FailedSpawnMessage; return None; } NewPlayer.StartSpot = StartSpot; // Init player's replication info NewPlayer.GameReplicationInfo = GameReplicationInfo; // Apply security to this controller MySecurityClass=class(DynamicLoadObject(SecurityClass,class'class')); if (MySecurityClass!=None) { NewPlayer.PlayerSecurity = spawn(MySecurityClass,NewPlayer); if (NewPlayer.PlayerSecurity==None) log("Could not spawn security for player "$NewPlayer,'Security'); } else if (SecurityClass == "") log("No value for Engine.GameInfo.SecurityClass -- System is not secure.",'Security'); else log("Unknown security class ["$SecurityClass$"] -- System is not secure.",'Security'); if ( bAttractCam ) NewPlayer.GotoState('AttractMode'); else NewPlayer.GotoState('Spectating'); // Init player's name if( InName=="" ) InName=DefaultPlayerName; if( Level.NetMode!=NM_Standalone || NewPlayer.PlayerReplicationInfo.PlayerName==DefaultPlayerName ) ChangeName( NewPlayer, InName, false ); // custom voicepack NewPlayer.PlayerReplicationInfo.VoiceTypeName = ParseOption ( Options, "Voice"); InCharacter = ParseOption(Options, "Character"); NewPlayer.SetPawnClass(DefaultPlayerClassName, InCharacter); InSex = ParseOption(Options, "Sex"); if ( Left(InSex,3) ~= "F" ) NewPlayer.SetPawnFemale(); // only effective if character not valid // Set the player's ID. NewPlayer.PlayerReplicationInfo.PlayerID = CurrentID++; if ( bSpectator || NewPlayer.PlayerReplicationInfo.bOnlySpectator || !ChangeTeam(newPlayer, InTeam, false) ) { NewPlayer.PlayerReplicationInfo.bOnlySpectator = true; NewPlayer.PlayerReplicationInfo.bIsSpectator = true; NewPlayer.PlayerReplicationInfo.bOutOfLives = true; NumSpectators++; return NewPlayer; } newPlayer.StartSpot = StartSpot; // Init player's administrative privileges and log it if (AccessControl != None && AccessControl.AdminLogin(NewPlayer, InAdminName, InPassword)) { AccessControl.AdminEntered(NewPlayer, InAdminName); } NumPlayers++; if ( NumPlayers > 20 ) bLargeGameVOIP = true; bWelcomePending = true; if ( bTestMode ) TestLevel(); // if delayed start, don't give a pawn to the player yet // Normal for multiplayer games if ( bDelayedStart ) { NewPlayer.GotoState('PlayerWaiting'); return NewPlayer; } return newPlayer; } 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 ) Found.Crash(); } /* StartMatch() Start the game - inform all actors that the match is starting, and spawn player pawns */ function StartMatch() { local Controller P; local Actor A; if (GameStats!=None) GameStats.StartGame(); // tell all actors the game is starting ForEach AllActors(class'Actor', A) A.MatchStarting(); // start human players first for ( P = Level.ControllerList; P!=None; P=P.nextController ) if ( P.IsA('PlayerController') && (P.Pawn == None) ) { if ( bGameEnded ) return; // telefrag ended the game with ridiculous frag limit else if ( PlayerController(P).CanRestartPlayer() ) RestartPlayer(P); } // start AI players for ( P = Level.ControllerList; P!=None; P=P.nextController ) if ( P.bIsPlayer && !P.IsA('PlayerController') ) { if ( Level.NetMode == NM_Standalone ) RestartPlayer(P); else P.GotoState('Dead','MPStart'); } bWaitingToStartMatch = false; GameReplicationInfo.bMatchHasBegun = true; } // Player Can be restarted ? function bool PlayerCanRestart( PlayerController aPlayer ) { return true; } function bool PlayerCanRestartGame( PlayerController aPlayer ) { return true; } // // Restart a player. // function RestartPlayer( Controller aPlayer ) { local NavigationPoint startSpot; local int TeamNum; local class DefaultPlayerClass; local Vehicle V, Best; local vector ViewDir; local float BestDist, Dist; if( bRestartLevel && Level.NetMode!=NM_DedicatedServer && Level.NetMode!=NM_ListenServer ) return; if ( (aPlayer.PlayerReplicationInfo == None) || (aPlayer.PlayerReplicationInfo.Team == None) ) TeamNum = 255; else TeamNum = aPlayer.PlayerReplicationInfo.Team.TeamIndex; startSpot = FindPlayerStart(aPlayer, TeamNum); if( startSpot == None ) { log(" Player start not found!!!"); return; } if (aPlayer.PreviousPawnClass!=None && aPlayer.PawnClass != aPlayer.PreviousPawnClass) BaseMutator.PlayerChangedClass(aPlayer); if ( aPlayer.PawnClass != None ) aPlayer.Pawn = Spawn(aPlayer.PawnClass,,,StartSpot.Location,StartSpot.Rotation); if( aPlayer.Pawn==None ) { DefaultPlayerClass = GetDefaultPlayerClass(aPlayer); aPlayer.Pawn = Spawn(DefaultPlayerClass,,,StartSpot.Location,StartSpot.Rotation); } if ( aPlayer.Pawn == None ) { log("Couldn't spawn player of type "$aPlayer.PawnClass$" at "$StartSpot); aPlayer.GotoState('Dead'); if ( PlayerController(aPlayer) != None ) PlayerController(aPlayer).ClientGotoState('Dead','Begin'); return; } if ( PlayerController(aPlayer) != None ) PlayerController(aPlayer).TimeMargin = -0.1; aPlayer.Pawn.Anchor = startSpot; aPlayer.Pawn.LastStartSpot = PlayerStart(startSpot); aPlayer.Pawn.LastStartTime = Level.TimeSeconds; aPlayer.PreviousPawnClass = aPlayer.Pawn.Class; aPlayer.Possess(aPlayer.Pawn); aPlayer.PawnClass = aPlayer.Pawn.Class; aPlayer.Pawn.PlayTeleportEffect(true, true); aPlayer.ClientSetRotation(aPlayer.Pawn.Rotation); AddDefaultInventory(aPlayer.Pawn); TriggerEvent( StartSpot.Event, StartSpot, aPlayer.Pawn); if ( bAllowVehicles && (Level.NetMode == NM_Standalone) && (PlayerController(aPlayer) != None) ) { // tell bots not to get into nearby vehicles for a little while BestDist = 2000; ViewDir = vector(aPlayer.Pawn.Rotation); for ( V=VehicleList; V!=None; V=V.NextVehicle ) if ( V.bTeamLocked && (aPlayer.GetTeamNum() == V.Team) ) { Dist = VSize(V.Location - aPlayer.Pawn.Location); if ( (ViewDir Dot (V.Location - aPlayer.Pawn.Location)) < 0 ) Dist *= 2; if ( Dist < BestDist ) { Best = V; BestDist = Dist; } } if ( Best != None ) Best.PlayerStartTime = Level.TimeSeconds + 8; } } function class GetDefaultPlayerClass(Controller C) { local PlayerController PC; local String PawnClassName; local class PawnClass; PC = PlayerController( C ); if( PC != None ) { PawnClassName = PC.GetDefaultURL( "Class" ); PawnClass = class( DynamicLoadObject( PawnClassName, class'Class') ); if( PawnClass != None ) return( PawnClass ); } return( class( DynamicLoadObject( DefaultPlayerClassName, class'Class' ) ) ); } // // 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 class HudClass; local class ScoreboardClass; if ( !bIsSaveGame ) { // Log player's login. if (GameStats!=None) { GameStats.ConnectEvent(NewPlayer.PlayerReplicationInfo); GameStats.GameEvent("NameChange",NewPlayer.PlayerReplicationInfo.playername,NewPlayer.PlayerReplicationInfo); } 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; } } // tell client what hud and scoreboard to use if( HUDType == "" ) log( "No HUDType specified in GameInfo", 'Log' ); else { HudClass = class(DynamicLoadObject(HUDType, class'Class')); if( HudClass == None ) log( "Can't find HUD class "$HUDType, 'Error' ); } if( ScoreBoardType != "" ) { ScoreboardClass = class(DynamicLoadObject(ScoreBoardType, class'Class')); if( ScoreboardClass == None ) log( "Can't find ScoreBoard class "$ScoreBoardType, 'Error' ); } NewPlayer.ClientSetHUD( HudClass, ScoreboardClass ); SetWeaponViewShake(NewPlayer); if ( bIsSaveGame ) return; if ( NewPlayer.Pawn != None ) NewPlayer.Pawn.ClientSetRotation(NewPlayer.Pawn.Rotation); if( VotingHandler != None ) VotingHandler.PlayerJoin(NewPlayer); if ( AccessControl != None ) NewPlayer.LoginDelay = AccessControl.LoginDelaySeconds; NewPlayer.ClientCapBandwidth(NewPlayer.Player.CurrentNetSpeed); NotifyLogin(NewPlayer.PlayerReplicationInfo.PlayerID); log("New Player"@NewPlayer.PlayerReplicationInfo.PlayerName@"id="$NewPlayer.GetPlayerIDHash()); } function SetWeaponViewShake(PlayerController P) { P.ClientSetWeaponViewShake(bWeaponShouldViewShake && bModViewShake); } // // Player exits. // function Logout( Controller Exiting ) { local bool bMessage; bMessage = true; if ( PlayerController(Exiting) != None ) { if ( AccessControl != None && AccessControl.AdminLogout( PlayerController(Exiting) ) ) AccessControl.AdminExited( PlayerController(Exiting) ); if ( PlayerController(Exiting).PlayerReplicationInfo.bOnlySpectator ) { bMessage = false; NumSpectators--; } else { NumPlayers--; } } if( bMessage && (Level.NetMode==NM_DedicatedServer || Level.NetMode==NM_ListenServer) ) BroadcastLocalizedMessage(GameMessageClass, 4, Exiting.PlayerReplicationInfo); if( VotingHandler != None ) VotingHandler.PlayerExit(Exiting); if ( GameStats!=None) GameStats.DisconnectEvent(Exiting.PlayerReplicationInfo); //notify mutators that a player exited NotifyLogout(Exiting); } // Called at the end of GameInfo.PostLogin() // Notify all existing PlayerControllers that this player has joined. Each player's ChatManager replicates // this information to the client for matching against the client's "Restricted" list of players. If a match is made, // the client's copy of ChatManager notifies the server's copy so that the corresponding type of communication is not // sent to the player. function NotifyLogin(int NewPlayerID) { local int i; local array PCArray; GetPlayerControllerList(PCArray); for ( i = 0; i < PCArray.Length; i++ ) PCArray[i].ServerRequestBanInfo(NewPlayerID); } function NotifyLogout(Controller Exiting) { local Controller C; local PlayerController PC; BaseMutator.NotifyLogout(Exiting); if ( PlayerController(Exiting) != None && Exiting.PlayerReplicationInfo != None ) { for ( C = Level.ControllerList; C != None; C = C.NextController ) { PC = PlayerController(C); if ( PC != None && PC.ChatManager != None ) PC.ChatManager.UnTrackPlayer(Exiting.PlayerReplicationInfo.PlayerID); } } } // // 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) } function AddGameSpecificInventory(Pawn p) { local Weapon newWeapon; local class WeapClass; // Spawn default weapon. WeapClass = BaseMutator.GetDefaultWeapon(); if( (WeapClass!=None) && (p.FindInventoryType(WeapClass)==None) ) { newWeapon = Spawn(WeapClass,,,p.Location); if( newWeapon != None ) { newWeapon.GiveTo(p); newWeapon.bCanThrow = false; // don't allow default weapon to be thrown out } } } // // Spawn any default inventory for the player. // function AddDefaultInventory( pawn PlayerPawn ) { local Weapon newWeapon; local class WeapClass; // Spawn default weapon. WeapClass = BaseMutator.GetDefaultWeapon(); if( (WeapClass!=None) && (PlayerPawn.FindInventoryType(WeapClass)==None) ) { newWeapon = Spawn(WeapClass,,,PlayerPawn.Location); if( newWeapon != None ) { newWeapon.GiveTo(PlayerPawn); //newWeapon.BringUp(); newWeapon.bCanThrow = false; // don't allow default weapon to be thrown out } } SetPlayerDefaults(PlayerPawn); } /* 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.JumpZ = PlayerPawn.Default.JumpZ; BaseMutator.ModifyPlayer(PlayerPawn); } function NotifyKilled(Controller Killer, Controller Killed, Pawn KilledPawn ) { local Controller C; for ( C=Level.ControllerList; C!=None; C=C.nextController ) C.NotifyKilled(Killer, Killed, KilledPawn); } function KillEvent(string Killtype, PlayerReplicationInfo Killer, PlayerReplicationInfo Victim, class Damage) { if ( GameStats != None ) GameStats.KillEvent(KillType, Killer, Victim, Damage); } function Killed( Controller Killer, Controller Killed, Pawn KilledPawn, class damageType ) { local vehicle V; if ( (Killed != None) && Killed.bIsPlayer ) { Killed.PlayerReplicationInfo.Deaths += 1; Killed.PlayerReplicationInfo.NetUpdateTime = FMin(Killed.PlayerReplicationInfo.NetUpdateTime, Level.TimeSeconds + 0.3 * FRand()); BroadcastDeathMessage(Killer, Killed, damageType); if ( (Killer == Killed) || (Killer == None) ) { if ( Killer == None ) KillEvent("K", None, Killed.PlayerReplicationInfo, DamageType); //"Kill" else KillEvent("K", Killer.PlayerReplicationInfo, Killed.PlayerReplicationInfo, DamageType); //"Kill" } else { if ( bTeamGame && (Killer.PlayerReplicationInfo != None) && (Killer.PlayerReplicationInfo.Team == Killed.PlayerReplicationInfo.Team) ) KillEvent("TK", Killer.PlayerReplicationInfo, Killed.PlayerReplicationInfo, DamageType); //"Teamkill" else KillEvent("K", Killer.PlayerReplicationInfo, Killed.PlayerReplicationInfo, DamageType); //"Kill" } } if ( Killed != None ) ScoreKill(Killer, Killed); DiscardInventory(KilledPawn); NotifyKilled(Killer,Killed,KilledPawn); if ( bAllowVehicles && (Level.NetMode == NM_Standalone) && (PlayerController(Killed) != None) ) { // tell bots not to get into nearby vehicles for ( V=VehicleList; V!=None; V=V.NextVehicle ) if ( Killed.GetTeamNum() == V.Team ) V.PlayerStartTime = 0; } } function bool PreventDeath(Pawn Killed, Controller Killer, class damageType, vector HitLocation) { if ( GameRulesModifiers == None ) return false; return GameRulesModifiers.PreventDeath(Killed,Killer, damageType,HitLocation); } function bool PreventSever(Pawn Killed, Name boneName, int Damage, class DamageType) { if ( GameRulesModifiers == None ) return false; return GameRulesModifiers.PreventSever(Killed, boneName, Damage, DamageType); } 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); } // %k = Owner's PlayerName (Killer) // %o = Other's PlayerName (Victim) // %w = Owner's Weapon ItemName static native function string ParseKillMessage( string KillerName, string VictimName, string DeathMessage ); function Kick( string S ) { if (AccessControl != None) AccessControl.Kick(S); } function SessionKickBan( string S ) // sjs { if (AccessControl != None) AccessControl.SessionKickBan( S ); } function KickBan( string S ) { if (AccessControl != None) AccessControl.KickBan(S); } function bool IsOnTeam(Controller Other, int TeamNum) { local int OtherTeam; if ( bTeamGame && (Other != None) ) { OtherTeam = Other.GetTeamNum(); if ( OtherTeam == 255 ) return false; return (OtherTeam == TeamNum); } return false; } //------------------------------------------------------------------------------------- // Level gameplay modification. // // Return whether Viewer is allowed to spectate from the // point of view of ViewTarget. // function bool CanSpectate( PlayerController Viewer, bool bOnlySpectator, actor ViewTarget ) { return true; } /* Use reduce damage for teamplay modifications, etc. */ function int ReduceDamage( int Damage, pawn injured, pawn instigatedBy, vector HitLocation, out vector Momentum, class DamageType ) { local int OriginalDamage; local armor FirstArmor, NextArmor; OriginalDamage = Damage; if( injured.PhysicsVolume.bNeutralZone ) Damage = 0; else if ( injured.InGodMode() ) // God mode return 0; else if ( (injured.Inventory != None) && (damage > 0) ) //then check if carrying armor { FirstArmor = injured.inventory.PrioritizeArmor(Damage, DamageType, HitLocation); while( (FirstArmor != None) && (Damage > 0) ) { NextArmor = FirstArmor.nextArmor; Damage = FirstArmor.ArmorAbsorbDamage(Damage, DamageType, HitLocation); FirstArmor = NextArmor; } } if ( GameRulesModifiers != None ) return GameRulesModifiers.NetDamage( OriginalDamage, Damage,injured,instigatedBy,HitLocation,Momentum,DamageType ); return Damage; } // // Return whether an item should respawn. // function bool ShouldRespawn( Pickup Other ) { if( Level.NetMode == NM_StandAlone ) return false; return Other.ReSpawnTime!=0.0; } /* 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. */ function bool PickupQuery( Pawn Other, Pickup item ) { local byte bAllowPickup; if ( (GameRulesModifiers != None) && GameRulesModifiers.OverridePickupQuery(Other, item, bAllowPickup) ) return (bAllowPickup == 1); if ( Other.Inventory == None ) return true; else return !Other.Inventory.HandlePickupQuery(Item); } /* Discard a player's inventory after he dies. */ function DiscardInventory( Pawn Other ) { Other.Weapon = None; Other.SelectedItem = None; while ( Other.Inventory != None ) Other.Inventory.Destroy(); } /* Try to change a player's name. */ function ChangeName( Controller Other, coerce string S, bool bNameChange ) { local Controller C; if( S == "" ) return; S = StripColor(s); // Stip out color codes Other.PlayerReplicationInfo.SetPlayerName(S); // notify local players if ( bNameChange ) for ( C=Level.ControllerList; C!=None; C=C.NextController ) if ( (PlayerController(C) != None) && (Viewport(PlayerController(C).Player) != None) ) PlayerController(C).ReceiveLocalizedMessage( class'GameMessage', 2, Other.PlayerReplicationInfo ); } /* 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 */ function byte PickTeam(byte Current, Controller C) { return Current; } /* Send a player to a URL. */ function SendPlayer( PlayerController aPlayer, string URL ) { aPlayer.ClientTravel( URL, TRAVEL_Relative, true ); } /* Restart the game. */ function RestartGame() { local string NextMap; local MapList MyList; if ( (GameRulesModifiers != None) && GameRulesModifiers.HandleRestartGame() ) return; if ( bGameRestarted ) return; bGameRestarted = true; // allow voting handler to stop travel to next map if ( VotingHandler != None && !VotingHandler.HandleRestartGame() ) return; // these server travels should all be relative to the current URL if ( bChangeLevels && !bAlreadyChanged && (MapListType != "") ) { // open a the nextmap actor for this game type and get the next map bAlreadyChanged = true; MyList = GetMapList(MapListType); if (MyList != None) { NextMap = MyList.GetNextMap(); MyList.Destroy(); } if ( NextMap == "" ) NextMap = GetMapName(MapPrefix, NextMap,1); if ( NextMap != "" ) { Level.ServerTravel(NextMap, false); return; } } Level.ServerTravel( "?Restart", false ); } function array GetMapRotation() { if ( MaplistHandler != None ) return MaplistHandler.GetCurrentMapRotation(); } function MapList GetMapList(string MapListClassType) { local class MapListClass; if (MapListClassType != "") { MapListClass = class(DynamicLoadObject(MapListClassType, class'Class')); if (MapListClass != None) return Spawn(MapListClass); } return None; } function ChangeVoiceChannel( PlayerReplicationInfo PRI, int NewChannelIndex, int OldChannelIndex ); //========================================================================== // 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); } //========================================================================== function bool CheckEndGame(PlayerReplicationInfo Winner, string Reason) { local Controller P; if ( (GameRulesModifiers != None) && !GameRulesModifiers.CheckEndGame(Winner, Reason) ) return false; // all player cameras focus on winner or final scene (picked by gamerules) for ( P=Level.ControllerList; P!=None; P=P.NextController ) { P.ClientGameEnded(); P.GameHasEnded(); } return true; } /* End of game. */ function EndGame( PlayerReplicationInfo Winner, string Reason ) { // don't end game if not really ready if ( !CheckEndGame(Winner, Reason) ) { bOverTime = true; return; } bGameEnded = true; TriggerEvent('EndGame', self, None); EndLogging(Reason); } function EndLogging(string Reason) { if (GameStats == None) return; GameStats.EndGame(Reason); GameStats.Destroy(); GameStats = None; } /* Return the 'best' player start for this player to start from. */ function NavigationPoint FindPlayerStart( Controller Player, optional byte InTeam, optional string incomingName ) { local NavigationPoint N, BestStart; local Teleporter Tel; local float BestRating, NewRating; local byte Team; // always pick StartSpot at start of match if ( (Player != None) && (Player.StartSpot != None) && (Level.NetMode == NM_Standalone) && (bWaitingToStartMatch || ((Player.PlayerReplicationInfo != None) && Player.PlayerReplicationInfo.bWaitingPlayer)) ) { return Player.StartSpot; } if ( GameRulesModifiers != None ) { N = GameRulesModifiers.FindPlayerStart(Player,InTeam,incomingName); if ( N != None ) return N; } // if incoming start is specified, then just use it if( incomingName!="" ) foreach AllActors( class 'Teleporter', Tel ) if( string(Tel.Tag)~=incomingName ) return Tel; // use InTeam if player doesn't have a team yet if ( (Player != None) && (Player.PlayerReplicationInfo != None) ) { if ( Player.PlayerReplicationInfo.Team != None ) Team = Player.PlayerReplicationInfo.Team.TeamIndex; else Team = InTeam; } else Team = InTeam; for ( N=Level.NavigationPointList; N!=None; N=N.NextNavigationPoint ) { NewRating = RatePlayerStart(N,Team,Player); if ( NewRating > BestRating ) { BestRating = NewRating; BestStart = N; } } if ( (BestStart == None) || ((PlayerStart(BestStart) == None) && (Player != None) && Player.bIsPlayer) ) { log("Warning - PATHS NOT DEFINED or NO PLAYERSTART with positive rating"); BestRating = -100000000; ForEach AllActors( class 'NavigationPoint', N ) { NewRating = RatePlayerStart(N,0,Player); if ( InventorySpot(N) != None ) NewRating -= 50; NewRating += 20 * FRand(); if ( NewRating > BestRating ) { BestRating = NewRating; BestStart = N; } } } return BestStart; } /* Rate whether player should choose this NavigationPoint as its start default implementation is for single player game */ function float RatePlayerStart(NavigationPoint N, byte Team, Controller Player) { local PlayerStart P; P = PlayerStart(N); if ( P != None ) { if ( P.bSinglePlayerStart ) { if ( P.bEnabled ) return 1000; return 20; } return 10; } return 0; } function ScoreObjective(PlayerReplicationInfo Scorer, float Score) { if ( Scorer != None ) Scorer.Score += Score; if ( GameRulesModifiers != None ) GameRulesModifiers.ScoreObjective(Scorer, Score); CheckScore(Scorer); } /* CheckScore() see if this score means the game ends */ function CheckScore(PlayerReplicationInfo Scorer) { if ( (GameRulesModifiers != None) && GameRulesModifiers.CheckScore(Scorer) ) return; } function ScoreEvent(PlayerReplicationInfo Who, float Points, string Desc) { if (GameStats!=None) GameStats.ScoreEvent(Who,Points,Desc); } function TeamScoreEvent(int Team, float Points, string Desc) { if ( GameStats != None ) GameStats.TeamScoreEvent(Team, Points, Desc); } function ScoreKill(Controller Killer, Controller Other) { if( (killer == Other) || (killer == None) ) { if ( (Other!=None) && (Other.PlayerReplicationInfo != None) ) { Other.PlayerReplicationInfo.Score -= 1; Other.PlayerReplicationInfo.NetUpdateTime = Level.TimeSeconds - 1; ScoreEvent(Other.PlayerReplicationInfo,-1,"self_frag"); } } else if ( killer.PlayerReplicationInfo != None ) { Killer.PlayerReplicationInfo.Score += 1; Killer.PlayerReplicationInfo.NetUpdateTime = Level.TimeSeconds - 1; Killer.PlayerReplicationInfo.Kills++; ScoreEvent(Killer.PlayerReplicationInfo,1,"frag"); } if ( GameRulesModifiers != None ) GameRulesModifiers.ScoreKill(Killer, Other); if ( (Killer != None) || (MaxLives > 0) ) CheckScore(Killer.PlayerReplicationInfo); } function bool TooManyBots(Controller botToRemove) { return false; } // Stub static function Texture GetRandomTeamSymbol(int base) { return None; } static function string FindTeamDesignation(GameReplicationInfo GRI, actor A) // Should be subclassed in various team games { return ""; } // - Given a %X var return the value. static function string ParseChatPercVar(Mutator BaseMutator, Controller Who, string Cmd) { // Pass along to Mutators if (BaseMutator!=None) Cmd = BaseMutator.ParseChatPercVar(Who,Cmd); if (Who!=None) Cmd = Who.ParseChatPercVar(Cmd); return Cmd; } // - Parse out % vars for various messages static function string ParseMessageString(Mutator BaseMutator, Controller Who, String Message) { return Message; } static function FillPlayInfo(PlayInfo PlayInfo) { Super.FillPlayInfo(PlayInfo); // Always begin with calling parent PlayInfo.AddSetting(default.BotsGroup, "GameDifficulty", GetDisplayText("GameDifficulty"), 0, 2, "Select", default.GIPropsExtras[0], "Xb"); PlayInfo.AddSetting(default.GameGroup, "GoalScore", GetDisplayText("GoalScore"), 0, 0, "Text", "3;0:999"); PlayInfo.AddSetting(default.GameGroup, "TimeLimit", GetDisplayText("TimeLimit"), 0, 0, "Text", "3;0:999"); PlayInfo.AddSetting(default.GameGroup, "MaxLives", GetDisplayText("MaxLives"), 0, 0, "Text", "3;0:999"); PlayInfo.AddSetting(default.GameGroup, "bWeaponStay", GetDisplayText("bWeaponStay"), 1, 0, "Check", , , ,True); PlayInfo.AddSetting(default.RulesGroup, "bAllowWeaponThrowing", GetDisplayText("bAllowWeaponThrowing"), 1, 0, "Check", , , ,True); PlayInfo.AddSetting(default.RulesGroup, "bAllowBehindView", GetDisplayText("bAllowBehindview"), 1, 0, "Check", , ,True,True); PlayInfo.AddSetting(default.RulesGroup, "bWeaponShouldViewShake", GetDisplayText("bWeaponShouldViewShake"),1, 0, "Check", , , ,True); PlayInfo.AddSetting(default.ServerGroup, "bEnableStatLogging", GetDisplayText("bEnableStatLogging"), 0, 1, "Check", , ,True); PlayInfo.AddSetting(default.ServerGroup, "bAdminCanPause", GetDisplayText("bAdminCanPause"), 1, 1, "Check", , ,True,True); PlayInfo.AddSetting(default.ServerGroup, "MaxSpectators", GetDisplayText("MaxSpectators"), 1, 1, "Text", "3;0:32", ,True,True); PlayInfo.AddSetting(default.ServerGroup, "MaxPlayers", GetDisplayText("MaxPlayers"), 0, 1, "Text", "3;0:32", ,True); PlayInfo.AddSetting(default.ServerGroup, "MaxIdleTime", GetDisplayText("MaxIdleTime"), 0, 1, "Text", "3;0:300", ,True,True); // Add GRI's PIData if (default.GameReplicationInfoClass != None) { default.GameReplicationInfoClass.static.FillPlayInfo(PlayInfo); PlayInfo.PopClass(); } if (default.VoiceReplicationInfoClass != None) { default.VoiceReplicationInfoClass.static.FillPlayInfo(PlayInfo); PlayInfo.PopClass(); } if (default.BroadcastClass != None) default.BroadcastClass.static.FillPlayInfo(PlayInfo); else class'BroadcastHandler'.static.FillPlayInfo(PlayInfo); PlayInfo.PopClass(); if (class'Engine.GameInfo'.default.VotingHandlerClass != None) { class'Engine.GameInfo'.default.VotingHandlerClass.static.FillPlayInfo(PlayInfo); PlayInfo.PopClass(); } else log("GameInfo::FillPlayInfo class'Engine.GameInfo'.default.VotingHandlerClass = None"); } static function string GetDisplayText(string PropName) { switch (PropName) { case "GameDifficulty": return default.GIPropsDisplayText[0]; case "bWeaponStay": return default.GIPropsDisplayText[1]; case "MaxSpectators": return default.GIPropsDisplayText[4]; case "MaxPlayers": return default.GIPropsDisplayText[5]; case "GoalScore": return default.GIPropsDisplayText[6]; case "MaxLives": return default.GIPropsDisplayText[7]; case "TimeLimit": return default.GIPropsDisplayText[8]; case "bEnableStatLogging": return default.GIPropsDisplayText[9]; case "bAllowWeaponThrowing": return default.GIPropsDisplayText[10]; case "bAllowBehindview": return default.GIPropsDisplayText[11]; case "bAdminCanPause": return default.GIPropsDisplayText[12]; case "MaxIdleTime": return default.GIPropsDisplayText[13]; case "bWeaponShouldViewShake": return default.GIPropsDisplayText[14]; } return ""; } static function string GetDescriptionText(string PropName) { switch (PropName) { case "GameDifficulty": return default.GIPropDescText[0]; case "bWeaponStay": return default.GIPropDescText[1]; case "MaxSpectators": return default.GIPropDescText[4]; case "MaxPlayers": return default.GIPropDescText[5]; case "GoalScore": return default.GIPropDescText[6]; case "MaxLives": return default.GIPropDescText[7]; case "TimeLimit": return default.GIPropDescText[8]; case "bEnableStatLogging": return default.GIPropDescText[9]; case "bAllowWeaponThrowing": return default.GIPropDescText[10]; case "bAllowBehindview": return default.GIPropDescText[11]; case "bAdminCanPause": return default.GIPropDescText[12]; case "MaxIdleTime": return default.GIPropDescText[13]; case "bWeaponShouldViewShake": return default.GIPropDescText[14]; } return Super.GetDescriptionText(PropName); } static event bool AcceptPlayInfoProperty(string PropName) { if ( PropName == "MaxLives" ) return false; return Super.AcceptPlayInfoProperty(PropName); } static function int OrderToIndex(int Order) { return Order; } function ReviewJumpSpots(name TestLabel); function string RecommendCombo(string ComboName) { return ComboName; } function string NewRecommendCombo(string ComboName, AIController C) { local string NewComboName; NewComboName = RecommendCombo(ComboName); if (NewComboName != ComboName) return NewComboName; return BaseMutator.NewRecommendCombo(ComboName, C); } function bool CanEnterVehicle(Vehicle V, Pawn P) { return BaseMutator.CanEnterVehicle(V, P); } function DriverEnteredVehicle(Vehicle V, Pawn P) { BaseMutator.DriverEnteredVehicle(V, P); } function bool CanLeaveVehicle(Vehicle V, Pawn P) { return BaseMutator.CanLeaveVehicle(V, P); } function DriverLeftVehicle(Vehicle V, Pawn P) { BaseMutator.DriverLeftVehicle(V, P); } function TeamInfo OtherTeam(TeamInfo Requester) { return None; } exec function KillBots(int num); exec function AdminSay(string Msg) { local controller C; for( C=Level.ControllerList; C!=None; C=C.nextController ) if( C.IsA('PlayerController') ) { PlayerController(C).ClearProgressMessages(); PlayerController(C).SetProgressTime(6); PlayerController(C).SetProgressMessage(0, Msg, class'Canvas'.Static.MakeColor(255,255,255)); } } function RegisterVehicle(Vehicle V) { // add to AI vehicle list V.NextVehicle = VehicleList; VehicleList = V; } function actor FindSpecGoalFor(PlayerReplicationInfo PRI, int TeamIndex) { return none; } function int GetDefenderNum() { return 255; } event SetGrammar() { if( BeaconName!="" ) LoadSRGrammar(BeaconName); } native function LoadSRGrammar( string Grammar ); // Server-only convenience function to retrieve a list of non-AI playercontrollers function GetPlayerControllerList(out array ControllerArray) { local Controller C; local PlayerController PC; if ( ControllerArray.Length > 0 ) ControllerArray.Remove(0, ControllerArray.Length); for (C = Level.ControllerList; C != None; C = C.NextController) { PC = PlayerController(C); if ( PC != None && PC.bIsPlayer && PC.PlayerReplicationInfo != None && !PC.PlayerReplicationInfo.bOnlySpectator && !PC.PlayerReplicationInfo.bBot && PC.Player != None ) ControllerArray[ControllerArray.Length] = PC; } } /* Parse voice command and give order to bot */ function ParseVoiceCommand( PlayerController Sender, string RecognizedString ); // Stub for UnrealMPGameInfo static function AdjustBotInterface(bool bSinglePlayer); // matinee Scene events event SceneStarted( SceneManager SM, Actor Other ); event SceneEnded( SceneManager SM, Actor Other ); event SceneAbort(); // Called from PlayerController when pressing fire. event NoTranslocatorKeyPressed( PlayerController PC ); static function array GetAllLoadHints(optional bool bThisClassOnly); static function string GetLoadingHint( PlayerController Ref, string MapName, color HintColor ) { local string Hint; local int Attempt; if ( Ref == None ) return ""; while ( Hint == "" && ++Attempt < 10 ) Hint = ParseLoadingHint(GetNextLoadHint(MapName), Ref, HintColor); return Hint; } static function string ParseLoadingHint(string Hint, PlayerController Ref, color HintColor) { local string CurrentHint, Cmd, Result; local int pos; pos = InStr(Hint, "%"); if ( pos == -1 ) return Hint; do { Cmd = ""; Result = ""; CurrentHint $= Left(Hint,pos); Hint = Mid(Hint, pos+1); pos = InStr(Hint, "%"); if ( pos == -1 ) break; Cmd = Left(Hint,pos); Hint = Mid(Hint,pos+1); Result = GetKeyBindName(Cmd,Ref); if ( Result == Cmd || Result == "" ) break; CurrentHint $= MakeColorCode(default.BindColor) $ Result $ MakeColorCode(HintColor); pos = InStr(Hint, "%"); } until ( Hint == "" || pos == -1 ); if ( Result != "" && Result != Cmd ) return CurrentHint $ Hint; return ""; } static function string GetKeyBindName( string Cmd, PlayerController Ref ) { local string BindStr; local array Bindings; local int i, idx, BestIdx, Weight, BestWeight; if ( Ref == None || Cmd == "" ) return Cmd; BestIdx = -1; BindStr = Ref.ConsoleCommand("BINDINGTOKEY" @ "\"" $ Cmd $ "\""); if ( BindStr != "" ) { Split(BindStr, ",", Bindings); if ( Bindings.Length > 0 ) { for ( i = 0; i < Bindings.Length; i++ ) { idx = int(Ref.ConsoleCommand("KEYNUMBER"@Bindings[i])); if ( idx != -1 ) { Weight = GetBindWeight(idx); if ( Weight > BestWeight ) { BestWeight = Weight; BestIdx = idx; } } } if ( BestIdx != -1 ) return Ref.ConsoleCommand("LOCALIZEDKEYNAME"@BestIdx); } } return Cmd; } static function string GetNextLoadHint(string MapName) { return ""; } static function string MakeColorCode(color NewColor) { // Text colours use 1 as 0. if(NewColor.R == 0) NewColor.R = 1; if(NewColor.G == 0) NewColor.G = 1; if(NewColor.B == 0) NewColor.B = 1; return Chr(0x1B)$Chr(NewColor.R)$Chr(NewColor.G)$Chr(NewColor.B); } static function int GetBindWeight( byte KeyNumber ) { // Left/Right mouse if ( KeyNumber == 0x01 || KeyNumber == 0x02 ) return 100; // Main number & letter keys if ( KeyNumber >= 0x30 && KeyNumber <= 0x5A ) return 75; // Space or Ctrl/Alt/Shift if ( KeyNumber==0x20 || (KeyNumber >= 0x10 && KeyNumber <= 0x12) ) return 50; // Arrow keys if ( KeyNumber >= 0x25 && KeyNumber <= 0x28 ) return 45; // Middle mouse if ( KeyNumber==0x04 ) return 40; // Mouse scroll wheel if ( KeyNumber == 0xEC || KeyNumber == 0xED ) return 35; // Home, PgDn, etc. if ( KeyNumber == 0x08 || (KeyNumber >= 0x21 && KeyNumber <= 0x28) ) return 30; // Number pad if ( KeyNumber >= 0x60 && KeyNumber <= 0x6F ) return 25; return 20; } static function bool IsVehicleMutator( string MutatorClassName ) { if ( MutatorClassName ~= "Onslaught.MutBigWheels" ) return true; if ( MutatorClassName ~= "Onslaught.MutWheeledVehicleStunts" ) return true; if ( MutatorClassName ~= "Onslaught.MutLightweightVehicles" ) return true; if ( MutatorClassName ~= "OnslaughtFull.MutVehicleArena" ) return true; return false; } // Returns whether a mutator should be allowed with this gametype static function bool AllowMutator( string MutatorClassName ) { if ( MutatorClassName == Default.MutatorClass ) return true; if ( !Default.bAllowVehicles && static.IsVehicleMutator(MutatorClassName) ) return false; return !class'LevelInfo'.static.IsDemoBuild(); } static function AddServerDetail( out ServerResponseLine ServerState, string RuleName, coerce string RuleValue ) { local int i; i = ServerState.ServerInfo.Length; ServerState.ServerInfo.Length = i + 1; ServerState.ServerInfo[i].Key = RuleName; ServerState.ServerInfo[i].Value = RuleValue; } function string StripColor(string s) { local int p; p = InStr(s,chr(27)); while ( p>=0 ) { s = left(s,p)$mid(S,p+4); p = InStr(s,Chr(27)); } return s; } function bool JustStarted(float T) { return ( Level.TimeSeconds < T ); } function int MultiMinPlayers() { return 0; } // cheat function WeakObjectives(); function DisableNextObjective(); // hacky. If you press use while dead, this function will get called. function DeadUse(PlayerController PC); sZ| U-wAnkw| *a| 9?| F]'9?| Y]'9?| F9?| Y Gs//============================================================================= // GameEngine: The game subsystem. // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class GameEngine extends Engine native noexport transient; // URL structure. struct URL { var string Protocol, // Protocol, i.e. "unreal" or "http". 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 "". var int Valid; }; var Level GLevel, GEntry; var PendingLevel GPendingLevel; var URL LastURL; var config array ServerActors, ServerPackages; var array DummyArray; // Do not modify var object DummyObject; // Do not modify var string DummyString; // Do not modify var globalconfig String MainMenuClass; // Menu that appears when you first start var globalconfig string SinglePlayerMenuClass; // Menu that appears when you return from a single player match after a cinematic game var globalconfig String ConnectingMenuClass; // Menu that appears when you are connecting var globalconfig String DisconnectMenuClass; // Menu that appears when you are disconnected var globalconfig String LoadingClass; // Loading screen that appears var bool bCheatProtection; var(Settings) config bool ColorHighDetailMeshes; var(Settings) config bool ColorSlowCollisionMeshes; var(Settings) config bool ColorNoCollisionMeshes; var(Settings) config bool ColorWorldTextures; var(Settings) config bool ColorPlayerAndWeaponTextures; var(Settings) config bool ColorInterfaceTextures; var(VoiceChat) globalconfig bool VoIPAllowVAD; su2//============================================================================= // Fragment. //============================================================================= class Fragment extends Effects; var() MESH Fragments[11]; var int numFragmentTypes; var bool bFirstHit; var() sound ImpactSound, AltImpactSound; var() float SplashTime; function bool CanSplash() { if ( (Level.TimeSeconds - SplashTime > 0.25) && (Physics == PHYS_Falling) && (Abs(Velocity.Z) > 100) ) { SplashTime = Level.TimeSeconds; return true; } return false; } simulated function CalcVelocity(vector Momentum) { local float ExplosionSize; ExplosionSize = 0.011 * VSize(Momentum); Velocity = 0.0033 * Momentum + 0.7 * VRand()*(ExplosionSize+FRand()*100.0+100.0); Velocity.z += 0.5 * ExplosionSize; } simulated function HitWall (vector HitNormal, actor HitWall) { local float speed; Velocity = 0.5*(( Velocity dot HitNormal ) * HitNormal * (-2.0) + Velocity); // Reflect off Wall w/damping speed = VSize(Velocity); if (bFirstHit && speed<400) { bFirstHit=False; bRotatetoDesired=True; bFixedRotationDir=False; DesiredRotation.Pitch=0; DesiredRotation.Yaw=FRand()*65536; DesiredRotation.roll=0; } RotationRate.Yaw = RotationRate.Yaw*0.75; RotationRate.Roll = RotationRate.Roll*0.75; RotationRate.Pitch = RotationRate.Pitch*0.75; if ( (speed < 60) && (HitNormal.Z > 0.7) ) { SetPhysics(PHYS_none); bBounce = false; GoToState('Dying'); } else if (speed > 80) { if (FRand()<0.5) PlaySound(ImpactSound, SLOT_None,,, 300, 0.85+FRand()*0.3,true); else PlaySound(AltImpactSound, SLOT_None,,, 300, 0.85+FRand()*0.3,true); } } simulated final function RandSpin(float spinRate) { DesiredRotation = RotRand(); RotationRate.Yaw = spinRate * 2 *FRand() - spinRate; RotationRate.Pitch = spinRate * 2 *FRand() - spinRate; RotationRate.Roll = spinRate * 2 *FRand() - spinRate; } auto state Flying { simulated function timer() { GoToState('Dying'); } simulated singular function PhysicsVolumeChange( PhysicsVolume NewVolume ) { if ( NewVolume.bWaterVolume ) { Velocity = 0.2 * Velocity; if (bFirstHit) { bFirstHit=False; bRotatetoDesired=True; bFixedRotationDir=False; DesiredRotation.Pitch=0; DesiredRotation.Yaw=FRand()*65536; DesiredRotation.roll=0; } RotationRate = 0.2 * RotationRate; GotoState('Dying'); } } simulated function BeginState() { RandSpin(125000); if (abs(RotationRate.Pitch)<10000) RotationRate.Pitch=10000; if (abs(RotationRate.Roll)<10000) RotationRate.Roll=10000; LinkMesh(Fragments[int(FRand()*numFragmentTypes)]); if ( Level.NetMode == NM_Standalone ) LifeSpan = 20 + 40 * FRand(); SetTimer(5.0,True); } } state Dying { function TakeDamage( int Dam, Pawn instigatedBy, Vector hitlocation, Vector momentum, class damageType) { Destroy(); } simulated function timer() { if ( !PlayerCanSeeMe() ) Destroy(); } simulated function BeginState() { SetTimer(1 + FRand(),True); SetCollision(true, false, false); } } s] #exec Texture Import File=Textures\S_FluidSurfOsc.pcx Name=S_FluidSurfOsc Mips=Off MASKED=1 //============================================================================= // FluidSurfaceOscillator. //============================================================================= class FluidSurfaceOscillator extends Actor native placeable; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // FluidSurface to oscillate var() edfindable FluidSurfaceInfo FluidInfo; var() float Frequency; var() byte Phase; var() float Strength; var() float Radius; var transient const float OscTime; syF#exec Texture Import File=Textures\S_FluidSurf.pcx Name=S_FluidSurf Mips=Off MASKED=1 class FluidSurfaceInfo extends Info showcategories(Movement,Collision,Lighting,LightColor,Karma,Force) native noexport placeable; var () enum EFluidGridType { FGT_Square, FGT_Hexagonal } FluidGridType; var () float FluidGridSpacing; // distance between grid points var () int FluidXSize; // num vertices in X direction var () int FluidYSize; // num vertices in Y direction var () float FluidHeightScale; // vertical scale factor var () float FluidSpeed; // wave speed var () float FluidTimeScale; var () float FluidDamping; // between 0 and 1 var () float FluidNoiseFrequency; var () range FluidNoiseStrength; var () bool TestRipple; var () float TestRippleSpeed; var () float TestRippleStrength; var () float TestRippleRadius; var () float UTiles; var () float UOffset; var () float VTiles; var () float VOffset; var () float AlphaCurveScale; var () float AlphaHeightScale; var () byte AlphaMax; var () float ShootStrength; // How hard to ripple water when shot var () float ShootRadius; // How large a radius is affected when water is shot // How much to ripple the water when interacting with actors var () float RippleVelocityFactor; var () float TouchStrength; // Class of effect spawned when water surface it shot or touched by an actor var () class ShootEffect; var () bool OrientShootEffect; var () class TouchEffect; var () bool OrientTouchEffect; // Bitmap indicating which water verts are 'clamped' ie. dont move var const array ClampBitmap; // Terrain used for auto-clamping water verts if below terrain level. var () edfindable TerrainInfo ClampTerrain; var () bool bShowBoundingBox; var () bool bUseNoRenderZ; var () float NoRenderZ; // Amount of time to simulate during postload before water is first displayed var () float WarmUpTime; // Rate at which fluid sim will be updated var () float UpdateRate; var () color FluidColor; // Sim storage var transient const array Verts0; var transient const array Verts1; var transient const array VertAlpha; var transient const int LatestVerts; var transient const box FluidBoundingBox; // Current world-space AABB var transient const vector FluidOrigin; // Current bottom-left corner var transient const float TimeRollover; //var transient const float AverageTimeStep; //var transient const int StepCount; var transient const float TestRippleAng; var transient const FluidSurfacePrimitive Primitive; var transient const array Oscillators; var transient const bool bHasWarmedUp; // Functions // Ripple water at a particlar location. // Ignores 'z' componenet of position. native final function Pling(vector Position, float Strength, optional float Radius); // Default behaviour when shot is to apply an impulse and kick the KActor. simulated function TakeDamage(int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, class damageType) { //Log("FS TakeDam:"$hitlocation@damageType); if (damageType.default.FluidSurfaceShootStrengthMod ~= 0) return; // Vibrate water at hit location. Pling(hitLocation, ShootStrength * damageType.default.FluidSurfaceShootStrengthMod, ShootRadius); // If present, spawn splashy hit effect. if( (ShootEffect != None) && EffectIsRelevant(HitLocation,false) ) { if(OrientShootEffect) spawn(ShootEffect, self, , hitLocation, rotator(momentum)); else spawn(ShootEffect, self, , hitLocation); } } simulated function Touch(Actor Other) { local vector touchLocation; Super.Touch(Other); if( (Other == None) || !Other.bDisturbFluidSurface ) return; touchLocation = Other.Location; // Now projectiles affect water by Touch instead of TakeDamage, use ShootStrength here. Pling(touchLocation, ShootStrength * Other.FluidSurfaceShootStrengthMod, Other.CollisionRadius); // JTODO: Fix for non-horizontal fluid touchLocation.Z = Location.Z; if( (TouchEffect != None) && EffectIsRelevant(touchLocation,false) ) { if(OrientTouchEffect) spawn(TouchEffect, self, , touchLocation, rotator(Other.Velocity)); else spawn(TouchEffect, self, , touchLocation); } } se[iLJs 9U"A~s .s s ~s .s  GsjgAERj Gscclass FinalBlend extends Modifier showcategories(Material) native; enum EFrameBufferBlending { FB_Overwrite, FB_Modulate, FB_AlphaBlend, FB_AlphaModulate_MightNotFogCorrectly, FB_Translucent, FB_Darken, FB_Brighten, FB_Invisible, }; var() EFrameBufferBlending FrameBufferBlending; var() bool ZWrite; var() bool ZTest; var() bool AlphaTest; var() bool TwoSided; var() byte AlphaRef; s=h%=`=Q, R GsiS*`4"wy *y Y+S* GslR/wy *y a Gsz// ==================================================================== // Class: Engine.FileLog // Parent: Engine.Info // // Creates a log device. // Important notes about this class since version 2225: // - the log file is always closed when destroyed // - open log files have the extention .tmp and change to .log when // closed // - old .tmp files will be overwritten // - limited freedom in file extentions, allowed extentions: // log, txt, html, htm // ==================================================================== class FileLog extends Info Native; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // Internal var pointer LogAr; // FArchive* // File Names var const string LogFileName; var const string TempFileName; // File Manipulation native final function OpenLog(string FName, optional string FExt, optional bool bOverwrite); // no extention in FName native final function CloseLog(); native final function Logf( string LogString ); s,class FellLava extends Fell abstract; sN*R!]Z-\y a k:wy *y V+ytZCould not create output file Gs@ss@sstLs.class Fell extends DamageType abstract; s@sszclass 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 PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ) { return Default.FailMessage[Clamp(Switch,0,3)]; } sPI*0`jwi{wI*a A@H*@@wj{i Gs^Lswlt(ssG*X* `hwg{{G*a AF*@@@wh{g Gs^dsHssiclass FadeColor extends ConstantMaterial native editinlinenew; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) enum EColorFadeType { FC_Linear, FC_Sinusoidal, }; var() Color Color1; var() Color Color2; var() float FadePeriod; var() float FadePhase; var() EColorFadeType ColorFadeType; sMxS9;n9:9:$*,we*e/a9 Hdcw.H>*eHd10e Gsf//============================================================================= // Engine: The base class of the global application object classes. // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class Engine extends Subsystem native noexport transient; // Variables. var primitive Cylinder; var const client Client; var const audiosubsystem Audio; var const renderdevice GRenDev; // Stats. var int bShowFrameRate; var int bShowRenderStats; var int bShowHardwareStats; var int bShowGameStats; var int bShowNetStats; var int bShowAnimStats; // Show animation statistics. // ifdef WITH_LIPSINC var int bShowLIPSincStats; // Show LIPSinc statistics. // endif var int bShowHistograph; var int bShowXboxMemStats; var int bShowMatineeStats; // Show Matinee specific information var int bShowAudioStats; var int bShowLightStats; // Show dynamic lighting statistics. var int TickCycles, GameCycles, ClientCycles; var(Settings) config int CacheSizeMegs; var(Settings) config bool UseSound; var(Settings) config bool UseStaticMeshBatching; var(Settings) config bool ServerReadsStdin; var(Settings) config bool bSlowRefChecking; // toggle object ref checking on cleanupdestroyed var(Settings) float CurrentTickRate; var config int DetectedVideoMemory; // Color preferences. var(Colors) config color C_WorldBox, C_GroundPlane, C_GroundHighlight, C_BrushWire, C_Pivot, C_Select, C_Current, C_AddWire, C_SubtractWire, C_GreyWire, C_BrushVertex, C_BrushSnap, C_Invalid, C_ActorWire, C_ActorHiWire, C_Black, C_White, C_Mask, C_SemiSolidWire, C_NonSolidWire, C_WireBackground, C_WireGridAxis, C_ActorArrow, C_ScaleBox, C_ScaleBoxHi, C_ZoneWire, C_Mover, C_OrthoBackground, C_StaticMesh, C_VolumeBrush, C_ConstraintLine, C_AnimMesh, C_TerrainWire; sa //============================================================================= // Emitter: An Unreal Emitter Actor. //============================================================================= class Emitter extends Actor native placeable; #exec Texture Import File=Textures\S_Emitter.pcx Name=S_Emitter Mips=Off MASKED=1 var() export editinline array Emitters; var (Global) rangevector GlobalOffsetRange; var (Global) range TimeTillResetRange; var (Global) bool AutoDestroy; var (Global) bool AutoReset; var (Global) bool DisableFogging; var transient vector OldLocation; // Laurent -- for ptcl location interpolation var transient vector GlobalOffset; var transient vector AbsoluteVelocity; var transient int Initialized; var transient box BoundingBox; var transient float EmitterRadius; var transient float EmitterHeight; var transient float TimeTillReset; var transient bool UseParticleProjectors; var transient bool DeleteParticleEmitters; var transient bool ActorForcesEnabled; var transient ParticleMaterial ParticleMaterial; // shutdown the emitter and make it auto-destroy when the last active particle dies. native function Kill(); simulated function UpdatePrecacheMaterials() { local int i; super.UpdatePrecacheMaterials(); for( i=0; i Decorations; sJS//============================================================================= // Decoration. //============================================================================= class Decoration extends Actor abstract placeable native; // If set, the pyrotechnic or explosion when item is damaged. var() class EffectWhenDestroyed; var() bool bPushable; var() bool bDamageable; var bool bPushSoundPlaying; var bool bSplash; var() sound PushSound, EndPushSound; var const int numLandings; // Used by engine physics. var() class contents; // spawned when destroyed var() int NumFrags; // number of fragments to spawn when destroyed var() texture FragSkin; // skin to use for fragments var() class FragType; // type of fragment to use var vector FragMomentum; // momentum to be imparted to frags when destroyed var() int Health; var() float SplashTime; var const NavigationPoint LastAnchor; // recent nearest path var float LastValidAnchorTime; // last time a valid anchor was found event NotReachableBy(Pawn P); // called when FindPathToward this decoration fails (used by GameObjects) function bool CanSplash() { if ( (Level.TimeSeconds - SplashTime > 0.25) && (Physics == PHYS_Falling) && (Abs(Velocity.Z) > 100) ) { SplashTime = Level.TimeSeconds; return true; } return false; } function Drop(vector newVel); function Landed(vector HitNormal) { local rotator NewRot; if (Velocity.Z<-500) TakeDamage(100,Pawn(Owner),HitNormal,HitNormal*10000,class'Crushed'); Velocity = vect(0,0,0); NewRot = Rotation; NewRot.Pitch = 0; NewRot.Roll = 0; SetRotation(NewRot); } function HitWall (vector HitNormal, actor Wall) { Landed(HitNormal); } function TakeDamage( int NDamage, Pawn instigatedBy, Vector hitlocation, Vector momentum, class damageType) { Instigator = InstigatedBy; if (!bDamageable || (Health<0) ) Return; if ( Instigator != None ) MakeNoise(1.0); Health -= NDamage; FragMomentum = Momentum; if (Health <0) Destroy(); else { SetPhysics(PHYS_Falling); Momentum.Z = 1000; Velocity=Momentum/Mass; } } singular function PhysicsVolumeChange( PhysicsVolume NewVolume ) { if( NewVolume.bWaterVolume ) { if( bSplash && !PhysicsVolume.bWaterVolume && Mass<=Buoyancy && ((Abs(Velocity.Z) < 100) || (Mass == 0)) && (FRand() < 0.05) && !PlayerCanSeeMe() ) { bSplash = false; SetPhysics(PHYS_None); } } if( PhysicsVolume.bWaterVolume && (Buoyancy > Mass) ) { if( Buoyancy > 1.1 * Mass ) Buoyancy = 0.95 * Buoyancy; // waterlog else if( Buoyancy > 1.03 * Mass ) Buoyancy = 0.99 * Buoyancy; } } function Trigger( actor Other, pawn EventInstigator ) { Instigator = EventInstigator; TakeDamage( 1000, Instigator, Location, Vect(0,0,1)*900, class'Crushed'); } singular function BaseChange() { if( Velocity.Z < -500 ) TakeDamage( (1-Velocity.Z/30),Instigator,Location,vect(0,0,0) , class'Crushed'); if( base == None ) { if ( !bInterpolating && bPushable && (Physics == PHYS_None) ) SetPhysics(PHYS_Falling); } else if( Pawn(Base) != None ) { Base.TakeDamage( (1-Velocity.Z/400)* mass/Base.Mass,Instigator,Location,0.5 * Velocity , class'Crushed'); Velocity.Z = 100; if (FRand() < 0.5) Velocity.X += 70; else Velocity.Y += 70; SetPhysics(PHYS_Falling); } else if( Decoration(Base)!=None && Velocity.Z<-500 ) { Base.TakeDamage((1 - Mass/Base.Mass * Velocity.Z/30), Instigator, Location, 0.2 * Velocity, class'Crushed'); Velocity.Z = 100; if (FRand() < 0.5) Velocity.X += 70; else Velocity.Y += 70; SetPhysics(PHYS_Falling); } else instigator = None; } simulated function Destroyed() { local inventory dropped; local int i; local Fragment s; local float BaseSize; if ( Role == ROLE_Authority ) { if( (Contents!=None) && !Level.bStartup ) { dropped = Spawn(Contents); dropped.DropFrom(Location); } TriggerEvent( Event, Self, None); if ( bPushSoundPlaying ) PlaySound(EndPushSound, SLOT_Misc); } if ( (Level.NetMode != NM_DedicatedServer ) && !PhysicsVolume.bDestructive && (NumFrags > 0) && (FragType != None) ) { // spawn fragments BaseSize = 0.8 * sqrt(CollisionRadius*CollisionHeight)/NumFrags; for ( i=0; i 40) ) { oldZ = Velocity.Z; speed = VSize(Other.Velocity); Velocity = Other.Velocity * FMin(120.0, 20 + speed)/speed; if ( Physics == PHYS_None ) { Velocity.Z = 25; if (!bPushSoundPlaying) { PlaySound(PushSound, SLOT_Misc); bPushSoundPlaying = True; } } else Velocity.Z = oldZ; SetPhysics(PHYS_Falling); SetTimer(0.3,False); Instigator = Pawn(Other); } } s.class Decal extends Actor; // DEPRECATED sD^'{)D uG9?ZJ9?Xa^'a'c'O 9Da'R 9Dc'C* W$Z q$G9?O ,Z $G9?O Z $G9?O J9?R ,Z $G9?O J9?R Z $G9?O ,J9?R Z $J9?R Z +$J9?R ,Z W$G9?O ,J9?R ,Z )GJa^' GIPKƆQʁ)ss DamageEffect; // Special effect. var() string DamageWeaponName; // weapon that caused this damage var() bool bArmorStops; // does regular armor provide protection against this damage var() bool bInstantHit; // done by trace hit weapon var() bool bFastInstantHit; // done by fast repeating trace hit weapon var() bool bAlwaysGibs; var() bool bLocationalHit; var() bool bAlwaysSevers; var() bool bSpecial; var() bool bDetonatesGoop; var() bool bSkeletize; // swap model to skeleton var() bool bCauseConvulsions; var() bool bSuperWeapon; // if true, also damages teammates even if no friendlyfire var() bool bCausesBlood; var() bool bKUseOwnDeathVel; // For ragdoll death. Rather than using default - use death velocity specified in this damage type. var() bool bKUseTearOffMomentum; // For ragdoll death. Add entirety of killing hit's momentum to ragdoll's initial velocity. var bool bDelayedDamage; // for delayed damage damagetypes that set Pawn's DelayedDamageInstigatorController var bool bNeverSevers; var bool bThrowRagdoll; var bool bRagdollBullet; var bool bLeaveBodyEffect; var bool bExtraMomentumZ; // Add extra Z to momentum on walking pawns var bool bFlaming; var bool bRubbery; var bool bCausedByWorld; //this damage was caused by the world (falling off level, into lava, etc) var bool bDirectDamage; var bool bBulletHit; var bool bVehicleHit; // caused by vehicle running over you var() float GibModifier; // these effects should be none if should use the pawn's blood effects var() class PawnDamageEffect; // effect to spawn when pawns are damaged by this damagetype var() class PawnDamageEmitter; // effect to spawn when pawns are damaged by this damagetype var() array PawnDamageSounds; // Sound Effect to Play when Damage occurs var() class LowGoreDamageEffect; // effect to spawn when low gore var() class LowGoreDamageEmitter; // Emitter to use when it's low gore var() array LowGoreDamageSounds; // Sound Effects to play with Damage occurs with low gore var() class LowDetailEffect; // Low Detail effect var() class LowDetailEmitter; // Low Detail emitter var() float FlashScale; //for flashing victim's screen var() vector FlashFog; var() int DamageDesc; // Describes the damage var() int DamageThreshold; // How much damage much occur before playing effects var() vector DamageKick; var() Material DamageOverlayMaterial; // for changing player's shader when hit var() Material DeathOverlayMaterial; // for changing player's shader when hit var() float DamageOverlayTime; // timing for this var() float DeathOverlayTime; // timing for this var() float GibPerterbation; // When gibbing, the chunks will fly off in random directions. var(Karma) float KDamageImpulse; // magnitude of impulse applied to KActor due to this damage type. var(Karma) float KDeathVel; // How fast ragdoll moves upon death var(Karma) float KDeathUpKick; // Amount of upwards kick ragdolls get when they die var float VehicleDamageScaling; // multiply damage by this for vehicles var float VehicleMomentumScaling; static function IncrementKills(Controller Killer); static function ScoreKill(Controller Killer, Controller Killed) { IncrementKills(Killer); } static function string DeathMessage(PlayerReplicationInfo Killer, PlayerReplicationInfo Victim) { return Default.DeathString; } static function string SuicideMessage(PlayerReplicationInfo Victim) { if ( Victim.bIsFemale ) return Default.FemaleSuicide; else return Default.MaleSuicide; } static function class GetPawnDamageEffect( vector HitLocation, float Damage, vector Momentum, Pawn Victim, bool bLowDetail ) { if ( class'GameInfo'.static.UseLowGore() ) { if ( Default.LowGoreDamageEffect != None ) return Default.LowGoreDamageEffect; else return Victim.LowGoreBlood; } else if ( bLowDetail ) { if ( Default.LowDetailEffect != None ) return Default.LowDetailEffect; else return Victim.BloodEffect; } else { if ( Default.PawnDamageEffect != None ) return Default.PawnDamageEffect; else return Victim.BloodEffect; } } static function class GetPawnDamageEmitter( vector HitLocation, float Damage, vector Momentum, Pawn Victim, bool bLowDetail ) { if ( class'GameInfo'.static.UseLowGore() ) { if ( Default.LowGoreDamageEmitter != None ) return Default.LowGoreDamageEmitter; else return none; } else if ( bLowDetail ) { if ( Default.LowDetailEmitter != None ) return Default.LowDetailEmitter; else return none; } else { if ( Default.PawnDamageEmitter != None ) return Default.PawnDamageEmitter; else return none; } } static function Sound GetPawnDamageSound() { if ( class'GameInfo'.static.UseLowGore() ) { if (Default.LowGoreDamageSounds.Length>0) return Default.LowGoreDamageSounds[Rand(Default.LowGoreDamageSounds.Length)]; else return none; } else { if (Default.PawnDamageSounds.Length>0) return Default.PawnDamageSounds[Rand(Default.PawnDamageSounds.Length)]; else return none; } } static function bool IsOfType(int Description) { local int result; result = Description & Default.DamageDesc; return (result == Description); } static function GetHitEffects( out class HitEffects[4], int VictemHealth ); static function string GetWeaponClass() { return ""; } sCclass Cubemap extends Texture native noexport; var() Texture Faces[6]; var transient pointer CubemapRenderInterface; s1class Crushed extends DamageType abstract; sl//============================================================================= // 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. // // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class Controller extends Actor config(user) native nativereplication abstract; var Pawn Pawn; var const int PlayerNum; // The player number - per-match player number. var float SightCounter; // Used to keep track of when to check player visibility var float FovAngle; // X field of view angle in degrees, usually 90. var globalconfig float Handedness; var bool bIsPlayer; // Pawn is a player or a player-bot. var bool bGodMode; // cheat - when true, can't be killed or hurt //AI flags var const bool bLOSflag; // used for alternating LineOfSight traces var bool bAdvancedTactics; // serpentine movement between pathnodes var bool bCanOpenDoors; var bool bCanDoSpecial; var bool bAdjusting; // adjusting around obstacle var bool bPreparingMove; // set true while pawn sets up for a latent move var bool bControlAnimations; // take control of animations from pawn (don't let pawn play animations based on notifications) var bool bEnemyInfoValid; // false when change enemy, true when LastSeenPos etc updated var bool bNotifyApex; // event NotifyJumpApex() when at apex of jump var bool bUsePlayerHearing; var bool bJumpOverWall; // true when jumping to clear obstacle var bool bEnemyAcquired; var bool bSoaking; // pause and focus on this bot if it encounters a problem var bool bHuntPlayer; // hunting player var bool bAllowedToTranslocate; var bool bAllowedToImpactJump; var bool bAdrenalineEnabled; var bool bNotifyFallingHitWall; var bool bSlowerZAcquire; // acquire targets above or below more slowly than at same height var bool bInDodgeMove; var bool bVehicleTransition; var bool bForceStrafe; var bool bNotifyPostLanded; // Input buttons. var input byte bRun, bDuck, bFire, bAltFire, bVoiceTalk; var vector AdjustLoc; // location to move to while adjusting around obstacle var const Controller nextController; // chained Controller list var float Stimulus; // Strength of stimulus - Set when stimulus happens // Navigation AI var float MoveTimer; var Actor MoveTarget; // actor being moved toward var vector Destination; // location being moved toward var vector FocalPoint; // location being looked at var Actor Focus; // actor being looked at var float FocusLead; // how much to lead view of focus var Mover PendingMover; // mover pawn is waiting for to complete its move var Actor GoalList[4]; // used by navigation AI - list of intermediate goals var NavigationPoint home; // set when begin play, used for retreating and attitude checks var float MinHitWall; // Minimum HitNormal dot Velocity.Normal to get a HitWall event from the physics var float RespawnPredictionTime; // how far ahead to predict respawns when looking for inventory var float DodgeToGoalPct; // Frequency bot tries to dodge to reachable goal var int AcquisitionYawRate; var float DodgeLandZ; // expected min landing height of dodge var Vehicle LastBlockingVehicle; // Enemy information var Pawn Enemy; var Actor Target; var vector LastSeenPos; // enemy position when I last saw enemy (auto updated if EnemyNotVisible() enabled) var vector LastSeeingPos; // position where I last saw enemy (auto updated if EnemyNotVisible enabled) var float LastSeenTime; var string VoiceType; // OBSOLETE var float OldMessageTime; //to limit frequency of voice messages // Route Cache for Navigation var Actor RouteCache[16]; var ReachSpec CurrentPath; var ReachSpec NextRoutePath; var vector CurrentPathDir; 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 vector DirectionHint; // used to pick which side of vehicle to get out on // Replication Info var() class PlayerReplicationInfoClass; var PlayerReplicationInfo PlayerReplicationInfo; var class PawnClass; // class of pawn to spawn (for players) var class PreviousPawnClass; // Holds the player's previous class var float GroundPitchTime; var vector ViewX, ViewY, ViewZ; // Viewrotation encoding for PHYS_Spider var NavigationPoint StartSpot; // where player started the match // for monitoring the position of a pawn var vector MonitorStartLoc; // used by latent function MonitorPawn() var Pawn MonitoredPawn; // used by latent function MonitorPawn() var float MonitorMaxDistSq; var AvoidMarker FearSpots[2]; // avoid these spots when moving var float WarningDelay; // delay before act on firing warning var Projectile WarningProjectile; var Pawn ShotTarget; var const Actor LastFailedReach; // cache to avoid trying failed actorreachable more than once per frame var const float FailedReachTime; var const vector FailedReachLocation; var float Adrenaline; var float AdrenalineMax; // maximum Adrenaline (combo energy) var class LastPawnWeapon; // used by game stats const LATENT_MOVETOWARD = 503; // LatentAction number for Movetoward() latent function replication { reliable if( bNetDirty && (Role==ROLE_Authority) ) PlayerReplicationInfo, Pawn; reliable if( bNetDirty && (Role== ROLE_Authority) && bNetOwner ) PawnClass, Adrenaline,bAdrenalineEnabled; // Functions the server calls on the client side. reliable if( RemoteRole==ROLE_AutonomousProxy ) ClientGameEnded, ClientRoundEnded, ClientDying, ClientSetRotation, ClientSetLocation, ClientSwitchToBestWeapon, ClientSetWeapon; reliable if ( (!bDemoRecording || (bClientDemoRecording && bClientDemoNetFunc)) && Role == ROLE_Authority ) ClientVoiceMessage; // Functions the client calls on the server. unreliable if( Role GoalClass, optional bool bWeightDetours); native(525) final function NavigationPoint FindRandomDest(); native(523) final function vector EAdjustJump(float BaseZ, float XYSpeed); //Reachable returns whether direct path from Actor to aPoint is traversable //using the current locomotion method native(521) final function bool pointReachable(vector aPoint); native(520) final function bool actorReachable(actor anActor); /* PickWallAdjust() Check if could jump up over obstruction (only if there is a knee height obstruction) If so, start jump, and return current destination Else, try to step around - return a destination 90 degrees right or left depending on traces out and floor checks */ native(526) final function bool PickWallAdjust(vector HitNormal); /* WaitForLanding() latent function returns when pawn is on ground (no longer falling) */ native(527) final latent function WaitForLanding(); native(540) final function actor FindBestInventoryPath(out float MinWeight); native final function actor FindBestSuperPickup(float MaxDist); // find nearest super pickup (base has bDelayedSpawn=true) native(529) final function AddController(); native(530) final function RemoveController(); // Pick best pawn target native(531) final function pawn PickTarget(out float bestAim, out float bestDist, vector FireDir, vector projStart, float MaxRange); native(534) final function actor PickAnyTarget(out float bestAim, out float bestDist, vector FireDir, vector projStart); native final function bool InLatentExecution(int LatentActionNumber); //returns true if controller currently performing latent action specified by LatentActionNumber // Force end to sleep native function StopWaiting(); native function EndClimbLadder(); native final function bool CanMakePathTo(Actor A); // assumes valid CurrentPath, tries to see if CurrentPath can be combine with path to N event MayFall(); //return true if allowed to fall - called by engine when pawn is about to fall event MayDodgeToMoveTarget(); event MissedDodge(); function PendingStasis() { bStasis = true; Pawn = None; } // ----- combos ----- // function AwardAdrenaline(float Amount) { if ( bAdrenalineEnabled ) { Adrenaline += Amount; Adrenaline = Clamp( Adrenaline, 0, AdrenalineMax ); } } function bool NeedsAdrenaline() { return ( (Pawn != None) && !Pawn.InCurrentCombo() && (Adrenaline < AdrenalineMax) ); } /* DisplayDebug() list important controller attributes on canvas */ function DisplayDebug(Canvas Canvas, out float YL, out float YPos) { local string DebugString; if ( Pawn == None ) { Super.DisplayDebug(Canvas,YL,YPos); return; } Canvas.SetDrawColor(255,0,0); Canvas.DrawText("CONTROLLER "$GetItemName(string(self))$" Pawn "$GetItemName(string(Pawn))$" viewpitch "$Rotation.Pitch); YPos += YL; Canvas.SetPos(4,YPos); if ( Enemy != None ) Canvas.DrawText(" STATE: "$GetStateName()$" Timer: "$TimerCounter$" Enemy "$Enemy.GetHumanReadableName(), false); else Canvas.DrawText(" STATE: "$GetStateName()$" Timer: "$TimerCounter$" NO Enemy ", false); YPos += YL; Canvas.SetPos(4,YPos); if ( MonitoredPawn != None ) DebugString $= " MonitoredPawn: "@MonitoredPawn.GetHumanReadableName(); else DebugString $= " MonitoredPawn: None"; if ( Target != None ) DebugString $= " Target: "@Target.GetHumanReadableName(); else DebugString $= " Target: None"; Canvas.DrawText(DebugString); YPos += YL; Canvas.SetPos(4,YPos); if ( PlayerReplicationInfo == None ) Canvas.DrawText(" NO PLAYERREPLICATIONINFO", false); else PlayerReplicationInfo.DisplayDebug(Canvas,YL,YPos); YPos += YL; Canvas.SetPos(4,YPos); } simulated function String GetHumanReadableName() { if ( PlayerReplicationInfo != None ) return PlayerReplicationInfo.PlayerName; return GetItemName(String(self)); } simulated function rotator GetViewRotation() { return Rotation; } /* Reset() reset actor to initial state */ function Reset() { super.Reset(); Enemy = None; LastSeenTime = 0; StartSpot = None; Adrenaline = 0; bAdjusting = false; bPreparingMove = false; bJumpOverWall = false; bEnemyAcquired = false; bHuntPlayer = false; bInDodgeMove = false; MoveTimer = -1; MoveTarget = None; PendingMover = None; CurrentPath = None; RouteGoal = None; MonitoredPawn = None; WarningProjectile = None; } function bool AvoidCertainDeath() { return false; } /* ClientSetLocation() replicated function to set location and rotation. Allows server to force new location for teleports, etc. */ function ClientSetLocation( vector NewLocation, rotator NewRotation ) { SetRotation(NewRotation); If ( (Rotation.Pitch > RotationRate.Pitch) && (Rotation.Pitch < 65536 - RotationRate.Pitch) ) { If (Rotation.Pitch < 32768) NewRotation.Pitch = RotationRate.Pitch; else NewRotation.Pitch = 65536 - RotationRate.Pitch; } if ( Pawn != None ) { NewRotation.Roll = 0; Pawn.SetRotation( NewRotation ); Pawn.SetLocation( NewLocation ); } } /* ClientSetRotation() replicated function to set rotation. Allows server to force new rotation. */ function ClientSetRotation( rotator NewRotation ) { SetRotation(NewRotation); if ( Pawn != None ) { NewRotation.Pitch = 0; NewRotation.Roll = 0; Pawn.SetRotation( NewRotation ); } } function ClientDying(class DamageType, vector HitLocation) { if ( Pawn != None ) { Pawn.PlayDying(DamageType, HitLocation); Pawn.GotoState('Dying'); } } /* AIHearSound() Called when AI controlled pawn would hear a sound. Default AI implementation uses MakeNoise() interface for hearing appropriate sounds instead */ event AIHearSound ( actor Actor, int Id, sound S, vector SoundLocation, vector Parameters, bool Attenuate ); event SoakStop(string problem); function Possess(Pawn aPawn) { aPawn.PossessedBy(self); Pawn = aPawn; if ( PlayerReplicationInfo != None ) { if ( Vehicle(Pawn) != None && Vehicle(Pawn).Driver != None ) PlayerReplicationInfo.bIsFemale = Vehicle(Pawn).Driver.bIsFemale; else PlayerReplicationInfo.bIsFemale = Pawn.bIsFemale; } // preserve Pawn's rotation initially for placed Pawns FocalPoint = Pawn.Location + 512*vector(Pawn.Rotation); Restart(); } // unpossessed a pawn (not because pawn was killed) function UnPossess() { if ( Pawn != None ) Pawn.UnPossessed(); Pawn = None; } function WasKilledBy(Controller Other); function class GetLastWeapon() { if ( (Pawn == None) || (Pawn.Weapon == None) ) return LastPawnWeapon; return Pawn.Weapon.Class; } /* PawnDied() unpossess a pawn (because pawn was killed) */ function PawnDied(Pawn P) { if ( Pawn != P ) return; if ( Pawn != None ) { if ( Pawn.InCurrentCombo() ) Adrenaline = 0; SetLocation(Pawn.Location); Pawn.UnPossessed(); } Pawn = None; PendingMover = None; if ( bIsPlayer ) { if ( !IsInState('GameEnded') && !IsInState('RoundEnded') ) GotoState('Dead'); // can respawn } else Destroy(); } function Restart() { Enemy = None; } event LongFall(); // called when latent function WaitForLanding() doesn't return after 4 seconds // notifications of pawn events (from C++) // if return true, then pawn won't get notified event bool NotifyPhysicsVolumeChange(PhysicsVolume NewVolume); event bool NotifyHeadVolumeChange(PhysicsVolume NewVolume); event bool NotifyLanded(vector HitNormal); event NotifyPostLanded(); event bool NotifyHitWall(vector HitNormal, actor Wall); event NotifyFallingHitWall(vector HitNormal, actor Wall); // only if bNotifyFallingHitWall is set event bool NotifyBump(Actor Other); event NotifyHitMover(vector HitNormal, mover Wall); event NotifyJumpApex(); event NotifyMissedJump(); function SetDoubleJump(); // notifications called by pawn in script function NotifyAddInventory(inventory NewItem); function NotifyTakeHit(pawn InstigatedBy, vector HitLocation, int Damage, class damageType, vector Momentum) { if ( (instigatedBy != None) && (instigatedBy != pawn) ) damageAttitudeTo(instigatedBy, Damage); } function SetFall(); //about to fall function PawnIsInPain(PhysicsVolume PainVolume); // called when pawn is taking pain volume damage event PreBeginPlay() { AddController(); Super.PreBeginPlay(); if ( bDeleteMe ) return; SightCounter = 0.2 * FRand(); //offset randomly } event PostBeginPlay() { Super.PostBeginPlay(); if ( !bDeleteMe && bIsPlayer && (Level.NetMode != NM_Client) ) { PlayerReplicationInfo = Spawn(PlayerReplicationInfoClass, Self,,vect(0,0,0),rot(0,0,0)); InitPlayerReplicationInfo(); } } function InitPlayerReplicationInfo() { if (PlayerReplicationInfo.PlayerName == "") PlayerReplicationInfo.SetPlayerName(class'GameInfo'.Default.DefaultPlayerName); PlayerReplicationInfo.bNoTeam = !Level.Game.bTeamGame; } simulated function int GetTeamNum() { if ( (PlayerReplicationInfo == None) || (PlayerReplicationInfo.Team == None) ) return 255; return PlayerReplicationInfo.Team.TeamIndex; } function bool SameTeamAs(Controller C) { if ( C == None ) return false; return Level.Game.IsOnTeam(C,GetTeamNum()); } function HandlePickup(Pickup pick) { if ( MoveTarget == pick ) { if ( pick.MyMarker != None ) { MoveTarget = pick.MyMarker; Pawn.Anchor = pick.MyMarker; MoveTimer = 0.5; } else MoveTimer = -1.0; } } simulated event Destroyed() { if ( Role < ROLE_Authority ) { Super.Destroyed(); return; } RemoveController(); if ( bIsPlayer && (Level.Game != None) ) Level.Game.logout(self); if ( PlayerReplicationInfo != None ) { if ( !PlayerReplicationInfo.bOnlySpectator && (PlayerReplicationInfo.Team != None) ) PlayerReplicationInfo.Team.RemoveFromTeam(self); PlayerReplicationInfo.Destroy(); } Super.Destroyed(); } event bool AllowDetourTo(NavigationPoint N) { return true; } /* AdjustView() by default, check and see if pawn still needs to update eye height (only if some playercontroller still has pawn as its viewtarget) Overridden in playercontroller */ function AdjustView( float DeltaTime ) { local Controller C; for ( C=Level.ControllerList; C!=None; C=C.NextController ) if ( C.IsA('PlayerController') && (PlayerController(C).ViewTarget == Pawn) ) return; Pawn.bUpdateEyeHeight =false; Pawn.Eyeheight = Pawn.BaseEyeheight; } function bool WantsSmoothedView() { return ( (Pawn != None) && ((Pawn.Physics==PHYS_Walking) || (Pawn.Physics==PHYS_Spider)) && !Pawn.bJustLanded ); } function GameHasEnded() { if ( Pawn != None ) Pawn.bNoWeaponFiring = true; GotoState('GameEnded'); } function ClientGameEnded() { GotoState('GameEnded'); } function RoundHasEnded() { if ( Pawn != None ) Pawn.bNoWeaponFiring = true; GotoState('RoundEnded'); } function ClientRoundEnded() { GotoState('RoundEnded'); } simulated event RenderOverlays( canvas Canvas ); /* GetFacingDirection() returns direction faced relative to movement dir 0 = forward 16384 = right 32768 = back 49152 = left */ function int GetFacingDirection() { return 0; } //------------------------------------------------------------------------------ // Speech related function byte GetMessageIndex(name PhraseName) { return 0; } function SendMessage(PlayerReplicationInfo Recipient, name MessageType, byte MessageID, float Wait, name BroadcastType) { SendVoiceMessage(PlayerReplicationInfo, Recipient, MessageType, MessageID, BroadcastType); } function bool AllowVoiceMessage(name MessageType) { if ( Level.TimeSeconds - OldMessageTime < 10 ) return false; else OldMessageTime = Level.TimeSeconds; return true; } function SendVoiceMessage(PlayerReplicationInfo Sender, PlayerReplicationInfo Recipient, name messagetype, byte messageID, name broadcasttype) { local Controller P; if ( ((Recipient == None) || (AIController(self) == None)) && !AllowVoiceMessage(MessageType) ) return; for ( P=Level.ControllerList; P!=None; P=P.NextController ) { if ( PlayerController(P) != None ) { if ((P.PlayerReplicationInfo == Sender) || (P.PlayerReplicationInfo == Recipient && (Level.Game.BroadcastHandler == None || Level.Game.BroadcastHandler.AcceptBroadcastSpeech(PlayerController(P), Sender))) ) P.ClientVoiceMessage(Sender, Recipient, messagetype, messageID); else if ( (Recipient == None) || (Level.NetMode == NM_Standalone) ) { if ( (broadcasttype == 'GLOBAL') || !Level.Game.bTeamGame || (Sender.Team == P.PlayerReplicationInfo.Team) ) if ( Level.Game.BroadcastHandler == None || Level.Game.BroadcastHandler.AcceptBroadcastSpeech(PlayerController(P), Sender) ) P.ClientVoiceMessage(Sender, Recipient, messagetype, messageID); } } else if ( (messagetype == 'ORDER') && ((Recipient == None) || (Recipient == P.PlayerReplicationInfo)) ) P.BotVoiceMessage(messagetype, messageID, self); } } function ClientVoiceMessage(PlayerReplicationInfo Sender, PlayerReplicationInfo Recipient, name messagetype, byte messageID); function BotVoiceMessage(name messagetype, byte MessageID, Controller Sender); //*************************************************************** // interface used by ScriptedControllers to query pending controllers function bool WouldReactToNoise( float Loudness, Actor NoiseMaker) { return false; } function bool WouldReactToSeeing(Pawn Seen) { return false; } //*************************************************************** // AI related /* AdjustToss() return adjustment to Z component of aiming vector to compensate for arc given the target distance */ function vector AdjustToss(float TSpeed, vector Start, vector End, bool bNormalize) { local vector Dest2D, Result, Vel2D; local float Dist2D; if ( Start.Z > End.Z + 64 ) { Dest2D = End; Dest2D.Z = Start.Z; Dist2D = VSize(Dest2D - Start); TSpeed *= Dist2D/VSize(End - Start); Result = SuggestFallVelocity(Dest2D,Start,TSpeed,TSpeed); Vel2D = result; Vel2D.Z = 0; Result.Z = Result.Z + (End.Z - Start.Z) * VSize(Vel2D)/Dist2D; } else { Result = SuggestFallVelocity(End,Start,TSpeed,TSpeed); } if ( bNormalize ) return TSpeed * Normal(Result); else return Result; } event PrepareForMove(NavigationPoint Goal, ReachSpec Path); function WaitForMover(Mover M); function MoverFinished(); function UnderLift(Mover M); function FearThisSpot(AvoidMarker aSpot) { local int i; if ( Pawn == None ) return; if ( !LineOfSightTo(aSpot) ) return; for ( i=0; i<2; i++ ) if ( FearSpots[i] == None ) { FearSpots[i] = aSpot; return; } for ( i=0; i<2; i++ ) if ( VSize(Pawn.Location - FearSpots[i].Location) > VSize(Pawn.Location - aSpot.Location) ) { FearSpots[i] = aSpot; return; } } event float Desireability(Pickup P) { return P.BotDesireability(Pawn); } event float SuperDesireability(Pickup P) { return P.BotDesireability(Pawn); } /* called before start of navigation network traversal to allow setup of transient navigation flags */ event SetupSpecialPathAbilities(); event HearNoise( float Loudness, Actor NoiseMaker); event SeePlayer( Pawn Seen ); // called when a player (bIsPlayer==true) pawn is seen event SeeMonster( Pawn Seen ); // called when a non-player (bIsPlayer==false) pawn is seen event EnemyNotVisible(); function DamageShake(int damage); function ShakeView(vector shRotMag, vector shRotRate, float shRotTime, vector shOffsetMag, vector shOffsetRate, float shOffsetTime); function NotifyKilled(Controller Killer, Controller Killed, pawn Other) { if ( Enemy == Other ) Enemy = None; } function damageAttitudeTo(pawn Other, float Damage); function float AdjustDesireFor(Pickup P); function bool FireWeaponAt(Actor A); function StopFiring() { if ( Pawn != None ) Pawn.StopWeaponFiring(); bFire = 0; bAltFire = 0; } simulated function float RateWeapon(Weapon w) { return w.Default.Priority; } function float WeaponPreference(Weapon W) { return 0.0; } /* AdjustAim() AIController version does adjustment for non-controlled pawns. PlayerController version does the adjustment for player aiming help. Only adjusts aiming at pawns allows more error in Z direction (full as defined by AutoAim - only half that difference for XY) */ function rotator AdjustAim(FireProperties FiredAmmunition, vector projStart, int aimerror) { return Rotation; } function InstantWarnTarget(Actor Target, FireProperties FiredAmmunition, vector FireDir) { local float Dist; if ( FiredAmmunition.bInstantHit && (Pawn(Target) != None) && (Pawn(Target).Controller != None) ) { Dist = VSize(Pawn.Location - Target.Location); if ( VSize(FireDir * Dist - Target.Location) < Target.CollisionRadius ) return; if ( FRand() < FiredAmmunition.WarnTargetPct ) Pawn(Target).Controller.ReceiveWarning(Pawn, -1, FireDir); return; } } /* ReceiveWarning() AI controlled creatures may duck if not falling, and projectile time is long enough often pick opposite to current direction (relative to shooter axis) */ event ReceiveWarning(Pawn shooter, float projSpeed, vector FireDir); function ReceiveProjectileWarning(Projectile proj) { if ( WarningProjectile == None ) ReceiveWarning(Proj.Instigator, Proj.speed, Normal(Proj.Velocity)); } /* If ReceiveWarning caused WarningDelay to be set, this will be called when it times out */ event DelayedWarning(); exec function SwitchToBestWeapon() { local float rating; if ( Pawn == None || Pawn.Inventory == None ) return; if ( (Pawn.PendingWeapon == None) || (AIController(self) != None) ) { Pawn.PendingWeapon = Pawn.Inventory.RecommendWeapon(rating); if ( Pawn.PendingWeapon == Pawn.Weapon ) Pawn.PendingWeapon = None; if ( Pawn.PendingWeapon == None ) return; } StopFiring(); if ( Pawn.Weapon == None ) Pawn.ChangedWeapon(); else if ( Pawn.Weapon != Pawn.PendingWeapon ) { Pawn.Weapon.PutDown(); } } // server calls this to force client to switch function ClientSwitchToBestWeapon() { SwitchToBestWeapon(); } function ClientSetWeapon( class WeaponClass ) { local Inventory Inv; local int Count; for( Inv = Pawn.Inventory; Inv != None; Inv = Inv.Inventory ) { Count++; if ( Count > 1000 ) return; if( !ClassIsChildOf( Inv.Class, WeaponClass ) ) continue; if( Pawn.Weapon == None ) { Pawn.PendingWeapon = Weapon(Inv); Pawn.ChangedWeapon(); } else if ( Pawn.Weapon != Weapon(Inv) ) { Pawn.PendingWeapon = Weapon(Inv); Pawn.Weapon.PutDown(); } return; } } function SetPawnClass(string inClass, string inCharacter) { local class pClass; if ( inClass == "" ) return; pClass = class(DynamicLoadObject(inClass, class'Class')); if ( pClass != None ) PawnClass = pClass; } function SetPawnFemale(); function bool CheckFutureSight(float DeltaTime) { return true; } function ChangedWeapon() { if ( Pawn.Weapon != None ) LastPawnWeapon = Pawn.Weapon.Class; } function ServerReStartPlayer() { if ( Level.NetMode == NM_Client ) return; if ( Pawn != None ) ServerGivePawn(); } function ServerGivePawn(); event MonitoredPawnAlert(); function StartMonitoring(Pawn P, float MaxDist) { MonitoredPawn = P; MonitorStartLoc = P.Location; MonitorMaxDistSq = MaxDist * MaxDist; } function bool AutoTaunt() { return false; } function bool DontReuseTaunt(int T) { return false; } // - ParseChatPercVar should be subclassed if a controller needs more of them function string ParseChatPercVar(string Cmd) { if (cmd~="%A") // Adrenaline return int(Adrenaline)@"Adrenaline"; if ( (Pawn != None) && (cmd~="%S") ) // Shield return int(Pawn.ShieldStrength)@"Shield"; return Cmd; } // ********************************************** // Controller States State Dead { ignores SeePlayer, HearNoise, KilledBy; function PawnDied(Pawn P) { if ( Level.NetMode != NM_Client ) warn(self$" Pawndied while dead"); } function ServerReStartPlayer() { if ( Level.NetMode == NM_Client ) return; Level.Game.RestartPlayer(self); } } state GameEnded { ignores SeePlayer, HearNoise, KilledBy, NotifyBump, HitWall, NotifyPhysicsVolumeChange, NotifyHeadVolumeChange, Falling, TakeDamage, ReceiveWarning; function BeginState() { if ( Pawn != None ) { if ( Pawn.Weapon != None ) Pawn.Weapon.HolderDied(); Pawn.SimAnim.AnimRate = 0; Pawn.TurnOff(); Pawn.UnPossessed(); Pawn = None; } if ( !bIsPlayer ) Destroy(); } } state RoundEnded { ignores SeePlayer, HearNoise, KilledBy, NotifyBump, HitWall, NotifyPhysicsVolumeChange, NotifyHeadVolumeChange, Falling, TakeDamage, ReceiveWarning; function BeginState() { if ( Pawn != None ) { if ( Pawn.Weapon != None ) Pawn.Weapon.HolderDied(); Pawn.SimAnim.AnimRate = 0; Pawn.TurnOff(); Pawn.UnPossessed(); Pawn = None; } if ( !bIsPlayer ) Destroy(); } } sTssAssVAsAsB~ sss[)s\)s])s^)s_)s`)sa)sb)sc)sd)se)sf)sg)sh)si)sj)sk)sl)sm)sn)so)sp)sq)sr)ss)st)su)sv)sw)sx)sy ss ss{,ss|ss}ss~ss~ssAssz1sC1s1sE@ ssG1Fss.sH0ss s.sJ1.sK1sL1sM1sN1sO ss ss}class ConstantMaterial extends RenderedMaterial editinlinenew abstract native; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) sVpsCclass ConstantColor extends ConstantMaterial native editinlinenew; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) var() Color Color; s[ 5sU//============================================================================= // Console: handles command input and manages menus. // Copyright 2001 Digital Extremes - All Rights Reserved. // Confidential. class Console extends Interaction; var config byte ConsoleHotKey; // The key used to bring the console up. var int HistoryTop, HistoryBot, HistoryCur; var string TypedStr, History[16]; // Holds the current command, and the history var int TypedStrPos; //Current position in TypedStr var bool bTyping; // Turn when someone is typing on the console var bool bIgnoreKeys; // Ignore Key presses until a new KeyDown is received var() transient bool bRunningDemo; var() transient bool bHoldingStart; var() transient bool bHoldingBack; var() transient float TimeIdle; // Time since last input. var() transient float TimeHoldingReboot; // If start+back are held for this long it'll reboot. var() globalconfig float TimePerTitle; // Time spent at title screen. var() globalconfig float TimePerDemo; // Time spent running in attract mode. var() globalconfig float TimeTooIdle; // Time allowed idle players in locked interactive demo. var() globalconfig float TimeBeforeReboot; // If start+back are held for this long it'll reboot. var() globalconfig float TimePerSoak; // TimePerDemo while soaking. var() globalconfig String DemoLevels[64]; var array BufferedConsoleCommands; // If this is blank, perform the command at Tick event Initialized() { if( IsSoaking() ) { TimePerTitle = 1; TimePerDemo = TimePerSoak; } } event ViewportInitialized() { if ( ViewportOwner.ConfiguredInternetSpeed == 0 ) ViewportOwner.ResetConfig("ConfiguredInternetSpeed"); if ( ViewportOwner.ConfiguredLanSpeed == 0 ) ViewportOwner.ResetConfig("ConfiguredLanSpeed"); } event NativeConsoleOpen() { } function UnPressButtons() { local PlayerController PC; if (ViewportOwner != none) { PC = ViewportOwner.Actor; if ( PC != None ) PC.UnPressButtons(); } } exec function Type() { TypedStr=""; TypedStrPos=0; TypingOpen(); } exec function Talk() { TypedStr="Say "; TypedStrPos=4; TypingOpen(); } exec function TeamTalk() { TypedStr="TeamSay "; TypedStrPos=8; TypingOpen(); } exec function ConsoleOpen(); exec function ConsoleClose(); exec function ConsoleToggle(); exec function StartRollingDemo() { local int i, tryCount; return; TimeIdle = 0; tryCount = 1024; do { i = int ( FRand() * float (ArrayCount(DemoLevels)) ); tryCount--; if (tryCount < 0) { log ("Couldn't find a random level to StartRollingDemo", 'Error'); return; } } until (DemoLevels[i] != "") bRunningDemo = true; if( InStr( DemoLevels[i], "NumBots" ) >= 0 ) ViewportOwner.Actor.ClientTravel( DemoLevels[i] $ "?SpectatorOnly=1", TRAVEL_Absolute, false ); else ViewportOwner.Actor.ClientTravel( DemoLevels[i] $ "?SpectatorOnly=1?bAutoNumBots=true", TRAVEL_Absolute, false ); } exec function StopRollingDemo() { bRunningDemo = false; TimeIdle = 0; ConsoleCommand( "DISCONNECT" ); } event NotifyLevelChange() { ConsoleClose(); } function DelayedConsoleCommand(string command) { BufferedConsoleCommands.Length = BufferedConsoleCommands.Length+1; BufferedConsoleCommands[BufferedConsoleCommands.Length-1] = Command; } //----------------------------------------------------------------------------- // Message - By default, the console ignores all output. //----------------------------------------------------------------------------- function Chat(coerce string Msg, float MsgLife, PlayerReplicationInfo PRI); event Message( coerce string Msg, float MsgLife); event bool KeyEvent( EInputKey Key, EInputAction Action, FLOAT Delta ) { if (Action!=IST_Press) return false; if (Key==ConsoleHotKey && Action==IST_Release) { ConsoleOpen(); return true; } if( Action == IST_Press ) { TimeIdle = 0; if( bRunningDemo && !IsSoaking() ) { StopRollingDemo(); return( true ); } } return( false ); } //----------------------------------------------------------------------------- // State used while typing a command on the console. function TypingOpen() { bTyping = true; if( (ViewportOwner != None) && (ViewportOwner.Actor != None) ) ViewportOwner.Actor.Typing( bTyping ); //TypedStr = ""; GotoState('Typing'); } function TypingClose() { bTyping = false; if( (ViewportOwner != None) && (ViewportOwner.Actor != None) ) ViewportOwner.Actor.Typing( bTyping ); TypedStr=""; TypedStrPos=0; if( GetStateName() == 'Typing' ) GotoState( '' ); } state Typing { exec function Type() { TypedStr=""; TypedStrPos=0; TypingClose(); } function bool KeyType( EInputKey Key, optional string Unicode ) { if (bIgnoreKeys) return true; if( Key>=0x20 ) { if( Unicode != "" ) TypedStr = Left(TypedStr, TypedStrPos) $ Unicode $ Right(TypedStr, Len(TypedStr) - TypedStrPos); else TypedStr = Left(TypedStr, TypedStrPos) $ Chr(Key) $ Right(TypedStr, Len(TypedStr) - TypedStrPos); TypedStrPos++; return( true ); } return false; } function bool KeyEvent( EInputKey Key, EInputAction Action, FLOAT Delta ) { local string Temp; if (Action== IST_PRess) { bIgnoreKeys=false; } if( Key==IK_Escape ) { if( TypedStr!="" ) { TypedStr=""; TypedStrPos=0; HistoryCur = HistoryTop; return( true ); } else { TypingClose(); return( true ); } } else if( Action != IST_Press ) { return( false ); } else if( Key==IK_Enter ) { if( TypedStr!="" ) { History[HistoryTop] = TypedStr; HistoryTop = (HistoryTop+1) % ArrayCount(History); if ( ( HistoryBot == -1) || ( HistoryBot == HistoryTop ) ) HistoryBot = (HistoryBot+1) % ArrayCount(History); HistoryCur = HistoryTop; // Make a local copy of the string. Temp=TypedStr; TypedStr=""; TypedStrPos=0; if( !ConsoleCommand( Temp ) ) Message( Localize("Errors","Exec","Core"), 6.0 ); Message( "", 6.0 ); } TypingClose(); return( true ); } else if( Key==IK_Up ) { if ( HistoryBot >= 0 ) { if (HistoryCur == HistoryBot) HistoryCur = HistoryTop; else { HistoryCur--; if (HistoryCur<0) HistoryCur = ArrayCount(History)-1; } TypedStr = History[HistoryCur]; TypedStrPos = Len(TypedStr); } return( true ); } else if( Key==IK_Down ) { if ( HistoryBot >= 0 ) { if (HistoryCur == HistoryTop) HistoryCur = HistoryBot; else HistoryCur = (HistoryCur+1) % ArrayCount(History); TypedStr = History[HistoryCur]; TypedStrPos = Len(TypedStr); } } else if( Key==IK_Backspace ) { if( TypedStrPos > 0 ) { TypedStr = Left(TypedStr,TypedStrPos-1)$Right(TypedStr, Len(TypedStr) - TypedStrPos); TypedStrPos--; } return( true ); } else if ( Key==IK_Delete ) { if ( TypedStrPos < Len(TypedStr) ) TypedStr = Left(TypedStr,TypedStrPos)$Right(TypedStr, Len(TypedStr) - TypedStrPos - 1); return true; } else if ( Key==IK_Left ) { TypedStrPos = Max(0, TypedStrPos - 1); return true; } else if ( Key==IK_Right ) { TypedStrPos = Min(Len(TypedStr), TypedStrPos + 1); return true; } else if ( Key==IK_Home ) { TypedStrPos = 0; return true; } else if ( Key==IK_End ) { TypedStrPos = Len(TypedStr); return true; } return( true ); } function BeginState() { bTyping = true; bVisible= true; bIgnoreKeys = true; HistoryCur = HistoryTop; } function EndState() { ConsoleCommand("toggleime 0"); bTyping = false; bVisible = false; } } simulated event Tick( float Delta ) { while (BufferedConsoleCommands.Length>0) { ViewportOwner.Actor.ConsoleCommand(BufferedConsoleCommands[0]); BufferedConsoleCommands.Remove(0,1); } /* if( bRunningDemo ) { if( (TimePerDemo > 0.0) && (TimeIdle > TimePerDemo) && (curMenu == None) ) StopRollingDemo(); } else if ( (ViewportOwner.Actor.Level == ViewportOwner.Actor.GetEntryLevel()) && (curMenu != None) && (curMenu.IsA('MenuMain')) && (ViewportOwner.Actor.Level.LevelAction == LEVACT_None) && (ViewportOwner.Actor.Level.Pauser == None) ) { if ( (TimePerTitle > 0.0) && (TimeIdle > TimePerTitle) ) StartRollingDemo(); } */ } event ConnectFailure(string FailCode,string URL); function SetMusic(string NewSong); function string SetInitialMusic(string NewSong) { return NewSong; } sd class Combiner extends Material editinlinenew native; enum EColorOperation { CO_Use_Color_From_Material1, CO_Use_Color_From_Material2, CO_Multiply, CO_Add, CO_Subtract, CO_AlphaBlend_With_Mask, CO_Add_With_Mask_Modulation, CO_Use_Color_From_Mask, }; enum EAlphaOperation { AO_Use_Mask, AO_Multiply, AO_Add, AO_Use_Alpha_From_Material1, AO_Use_Alpha_From_Material2, }; var int combiner_dummy; // hammer padding. --ryan. var() EColorOperation CombineOperation; var() EAlphaOperation AlphaOperation; var() editinlineuse Material Material1; var() editinlineuse Material Material2; var() editinlineuse Material Mask; var() bool InvertMask; var() bool Modulate2X; var() bool Modulate4X; sS 7sPclass ColorModifier extends Modifier noteditinlinenew native; var() color Color; var() bool RenderTwoSided; var() bool AlphaBlend; s@ssO //============================================================================= // ClipMarker. // // These are markers for the brush clip mode. You place 2 or 3 of these in // the level and that defines your clipping plane. // // These should NOT be manually added to the level. The editor adds and // deletes them on it's own. // //============================================================================= class ClipMarker extends Keypoint placeable native; #exec Texture Import File=Textures\S_ClipMarker.pcx Name=S_ClipMarker Mips=Off MASKED=1 #exec Texture Import File=Textures\S_ClipMarker1.pcx Name=S_ClipMarker1 Mips=Off MASKED=1 #exec Texture Import File=Textures\S_ClipMarker2.pcx Name=S_ClipMarker2 Mips=Off MASKED=1 #exec Texture Import File=Textures\S_ClipMarker3.pcx Name=S_ClipMarker3 Mips=Off MASKED=1 sV 4scB*a!7 B** Gs]@ss@*@ss@dbsD//============================================================================= // CheatManager // Object within playercontroller that manages "cheat" commands // only spawned in single player mode //============================================================================= class CheatManager extends Object within PlayerController native; var rotator LockedRotation; var bool bCheatsEnabled; /* Used for correlating game situation with log file */ exec function ReviewJumpSpots(name TestLabel) { if ( TestLabel == 'Transloc' ) TestLabel = 'Begin'; else if ( TestLabel == 'Jump' ) TestLabel = 'Finished'; else if ( TestLabel == 'Combo' ) TestLabel = 'FinishedJumping'; else if ( TestLabel == 'LowGrav' ) TestLabel = 'FinishedComboJumping'; log("TestLabel is "$TestLabel); Level.Game.ReviewJumpSpots(TestLabel); } exec function ListDynamicActors() { local Actor A; local int i; ForEach DynamicActors(class'Actor',A) { i++; log(i@A); } log("Num dynamic actors: "$i); } exec function FreezeFrame(float delay) { Level.Game.SetPause(true,outer); Level.PauseDelay = Level.TimeSeconds + delay; } exec function WriteToLog( string Param ) { log("NOW!" $ Eval(Param != "", " '" $ Param $ "'", "")); } exec function SetFlash(float F) { FlashScale.X = F; } exec function SetFogR(float F) { FlashFog.X = F; } exec function SetFogG(float F) { FlashFog.Y = F; } exec function SetFogB(float F) { FlashFog.Z = F; } exec function KillViewedActor() { if ( ViewTarget != None ) { if ( (Pawn(ViewTarget) != None) && (Pawn(ViewTarget).Controller != None) ) Pawn(ViewTarget).Controller.Destroy(); ViewTarget.Destroy(); SetViewTarget(None); ReportCheat("KillViewedActor"); } } /* LogScriptedSequences() Toggles logging of scripted sequences on and off */ exec function LogScriptedSequences() { local AIScript S; ForEach AllActors(class'AIScript',S) S.bLoggingEnabled = !S.bLoggingEnabled; } /* Teleport() Teleport to surface player is looking at */ exec function Teleport() { local actor HitActor; local vector HitNormal, HitLocation; if (!areCheatsEnabled()) return; HitActor = Trace(HitLocation, HitNormal, ViewTarget.Location + 10000 * vector(Rotation),ViewTarget.Location, true); if ( HitActor == None ) HitLocation = ViewTarget.Location + 10000 * vector(Rotation); else HitLocation = HitLocation + ViewTarget.CollisionRadius * HitNormal; ViewTarget.SetLocation(HitLocation); ReportCheat("Teleport"); } /* Scale the player's size to be F * default size */ exec function ChangeSize( float F ) { if ( Pawn.SetCollisionSize(Pawn.Default.CollisionRadius * F,Pawn.Default.CollisionHeight * F) ) { Pawn.SetDrawScale(F); Pawn.SetLocation(Pawn.Location); } } exec function LockCamera() { local vector LockedLocation; local rotator LockedRot; local actor LockedActor; if ( !bCameraPositionLocked ) { PlayerCalcView(LockedActor,LockedLocation,LockedRot); Outer.SetLocation(LockedLocation); LockedRotation = LockedRot; SetViewTarget(outer); } else SetViewTarget(Pawn); bCameraPositionLocked = !bCameraPositionLocked; bBehindView = bCameraPositionLocked; bFreeCamera = false; } exec function SetCameraDist( float F ) { CameraDist = FMax(F,2); } /* Stop interpolation */ exec function EndPath() { } /* Camera and pawn aren't rotated together in behindview when bFreeCamera is true */ exec function FreeCamera( bool B ) { bFreeCamera = B; bBehindView = B; } exec function CauseEvent( name EventName ) { TriggerEvent( EventName, Pawn, Pawn); } exec function Amphibious() { if (!areCheatsEnabled()) return; Pawn.UnderwaterTime = +999999.0; ReportCheat("Amphibious"); } exec function Fly() { if (!areCheatsEnabled()) return; if ( (Pawn != None) && Pawn.CheatFly() ) { ClientMessage("You feel much lighter"); bCheatFlying = true; Outer.GotoState('PlayerFlying'); ReportCheat("Fly"); } } exec function Walk() { bCheatFlying = false; if ( (Pawn != None) && Pawn.CheatWalk() ) ClientReStart(Pawn); } exec function Ghost() { if (!areCheatsEnabled()) return; if ( (Pawn != None) && Pawn.CheatGhost() ) { ClientMessage("You feel ethereal"); bCheatFlying = true; Outer.GotoState('PlayerFlying'); ReportCheat("Ghost"); } } exec function AllAmmo() { local Inventory Inv; if (!areCheatsEnabled()) return; for( Inv=Pawn.Inventory; Inv!=None; Inv=Inv.Inventory ) if ( Weapon(Inv)!=None ) Weapon(Inv).SuperMaxOutAmmo(); AwardAdrenaline( 999 ); ReportCheat("AllAmmo"); } exec function Invisible(bool B) { if (!areCheatsEnabled()) return; Pawn.bHidden = B; if (B) Pawn.Visibility = 0; else Pawn.Visibility = Pawn.Default.Visibility; ReportCheat("Invisible"); } exec function Phil() { if (!areCheatsEnabled()) return; if( !bGodMode ) { bGodMode = true; ClientMessage("phil == god"); ReportCheat("God"); } else { bGodMode = false; ClientMessage("you're not phil!"); } } exec function God() { if (!areCheatsEnabled()) return; if ( bGodMode ) { bGodMode = false; ClientMessage("God mode off"); return; } bGodMode = true; ClientMessage("God Mode on"); ReportCheat("God"); } exec function SloMo( float T ) { if (!areCheatsEnabled()) return; Level.Game.SetGameSpeed(T); Level.Game.SaveConfig(); Level.Game.GameReplicationInfo.SaveConfig(); ReportCheat("SloMo"); } exec function SetJumpZ( float F ) { if (!areCheatsEnabled()) return; Pawn.JumpZ = F; ReportCheat("SetJumpZ"); } exec function SetGravity( float F ) { if (!areCheatsEnabled()) return; PhysicsVolume.Gravity.Z = F; ReportCheat("SetGravity"); } exec function SetSpeed( float F ) { if (!areCheatsEnabled()) return; Pawn.GroundSpeed = Pawn.Default.GroundSpeed * f; Pawn.WaterSpeed = Pawn.Default.WaterSpeed * f; ReportCheat("SetSpeed"); } exec function KillPawns() { if (!areCheatsEnabled()) return; KillAllPawns(class'Pawn'); ReportCheat("KillPawns"); } /* Avatar() Possess a pawn of the requested class */ exec function Avatar( string ClassName ) { local class NewClass; local Pawn P; NewClass = class( DynamicLoadObject( ClassName, class'Class' ) ); if( NewClass!=None ) { Foreach DynamicActors(class'Pawn',P) { if ( (P.Class == NewClass) && (P != Pawn) ) { if ( Pawn.Controller != None ) Pawn.Controller.PawnDied(Pawn); Possess(P); break; } } } } exec function Summon( string ClassName ) { local class NewClass; local vector SpawnLoc; if (!areCheatsEnabled()) return; 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 ); } ReportCheat("Summon"); } exec function PlayersOnly() { if (!areCheatsEnabled()) return; Level.bPlayersOnly = !Level.bPlayersOnly; ReportCheat("PlayersOnly"); } exec function FreezeAll() { if (!areCheatsEnabled()) return; Level.bPlayersOnly = !Level.bPlayersOnly; Level.bFreezeKarma = Level.bPlayersOnly; ReportCheat("FreezeAll"); } exec function ClearAllDebugLines() { local actor A; foreach AllActors(class'Actor', A) A.ClearStayingDebugLines(); } exec function CheatView( class aClass, optional bool bQuiet ) { ViewClass(aClass,bQuiet, true); } // *********************************************************** // Navigation Aids (for testing) // remember spot for path testing (display path using ShowDebug) exec function RememberSpot() { if ( Pawn != None ) Destination = Pawn.Location; else Destination = Location; } // *********************************************************** // Changing viewtarget exec function ViewSelf(optional bool bQuiet) { bBehindView = false; bViewBot = false; if ( Pawn != None ) SetViewTarget(Pawn); else SetViewtarget(outer); if (!bQuiet ) ClientMessage(OwnCamera, 'Event'); FixFOV(); } exec function ViewPlayer( string S ) { local Controller P; for ( P=Level.ControllerList; P!=None; P= P.NextController ) if ( P.bIsPlayer && (P.PlayerReplicationInfo.PlayerName ~= S) ) break; if ( P.Pawn != None ) { ClientMessage(ViewingFrom@P.PlayerReplicationInfo.PlayerName, 'Event'); SetViewTarget(P.Pawn); } bBehindView = ( ViewTarget != Pawn ); if ( bBehindView ) ViewTarget.BecomeViewTarget(); } exec function ViewActor( name ActorName) { local Actor A; ForEach AllActors(class'Actor', A) if ( A.Name == ActorName ) { SetViewTarget(A); bBehindView = true; return; } } exec function ViewFlag() { local Controller C; For ( C=Level.ControllerList; C!=None; C=C.NextController ) if ( C.IsA('AIController') && (C.PlayerReplicationInfo != None) && (C.PlayerReplicationInfo.HasFlag != None) ) { SetViewTarget(C.Pawn); return; } } exec function ViewBot() { local actor first; local bool bFound; local Controller C; bViewBot = true; For ( C=Level.ControllerList; C!=None; C=C.NextController ) if ( C.IsA('Bot') && (C.Pawn != None) ) { if ( bFound || (first == None) ) { first = C; if ( bFound ) break; } if ( C == RealViewTarget ) bFound = true; } if ( first != None ) { SetViewTarget(first); bBehindView = true; ViewTarget.BecomeViewTarget(); FixFOV(); } else ViewSelf(true); } exec function ViewTurret() { local actor first; local bool bFound; local Controller C; bViewBot = true; For ( C=Level.ControllerList; C!=None; C=C.NextController ) if ( C.IsA('AIController') && (C.Pawn != None) && !C.IsA('Bot') ) { if ( bFound || (first == None) ) { first = C.Pawn; if ( bFound ) break; } if ( C.Pawn == ViewTarget ) bFound = true; } if ( first != None ) { SetViewTarget(first); bBehindView = true; ViewTarget.BecomeViewTarget(); FixFOV(); } else ViewSelf(true); } exec function ViewClass( class aClass, optional bool bQuiet, optional bool bCheat ) { local actor other, first; local bool bFound; if ( !bCheat && (Level.Game != None) && !Level.Game.bCanViewOthers ) return; first = None; ForEach AllActors( aClass, other ) { if ( bFound || (first == None) ) { first = other; if ( bFound ) break; } if ( other == ViewTarget ) bFound = true; } if ( first != None ) { if ( !bQuiet ) { if ( Pawn(first) != None ) ClientMessage(ViewingFrom@First.GetHumanReadableName(), 'Event'); else ClientMessage(ViewingFrom@first, 'Event'); } SetViewTarget(first); bBehindView = ( ViewTarget != outer ); if ( bBehindView ) ViewTarget.BecomeViewTarget(); FixFOV(); } else ViewSelf(bQuiet); } exec function Loaded() { local Inventory Inv; if (!areCheatsEnabled()) return; if( Level.Netmode!=NM_Standalone ) return; AllWeapons(); AllAmmo(); if ( Pawn != None ) For ( Inv=Pawn.Inventory; Inv!=None; Inv=Inv.Inventory ) if ( Weapon(Inv) != None ) Weapon(Inv).Loaded(); ReportCheat("Loaded"); } exec function AllWeapons() { if (!areCheatsEnabled()) return; if( (Level.Netmode!=NM_Standalone) || (Pawn == None) || (Vehicle(Pawn) != None) ) return; Pawn.GiveWeapon("XWeapons.AssaultRifle"); Pawn.GiveWeapon("XWeapons.RocketLauncher"); Pawn.GiveWeapon("XWeapons.ShockRifle"); Pawn.GiveWeapon("XWeapons.ShieldGun"); Pawn.GiveWeapon("XWeapons.LinkGun"); Pawn.GiveWeapon("XWeapons.SniperRifle"); Pawn.GiveWeapon("XWeapons.FlakCannon"); Pawn.GiveWeapon("XWeapons.MiniGun"); Pawn.GiveWeapon("XWeapons.TransLauncher"); Pawn.GiveWeapon("XWeapons.Painter"); Pawn.GiveWeapon("XWeapons.BioRifle"); Pawn.GiveWeapon("XWeapons.Redeemer"); Pawn.GiveWeapon("UTClassic.ClassicSniperRifle"); Pawn.GiveWeapon("Onslaught.ONSGrenadeLauncher"); Pawn.GiveWeapon("Onslaught.ONSAVRiL"); Pawn.GiveWeapon("Onslaught.ONSMineLayer"); Pawn.GiveWeapon("OnslaughtFull.ONSPainter"); ReportCheat("AllWeapons"); } // Win and skip the current ladder match, if in single-player mode exec function SkipMatch() { if (!areCheatsEnabled()) return; if( (Level.Netmode!=NM_Standalone) || (Pawn == None) ) return; ReportCheat("SkipMatch"); if ( Level.Game.CurrentGameProfile != none ) { Level.Game.CurrentGameProfile.CheatSkipMatch(Level.Game); } } // jump to a specific match in the ladders // combine the ladder/rung into one number, i.e., 54 = ladder 5, rung 4 exec function JumpMatch(int ladderrung) { if (!areCheatsEnabled()) return; if( (Level.Netmode!=NM_Standalone) || (Pawn == None) ) return; if (ladderrung < 0) { return; } ReportCheat("JumpMatch"); if ( Level.Game.CurrentGameProfile != none ) { Level.Game.CurrentGameProfile.CheatJumpMatch(Level.Game, ladderrung); } } exec function WinMatch() { if (!areCheatsEnabled()) return; ReportCheat("WinMatch"); if (PlayerReplicationInfo.Team != none) { PlayerReplicationInfo.Team.Score = Level.Game.GoalScore; } else { PlayerReplicationInfo.Score = Level.Game.GoalScore; } Level.Game.CheckScore(PlayerReplicationInfo); } exec function EnableCheats() { bCheatsEnabled=true; ClientMessage("Cheats enabled"); } /** check if cheats are enabled, if not playing a SP game always return true */ function bool areCheatsEnabled() { if ( Level.Game.CurrentGameProfile != none ) { if (!bCheatsEnabled) { ClientMessage("Cheats are NOT enabled, to enable cheats type: EnableCheats"); ClientMessage("Enabling cheats prevents you from unlocking the bonus characters"); } return bCheatsEnabled; } return true; } // report the cheat used function ReportCheat(optional string cheat) { if ( Level.Game.CurrentGameProfile != none ) { Level.Game.CurrentGameProfile.ReportCheat(outer, cheat); } } exec function WeakObjectives() { if (!areCheatsEnabled()) return; ReportCheat("WeakObjectives"); Level.Game.WeakObjectives(); } exec function DisableNextObjective() { if (!areCheatsEnabled()) return; ReportCheat("DisableNextObjective"); Level.Game.DisableNextObjective(); } exec function ruler() { local NavigationPoint N; ForEach AllActors(class'NavigationPoint',N) if ( N.IsA('ONSPowerCore') ) N.Bump(Pawn); } sKss`//============================================================================= // Canvas: A drawing canvas. // This is a built-in Unreal class and it shouldn't be modified. // // Notes. // To determine size of a drawable object, set Style to STY_None, // remember CurX, draw the thing, then inspect CurX and CurYL. //============================================================================= class Canvas extends Object native noexport; // added for drawing solid primatives. #exec TEXTURE IMPORT NAME=WhiteTexture FILE=Textures\White.tga MIPS=0 #exec TEXTURE IMPORT NAME=BlackTexture FILE=Textures\Black.tga MIPS=0 #exec TEXTURE IMPORT NAME=GrayTexture FILE=Textures\Gray.tga MIPS=0 // simple default font, so various stuff doesn't crash #exec Font Import File=Textures\SmallFont.bmp Name="DefaultFont" // Modifiable properties. var font Font; // Font for DrawText. var float FontScaleX, FontScaleY; // Scale for DrawText & DrawTextClipped. // gam var float SpaceX, SpaceY; // Spacing for after Draw*. var float OrgX, OrgY; // Origin for drawing. var float ClipX, ClipY; // Bottom right clipping region. var float CurX, CurY; // Current position for drawing. var float Z; // Z location. 1=no screenflash, 2=yes screenflash. var byte Style; // Drawing style STY_None means don't draw. 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. var Plane ColorModulate; // sjs - Modulate all colors by this before rendering var bool bForceAlpha; // Force all drawing to be alpha'ed var float ForcedAlpha; // How much to force var bool bRenderLevel; // gam - Will render the level if enabled. // Stock fonts. var font TinyFont, SmallFont, MedFont; var localized string TinyFontName, SmallFontName, MedFontName; // Internal. var const viewport Viewport; // Viewport that owns the canvas. var const pointer pCanvasUtil; // sjs // native functions. native(464) final function StrLen( coerce string String, out float XL, out float YL ); // Wrapped! native(465) final function DrawText( coerce string Text, optional bool CR ); native(466) final function DrawTile( material Mat, float XL, float YL, float U, float V, float UL, float VL ); native(467) final function DrawActor( Actor A, bool WireFrame, optional bool ClearZ, optional float DisplayFOV ); native(468) final function DrawTileClipped( Material Mat, float XL, float YL, float U, float V, float UL, float VL ); native(469) final function DrawTextClipped( coerce string Text, optional bool bCheckHotKey ); native(470) final function TextSize( coerce string String, out float XL, out float YL ); // Clipped! native(480) final function DrawPortal( int X, int Y, int Width, int Height, actor CamActor, vector CamLocation, rotator CamRotation, optional int FOV, optional bool ClearZ ); native final function vector WorldToScreen( vector WorldLoc ); native final function GetCameraLocation( out vector CameraLocation, out rotator CameraRotation ); native final function SetScreenLight( int index, vector Position, color lightcolor, float radius ); native final function SetScreenProjector( int index, vector Position, color color, float radius, texture tex ); native final function DrawScreenActor( Actor A, optional float FOV, optional bool WireFrame, optional bool ClearZ ); native final function Clear(optional bool ClearRGB, optional bool ClearZ); native final function WrapStringToArray(string Text, out array OutArray, float dx, optional string EOL); static native final function WrapText( out String Text, out String Line, float dx, Font F, float FontScaleX ); // jmw - These are two helper functions. The use the whole texture only. If you need better support, use DrawTile native final function DrawTilePartialStretched( Material Mat, float XL, float YL ); // rjp native final function DrawTileStretched(material Mat, float XL, float YL); native final function DrawTileJustified(material Mat, byte Justification, float XL, float YL); native final function DrawTileScaled(material Mat, float XScale, float YScale); native final function DrawTextJustified(coerce string String, byte Justification, float x1, float y1, float x2, float y2); native final function DrawActorClipped( Actor A, bool WireFrame, float Left, float Top, float Width, float Height, optional bool ClearZ, optional float DisplayFOV); // UnrealScript functions. event Reset() { Font = Default.Font; FontScaleX = Default.FontScaleX; // gam FontScaleY = Default.FontScaleY; // gam SpaceX = Default.SpaceX; SpaceY = Default.SpaceY; OrgX = Default.OrgX; OrgY = Default.OrgY; CurX = Default.CurX; CurY = Default.CurY; Style = Default.Style; DrawColor = Default.DrawColor; CurYL = Default.CurYL; bCenter = false; bNoSmooth = false; Z = 1.0; ColorModulate = Default.ColorModulate; // sjs } final function SetPos( float X, float Y ) { CurX = X; CurY = Y; } final function SetOrigin( float X, float Y ) { OrgX = X; OrgY = Y; } final function SetClip( float X, float Y ) { ClipX = X; ClipY = Y; } final function DrawPattern( material Tex, float XL, float YL, float Scale ) { DrawTile( Tex, XL, YL, (CurX-OrgX)*Scale, (CurY-OrgY)*Scale, XL*Scale, YL*Scale ); } final function DrawIcon( texture Tex, float Scale ) { if ( Tex != None ) DrawTile( Tex, Tex.USize*Scale, Tex.VSize*Scale, 0, 0, Tex.USize, Tex.VSize ); } final function DrawRect( texture Tex, float RectX, float RectY ) { DrawTile( Tex, RectX, RectY, 0, 0, Tex.USize, Tex.VSize ); } final function SetDrawColor(byte R, byte G, byte B, optional byte A) { local Color C; C.R = R; C.G = G; C.B = B; if ( A == 0 ) A = 255; C.A = A; DrawColor = C; } 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; if ( A == 0 ) A = 255; C.A = A; return C; } // Draw a vertical line final function DrawVertical(float X, float height) { local float cX,cY; CX = CurX; CY = CurY; CurX = X; DrawTile(Texture'engine.WhiteSquareTexture', 2, height, 0, 0, 2, 2); CurX = CX; CurY = CY; } // Draw a horizontal line final function DrawHorizontal(float Y, float width) { local float cx,cy; CX = CurX; CY = CurY; CurY = Y; DrawTile(Texture'engine.WhiteSquareTexture', width, 2, 0, 0, 2, 2); CurX = CX; CurY = CY; } // Draw Line is special as it saves it's original position final function DrawLine(int direction, float size) { local float cx,cy; CX = CurX; CY = CurY; switch (direction) { case 0: CurY-=Size; DrawVertical(CurX,size); break; case 1: DrawVertical(CurX,size); break; case 2: CurX-=Size; DrawHorizontal(CurY,size); break; case 3: DrawHorizontal(CurY,size); break; } CurX = CX; CurY = CY; } final simulated function DrawBracket(float width, float height, float bracket_size) { local float x,y; Width = max(width,5); Height = max(height,5); x = curX; Y = curY; DrawHorizontal(CurY,bracket_size); DrawHorizontal(CurY+Height,bracket_size); DrawVertical(CurX,bracket_size); DrawVertical(CurX+Width,bracket_size); CurY = Y + Height-bracket_size; DrawVertical(CurX,Bracket_size); DrawVertical(CurX+Width,Bracket_Size); CurX = X+Width-Bracket_Size; DrawHorizontal(Y,Bracket_Size); DrawHorizontal(Y+Height, Bracket_Size); } final simulated function DrawBox(canvas canvas, float width, float height) { DrawHorizontal(CurY,Width); DrawHorizontal(CurY+Height,Width); DrawVertical(CurX,Height); DrawVertical(CurX+Width,Height); } simulated function DrawScreenText (String Text, float X, float Y, EDrawPivot Pivot) { local int TextScreenWidth, TextScreenHeight; local float UL, VL; X *= SizeX; Y *= SizeY; TextSize (Text, UL, VL); TextScreenWidth = UL; TextScreenHeight = VL; switch (Pivot) { case DP_UpperLeft: break; case DP_UpperMiddle: X -= TextScreenWidth / 2; break; case DP_UpperRight: X -= TextScreenWidth; break; case DP_MiddleRight: X -= TextScreenWidth; Y -= TextScreenHeight / 2; break; case DP_LowerRight: X -= TextScreenWidth; Y -= TextScreenHeight; break; case DP_LowerMiddle: X -= TextScreenWidth / 2; Y -= TextScreenHeight; break; case DP_LowerLeft: Y -= TextScreenHeight; break; case DP_MiddleLeft: Y -= TextScreenHeight / 2; break; case DP_MiddleMiddle: X -= TextScreenWidth / 2; Y -= TextScreenHeight / 2; break; } SetPos (X, Y); DrawTextClipped (Text); } ssmsr`'C59~`'%%URL Contains illegal character '%'. ~~`':%~`'/%~`'\%URL blocked z\-`'-])-_'\`'w*Y`'-_'t' Gs@ssedU4 Gsss@ssfclass CameraOverlay extends CameraEffect native noexport editinlinenew collapsecategories; var() color OverlayColor; var() Material OverlayMaterial; sZ 6snclass CameraEffect extends Object abstract native noexport noteditinlinenew; var float Alpha; // Used to transition camera effects. 0 = no effect, 1 = full effect var bool FinalEffect; // Forces the renderer to ignore effects on the stack below this one. var int cameraeffect_dummy; // hammer padding. --ryan. // // Default properties // spg^!|+3 GsU//============================================================================= // A camera, used in UnrealEd. //============================================================================= class Camera extends PlayerController native; // Sprite. #exec Texture Import File=Textures\S_Camera.pcx Name=S_Camera Mips=Off MASKED=1 sE//============================================================================= // The brush class. // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class Brush extends Actor 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; // Outdated. var const object UnusedLightMesh; var vector PostPivot; // Scaling. // Outdated : these are only here to allow the "ucc mapconvert" commandlet to work. // They are NOT used by the engine/editor for anything else. var scale MainScale; var scale PostScale; var scale TempScale; // Information. var() color BrushColor; var() int PolyFlags; var() bool bColored; sb//============================================================================= // 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. // // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class BroadcastHandler extends Info config; // rjp -- Generally, you should only need to override the 'Accept' functions var BroadcastHandler NextBroadcastHandler; var class NextBroadcastHandlerClass; // -- rjp var int SentText; var globalconfig bool bMuteSpectators; // Whether spectators are allowed to speak. var globalconfig bool bPartitionSpectators; // Whether spectators are can only speak to spectators. const PROPNUM = 2; var localized string BHDisplayText[PROPNUM]; var localized string BHDescText[PROPNUM]; function UpdateSentText() { SentText = 0; } static function FillPlayInfo(PlayInfo PlayInfo) { Super.FillPlayInfo(PlayInfo); // Always begin with calling parent PlayInfo.AddSetting(default.ChatGroup, "bMuteSpectators", default.BHDisplayText[0], 0, 1, "Check",,,True,True); PlayInfo.AddSetting(default.ChatGroup, "bPartitionSpectators", default.BHDisplayText[1], 1, 1, "Check",,,True,True); if ( default.NextBroadcastHandlerClass != None ) { default.NextBroadcastHandlerClass.static.FillPlayInfo(PlayInfo); PlayInfo.PopClass(); } } static event string GetDescriptionText(string PropName) { switch (PropName) { case "bMuteSpectators": return default.BHDescText[0]; case "bPartitionSpectators":return default.BHDescText[1]; } return Super.GetDescriptionText(PropName); } /* Whether actor is allowed to broadcast messages now. */ function bool AllowsBroadcast( actor broadcaster, int Len ) { if ( bMuteSpectators && (PlayerController(Broadcaster) != None) && !PlayerController(Broadcaster).PlayerReplicationInfo.bAdmin && (PlayerController(Broadcaster).PlayerReplicationInfo.bOnlySpectator || PlayerController(Broadcaster).PlayerReplicationInfo.bOutOfLives) ) return false; SentText += Len; if ( NextBroadcastHandler != None && !NextBroadcastHandler.HandlerAllowsBroadcast(Broadcaster, SentText) ) return false; return ( (Level.Pauser != None) || (SentText < 200) ); } function bool HandlerAllowsBroadcast( Actor Broadcaster, int SentTextNum ) { if ( NextBroadcastHandler != None ) return NextBroadcastHandler.HandlerAllowsBroadcast(Broadcaster, SentTextNum); return true; } function BroadcastText( PlayerReplicationInfo SenderPRI, PlayerController Receiver, coerce string Msg, optional name Type ) { if ( !AcceptBroadcastText(Receiver, SenderPRI, Msg, Type) ) return; if ( NextBroadcastHandler != None ) NextBroadcastHandler.BroadcastText( SenderPRI, Receiver, Msg, Type ); else 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 ) { if ( !AcceptBroadcastLocalized(Receiver, Sender, Message, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject) ) return; if ( NextBroadcastHandler != None ) NextBroadcastHandler.BroadcastLocalized( Sender, Receiver, Message, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject ); else Receiver.ReceiveLocalizedMessage( Message, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject ); } function Broadcast( Actor Sender, coerce string Msg, optional name Type ) { local Controller C; 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; if ( bPartitionSpectators && !Level.Game.bGameEnded && (PRI != None) && !PRI.bAdmin && (PRI.bOnlySpectator || PRI.bOutOfLives) ) { For ( C=Level.ControllerList; C!=None; C=C.NextController ) { P = PlayerController(C); if ( (P != None) && (P.PlayerReplicationInfo.bOnlySpectator || P.PlayerReplicationInfo.bOutOfLives) ) BroadcastText(PRI, P, Msg, Type); } } else { For ( C=Level.ControllerList; C!=None; C=C.NextController ) { P = PlayerController(C); if ( P != None ) BroadcastText(PRI, P, Msg, Type); } } } function BroadcastTeam( Controller Sender, coerce string Msg, optional name Type ) { local Controller C; local PlayerController P; // see if allowed (limit to prevent spamming) if ( !AllowsBroadcast(Sender, Len(Msg)) ) return; if ( bPartitionSpectators && !Level.Game.bGameEnded && (Sender != None) && !Sender.PlayerReplicationInfo.bAdmin && (Sender.PlayerReplicationInfo.bOnlySpectator || Sender.PlayerReplicationInfo.bOutOfLives) ) { For ( C=Level.ControllerList; C!=None; C=C.NextController ) { P = PlayerController(C); if ( (P != None) && (P.PlayerReplicationInfo.Team == Sender.PlayerReplicationInfo.Team) && (P.PlayerReplicationInfo.bOnlySpectator || P.PlayerReplicationInfo.bOutOfLives) ) BroadcastText(Sender.PlayerReplicationInfo, P, Msg, Type); } } else { For ( C=Level.ControllerList; C!=None; C=C.NextController ) { P = PlayerController(C); if ( (P != None) && (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 Controller C; local PlayerController P; For ( C=Level.ControllerList; C!=None; C=C.NextController ) { P = PlayerController(C); if ( P != None ) BroadcastLocalized(Sender, P, Message, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject); } } // rjp --- Linked list for broadcast handlers function RegisterBroadcastHandler(BroadcastHandler NewBH) { if ( NextBroadcastHandler == None ) { NextBroadcastHandler = NewBH; default.NextBroadcastHandlerClass = NewBH.Class; } else NextBroadcastHandler.RegisterBroadcastHandler(NewBH); } function bool AcceptBroadcastText( PlayerController Receiver, PlayerReplicationInfo SenderPRI, out string Msg, optional name Type ) { if ( NextBroadcastHandler != None ) return NextBroadcastHandler.AcceptBroadcastText(Receiver, SenderPRI, Msg, Type); return true; } function bool AcceptBroadcastLocalized(PlayerController Receiver, Actor Sender, class Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object Obj) { if ( NextBroadcastHandler != None ) return NextBroadcastHandler.AcceptBroadcastLocalized(Receiver, Sender, Message, Switch, RelatedPRI_1, RelatedPRI_2, Obj); return true; } function bool AcceptBroadcastSpeech(PlayerController Receiver, PlayerReplicationInfo SenderPRI) { if ( NextBroadcastHandler != None ) return NextBroadcastHandler.AcceptBroadcastSpeech(Receiver, SenderPRI); return true; } function bool AcceptBroadcastVoice(PlayerController Receiver, PlayerReplicationInfo SenderPRI) { if ( NextBroadcastHandler != None ) return NextBroadcastHandler.AcceptBroadcastVoice(Receiver, SenderPRI); return true; } // --- rjp event Destroyed() { default.NextBroadcastHandlerClass = None; Super.Destroyed(); } s\v)q= )v))t) G4szb'Xo1T9:9:$ rb'* g7N@Ng&gNb' Gso//============================================================================= // 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 //============================================================================= class BlockingVolume extends Volume native; // (cpptext) // (cpptext) // (cpptext) // (cpptext) var() bool bClampFluid; var() bool bClassBlocker; // sjs var() Array< class > BlockedClasses; // sjs s{class BitmapMaterial extends RenderedMaterial abstract native noexport; var(TextureFormat) const editconst enum ETextureFormat { TEXF_P8, TEXF_RGBA7, TEXF_RGB16, TEXF_DXT1, TEXF_RGB8, TEXF_RGBA8, TEXF_NODATA, TEXF_DXT3, TEXF_DXT5, TEXF_L8, TEXF_G16, TEXF_RRRGGGBBB, } Format; var(Texture) enum ETexClampMode { TC_Wrap, TC_Clamp, } UClampMode, VClampMode; var const byte UBits, VBits; var const int USize, VSize; var(Texture) const int UClamp, VClamp; sii'BE&ru*uWx) lk'Kk'B i'UwB *w.B *i'r.B K(B B SYw)*u)* Gs0class Bitmap extends Object; // Deprecated tWur@Essk(//============================================================================= // BeamEmitter: An Unreal Beam Particle Emitter. //============================================================================= class BeamEmitter extends ParticleEmitter native; enum EBeamEndPointType { PTEP_Velocity, PTEP_Distance, PTEP_Offset, PTEP_Actor, PTEP_TraceOffset, PTEP_OffsetAsAbsolute, PTEP_DynamicDistance // Length can be scaled by Size.Y and Distance can be changed in realtime through code. }; struct ParticleBeamData { var vector Location; var float t; }; struct ParticleBeamEndPoint { var () name ActorTag; var () rangevector Offset; var () float Weight; }; struct ParticleBeamScale { var () vector FrequencyScale; var () float RelativeLength; }; var (Beam) range BeamDistanceRange; var (Beam) array BeamEndPoints; var (Beam) EBeamEndPointType DetermineEndPointBy; var (Beam) float BeamTextureUScale; var (Beam) float BeamTextureVScale; var (Beam) int RotatingSheets; var (Beam) bool TriggerEndpoint; var (BeamNoise) rangevector LowFrequencyNoiseRange; var (BeamNoise) int LowFrequencyPoints; var (BeamNoise) rangevector HighFrequencyNoiseRange; var (BeamNoise) int HighFrequencyPoints; var (BeamNoise) array LFScaleFactors; var (BeamNoise) array HFScaleFactors; var (BeamNoise) float LFScaleRepeats; var (BeamNoise) float HFScaleRepeats; var (BeamNoise) bool UseHighFrequencyScale; var (BeamNoise) bool UseLowFrequencyScale; var (BeamNoise) bool NoiseDeterminesEndPoint; var (BeamNoise) rangevector DynamicHFNoiseRange; var (BeamNoise) range DynamicHFNoisePointsRange; var (BeamNoise) range DynamicTimeBetweenNoiseRange; var (BeamBranching) bool UseBranching; var (BeamBranching) range BranchProbability; var (BeamBranching) range BranchHFPointsRange; var (BeamBranching) int BranchEmitter; var (BeamBranching) range BranchSpawnAmountRange; var (BeamBranching) bool LinkupLifetime; var transient int SheetsUsed; var transient int VerticesPerParticle; var transient int IndicesPerParticle; var transient int PrimitivesPerParticle; var transient float BeamValueSum; var transient array HFPoints; var transient array LFPoints; var transient array HitActors; var transient float TimeSinceLastDynamicNoise; sss)Z\ 2g'u gcTs) GsoABDe /a0 RA!s!\A109:W9:$/a0 RA!sA-W%A-u\A109:W9:$/a0 RA!sA-u\A109:W9:$/a0 RA!s\A10 Gswr)Wfp Ol', Vl'O, MO% O, V% -F'cOc@V`VF r)UwF *w.F *.F VSTARTuIF F S GsAd'aa0T9:9:$ rd'* h7s@sh&hsd' GsT"// ==================================================================== // Class: Engine.BaseGUIController // // This is just a stub class that should be subclassed to support menus. // // Written by Joe Wilcox // (c) 2002, Epic Games, Inc. All Rights Reserved // ==================================================================== class BaseGUIController extends Interaction Native transient; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) #exec TEXTURE IMPORT NAME=MenuWhite FILE=Textures\White.tga MIPS=0 #exec TEXTURE IMPORT NAME=MenuBlack FILE=Textures\Black.tga MIPS=0 #exec TEXTURE IMPORT NAME=MenuGray FILE=Textures\Gray.tga MIPS=0 var Material DefaultPens[3]; // Contain to hold some default pens for drawing purposes // Default work menus var config string NetworkMsgMenu; // Menu used for network messages var config string QuestionMenuClass; // Menu that appears for questions // Delegates Delegate OnAdminReply(string Reply); // Called By PlayerController // ================================================ // OpenMenu - Opens a new menu and places it on top of the stack event bool OpenMenu(string NewMenuName, optional string Param1, optional string Param2) { return false; } // ================================================ // Create a bunch of menus at start up event AutoLoadMenus(); // Subclass me // ================================================ // Replaces a menu in the stack. returns true if success event bool ReplaceMenu(string NewMenuName, optional string Param1, optional string Param2, optional bool bCancelled) { return false; } event bool CloseMenu(optional bool bCanceled) // Close the top menu. returns true if success. { return true; } event CloseAll(bool bCancel, optional bool bForced); function SetControllerStatus(bool On) { bActive = On; bVisible = On; bRequiresTick=On; // Add code to pause/unpause/hide/etc the game here. } event InitializeController(); // Should be subclassed. event bool NeedsMenuResolution(); // Big Hack that should be subclassed event SetRequiredGameResolution(string GameRes); sN//============================================================================= // AvoidMarker. // Creatures will tend to back away when near this spot //============================================================================= class AvoidMarker extends Triggers native notPlaceable; var byte TeamNum; function Touch( actor Other ) { if ( (Pawn(Other) != None)&& RelevantTo(Pawn(Other)) ) Pawn(Other).Controller.FearThisSpot(self); } function bool RelevantTo(Pawn P) { return ( (AIController(P.Controller) != None) && ((P.Controller.PlayerReplicationInfo == None) || (P.Controller.PlayerReplicationInfo.Team == None) || (P.Controller.PlayerReplicationInfo.Team.TeamIndex != TeamNum)) ); } function StartleBots() { local Pawn P; ForEach CollidingActors(class'Pawn', P, CollisionRadius) if ( RelevantTo(P) ) AIController(P.Controller).Startle(self); } sd/*============================================================================= // AutoLadder - automatically placed at top and bottom of LadderVolume ============================================================================= */ class AutoLadder extends Ladder notplaceable native; // (cpptext) // (cpptext) // (cpptext) // (cpptext) sG/*============================================================================= // AutoDoor - automatically placed Door ============================================================================= */ class AutoDoor extends Door notplaceable native; syp)u|-(wu*uup)o)** GsssRhDG-,9:9:$ r*cwK*{K` oK` ro* {V oV ro*oz' wo*ow/a0 h'('h'-]-hh'g h'-]'10 G ssDsDx^SINGLEPLAYER GameProfile::RegisterGame for profilel~)IE&})Ig,|)9DIdy)-bg'u gc{)-b( GsIssiclass ArmorPickup extends Pickup abstract; function float BotDesireability( pawn Bot ) { local Inventory AlreadyHas; local Armor AlreadyHasArmor; local float desire; local bool bChecked; desire = MaxDesireability; if ( RespawnTime < 10 ) { bChecked = true; AlreadyHas = Bot.FindInventoryType(InventoryType); if ( AlreadyHas != None ) { if ( Inventory != None ) { if( Inventory.Charge <= AlreadyHas.Charge ) return -1; } else if ( InventoryType.Default.Charge <= AlreadyHas.Charge ) return -1; } } if ( !bChecked ) AlreadyHasArmor = Armor(Bot.FindInventoryType(InventoryType)); if ( AlreadyHasArmor != None ) desire *= (1 - AlreadyHasArmor.Charge * AlreadyHasArmor.ArmorAbsorption * 0.00003); if ( Armor(Inventory) != None ) { // pointing to specific, existing item desire *= (Inventory.Charge * 0.005); desire *= (Armor(Inventory).ArmorAbsorption * 0.01); } else { desire *= (InventoryType.default.Charge * 0.005); desire *= (class(InventoryType).default.ArmorAbsorption * 0.01); } return desire; } sCm)V-b(-F'cm)m' ElT m'UwT *w.T *.T VSTARTuIT T SL GssERkX3H::?#h@q@q@q@qhff@qf@qfssk(class Armor extends Powerups abstract; var() class ProtectionType; // Protects against DamageType (None if non-armor). var() int ArmorAbsorption; // Percent of damage item absorbs 0-100. var() int AbsorptionPriority; // Which items absorb damage first (higher=first). var armor NextArmor; // Temporary list created by Armors to prioritize damage absorption. // // Absorb damage. // function int ArmorAbsorbDamage(int Damage, class DamageType, vector HitLocation) { local int ArmorDamage; if ( DamageType.default.bArmorStops ) ArmorImpactEffect(HitLocation); if( (DamageType!=None) && (ProtectionType==DamageType) ) return 0; if ( !DamageType.default.bArmorStops ) Return Damage; ArmorDamage = (Damage * ArmorAbsorption) / 100; if( ArmorDamage >= Charge ) { ArmorDamage = Charge; Destroy(); } else Charge -= ArmorDamage; return (Damage - ArmorDamage); } // // Return armor value. // function int ArmorPriority(class DamageType) { if ( DamageType.default.bArmorStops ) return 0; if( (DamageType!=None) && (ProtectionType==DamageType) ) return 1000000; return AbsorptionPriority; } // // This function is called by ArmorAbsorbDamage and displays a visual effect // for an impact on an armor. // function ArmorImpactEffect(vector HitLocation); state Activated { function BeginState() { Super.BeginState(); if ( ProtectionType != None ) Pawn(Owner).ReducedDamageType = ProtectionType; } function EndState() { Super.EndState(); if ( (Pawn(Owner) != None) && (ProtectionType != Pawn(Owner).ReducedDamageType) ) Pawn(Owner).ReducedDamageType = None; } } // // Return the best armor to use. // function armor PrioritizeArmor( int Damage, class DamageType, vector HitLocation ) { local Armor FirstArmor, InsertAfter; if ( Inventory != None ) FirstArmor = Inventory.PrioritizeArmor(Damage, DamageType, HitLocation); else FirstArmor = None; if ( FirstArmor == None ) { nextArmor = None; return self; } // insert this armor into the prioritized armor list if ( FirstArmor.ArmorPriority(DamageType) < ArmorPriority(DamageType) ) { nextArmor = FirstArmor; return self; } InsertAfter = FirstArmor; while ( (InsertAfter.nextArmor != None) && (InsertAfter.nextArmor.ArmorPriority(DamageType) > ArmorPriority(DamageType)) ) InsertAfter = InsertAfter.nextArmor; nextArmor = InsertAfter.nextArmor; InsertAfter.nextArmor = self; return FirstArmor; } sFKULV %GV ,=V @u  V V V % GsV ssC //============================================================================= // AntiPortalActor. //============================================================================= class AntiPortalActor extends Actor native placeable; // // TriggerControl // state() TriggerControl { // Trigger simulated event Trigger(Actor Other,Pawn EventInstigator) { SetDrawType(DT_None); } // UnTrigger simulated event UnTrigger(Actor Other,Pawn EventInstigator) { SetDrawType(DT_AntiPortal); } } // // TriggerToggle // state() TriggerToggle { // Trigger simulated event Trigger(Actor Other,Pawn EventInstigator) { if (DrawType == DT_AntiPortal) SetDrawType(DT_None); else if(DrawType == DT_None) SetDrawType(DT_AntiPortal); } } // // Default properties // sJn'T1n' ElVUn' Gsmclass AnimNotify_Trigger extends AnimNotify_Scripted; var() name EventName; event Notify( Actor Owner ) { Owner.TriggerEvent( EventName, Owner, Pawn(Owner) ); } sssMQZuZ Gs@ssPSBy, G sssRUJMzpuOd|ptxGame.xDeathmatch|ptxGame.BossDM%wpB, GspsM(Nv^0VG1M(tʁ)ssTBQ\!B% B,ErrorB ?9:$d %V V9:$d &V n9:$d ,V 9:$d ,V 9:$d ,V d  G s~class AnimNotify_Sound extends AnimNotify native; var() sound Sound; var() float Volume; var() int Radius; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) sd @sslclass AnimNotify_Scripted extends AnimNotify native abstract; event Notify( Actor Owner ); // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) sWbK7zb%Vg $8zb&Vg $Uzb,Vg $rzb,Vg $zb,Vg $g $g  G sYclass AnimNotify_Script extends AnimNotify native; var() name NotifyName; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) sg s[sqclass AnimNotify_MatSubAction extends AnimNotify native; var() editinline MatSubAction SubAction; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) s[Va^8!V% V,ErrorQ9:Ve' GsZclass AnimNotify_Effect extends AnimNotify native; var() class EffectClass; var() name Bone; var() vector OffsetLocation; var() rotator OffsetRotation; var() bool Attach; var() name Tag; var() float DrawScale; var() vector DrawScale3D; var private transient Actor LastSpawnedEffect; // Valid only in the editor. // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) s@ss_pia96p% p,pj e'Kl) Gs@class AnimNotify_DestroyEffect extends AnimNotify native; var() name DestroyTag; var() bool bExpireParticles; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) sGkAb)9:9:$ J-G-kJw*swK*{K` sK` ws*sy-G'rs* {V sV  rs*sz' Jws*-~-P-P(sy-P-~/a0 j'j'-X-kj'Ij'-X'10 G sbe j( e % e , 6d % d , Me j d  h l %l ,l j d h l l _h %o'e j e j d h %h j o' Gsxclass AnimNotify extends Object native abstract editinlinenew hidecategories(Object) collapsecategories; var transient int Revision; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) sQ-//============================================================================= // Ammunition: the base class of weapon ammunition // // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class Ammunition extends Inventory abstract native nativereplication; var travel int MaxAmmo; // Max amount of ammo var travel int AmmoAmount; var int InitialAmount; // sjs // Amount of Ammo current available var travel int PickupAmmo; // Amount of Ammo to give when this is picked up for the first time // Used by Bot AI var bool bRecommendSplashDamage; var bool bTossed; var bool bTrySplash; var bool bLeadTarget; var bool bInstantHit; var bool bSplashDamage; var bool bTryHeadShot; // Damage and Projectile information var class ProjectileClass; var class MyDamageType; var float WarnTargetPct; var float RefireRate; var Sound FireSound; var float MaxRange; // for autoaim var() Material IconFlashMaterial; // Network replication // replication { // Things the server should send to the client. reliable if( bNetOwner && bNetDirty && (Role==ROLE_Authority) ) AmmoAmount; } simulated function CheckOutOfAmmo() { if (AmmoAmount <= 0) Pawn(Owner).Weapon.OutOfAmmo(); } simulated function bool UseAmmo(int AmountNeeded, optional bool bAmountNeededIsMax) { if (bAmountNeededIsMax && AmmoAmount < AmountNeeded) AmountNeeded = AmmoAmount; if (AmmoAmount < AmountNeeded) { CheckOutOfAmmo(); return false; // Can't do it } AmmoAmount -= AmountNeeded; NetUpdateTime = Level.TimeSeconds - 1; if (Level.NetMode == NM_StandAlone || Level.NetMode == NM_ListenServer) CheckOutOfAmmo(); return true; } simulated function bool HasAmmo() { return ( AmmoAmount > 0 ); } simulated function DisplayDebug(Canvas Canvas, out float YL, out float YPos) { Canvas.DrawText("Ammunition "$GetItemName(string(self))$" amount "$AmmoAmount$" Max "$MaxAmmo); YPos += YL; Canvas.SetPos(4,YPos); } function bool HandlePickupQuery( pickup Item ) { if ( class == item.InventoryType ) { if (AmmoAmount==MaxAmmo) return true; item.AnnouncePickup(Pawn(Owner)); AddAmmo(Ammo(item).AmmoAmount); item.SetRespawn(); return true; } if ( Inventory == None ) return false; return Inventory.HandlePickupQuery(Item); } // If we can, add ammo and return true. // If we are at max ammo, return false // function bool AddAmmo(int AmmoToAdd) { if ( Level.GRI.WeaponBerserk > 1.0 ) AmmoAmount = MaxAmmo; else if ( AmmoAmount < MaxAmmo ) AmmoAmount = Min(MaxAmmo, AmmoAmount+AmmoToAdd); NetUpdateTime = Level.TimeSeconds - 1; return true; } sG//============================================================================= // Ammo. //============================================================================= class Ammo extends Pickup abstract native; #exec Texture Import File=Textures\Ammo.pcx Name=S_Ammo Mips=Off MASKED=1 var() int AmmoAmount; simulated static function UpdateHUD(HUD H) { H.LastPickupTime = H.Level.TimeSeconds; H.LastAmmoPickupTime = H.LastPickupTime; } /* 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) { local Inventory inv; local Weapon W; local float Desire; if ( Other.Weapon.AIRating >= 0.5 ) return 0; for ( Inv=Other.Inventory; Inv!=None; Inv=Inv.Inventory ) { W = Weapon(Inv); if ( W != None ) { Desire = W.DesireAmmo(InventoryType, true); if ( Desire != 0 ) return Desire * MaxDesireability/PathWeight; } } return 0; } function float BotDesireability(Pawn Bot) { local Inventory inv; local Weapon W; local float Desire; local Ammunition M; if ( Bot.Controller.bHuntPlayer ) return 0; for ( Inv=Bot.Inventory; Inv!=None; Inv=Inv.Inventory ) { W = Weapon(Inv); if ( W != None ) { Desire = W.DesireAmmo(InventoryType, false); if ( Desire != 0 ) return Desire * MaxDesireability; } } M = Ammunition(Bot.FindInventoryType(InventoryType)); if ( (M != None) && (M.AmmoAmount >= M.MaxAmmo) ) return -1; return 0.25 * MaxDesireability; } function inventory SpawnCopy( Pawn Other ) { local Inventory Copy; Copy = Super.SpawnCopy(Other); Ammunition(Copy).AmmoAmount = AmmoAmount; return Copy; } sq//============================================================================= // Ambient sound -- Extended to support random interval sound emitters (gam). // Copyright 2001 Digital Extremes - All Rights Reserved. // Confidential. //============================================================================= class AmbientSound extends Keypoint native exportstructs hidecategories(Movement,Collision,Lighting,LightColor,Karma,Force,Wind); // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) #exec Texture Import File=Textures\Ambient.pcx Name=S_Ambient Mips=Off MASKED=1 // Sound will trigger every EmitInterval +/- Rand(EmitVariance) seconds. struct SoundEmitter { var() float EmitInterval; var() float EmitVariance; var transient float EmitTime; var() Sound EmitSound; // Manually re-order because Dan turned off property sorting and broke binary compatibility. }; var(Sound) Array SoundEmitters; var globalconfig float AmbientVolume; // ambient volume multiplier (scaling) sy//============================================================================= // AIScript - used by Level Designers to specify special AI scripts for pawns // placed in a level, and to change which type of AI controller to use for a pawn. // AIScripts can be shared by one or many pawns. // Game specific subclasses of AIScript will have editable properties defining game specific behavior and AI // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class AIScript extends Keypoint native placeable; #exec Texture Import File=Textures\AIScript.pcx Name=S_AIScript Mips=Off MASKED=1 var() class ControllerClass; var bool bNavigate; // if true, put an associated path in the navigation network var bool bLoggingEnabled; var AIMarker myMarker; // (cpptext) // (cpptext) // (cpptext) // (cpptext) // (cpptext) /* SpawnController() Spawn and initialize an AI Controller (called by a non-player controlled Pawn at level startup) */ function SpawnControllerFor(Pawn P) { local AIController C; if ( ControllerClass == None ) { if ( P.ControllerClass == None ) return; C = Spawn(P.ControllerClass,,,P.Location, P.Rotation); } else C = Spawn(ControllerClass,,,P.Location, P.Rotation); C.MyScript = self; C.Possess(P); } function Actor GetMoveTarget() { if ( MyMarker != None ) return MyMarker; return self; } function TakeOver(Pawn P); seh{I#~zh(t %yt ,Xt 7nzt nt nh'o|t nh(t ( GsB//============================================================================= // AIMarker. //============================================================================= class AIMarker extends SmallNavigationPoint native; // (cpptext) // (cpptext) // (cpptext) // (cpptext) var AIScript markedScript; st ssEx//============================================================================= // 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. // // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class AIController extends Controller native; var bool bHunting; // tells navigation code that pawn is hunting another pawn, // so fall back to finding a path to a visible pathnode if none // are reachable var bool bAdjustFromWalls; // 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 bPlannedJump; // set when doing voluntary jump var AIScript MyScript; var float Skill; // skill, scaled by game difficulty (add difficulty to this value) native(510) final latent function WaitToSeeEnemy(); // return when looking directly at visible enemy event PreBeginPlay() { Super.PreBeginPlay(); if ( bDeleteMe ) return; if ( Level.Game != None ) Skill += Level.Game.GameDifficulty; Skill = FClamp(Skill, 0, 3); } function Reset() { bHunting = false; bPlannedJump = false; Super.Reset(); } simulated function float RateWeapon(Weapon w) { return (W.GetAIRating() + FRand() * 0.05); } function Trigger( actor Other, pawn EventInstigator ) { TriggerScript(Other,EventInstigator); } /* WeaponFireAgain() Notification from weapon when it is ready to fire (either just finished firing, or just finished coming up/reloading). Returns true if weapon should fire. If it returns false, can optionally set up a weapon change */ function bool WeaponFireAgain(float RefireRate, bool bFinishedFire) { if ( Pawn.PressingFire() && (FRand() < RefireRate) ) { Pawn.Weapon.BotFire(bFinishedFire); return true; } StopFiring(); return false; } /* TriggerScript() trigger AI script (this may enable it) */ function bool TriggerScript( actor Other, pawn EventInstigator ) { if ( MyScript != None ) { MyScript.Trigger(EventInstigator,pawn); return true; } return false; } /* DisplayDebug() list important controller attributes on canvas */ function DisplayDebug(Canvas Canvas, out float YL, out float YPos) { local int i; local string T; Super.DisplayDebug(Canvas,YL, YPos); Canvas.DrawColor.B = 255; if ( (Pawn != None) && (MoveTarget != None) && Pawn.ReachedDestination(MoveTarget) ) Canvas.DrawText(" Skill "$Skill$" NAVIGATION MoveTarget "$GetItemName(String(MoveTarget))$"(REACHED) PendingMover "$PendingMover$" MoveTimer "$MoveTimer, false); else Canvas.DrawText(" Skill "$Skill$" NAVIGATION MoveTarget "$GetItemName(String(MoveTarget))$" PendingMover "$PendingMover$" MoveTimer "$MoveTimer, false); YPos += YL; Canvas.SetPos(4,YPos); T = " Destination "$Destination$" Focus "$GetItemName(string(Focus)); if ( bPreparingMove ) T = T$" (Preparing Move)"; Canvas.DrawText(T, false); YPos += YL; Canvas.SetPos(4,YPos); Canvas.DrawText(" RouteGoal "$GetItemName(string(RouteGoal))$" RouteDist "$RouteDist, false); YPos += YL; Canvas.SetPos(4,YPos); for ( i=0; i<16; i++ ) { if ( RouteCache[i] == None ) { if ( 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); YPos += YL; Canvas.SetPos(4,YPos); } function float AdjustDesireFor(Pickup P) { return 0; } /* GetFacingDirection() returns direction faced relative to movement dir 0 = forward 16384 = right 32768 = back 49152 = left */ function int GetFacingDirection() { local float strafeMag; local vector Focus2D, Loc2D, Dest2D, Dir, LookDir, Y; // check for strafe or backup Focus2D = FocalPoint; Focus2D.Z = 0; Loc2D = Pawn.Location; Loc2D.Z = 0; Dest2D = Destination; Dest2D.Z = 0; lookDir = Normal(Focus2D - Loc2D); Dir = Normal(Dest2D - Loc2D); strafeMag = lookDir dot Dir; Y = (lookDir Cross vect(0,0,1)); if ((Y Dot (Dest2D - Loc2D)) < 0) return ( 49152 + 16384 * strafeMag ); else return ( 16384 - 16384 * strafeMag ); } // AdjustView() called if Controller's pawn is viewtarget of a player function AdjustView(float DeltaTime) { local float TargetYaw, TargetPitch; local rotator OldViewRotation,ViewRotation; Super.AdjustView(DeltaTime); if( !Pawn.bUpdateEyeHeight ) return; // update viewrotation ViewRotation = Rotation; OldViewRotation = Rotation; if ( Enemy == None ) { ViewRotation.Roll = 0; if ( DeltaTime < 0.2 ) { OldViewRotation.Yaw = OldViewRotation.Yaw & 65535; OldViewRotation.Pitch = OldViewRotation.Pitch & 65535; TargetYaw = float(Rotation.Yaw & 65535); if ( Abs(TargetYaw - OldViewRotation.Yaw) > 32768 ) { if ( TargetYaw < OldViewRotation.Yaw ) TargetYaw += 65536; else TargetYaw -= 65536; } TargetYaw = float(OldViewRotation.Yaw) * (1 - 5 * DeltaTime) + TargetYaw * 5 * DeltaTime; ViewRotation.Yaw = int(TargetYaw); TargetPitch = float(Rotation.Pitch & 65535); if ( Abs(TargetPitch - OldViewRotation.Pitch) > 32768 ) { if ( TargetPitch < OldViewRotation.Pitch ) TargetPitch += 65536; else TargetPitch -= 65536; } TargetPitch = float(OldViewRotation.Pitch) * (1 - 5 * DeltaTime) + TargetPitch * 5 * DeltaTime; ViewRotation.Pitch = int(TargetPitch); SetRotation(ViewRotation); } } } function SetOrders(name NewOrders, Controller OrderGiver); function actor GetOrderObject() { return None; } function name GetOrders() { return 'None'; } /* PrepareForMove() Give controller a chance to prepare for a move along the navigation network, from Anchor (current node) to Goal, given the reachspec for that movement. Called if the reachspec doesn't support the pawn's current configuration. By default, the pawn will crouch when it hits an actual obstruction. However, Pawns with complex behaviors for setting up their smaller collision may want to call that behavior from here */ event PrepareForMove(NavigationPoint Goal, ReachSpec Path); /* WaitForMover() Wait for Mover M to tell me it has completed its move */ function WaitForMover(Mover M) { if ( (Enemy != None) && (Level.TimeSeconds - LastSeenTime < 3.0) ) Focus = Enemy; PendingMover = M; bPreparingMove = true; Pawn.Acceleration = vect(0,0,0); } /* MoverFinished() Called by Mover when it finishes a move, and this pawn has the mover set as its PendingMover */ function MoverFinished() { if ( PendingMover.MyMarker.ProceedWithMove(Pawn) ) { PendingMover = None; bPreparingMove = false; } } /* UnderLift() called by mover when it hits a pawn with that mover as its pendingmover while moving to its destination */ function UnderLift(Mover M) { local NavigationPoint N; bPreparingMove = false; PendingMover = None; // find nearest lift exit and go for that if ( (MoveTarget == None) || MoveTarget.IsA('LiftCenter') ) for ( N=Level.NavigationPointList; N!=None; N=N.NextNavigationPoint ) if ( N.IsA('LiftExit') && (LiftExit(N).LiftTag == M.Tag) && ActorReachable(N) ) { MoveTarget = N; return; } } function bool PriorityObjective() { return false; } function Startle(Actor A); skp'Ee%zp'(F%F7n|Fnp'SF|S7n&SnS&nSE7n&n'F( Gsf// ==================================================================== // Class: Engine.AdminBase // Parent: Core.Object // // // ==================================================================== class AdminBase extends Object Within PlayerController abstract native; var bool bAdmin; var AccessControl Manager; var localized string Msg_PlayerList; var localized string Msg_AllGameMaps; var localized string Msg_AllMapLists; var localized string Msg_MapRotationList; var localized string Msg_NoMapsAdded; var localized string Msg_AddedMapToList; var localized string Msg_NoMapsRemoved; var localized string Msg_RemovedFromList; var localized string Msg_PlayerBanned; var localized string Msg_SessionBanned; var localized string Msg_PlayerKicked; var localized string Msg_NextMapNotFound; var localized string Msg_ChangingMapTo; var localized string Msg_NoMapInRotation; var localized string Msg_NoMapsFound; var localized string Msg_MapIsInRotation; var localized string Msg_MapNotInRotation; var localized string Msg_UnknownParam; var localized string Msg_NoParamsFound; var localized string Msg_ParamModified; var localized string Msg_ParamNotModified; var localized string Msg_MapListAdded; var localized string Msg_MapListRemoved; var localized string Msg_MapIsNotInRotation; var localized string Msg_EditingMapList; function Created() { if (Level.Game.AccessControl != None) Manager = Level.Game.AccessControl; } function DoLogin( string UserName, string Password ); function DoLogout(); function DoSwitch( string URL) { Level.ServerTravel( URL, false ); } function GoToNextMap() { if (bAdmin) { Level.Game.bChangeLevels=true; Level.Game.bAlreadyChanged=false; Level.Game.RestartGame(); } } function ShowCurrentMapList() { local int i, c; local array Ar; i = MapHandler.GetGameIndex(string(Level.Game.Class)); c = MapHandler.GetActiveList(i); Ar = MapHandler.GetCacheMapList( Level.Game.Acronym ); SendComplexMsg(Ar, Msg_AllGameMaps@MapHandler.GetMapListTitle(i,c)); } function array GetMapListNames(string GameType) { local int i; local array Ar; i = MapHandler.GetGameIndex(GameType); Ar = MapHandler.GetMapListNames(i); return Ar; } function MaplistCommand( string Cmd, string Extra ) { local array Values; local string Str; local int i, c; if (CanPerform("Ml")) { Cmd = Caps(Cmd); i = MapHandler.GetGameIndex(string(Level.Game.Class)); switch (Cmd) { case "LIST": Values = MapHandler.GetMapListNames(i); SendComplexMsg(Values, Repl(Msg_AllMapLists, "%gametype%", string(Level.Game.Class))); break; case "USED": if (Extra == "") c = MapHandler.GetActiveList(i); else c = int(Extra); Str = MapHandler.GetMapListTitle(i, c); Values = MapHandler.GetMapList(i, c); SendComplexMsg(Values, Repl(Msg_MapRotationList, "%maplist%", Str)); break; case "SWITCH": if (Extra == "") c = MapHandler.GetActiveList(i); else c = int(Extra); Str = MapHandler.GetMapListTitle(i, c); case "ADD": c = MapHandler.GetActiveList(i); Split(Extra, ",", Values); if (Values.Length == 0) ClientMessage( Repl(Msg_NoMapsAdded, "%maplist%", MapHandler.GetMapListTitle(i,c)) ); else { for ( i = Values.Length - 1; i >= 0; i-- ) { if ( !MapHandler.AddMap(i,c,Values[i]) ) Values.Remove(i,1); } SendComplexMsg(Values, Msg_AddedMapToList @ MapHandler.GetMapListTitle(i, c)); } break; case "DEL": c = MapHandler.GetActiveList(i); Split(Extra, ",", Values); if ( Values.Length == 0 ) ClientMessage( Repl(Msg_NoMapsRemoved, "%maplist%", MapHandler.GetMaplistTitle(i,c)) ); else { for ( i = Values.Length - 1; i >= 0; i-- ) { if ( !MapHandler.RemoveMap(i,c,Values[i]) ) Values.Remove(i,1); } SendComplexMsg(Values, Msg_RemovedFromList @ MapHandler.GetMapListTitle(i, c)); } break; } } } function RestartCurrentMap() { Level.ServerTravel("?restart",false); } // ===================================================================================================================== // ===================================================================================================================== // Console Commands // ===================================================================================================================== // ===================================================================================================================== exec function PlayerList() { local PlayerReplicationInfo PRI; if ( CanPerform("Xp") ) { log(Msg_PlayerList); ForEach DynamicActors(class'PlayerReplicationInfo', PRI) log(PRI.PlayerName@"( ping"@PRI.Ping$")"); } } exec function Kick( string Cmd, string Extra ) { local array Params; local array AllPRI; local Controller C, NextC; local int i; if (CanPerform("Kp") || CanPerform("Kb")) // Kp = Kick Players, Kb = Kick/Ban { if (Cmd ~= "List") { // Get the list of players to kick by showing their PlayerID // TODO: Display Fixed Playername (no garbage chars in name)? // TODO: Display Sorted ? Level.Game.GameReplicationInfo.GetPRIArray(AllPRI); for (i = 0; i Records; class'CacheManager'.static.GetGameTypeList(Records); for ( i = 0; i < Records.Length; i++ ) { if (GameType ~= Records[i].ClassName) break; if (GameType ~= Records[i].GameAcronym) break; if (GameType ~= Records[i].TextName) break; if (Right(Records[i].ClassName, Len(GameType)+1) ~= ("."$GameType)) break; if (Right(Records[i].TextName, Len(GameType)+1) ~= ("."$GameType)) break; } if ( i < Records.Length ) return Records[i].ClassName; return ""; } protected function SendComplexMsg(array Arr, string Title) { local int i, Longest; local string Line, Border; local string Prefix, Suffix; for (i = 0; i < Arr.Length; i++) if ( Len(Arr[i]) > Longest ) Longest = Len(Arr[i]); // Account for borders Longest += 8; for (Border = ""; Len(Border) < Longest; Border = Border $ "-"); ClientMessage(Title); ClientMessage(Border); for (i = 0; i < Arr.Length; i++) { Prefix = Right("[] "$i, 4)$")"; Suffix = " []"; Line = Prefix $ Arr[i] $ Suffix; while (Len(Line) < Longest) { Suffix = " " $ Suffix; Line = Prefix $ Arr[i] $ Suffix; } ClientMessage(Line); } ClientMessage(Border); } // Mask can be *|*Name|Name*|*Name*|Name protected function bool MaskedCompare(string SettingName, string Mask) { local bool bMaskLeft, bMaskRight; local int MaskLen; if (Mask == "*" || Mask == "**") return true; MaskLen = Len(Mask); bMaskLeft = Left(Mask, 1) == "*"; bMaskRight = Right(Mask, 1) == "*"; if (bMaskLeft && bMaskRight) return Instr(Caps(SettingName), Mid(Caps(Mask), 1, MaskLen-2)) >= 0; if (bMaskLeft) return Left(SettingName, MaskLen -1) ~= Left(Mask, MaskLen - 1); if (bMaskRight) return Right(SettingName, MaskLen -1) ~= Right(Mask, MaskLen - 1); return SettingName ~= Mask; } // TODO: Add support for bPositiveOnly function bool IsNumeric(string Param, optional bool bPositiveOnly) { local int p; p=0; while (Mid(Param, p, 1) == " ") p++; while (Mid(Param, p, 1) >= "0" && Mid(Param, p, 1) <= "9") p++; while (Mid(Param, p, 1) == " ") p++; if (Mid(Param, p) != "") return false; return true; } function array SplitParams(string Params) { local array Splitted; local string Delim; local int p, start; while (Params != "") { p = 0; while (Mid(Params, p, 1) == " ") p++; if (Mid(Params, p) == "") break; // Special case: Delimited string start = p; if (Mid(Params, p, 1) == "\"") { p++; start++; while (Mid(Params, p, 1) != "" && Mid(Params, p, 1) != "\"") p++; // Do not accept unfinished quoted strings if (Mid(Params, p, 1) == "\"") { Splitted[Splitted.Length] = Mid(Params, start, p-start); p++; } } else { while (Mid(Params, p, 1) != "" && Mid(Params, p, 1) != Delim) p++; Splitted[Splitted.Length] = Mid(Params, start, p-start); } Params = Mid(Params, p); } return Splitted; } sFssNclass Admin extends AdminBase; // Execute an administrative console command on the server. function DoLogin( string Username, string Password ) { if (Level.Game.AccessControl.AdminLogin(Outer, Username, Password)) { bAdmin = true; Level.Game.AccessControl.AdminEntered(Outer, ""); } } function DoLogout() { if (Level.Game.AccessControl.AdminLogout(Outer)) { bAdmin = false; Level.Game.AccessControl.AdminExited(Outer); } } sUssoRG~'2R%/R7nRnR Gsa//============================================================================= // Actor: The base class of all actors. // Actor is the base class of all gameplay objects. // A large number of properties, behaviors and interfaces are implemented in Actor, including: // // - Display // - Animation // - Physics and world interaction // - Making sounds // - Networking properties // - Actor creation and destruction // - Triggering and timers // - Actor iterator functions // - Message broadcasting // // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class Actor extends Object abstract native nativereplication; // Imported data (during full rebuild). #exec Texture Import File=Textures\S_Actor.pcx Name=S_Actor Mips=Off MASKED=1 //----------------------------------------------------------------------------- // Lighting. // Light modulation. var(Lighting) enum ELightType { LT_None, LT_Steady, LT_Pulse, LT_Blink, LT_Flicker, LT_Strobe, LT_BackdropLight, LT_SubtlePulse, LT_TexturePaletteOnce, LT_TexturePaletteLoop, LT_FadeOut } LightType; // Spatial light effect to use. var(Lighting) enum ELightEffect { LE_None, LE_TorchWaver, LE_FireWaver, LE_WateryShimmer, LE_Searchlight, LE_SlowWave, LE_FastWave, LE_CloudCast, LE_StaticSpot, LE_Shock, LE_Disco, LE_Warp, LE_Spotlight, LE_NonIncidence, LE_Shell, LE_OmniBumpMap, LE_Interference, LE_Cylinder, LE_Rotor, LE_Negative, // sjs LE_Sunlight, LE_QuadraticNonIncidence } LightEffect; // Lighting info. var(LightColor) byte LightHue, LightSaturation; var(LightColor) float LightBrightness; var(Lighting) float LightRadius; var(Lighting) byte LightPeriod, LightPhase, LightCone; // Drawing effect. var(Display) const enum EDrawType { DT_None, DT_Sprite, DT_Mesh, DT_Brush, DT_RopeSprite, DT_VerticalSprite, DT_Terraform, DT_SpriteAnimOnce, DT_StaticMesh, DT_DrawType, DT_Particle, DT_AntiPortal, DT_FluidSurface } DrawType; enum EFilterState { FS_Maybe, FS_Yes, FS_No }; var const native EFilterState StaticFilterState; var(Display) const StaticMesh StaticMesh; // StaticMesh if DrawType=DT_StaticMesh // Owner. var const Actor Owner; // Owner actor. var const Actor Base; // Actor we're standing on. struct ActorRenderDataPtr { var pointer Ptr; }; struct LightRenderDataPtr { var pointer Ptr; }; var const native ActorRenderDataPtr ActorRenderData; var const native LightRenderDataPtr LightRenderData; var const native int RenderRevision; struct BatchReference { var int BatchIndex, ElementIndex; }; var const native array StaticSectionBatches; var(Display) const name ForcedVisibilityZoneTag; // Makes the visibility code treat the actor as if it was in the zone with the given tag. var(Display) float CullDistance; // 0 == no distance cull, < 0 only drawn at distance > 0 cull at distance // Lighting. var(Lighting) bool bSpecialLit; // Only affects special-lit surfaces. var(Lighting) bool bActorShadows; // Light casts actor shadows. var(Lighting) bool bCorona; // Light uses Skin as a corona. var(Lighting) bool bDirectionalCorona; // (if bCorona) Make corona bigger if it faces you, and zero and 90 degrees or beyond. var(Lighting) bool bAttenByLife; // sjs - attenuate light by diminishing lifespan var(Lighting) bool bLightingVisibility; // Calculate lighting visibility for this actor with line checks. var(Display) bool bUseDynamicLights; var bool bLightChanged; // Recalculate this light's lighting now. var bool bDramaticLighting; // Flags. var const bool bStatic; // Does not move or change over time. Don't let L.D.s change this - screws up net play var(Advanced) bool bHidden; // Is hidden during gameplay. var(Advanced) 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(Lighting) bool bDynamicLight; // This light is dynamic. var bool bTimerLoop; // Timer loops (else is one-shot). var bool bOnlyOwnerSee; // Only owner can see this actor. var(Advanced) bool bHighDetail; // Only show up in high or super high detail mode. var(Advanced) bool bSuperHighDetail; // Only show up in super high detail mode. var bool bOnlyDrawIfAttached; // don't draw this actor if not attached (useful for net clients where attached actors and their bases' replication may not be synched) var(Advanced) bool bStasis; // In StandAlone games, turn off if not in a recently rendered zone turned off if bStasis and physics = PHYS_None or PHYS_Rotating. var bool bTrailerAllowRotation; // If PHYS_Trailer and want independent rotation control. var bool bTrailerSameRotation; // If PHYS_Trailer and true, have same rotation as owner. var bool bTrailerPrePivot; // If PHYS_Trailer and true, offset from owner by PrePivot. var bool bWorldGeometry; // Collision and Physics treats this actor as world geometry var(Display) bool bAcceptsProjectors; // Projectors can project onto this actor var bool bOrientOnSlope; // when landing, orient base on slope of floor var const bool bOnlyAffectPawns; // Optimisation - only test ovelap against pawns. Used for influences etc. var(Display) bool bDisableSorting; // Manual override for translucent material sorting. var(Movement) bool bIgnoreEncroachers; // Ignore collisions between movers and this actor var bool bShowOctreeNodes; var bool bWasSNFiltered; // Mainly for debugging - the way this actor was inserted into Octree. var transient const bool bShouldStopKarma; // Internal. var const bool bDetailAttachment; // If actor is attached to Karma object, only move once a frame regardless of timestep subdivision. Only valid when bCollideActors is false. // Networking flags var const bool bNetTemporary; // Tear-off simulation in network play. var bool bOnlyRelevantToOwner; // this actor is only relevant to its owner. var transient const 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 var bool bReplicateAnimations; // Should replicate SimAnim var const bool bNetInitialRotation; // Should replicate initial rotation var bool bCompressedPosition; // used by networking code to flag compressed position replication var bool bAlwaysZeroBoneOffset; // if true, offset always zero when attached to skeletalmesh var bool bIgnoreVehicles; // Ignore collisions between vehicles and this actor (only relevant if bIgnoreEncroachers is false) var(Display) bool bDeferRendering; // defer rendering if DrawType is DT_Particle or Style is STY_Additive var bool bBadStateCode; // used for recovering from illegal state transitions (hack) // 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_MovingBrush, PHYS_Spider, PHYS_Trailer, PHYS_Ladder, PHYS_RootMotion, PHYS_Karma, PHYS_KarmaRagDoll, PHYS_Hovering, PHYS_CinMotion, } Physics; // Net variables. enum ENetRole { ROLE_None, // No role at all. ROLE_DumbProxy, // Dumb proxy of this actor. 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; var const transient int NetTag; var float NetUpdateTime; // time of last update var float NetUpdateFrequency; // How many net updates per seconds. var float NetPriority; // Higher priorities means update it more frequently. var Pawn Instigator; // Pawn responsible for damage caused by this actor. var(Sound) sound AmbientSound; // Ambient sound effect. var const name AttachmentBone; // name of bone to which actor is attached (if attached to center of base, =='') var const LevelInfo Level; // Level this actor is on. var transient const Level XLevel; // Level object. var(Advanced) float LifeSpan; // How old the object lives before dying, 0=forever. //----------------------------------------------------------------------------- // Structures. // Identifies a unique convex volume in the world. struct PointRegion { var zoneinfo Zone; // Zone. var int iLeaf; // Bsp leaf. var byte ZoneNumber; // Zone number. }; //----------------------------------------------------------------------------- // Major actor properties. // Scriptable. var const PointRegion Region; // Region this actor is in. var float TimerRate; // Timer event, 0=no timer. var(Display) Material OverlayMaterial; // sjs - shader/material effect to use with skin var(Display) const mesh Mesh; // Mesh if DrawType=DT_Mesh. var transient float LastRenderTime; // last time this actor was rendered. var(Events) name Tag; // Actor's tag name. var transient array Leaves; // BSP leaves this actor is in. var(Events) name Event; // The event this actor causes. var Inventory Inventory; // Inventory chain. var const float TimerCounter; // Counts up until it reaches TimerRate. var transient MeshInstance MeshInstance; // Mesh instance. var(Display) float LODBias; var(Object) name InitialState; var(Object) name Group; // Internal. var const array Touching; // List of touching actors. var const transient array OctreeNodes;// Array of nodes of the octree Actor is currently in. Internal use only. var const transient Box OctreeBox; // Actor bounding box cached when added to Octree. Internal use only. var const transient vector OctreeBoxCenter; var const transient vector OctreeBoxRadii; var const actor Deleted; // Next actor in just-deleted chain. var const float LatentFloat; // Internal latent function use. // Internal tags. var const native int CollisionTag; var const transient int JoinedTag; // The actor's position and rotation. var const PhysicsVolume PhysicsVolume; // physics volume this actor is currently in var(Movement) const vector Location; // Actor's location; use Move to set. var(Movement) const rotator Rotation; // Rotation. var(Movement) vector Velocity; // Velocity. var vector Acceleration; // Acceleration. var const vector CachedLocation; var const Rotator CachedRotation; var Matrix CachedLocalToWorld; // Attachment related variables var(Movement) name AttachTag; var const array Attached; // array of actors attached to this actor. var const vector RelativeLocation; // location relative to base/bone (valid if base exists) var const rotator RelativeRotation; // rotation relative to base/bone (valid if base exists) var const Matrix HardRelMatrix; // Transform of actor in base's ref frame. Doesn't change after SetBase. // Projectors struct ProjectorRenderInfoPtr { var pointer Ptr; }; // Hack to to fool C++ header generation... struct StaticMeshProjectorRenderInfoPtr { var pointer Ptr; }; var const native array Projectors;// Projected textures on this actor var const native array StaticMeshProjectors; //----------------------------------------------------------------------------- // Display properties. var(Display) Material Texture; // Sprite texture.if DrawType=DT_Sprite var StaticMeshInstance StaticMeshInstance; // Contains per-instance static mesh data, like static lighting data. var const export model Brush; // Brush if DrawType=DT_Brush. var(Display) const float DrawScale; // Scaling factor, 1.0=normal size. var(Display) const vector DrawScale3D; // Scaling vector, (1.0,1.0,1.0)=normal size. var(Display) vector PrePivot; // Offset from box center for drawing. var(Display) array Skins; // Multiple skin support - not replicated. var Material RepSkin; // replicated skin (sets Skins[0] if not none) var(Display) byte AmbientGlow; // Ambient brightness, or 255=pulsing. var(Display) byte MaxLights; // Limit to hardware lights active on this primitive. var(Display) enum EUV2Mode { UVM_MacroTexture, UVM_LightMap, UVM_Skin, } UV2Mode; var(Display) ConvexVolume AntiPortal; // Convex volume used for DT_AntiPortal var(Display) Material UV2Texture; var(Display) float ScaleGlow; var(Collision) enum ESurfaceTypes // !! - must mirror with Texture.uc in order for BSP geom surface's to match { EST_Default, EST_Rock, EST_Dirt, EST_Metal, EST_Wood, EST_Plant, EST_Flesh, EST_Ice, EST_Snow, EST_Water, EST_Glass, EST_Custom00, EST_Custom01, EST_Custom02, EST_Custom03, EST_Custom04, EST_Custom05, EST_Custom06, EST_Custom07, EST_Custom08, EST_Custom09, EST_Custom10, EST_Custom11, EST_Custom12, EST_Custom13, EST_Custom14, EST_Custom15, EST_Custom16, EST_Custom17, EST_Custom18, EST_Custom19, EST_Custom20, EST_Custom21, EST_Custom22, EST_Custom23, EST_Custom24, EST_Custom25, EST_Custom26, EST_Custom27, EST_Custom28, EST_Custom29, EST_Custom30, EST_Custom31, } SurfaceType; // Style for rendering sprites, meshes. var(Display) enum ERenderStyle { STY_None, STY_Normal, STY_Masked, STY_Translucent, STY_Modulated, STY_Alpha, STY_Additive, STY_Subtractive, STY_Particle, STY_AlphaZ, } Style; // Display. var(Display) bool bUnlit; // Lights don't affect actor. var(Display) bool bShadowCast; // Casts static shadows. var(Display) bool bStaticLighting; // Uses raytraced lighting. var(Display) bool bUseLightingFromBase; // Use Unlit/AmbientGlow from Base // Advanced. var bool bHurtEntry; // keep HurtRadius from being reentrant var(Advanced) bool bGameRelevant; // Always relevant for game var(Advanced) bool bCollideWhenPlacing; // This actor collides with the world when placing. var bool bTravel; // Actor is capable of travelling among servers. var(Advanced) 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(Advanced) 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 bAnimByOwner; // Animation dictated by owner. var bool bOwnerNoSee; // Everything but the owner can see this actor. var(Advanced) bool bCanTeleport; // This actor can be teleported. var bool bClientAnim; // Don't replicate any animations - animation done client-side var bool bDisturbFluidSurface; // Cause ripples when in contact with FluidSurface. var float FluidSurfaceShootStrengthMod; // if bDisturbFluidSurface == true, FluidSurface's ShootStrength is multiplied by this before doing the ripples var const bool bAlwaysTick; // Update even when players-only. var(Sound) bool bFullVolume; // Whether to apply ambient attenuation. var bool bNotifyLocalPlayerTeamReceived; //wants NotifyLocalPlayerTeamReceived() var(Movement) bool bHardAttach; // Uses 'hard' attachment code. bBlockActor and bBlockPlayer must also be false. // This actor cannot then move relative to base (setlocation etc.). // Dont set while currently based on something! var bool bForceSkelUpdate; // update skeleton (and attached actor positions) even if not rendered var const bool bClientAuthoritative; // Remains ROLE_Authority on client (only valid for bStatic or bNoDelete actors) //----------------------------------------------------------------------------- // Sound. // Ambient sound. var(Sound) byte SoundVolume; // Volume of ambient sound. var(Sound) byte SoundPitch; // Sound pitch shift, 64.0=none. // Sound occlusion enum ESoundOcclusion { OCCLUSION_Default, OCCLUSION_None, OCCLUSION_BSP, OCCLUSION_StaticMeshes, }; var(Sound) ESoundOcclusion SoundOcclusion; // Sound occlusion approach. // Sound slots for actors. enum ESoundSlot { SLOT_None, SLOT_Misc, SLOT_Pain, SLOT_Interact, SLOT_Ambient, SLOT_Talk, SLOT_Interface, }; // Music transitions. enum EMusicTransition { MTRAN_None, MTRAN_Instant, MTRAN_Segue, MTRAN_Fade, MTRAN_FastFade, MTRAN_SlowFade, }; var(Sound) float SoundRadius; // Radius of ambient sound. // Regular sounds. var(Sound) float TransientSoundVolume; // default sound volume for regular sounds (can be overridden in playsound) var(Sound) float TransientSoundRadius; // default sound radius for regular sounds (can be overridden in playsound) //----------------------------------------------------------------------------- // Collision. // Collision size. var(Collision) const float CollisionRadius; // Radius of collision cyllinder. var(Collision) const float CollisionHeight; // Half-height cyllinder. // Collision flags. var(Collision) const bool bCollideActors; // Collides with other actors. var bool bCollideWorld; // Collides with the world. var(Collision) bool bBlockActors; // Blocks other nonplayer actors. var bool bBlockPlayers; // OBSOLETE - no longer used var bool bBlockProjectiles; // hack for Paladin shield var(Collision) bool bProjTarget; // Projectiles should potentially target this actor. var(Collision) bool bBlockZeroExtentTraces; // block zero extent actors/traces var(Collision) bool bBlockNonZeroExtentTraces; // block non-zero extent actors/traces var(Collision) bool bAutoAlignToTerrain; // Auto-align to terrain in the editor var(Collision) bool bUseCylinderCollision;// Force axis aligned cylinder collision (useful for static mesh pickups, etc.) var(Collision) const bool bBlockKarma; // Block actors being simulated with Karma. var bool bBlocksTeleport; var(Display) bool bAlwaysFaceCamera; // actor will be rendered always facing the camera like a sprite var bool bNetNotify; // actor wishes to be notified of replication events var bool bClientTrigger; // replicated property used to trigger client side ClientTrigger() event var bool bUseCollisionStaticMesh; var bool bSmoothKarmaStateUpdates; // When true, karma state updates will be smoothly interpolated //----------------------------------------------------------------------------- // Physics. // Options. var bool bIgnoreOutOfWorld; // Don't destroy if enters zone zero var(Movement) bool bBounce; // Bounces when hits ground fast. var(Movement) bool bFixedRotationDir; // Fixed direction of rotation. var(Movement) bool bRotateToDesired; // Rotate to DesiredRotation. var(Movement) bool bIgnoreTerminalVelocity; // If PHYS_Falling, ignore the TerminalVelocity of the PhysicsVolume. var(Movement) bool bOrientToVelocity; // Orient in the direction of current velocity. var bool bInterpolating; // Performing interpolating. var const bool bJustTeleported; // Used by engine physics - not valid for scripts. // Physics properties. var(Movement) float Mass; // Mass of this actor. var(Movement) float Buoyancy; // Water buoyancy. var(Movement) rotator RotationRate; // Change in rotation per second. var(Movement) rotator DesiredRotation; // Physics will smoothly rotate actor to this rotation if bRotateToDesired. var Actor PendingTouch; // Actor touched during move which wants to add an effect after the movement completes var const vector ColLocation; // Actor's old location one move ago. Only for debugging var(Events) Name ExcludeTag[8]; // sjs - multipurpose exclusion tag for excluding lights, projectors, rendering actors, blocking weather const MAXSTEPHEIGHT = 35.0; // Maximum step height walkable by pawns const MINFLOORZ = 0.7; // minimum z value for floor normal (if less, not a walkable floor) // 0.7 ~= 45 degree angle for floor // ifdef WITH_KARMA // Used to avoid compression struct KRBVec { var float X, Y, Z; }; struct KRigidBodyState { var KRBVec Position; var Quat Quaternion; var KRBVec LinVel; var KRBVec AngVel; }; // Scary internal params used by Karma. BE VERY CAREFUL!! // NB. These take affect until you quit the game! Make sure you reset them to defaults when leaving mod etc. struct KSimParams { var float GammaPerSec; // Relaxation constant. Making it larger pushes things apart harder when they penetrate. var float Epsilon; // Global constraint compliance. Making it larger makes contacts/joints softer. var float PenetrationOffset; // Resting penetration. Making this larger can reduce jiggling. var float PenetrationScale; // Artificially increase penetration - makes contacts 'stiffer' var float ContactSoftness; // Softness of just contact constraints. var float MaxPenetration; // Maximum penetration allowed. var float MaxTimestep; // Maximum timestep ever used to advance rigid body simulation. }; var(Karma) export editinline KarmaParamsCollision KParams; // Parameters for Karma Collision/Dynamics. var const native int KStepTag; var float AccumKarmaAngleError; // endif //----------------------------------------------------------------------------- // Animation replication (can be used to replicate channel 0 anims for dumb proxies) struct AnimRep { var name AnimSequence; var bool bAnimLoop; var byte AnimRate; // note that with compression, max replicated animrate is 4.0 var byte AnimFrame; var byte TweenRate; // note that with compression, max replicated tweentime is 4 seconds }; var AnimRep SimAnim; // only replicated if bReplicateAnimations is true //----------------------------------------------------------------------------- // Forces. enum EForceType { FT_None, FT_DragAlong, FT_Constant, }; var (Force) EForceType ForceType; var (Force) float ForceRadius; var (Force) float ForceScale; var (Force) float ForceNoise; // sjs - 0.0 - 1.0 //----------------------------------------------------------------------------- // Networking. // Symmetric network flags, valid during replication only. var const bool bNetInitial; // Initial network update. var const bool bNetOwner; // Player owns this actor. var const bool bNetRelevant; // Actor is currently relevant. Only valid server side, only when replicating variables. var const bool bDemoRecording; // True we are currently demo recording var const bool bClientDemoRecording;// True we are currently recording a client-side demo var const bool bRepClientDemo; // True if remote client is recording demo var const bool bClientDemoNetFunc;// True if we're client-side demo recording and this call originated from the remote. var const bool bDemoOwner; // Demo recording driver owns this actor. var bool bNoRepMesh; // don't replicate mesh var bool bNotOnDedServer; // destroy if on dedicated server and RemoteRole == ROLE_None (emitters, etc.) var bool bAlreadyPrecachedMaterials; var bool bAlreadyPrecachedMeshes; //Editing flags var(Advanced) bool bHiddenEd; // Is hidden during editing. var(Advanced) bool bHiddenEdGroup;// Is hidden by the group brower. var(Advanced) bool bDirectional; // Actor shows direction arrow during editing. var const bool bSelected; // Selected in UnrealEd. var(Advanced) bool bEdShouldSnap; // Snap to grid in editor. var transient bool bEdSnap; // Should snap to grid in UnrealEd. var transient const bool bTempEditor; // Internal UnrealEd. var bool bObsolete; // actor is obsolete - warn level designers to remove it 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. var bool bTraceWater; // if true, trace() by this actor returns collisions with water volumes var class MessageClass; //----------------------------------------------------------------------------- // Enums. // Travelling 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 }; enum eKillZType { KILLZ_None, KILLZ_Lava, KILLZ_Suicide }; enum EFlagState { FLAG_Home, FLAG_HeldFriendly, FLAG_HeldEnemy, FLAG_Down, }; var(Display) float OverlayTimer; // sjs - set by server var(Display) transient float ClientOverlayTimer; // sjs - client inital time count var(Display) transient float ClientOverlayCounter; // sjs - current secs left to show overlay effect var Material HighDetailOverlay; // if high detail mode, use this overlay when no other overlay is active struct FireProperties { var class AmmoClass; var class ProjectileClass; var float WarnTargetPct; var float MaxRange; var bool bTossed; var bool bTrySplash; var bool bLeadTarget; var bool bInstantHit; var bool bInitialized; }; //----------------------------------------------------------------------------- // natives. // Execute a console command in the context of the current level and game engine. native function string ConsoleCommand( string Command, optional bool bWriteToLog ); // Copy the specified object's properties to the clipboard. The format generated is for pasting into the editor if it's an actor or into the defaultproperties block of a class if it isn't native function CopyObjectToClipboard(Object Obj); native function TextToSpeech( string Text, float Volume ); //----------------------------------------------------------------------------- // Network replication. replication { // Location unreliable if ( (!bSkipActorPropertyReplication || bNetInitial) && bReplicateMovement && (((RemoteRole == ROLE_AutonomousProxy) && bNetInitial) || ((RemoteRole == ROLE_SimulatedProxy) && (bNetInitial || bUpdateSimulatedPosition) && ((Base == None) || Base.bWorldGeometry)) || ((RemoteRole == ROLE_DumbProxy) && ((Base == None) || Base.bWorldGeometry))) ) Location; unreliable if ( (!bSkipActorPropertyReplication || bNetInitial) && bReplicateMovement && ((DrawType == DT_Mesh) || (DrawType == DT_StaticMesh)) && (((RemoteRole == ROLE_AutonomousProxy) && bNetInitial) || ((RemoteRole == ROLE_SimulatedProxy) && (bNetInitial || bUpdateSimulatedPosition) && ((Base == None) || Base.bWorldGeometry)) || ((RemoteRole == ROLE_DumbProxy) && ((Base == None) || Base.bWorldGeometry))) ) Rotation; unreliable if ( (!bSkipActorPropertyReplication || bNetInitial) && bReplicateMovement && RemoteRole<=ROLE_SimulatedProxy ) Base,bOnlyDrawIfAttached; unreliable if( (!bSkipActorPropertyReplication || bNetInitial) && bReplicateMovement && RemoteRole<=ROLE_SimulatedProxy && (Base != None) && !Base.bWorldGeometry) RelativeRotation, RelativeLocation, AttachmentBone; // Physics unreliable if( (!bSkipActorPropertyReplication || bNetInitial) && bReplicateMovement && (((RemoteRole == ROLE_SimulatedProxy) && (bNetInitial || bUpdateSimulatedPosition)) || ((RemoteRole == ROLE_DumbProxy) && (Physics == PHYS_Falling))) ) Velocity; unreliable if( (!bSkipActorPropertyReplication || bNetInitial) && bReplicateMovement && (((RemoteRole == ROLE_SimulatedProxy) && bNetInitial) || (RemoteRole == ROLE_DumbProxy)) ) Physics; unreliable if( (!bSkipActorPropertyReplication || bNetInitial) && bReplicateMovement && (RemoteRole <= ROLE_SimulatedProxy) && (Physics == PHYS_Rotating) ) bFixedRotationDir, bRotateToDesired, RotationRate, DesiredRotation; // Ambient sound. unreliable if( (!bSkipActorPropertyReplication || bNetInitial) && (Role==ROLE_Authority) && (!bNetOwner || !bClientAnim) ) AmbientSound; unreliable if( (!bSkipActorPropertyReplication || bNetInitial) && (Role==ROLE_Authority) && (!bNetOwner || !bClientAnim) && (AmbientSound!=None) ) SoundRadius, SoundVolume, SoundPitch; // Animation. unreliable if( (!bSkipActorPropertyReplication || bNetInitial) && (Role==ROLE_Authority) && (DrawType==DT_Mesh) && bReplicateAnimations ) SimAnim; unreliable if ( (!bSkipActorPropertyReplication || bNetInitial) && (Role==ROLE_Authority) ) bHidden; // Properties changed using accessor functions (Owner, rendering, and collision) unreliable if ( (!bSkipActorPropertyReplication || bNetInitial) && (Role==ROLE_Authority) && bNetDirty ) DrawScale, DrawType, bCollideActors,bCollideWorld,bOnlyOwnerSee,Texture,Style, RepSkin, bClientTrigger; unreliable if ( (!bSkipActorPropertyReplication || bNetInitial) && (Role==ROLE_Authority) && bNetDirty && (bCollideActors || bCollideWorld) ) bProjTarget, bBlockActors, CollisionRadius, CollisionHeight, bIgnoreEncroachers; // Properties changed only when spawning or in script (relationships, rendering, lighting) unreliable if ( (!bSkipActorPropertyReplication || bNetInitial) && (Role==ROLE_Authority) ) Role,RemoteRole,bNetOwner,LightType,bTearOff; unreliable if ( (!bSkipActorPropertyReplication || bNetInitial) && (Role==ROLE_Authority) && bNetDirty && bNetOwner ) Owner, Inventory; unreliable if ( (!bSkipActorPropertyReplication || bNetInitial) && (Role==ROLE_Authority) && bNetDirty && bReplicateInstigator ) Instigator; unreliable if (bNetDirty && Role==ROLE_Authority) OverlayMaterial, OverlayTimer; // Infrequently changed mesh properties unreliable if ( (!bSkipActorPropertyReplication || bNetInitial) && (Role==ROLE_Authority) && bNetDirty && (DrawType == DT_Mesh) ) AmbientGlow,bUnlit,PrePivot; unreliable if ( (!bSkipActorPropertyReplication || bNetInitial) && (Role==ROLE_Authority) && bNetDirty && !bNoRepMesh && (DrawType == DT_Mesh) ) Mesh; unreliable if ( (!bSkipActorPropertyReplication || bNetInitial) && (Role==ROLE_Authority) && bNetDirty && (DrawType == DT_StaticMesh) ) StaticMesh; // Infrequently changed lighting properties. unreliable if ( (!bSkipActorPropertyReplication || bNetInitial) && (Role==ROLE_Authority) && bNetDirty && (LightType != LT_None) ) LightEffect, LightBrightness, LightHue, LightSaturation, LightRadius, LightPeriod, LightPhase, bSpecialLit; // replicated functions unreliable if( bDemoRecording ) DemoPlaySound; } //============================================================================= // Actor error handling. // Handle an error and kill this one actor. native(233) final function Error( coerce string S ); // check if class has HideDropDown specifier native final static function bool ShouldBeHidden(); //============================================================================= // General functions. // Latent functions. native(256) final latent function Sleep( float Seconds ); // Collision. native(262) final function SetCollision( optional bool NewColActors, optional bool NewBlockActors, optional bool NewBlockPlayers ); // NOTE - bBlockPlayers is obsolete native(283) final function bool SetCollisionSize( float NewRadius, float NewHeight ); native final function SetDrawScale(float NewScale); native final function SetDrawScale3D(vector NewScale3D); native final function SetStaticMesh(StaticMesh NewStaticMesh); native final function SetDrawType(EDrawType NewDrawType); // 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 ); // 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(3969) final function bool MoveSmooth( vector Delta ); native(3971) final function AutonomousPhysics(float DeltaSeconds); // Relations. native(298) final function SetBase( actor NewBase, optional vector NewFloor ); native(272) final function SetOwner( actor NewOwner ); native final function bool IsJoinedTo( actor Other ); //============================================================================= // Animation. native final function string GetMeshName(); // Animation functions. native(259) final function bool PlayAnim( name Sequence, optional float Rate, optional float TweenTime, optional int Channel ); native(260) final function bool LoopAnim( name Sequence, optional float Rate, optional float TweenTime, optional int Channel ); native(294) final function bool TweenAnim( name Sequence, float Time, optional int Channel ); native(282) final function bool IsAnimating(optional int Channel); native(261) final latent function FinishAnim(optional int Channel); native(263) final function bool HasAnim( name Sequence ); native final function StopAnimating( optional bool ClearAllButBase ); native final function FreezeAnimAt( float Time, optional int Channel); native final function SetAnimFrame( float Time, optional int Channel, optional int UnitFlag ); native final function bool IsTweening(int Channel); native final function AnimStopLooping(optional int Channel); // jjs // ifdef WITH_LIPSINC native final function PlayLIPSincAnim( name LIPSincAnimName, optional float Volume, optional float Radius, optional float Pitch ); native final function StopLIPSincAnim(); native final function bool HasLIPSincAnim( name LIPSincAnimName ); native final function bool IsPlayingLIPSincAnim(); native final function string CurrentLIPSincAnim(); // LIPSinc Animation notifications. event LIPSincAnimEnd(); // endif // Animation notifications. event AnimEnd( int Channel ); native final function EnableChannelNotify ( int Channel, int Switch ); native final function int GetNotifyChannel(); // Skeletal animation. simulated native final function LinkSkelAnim( MeshAnimation Anim, optional mesh NewMesh ); simulated native final function LinkMesh( mesh NewMesh, optional bool bKeepAnim ); native final function BoneRefresh(); native final function AnimBlendParams( int Stage, optional float BlendAlpha, optional float InTime, optional float OutTime, optional name BoneName, optional bool bGlobalPose); native final function AnimBlendToAlpha( int Stage, float TargetAlpha, float TimeInterval ); native final function coords GetBoneCoords( name BoneName ); native final function rotator GetBoneRotation( name BoneName, optional int Space ); native final function vector GetRootLocation(); native final function rotator GetRootRotation(); native final function vector GetRootLocationDelta(); native final function rotator GetRootRotationDelta(); native final function bool AttachToBone( actor Attachment, name BoneName ); native final function bool DetachFromBone( actor Attachment ); native final function LockRootMotion( int Lock ); native final function SetBoneScale( int Slot, optional float BoneScale, optional name BoneName ); native final function SetBoneDirection( name BoneName, rotator BoneTurn, optional vector BoneTrans, optional float Alpha, optional int Space ); native final function SetBoneLocation( name BoneName, optional vector BoneTrans, optional float Alpha ); native final simulated function SetBoneRotation( name BoneName, optional rotator BoneTurn, optional int Space, optional float Alpha ); native final function GetAnimParams( int Channel, out name OutSeqName, out float OutAnimFrame, out float OutAnimRate ); native final function bool AnimIsInGroup( int Channel, name GroupName ); native final function Name GetClosestBone( Vector loc, Vector ray, out float boneDist, optional Name BiasBone, optional float BiasDistance ); // sjs // gam --- native final function UpdateURL(string NewOption, string NewValue, bool bSaveDefault); native final function string GetUrlOption(string Option); // --- gam //========================================================================= // Rendering. native final function plane GetRenderBoundingSphere(); native final function DrawDebugLine( vector LineStart, vector LineEnd, byte R, byte G, byte B); // SLOW! Use for debugging only! native final function DrawStayingDebugLine( vector LineStart, vector LineEnd, byte R, byte G, byte B); // SLOW! Use for debugging only! native final function DrawDebugCircle( vector Base, vector X, vector Y, float Radius, int NumSides, byte R, byte G, byte B); // SLOW! Use for debugging only! native final function DrawDebugSphere( vector Base, float Radius, int NumDivisions, byte R, byte G, byte B); // SLOW! Use for debugging only! native final function ClearStayingDebugLines(); //========================================================================= // Physics. native final function DebugClock(); native final function DebugUnclock(); // Physics control. native(301) final latent function FinishInterpolation(); native(3970) final function SetPhysics( EPhysics newPhysics ); native final function OnlyAffectPawns(bool B); // ifdef WITH_KARMA // NB. These take affect until you quit the game! Make sure you reset them to defaults when leaving mod etc. native final function KGetSimParams(out KSimParams SimParams); native final function KSetSimParams(KSimParams SimParams); native final function quat KGetRBQuaternion(); native final function KGetRigidBodyState(out KRigidBodyState RBstate); native final function KDrawRigidBodyState(KRigidBodyState RBState, bool AltColour); // SLOW! Use for debugging only! native final function vector KRBVecToVector(KRBVec RBvec); native final function KRBVec KRBVecFromVector(vector v); native final function KSetMass( float mass ); native final function float KGetMass(); // Set inertia tensor assuming a mass of 1. Scaled by mass internally to calculate actual inertia tensor. native final function KSetInertiaTensor( vector it1, vector it2 ); native final function KGetInertiaTensor( out vector it1, out vector it2 ); native final function KSetDampingProps( float lindamp, float angdamp ); native final function KGetDampingProps( out float lindamp, out float angdamp ); native final function KSetFriction( float friction ); native final function float KGetFriction(); native final function KSetRestitution( float rest ); native final function float KGetRestitution(); native final function KSetCOMOffset( vector offset ); native final function KGetCOMOffset( out vector offset ); native final function KGetCOMPosition( out vector pos ); // get actual position of actors COM in world space native final function KSetImpactThreshold( float thresh ); native final function float KGetImpactThreshold(); native final function KWake(); native final function bool KIsAwake(); native final function KAddImpulse( vector Impulse, vector Position, optional name BoneName ); // A position of (0,0,0) applies impulse at COM (ie no angular component) native final function KAddAngularImpulse( vector AngImpulse ); native final function KSetStayUpright( bool stayUpright, bool allowRotate ); native final function KSetStayUprightParams( float stiffness, float damping ); native final function KSetBlockKarma( bool newBlock ); native final function KSetActorGravScale( float ActorGravScale ); native final function float KGetActorGravScale(); // Disable/Enable Karma contact generation between this actor, and another actor. // Collision is on by default. native final function KDisableCollision( actor Other ); native final function KEnableCollision( actor Other ); // Ragdoll-specific functions native final function KSetSkelVel( vector Velocity, optional vector AngVelocity, optional bool AddToCurrent ); native final function float KGetSkelMass(); native final function KFreezeRagdoll(); native final function KScaleJointLimits(float scale, float stiffness); // You MUST turn collision off (KSetBlockKarma) before using bone lifters! native final function KAddBoneLifter( name BoneName, InterpCurve LiftVel, float LateralFriction, InterpCurve Softness ); native final function KRemoveLifterFromBone( name BoneName ); native final function KRemoveAllBoneLifters(); // Used for only allowing a fixed maximum number of ragdolls in action. native final function KMakeRagdollAvailable(); native final function bool KIsRagdollAvailable(); // event called when Karmic actor hits with impact velocity over KImpactThreshold event KImpact(actor other, vector pos, vector impactVel, vector impactNorm); // event called when karma actor's velocity drops below KVelDropBelowThreshold; event KVelDropBelow(); // event called when a ragdoll convulses (see KarmaParamsSkel) event KSkelConvulse(); // event called just before sim to allow user to // NOTE: you should ONLY put numbers into Force and Torque during this event!!!! event KApplyForce(out vector Force, out vector Torque); // This is called from inside C++ physKarma at the appropriate time to update state of Karma rigid body. // If you return true, newState will be set into the rigid body. Return false and it will do nothing. event bool KUpdateState(out KRigidBodyState newState); // endif // Timing native final function Clock(out float time); native final function UnClock(out float time); //========================================================================= // Music native final function AllowMusicPlayback( bool Allow ); // used for playing custom music - not cached, and will not be stopped at level transition // Song parameter must contain extension, but can be relative or absolute directory // ex: PlayStream("D:\\alongtheway.mp3",false,1,0,0); native final function int PlayStream( string Song, optional bool UseMusicVolume, optional float Volume, optional float FadeInTime, optional float SeekTime ); native final function StopStream( int Handle, optional float FadeOutTime ); native final function int SeekStream( int Handle, float Seconds ); native final function bool AdjustVolume( int Handle, float NewVolume ); native final function bool PauseStream( int Handle ); // only used for level music - will be stopped when level changes // Song parameter should not include extension (assumes .ogg) native final function int PlayMusic( string Song, optional float FadeInTime ); native final function StopMusic( int SongHandle, optional float FadeOutTime ); native final function StopAllMusic( optional float FadeOutTime ); //========================================================================= // Engine notification functions. // // Major notifications. // event Destroyed(); event GainedChild( Actor Other ); event LostChild( Actor Other ); event Tick( float DeltaTime ); event PostNetReceive(); event ClientTrigger(); // called on client whenever bClientTrigger changes values // // Triggers. // event Trigger( Actor Other, Pawn EventInstigator ); event UnTrigger( Actor Other, Pawn EventInstigator ); event BeginEvent(); event EndEvent(); // // Physics & world interaction. // // Since Volumes are static, VolumeTimer can be used to get timer notifications (1sec steps) // Laurent -- Moved from Volume to Actor. simulated function TimerPop(VolumeTimer T); event Timer(); event HitWall( vector HitNormal, actor HitWall ); event Falling(); event Landed( vector HitNormal ); event ZoneChange( ZoneInfo NewZone ); event PhysicsVolumeChange( PhysicsVolume NewVolume ); event Touch( Actor Other ); event PostTouch( Actor Other ); // called for PendingTouch actor after physics completes event UnTouch( Actor Other ); event Bump( Actor Other ); event BaseChange(); event Attach( Actor Other ); event Detach( Actor Other ); event Actor SpecialHandling(Pawn Other); 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 event FinishedInterpolation() { bInterpolating = false; } event EndedRotation(); // called when rotation completes event UsedBy( Pawn user ); // called if this Actor was touching a Pawn who pressed Use simulated event FellOutOfWorld(eKillZType KillType) { SetPhysics(PHYS_None); Destroy(); } // // Damage and kills. // event KilledBy( pawn EventInstigator ); event TakeDamage(int Damage, Pawn EventInstigator, vector HitLocation, vector Momentum, class DamageType); function bool HealDamage(int Amount, Controller Healer, class DamageType); // // 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) final function Actor Trace ( out vector HitLocation, out vector HitNormal, vector TraceEnd, optional vector TraceStart, optional bool bTraceActors, optional vector Extent, optional out material Material ); // returns true if did not hit world geometry native(548) final function bool FastTrace ( vector TraceEnd, optional vector TraceStart ); // Line check just against this actor. // Returns true if did not hit this actor. native final function bool TraceThisActor ( out vector HitLocation, out vector HitNormal, vector TraceEnd, vector TraceStart, optional vector Extent ); // // 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 (either the actor wouldn't fit in // the specified location, or the actor list is full). // Defaults to spawning at the spawner's location. // native(278) final function actor Spawn ( class SpawnClass, optional actor SpawnOwner, optional name SpawnTag, optional vector SpawnLocation, optional rotator SpawnRotation ); // // Destroy this actor. Returns true if destroyed, false if indestructable. // Destruction is latent. It occurs at the end of the tick. // native(279) final function bool Destroy(); // Networking - called on client when actor is torn off (bTearOff==true) event TornOff(); //============================================================================= // Timing. // Causes Timer() events every NewTimerRate seconds. native(280) final function SetTimer( float NewTimerRate, bool bLoop ); //============================================================================= // Save Games /* PreSaveGame() is called right before game is saved. PostLoadSavedGame() is called right after a saved game is loaded. */ event PreSaveGame(); event PostLoadSavedGame(); //============================================================================= // Sound functions. /* Play a sound effect. */ native(264) final function PlaySound ( sound Sound, optional ESoundSlot Slot, optional float Volume, optional bool bNoOverride, optional float Radius, optional float Pitch, optional bool Attenuate ); /* play a sound effect, but don't propagate to a remote owner (he is playing the sound clientside) */ native simulated final function PlayOwnedSound ( sound Sound, optional ESoundSlot Slot, optional float Volume, optional bool bNoOverride, optional float Radius, optional float Pitch, optional bool Attenuate ); native simulated event DemoPlaySound ( sound Sound, optional ESoundSlot Slot, optional float Volume, optional bool bNoOverride, optional float Radius, optional float Pitch, optional bool Attenuate ); /* Get a sound duration. */ native final function float GetSoundDuration( sound Sound ); //============================================================================= // Force Feedback. // jdf --- native(566) final function PlayFeedbackEffect( String EffectName ); native(567) final function StopFeedbackEffect( optional String EffectName ); // Pass no parameter or "" to stop all native(568) final function ChangeSpringFeedbackEffect( String EffectName, float CenterX, float CenterY ); // 0, 0 is straight up native(569) final function ChangeBaseParamsFeedbackEffect( String EffectName, optional float DirectionX, optional float DirectionY, optional float Gain ); // Direction range -1.0 to 1.0, Gain range 0.0 to 1.0 native final function bool ForceFeedbackSupported( optional bool Enable ); // --- jdf //============================================================================= // 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 ); /* PlayerCanSeeMe returns true if any player (server) or the local player (standalone or client) has a line of sight to actor's location. */ native(532) final function bool PlayerCanSeeMe(); native final function vector SuggestFallVelocity(vector Destination, vector Start, float MaxZ, float MaxXYSpeed); //============================================================================= // Regular engine functions. // Teleportation. event bool PreTeleport( Teleporter InTeleporter ); event PostTeleport( Teleporter OutTeleporter ); // Level state. event BeginPlay(); native final function ResetStaticFilterState(); // use when change rendering of bStatic actors //Add PackageName to the packagemap (as if it was in GameEngine's ServerPackages list) //If omitted, adds this actor's package //This function is only valid during initialization (between GameInfo::InitGame() and GameInfo::SetInitialState()) //If called outside of that window, or anytime on a client, the function returns without doing anything native final function AddToPackageMap(optional string PackageName); //======================================================================== // Disk access. // Find files. native(539) final function string GetMapName( string NameEnding, string MapName, int Dir ); native(545) final function GetNextSkin( string Prefix, string CurrentSkin, int Dir, out string SkinName, out string SkinDesc ); native(547) final function string GetURLMap( optional bool bIncludeOptions ); native final function string GetNextInt( string ClassName, int Num ); native final function GetNextIntDesc( string ClassName, int Num, out string Entry, out string Description ); // Much faster versions of GetNextInt & GetNextIntDesc native static final function GetAllInt( string MetaClass, array Entries ); native static final function GetAllIntDesc( string MetaClass, out array Entry, out array Description ); native final function bool GetCacheEntry( int Num, out string GUID, out string Filename ); native final function bool MoveCacheEntry( string GUID, optional string NewFilename ); //============================================================================= // 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 name MatchTag ); /* DynamicActors() only iterates through the non-static actors on the list (still relatively slow, bu 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 name MatchTag ); /* 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 (slow, like AllActors) */ 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 ); /* RadiusActors() returns all actors within a give radius. Slow like AllActors(). Use CollidingActors() or VisibleCollidingActors() instead if desired actor types are visible (not bHidden) and in the collision hash (bCollideActors is true) */ native(310) final iterator function RadiusActors ( class BaseClass, out actor Actor, float Radius, optional vector Loc ); /* 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 hash */ native(312) final iterator function VisibleCollidingActors ( class BaseClass, out actor Actor, float Radius, optional vector Loc, optional bool bIgnoreHidden ); /* CollidingActors() returns colliding (bCollideActors==true) actors within a certain radius. Much faster than AllActors() for reasonably small radii since it uses the collision hash */ native(321) final iterator function CollidingActors ( class BaseClass, out actor Actor, float Radius, optional vector Loc ); //============================================================================= // Color functions native(549) static final operator(20) color - ( color A, color B ); native(550) static final operator(16) color * ( float A, color B ); native(551) static final operator(20) color + ( color A, color B ); native(552) static final operator(16) color * ( color A, float B ); //============================================================================= // Scripted Actor functions. event RecoverFromBadStateCode(); /* RenderOverlays() called by player's hud to request drawing of actor specific overlays onto canvas */ function RenderOverlays(Canvas Canvas); // RenderTexture event RenderTexture(ScriptedTexture Tex); // // Called immediately before gameplay begins. // event PreBeginPlay() { // Handle autodestruction if desired. if( !bGameRelevant && (Level.NetMode != NM_Client) && !Level.Game.BaseMutator.CheckRelevance(Self) ) Destroy(); else if ( (Level.DetailMode == DM_Low) && (CullDistance == Default.CullDistance) ) CullDistance *= 0.8; } // // 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 MessageClass, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ) { Level.Game.BroadcastLocalized( self, MessageClass, 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' ); } // called after PostBeginPlay. On a net client, PostNetBeginPlay() is spawned after replicated variables have been initialized to // their replicated values event PostNetBeginPlay(); simulated function UpdatePrecacheMaterials() { local int i; if ( Skins.Length > 0 ) for ( i=0; i DamageType, float Momentum, vector HitLocation ) { local actor Victims; local float damageScale, dist; local vector dir; if( bHurtEntry ) return; bHurtEntry = true; foreach VisibleCollidingActors( class 'Actor', Victims, DamageRadius, HitLocation ) { // don't let blast damage affect fluid - VisibleCollisingActors doesn't really work for them - jag if( (Victims != self) && (Victims.Role == ROLE_Authority) && (!Victims.IsA('FluidSurfaceInfo')) ) { dir = Victims.Location - HitLocation; dist = FMax(1,VSize(dir)); dir = dir/dist; damageScale = 1 - FMax(0,(dist - Victims.CollisionRadius)/DamageRadius); Victims.TakeDamage ( damageScale * DamageAmount, Instigator, Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius) * dir, (damageScale * Momentum * dir), DamageType ); if (Instigator != None && Vehicle(Victims) != None && Vehicle(Victims).Health > 0) Vehicle(Victims).DriverRadiusDamage(DamageAmount, DamageRadius, Instigator.Controller, DamageType, Momentum, HitLocation); } } bHurtEntry = false; } function bool CheckForErrors() { if ( bObsolete ) log(self$" is Obsolete"); return bObsolete; } // Called when carried onto a new level, before AcceptInventory. // event TravelPreAccept(); // Called when carried into a new level, after AcceptInventory. // event TravelPostAccept(); // Called by PlayerController when this actor becomes its ViewTarget. // function BecomeViewTarget(); // Called by PlayerController from on its current ViewTarget when its ViewTarget and/or bBehindView change // function POVChanged(PlayerController PC, bool bBehindViewChanged); // Returns the human readable string representation of an object. // simulated function String GetHumanReadableName() { return GetItemName(string(class)); } // Set the display properties of an actor. By setting them through this function, it allows // the actor to modify other components (such as a Pawn's weapon) or to adjust the result // based on other factors (such as a Pawn's other inventory wanting to affect the result) function SetDisplayProperties(ERenderStyle NewStyle, Material NewTexture, bool bLighting ) { Style = NewStyle; texture = NewTexture; bUnlit = bLighting; } function SetDefaultDisplayProperties() { Style = Default.Style; texture = Default.Texture; bUnlit = Default.bUnlit; } // 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 SetGRI(GameReplicationInfo GRI); function String GetDebugName() { return GetItemName(string(self)); } /* DisplayDebug() list important actor variable on canvas. HUD will call DisplayDebug() on the current ViewTarget when the ShowDebug exec is used */ simulated function DisplayDebug(Canvas Canvas, out float YL, out float YPos) { local string T; local float XL; local int i; local Actor A; local name anim; local float frame,rate; Canvas.Style = ERenderStyle.STY_Normal; Canvas.StrLen("TEST", XL, YL); YPos = YPos + YL; Canvas.SetPos(4,YPos); Canvas.SetDrawColor(255,0,0); T = GetDebugName(); if ( bDeleteMe ) T = T$" DELETED (bDeleteMe == true)"; Canvas.DrawText(T, false); YPos += YL; Canvas.SetPos(4,YPos); Canvas.SetDrawColor(255,255,255); if ( Level.NetMode != NM_Standalone ) { // networking attributes T = "ROLE "; Switch(Role) { case ROLE_None: T=T$"None"; break; case ROLE_DumbProxy: T=T$"DumbProxy"; break; case ROLE_SimulatedProxy: T=T$"SimulatedProxy"; break; case ROLE_AutonomousProxy: T=T$"AutonomousProxy"; break; case ROLE_Authority: T=T$"Authority"; break; } T = T$" REMOTE ROLE "; Switch(RemoteRole) { case ROLE_None: T=T$"None"; break; case ROLE_DumbProxy: T=T$"DumbProxy"; break; case ROLE_SimulatedProxy: T=T$"SimulatedProxy"; break; case ROLE_AutonomousProxy: T=T$"AutonomousProxy"; break; case ROLE_Authority: T=T$"Authority"; break; } if ( bTearOff ) T = T$" Tear Off"; Canvas.DrawText(T, false); YPos += YL; Canvas.SetPos(4,YPos); } T = "Physics "; Switch(PHYSICS) { case PHYS_None: T=T$"None"; break; case PHYS_Walking: T=T$"Walking"; break; case PHYS_Falling: T=T$"Falling"; break; case PHYS_Swimming: T=T$"Swimming"; break; case PHYS_Flying: T=T$"Flying"; break; case PHYS_Rotating: T=T$"Rotating"; break; case PHYS_Projectile: T=T$"Projectile"; break; case PHYS_Interpolating: T=T$"Interpolating"; break; case PHYS_MovingBrush: T=T$"MovingBrush"; break; case PHYS_Spider: T=T$"Spider"; break; case PHYS_Trailer: T=T$"Trailer"; break; case PHYS_Ladder: T=T$"Ladder"; break; case PHYS_Karma: T=T$"Karma"; break; } T = T$" in physicsvolume "$GetItemName(string(PhysicsVolume))$" on base "$GetItemName(string(Base)); if ( bBounce ) T = T$" - will bounce"; Canvas.DrawText(T, false); YPos += YL; Canvas.SetPos(4,YPos); Canvas.DrawText("Location: "$Location$" Rotation "$Rotation, false); YPos += YL; Canvas.SetPos(4,YPos); Canvas.DrawText("Velocity: "$Velocity$" Speed "$VSize(Velocity)$" Speed2D "$VSize(Velocity-Velocity.Z*vect(0,0,1)), false); YPos += YL; Canvas.SetPos(4,YPos); Canvas.DrawText("Acceleration: "$Acceleration, false); YPos += YL; Canvas.SetPos(4,YPos); Canvas.DrawColor.B = 0; Canvas.DrawText("Collision Radius "$CollisionRadius$" Height "$CollisionHeight); YPos += YL; Canvas.SetPos(4,YPos); Canvas.DrawText("Collides with Actors "$bCollideActors$", world "$bCollideWorld$", proj. target "$bProjTarget); YPos += YL; Canvas.SetPos(4,YPos); Canvas.DrawText("Blocks Actors "$bBlockActors); YPos += YL; Canvas.SetPos(4,YPos); T = "Touching "; ForEach TouchingActors(class'Actor', A) T = T$GetItemName(string(A))$" "; if ( T == "Touching ") T = "Touching nothing"; Canvas.DrawText(T, false); YPos += YL; Canvas.SetPos(4,YPos); Canvas.DrawColor.R = 0; T = "Rendered: "; Switch(Style) { case STY_None: T=T; break; case STY_Normal: T=T$"Normal"; break; case STY_Masked: T=T$"Masked"; break; case STY_Translucent: T=T$"Translucent"; break; case STY_Modulated: T=T$"Modulated"; break; case STY_Alpha: T=T$"Alpha"; break; } Switch(DrawType) { case DT_None: T=T$" None"; break; case DT_Sprite: T=T$" Sprite "; break; case DT_Mesh: T=T$" Mesh "; break; case DT_Brush: T=T$" Brush "; break; case DT_RopeSprite: T=T$" RopeSprite "; break; case DT_VerticalSprite: T=T$" VerticalSprite "; break; case DT_Terraform: T=T$" Terraform "; break; case DT_SpriteAnimOnce: T=T$" SpriteAnimOnce "; break; case DT_StaticMesh: T=T$" StaticMesh "; break; } if ( DrawType == DT_Mesh ) { T = T$GetItemName(string(Mesh)); if ( Skins.length > 0 ) { T = T$" skins: "; for ( i=0; i CollisionHeight ) return false; Dir.Z = 0; return ( VSize(Dir) <= CollisionRadius ); } simulated final function bool TouchingActor(Actor A) { local vector Dir; Dir = Location - A.Location; if ( abs(Dir.Z) > CollisionHeight + A.CollisionHeight ) return false; Dir.Z = 0; return ( VSize(Dir) <= CollisionRadius + A.CollisionRadius ); } /* StartInterpolation() when this function is called, the actor will start moving along an interpolation path beginning at Dest */ simulated function StartInterpolation() { GotoState(''); SetCollision(True,false); bCollideWorld = False; bInterpolating = true; SetPhysics(PHYS_None); } /* Reset() reset actor to initial state - used when restarting level without reloading. */ function Reset(); /* Trigger an event */ simulated event TriggerEvent( Name EventName, Actor Other, Pawn EventInstigator ) { local Actor A; local NavigationPoint N; if ( EventName == '' ) return; ForEach DynamicActors( class 'Actor', A, EventName ) A.Trigger(Other, EventInstigator); For ( N=Level.NavigationPointList; N!=None; N=N.NextNavigationPoint ) if ( N.bStatic && N.Tag == EventName ) N.Trigger(Other, EventInstigator); } /* Untrigger an event */ function UntriggerEvent( Name EventName, Actor Other, Pawn EventInstigator ) { local Actor A; local NavigationPoint N; if ( EventName == '' ) return; ForEach DynamicActors( class 'Actor', A, EventName ) A.Untrigger(Other, EventInstigator); For ( N=Level.NavigationPointList; N!=None; N=N.NextNavigationPoint ) if ( N.bStatic && N.Tag == EventName ) N.Untrigger(Other, EventInstigator); } function bool IsInVolume(Volume aVolume) { local Volume V; ForEach TouchingActors(class'Volume',V) if ( V == aVolume ) return true; return false; } 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; } function vector GetCollisionExtent() { local vector Extent; Extent = CollisionRadius * vect(1,1,0); Extent.Z = CollisionHeight; return Extent; } static function Crash() { assert(false); } simulated function SetOverlayMaterial( Material mat, float time, bool bOverride ) { if (OverlayMaterial == None || OverlayMaterial == mat || bOverride) { OverlayMaterial = mat; if ( OverlayTimer == time ) OverlayTimer = time + 0.001; else OverlayTimer = time; ClientOverlayTimer = OverlayTimer; ClientOverlayCounter = OverlayTimer; NetUpdateTime = Level.TimeSeconds - 1; } } simulated function bool CheckMaxEffectDistance(PlayerController P, vector SpawnLocation) { return !P.BeyondViewDistance(SpawnLocation,0); } simulated function bool EffectIsRelevant(vector SpawnLocation, bool bForceDedicated ) { local PlayerController P; local bool bResult; if ( Level.NetMode == NM_DedicatedServer ) return bForceDedicated; if ( Level.NetMode != NM_Client ) bResult = true; else if ( (Instigator != None) && Instigator.IsHumanControlled() ) return true; else if ( SpawnLocation == Location ) bResult = ( Level.TimeSeconds - LastRenderTime < 3 ); else if ( (Instigator != None) && (Level.TimeSeconds - Instigator.LastRenderTime < 3) ) bResult = true; if ( bResult ) { P = Level.GetLocalPlayerController(); if ( (P == None) || (P.ViewTarget == None) ) bResult = false; else if ( P.Pawn == Instigator ) bResult = CheckMaxEffectDistance(P, SpawnLocation); else if ( (Vector(P.Rotation) Dot (SpawnLocation - P.ViewTarget.Location)) < 0.0 ) bResult = (VSize(P.ViewTarget.Location - SpawnLocation) < 1600); else bResult = CheckMaxEffectDistance(P, SpawnLocation); } return bResult; } function bool SelfTriggered() { return false; } function bool TeamLink(int TeamNum) { return false; } function SetDelayedDamageInstigatorController(Controller C); function NotifyLocalPlayerDead(PlayerController PC); // called only if bNotifyLocalPlayerTeamReceived and is a net client when local playercontroller receives PlayerReplicationInfo.Team function NotifyLocalPlayerTeamReceived(); //for AI... bots have perfect aim shooting non-pawn stationary targets function bool IsStationary() { return true; } //this actor is based on a pawn and that pawn has just died function PawnBaseDied(); function bool BlocksShotAt(Actor Other) { return false; } s@E ws@ssy@@Vsa@@VsC//============================================================================= // ActionPause: // // Pauses for X seconds. //============================================================================= class ActionPause extends MatAction native; sxq']-fra*aq'ciaOwia*iia$iaq' GsI//============================================================================= // ActionMoveCamera: // // Moves the camera to a specified interpolation point. //============================================================================= class ActionMoveCamera extends MatAction native; var(Path) config enum EPathStyle { PATHSTYLE_Linear, PATHSTYLE_Bezier, } PathStyle; sH//============================================================================= // 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, and also controls whether or not a player // can enter as a spectator or a game administrator. // //============================================================================= class AccessControl extends Info Config; struct AdminPlayer { var xAdminUser User; var PlayerReplicationInfo PRI; }; var xAdminUserList Users; var xAdminGroupList Groups; var protected array LoggedAdmins; var config array< class > PrivClasses; var array PrivManagers; var string AllPrivs; var globalconfig array IPPolicies; 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; var bool bReplyToGUI; var bool bDontAddDefaultAdmin; var private string AdminName; var private globalconfig string AdminPassword; // Password to receive bAdmin privileges. var private globalconfig string GamePassword; // Password to enter game. var globalconfig float LoginDelaySeconds; // Delay between login attempts var globalconfig bool bBanByID; // Set to true to ban by CDKey hash var globalconfig Array BannedIDs; // Holds information about how got banned var transient Array SessionIPPolicies; // sjs var transient array SessionBannedIDs; const PROPNUM = 4; var localized string ACDisplayText[PROPNUM]; var localized string ACDescText[PROPNUM]; event PreBeginPlay() { local xAdminUser NewUser; Super.PreBeginPlay(); assert( Users == None ); Users = new(Level.xLevel) class'xAdminUserList'; assert( Groups == None ); Groups = new(Level.xLevel) class'xAdminGroupList'; if (!bDontAddDefaultAdmin) { Groups.Add(Groups.CreateGroup("Admin", "", 255)); NewUser = Users.Create(AdminName, AdminPassword, ""); NewUser.AddGroup(Groups.FindByName("Admin")); Users.Add(NewUser); AdminName = "Admin"; } InitPrivs(); } function InitPrivs(); function SaveAdmins() { AdminPassword = Users.Get(0).Password; } function bool AdminLogin( PlayerController P, string Username, string Password) { if ( ValidLogin(Username, Password) ) { P.PlayerReplicationInfo.bAdmin = true; return true; } return false; } function bool AdminLogout( PlayerController P ) { if (P.PlayerReplicationInfo.bAdmin) { P.PlayerReplicationInfo.bAdmin = false; return true; } return false; } function AdminEntered( PlayerController P, string Username) { Log(P.PlayerReplicationInfo.PlayerName@"logged in as Administrator."); Level.Game.Broadcast( P, P.PlayerReplicationInfo.PlayerName@"logged in as a server administrator." ); } function AdminExited( PlayerController P ) { Log(P.PlayerReplicationInfo.PlayerName@"logged out."); Level.Game.Broadcast( P, P.PlayerReplicationInfo.PlayerName@"gave up administrator abilities."); } function bool IsAdmin(PlayerController P) { return P.PlayerReplicationInfo.bAdmin; } function SetAdminFromURL(string N, string P) { local xAdminUser NewUser; local xAdminGroup NewGroup; Log("SetAdminFromURL called"); NewGroup = Groups.CreateGroup("URL::Admin", "", 255); NewGroup.bMasterAdmin = true; Groups.Add(NewGroup); NewUser = Users.Create(N, P, ""); NewUser.AddGroup(NewGroup); Users.Add(NewUser); AdminName = N; SetAdminPassword(P); } function bool SetAdminPassword(string P) { AdminPassword = P; return true; } function SetGamePassword(string P) { GamePassword = P; } function bool RequiresPassword() { return GamePassword != ""; } function xAdminUser GetAdmin( PlayerController PC) { return None; } function string GetAdminName( PlayerController PC) { return AdminName; } function Kick( string S ) { local Controller C, NextC; for ( C=Level.ControllerList; C!=None; C=NextC ) { NextC = C.NextController; if ( C.PlayerReplicationInfo != None && C.PlayerReplicationInfo.PlayerName~=S ) { if (PlayerController(C) != None) KickPlayer(PlayerController(C)); else if ( C.PlayerReplicationInfo.bBot ) { if (C.Pawn != None) C.Pawn.Destroy(); if (C != None) C.Destroy(); } break; } } } function SessionKickBan( string S ) // sjs { local PlayerController P; ForEach DynamicActors(class'PlayerController', P) if ( P.PlayerReplicationInfo.PlayerName~=S && (NetConnection(P.Player)!=None) ) { BanPlayer(P, true); } } function KickBan( string S ) { local PlayerController P; ForEach DynamicActors(class'PlayerController', P) if ( P.PlayerReplicationInfo.PlayerName~=S && (NetConnection(P.Player)!=None) ) { BanPlayer(P); return; } } function bool KickPlayer(PlayerController C) { // Do not kick logged admins if (C != None && !IsAdmin(C) && NetConnection(C.Player)!=None ) { // TODO implement a way for admins to specify the reason C.ClientNetworkMessage("AC_Kicked",DefaultKickReason); if (C.Pawn != None) C.Pawn.Destroy(); if (C != None) C.Destroy(); return true; } return false; } function bool BanPlayer(PlayerController C, optional bool bSession) { local string IP; if (IsAdmin(C)) return false; IP = C.GetPlayerNetworkAddress(); if( CheckIPPolicy(IP) == 0 ) { IP = Left(IP, InStr(IP, ":")); if (bSession) { Log("Adding Session Ban for: "$IP@C.GetPlayerIDHash()@C.PlayerReplicationInfo.PlayerName); if (bBanByID) SessionBannedIDs[SessionBannedIDs.Length] = C.GetPlayerIDHash()$"|"$C.PlayerReplicationInfo.PlayerName; else SessionIPPolicies[SessionIPPolicies.Length] = "DENY;"$IP; SaveConfig(); C.ClientNetworkMessage("AC_SessionBan",Level.Game.GameReplicationInfo.AdminEmail); } else { Log("Adding Global Ban for: "$IP@C.GetPlayerIDHash()@C.PlayerReplicationInfo.PlayerName); if (bBanByID) BannedIDs[BannedIDs.Length] = C.GetPlayerIDHash()@C.PlayerReplicationInfo.PlayerName; else IPPolicies[IPPolicies.Length] = "DENY;"$IP; SaveConfig(); C.ClientNetworkMessage("AC_Ban",Level.Game.GameReplicationInfo.AdminEmail); } if ( C.Pawn != None ) C.Pawn.Destroy(); C.Destroy(); return true; } return false; } function bool KickBanPlayer(PlayerController P) { local string IP; if (!IsAdmin(P)) { IP = P.GetPlayerNetworkAddress(); if( CheckIPPolicy(IP) == 0 ) { IP = Left(IP, InStr(IP, ":")); Log("Adding Global Ban for: "$IP@P.GetPlayerIDHash()@P.PlayerReplicationInfo.PlayerName); if (bBanById) BannedIDs[BannedIDs.Length] = P.GetPlayerIDHash()@P.PlayerReplicationInfo.PlayerName; else IPPolicies[IPPolicies.Length] = "DENY;"$IP; SaveConfig(); P.ClientNetworkMessage("AC_Ban",Level.Game.GameReplicationInfo.AdminEmail); } else P.ClientNetworkMessage("AC_Kicked",DefaultKickReason); if ( P.Pawn != None ) P.Pawn.Destroy(); P.Destroy(); return true; } return false; } function bool CheckOptionsAdmin( string Options) { local string InAdminName, InPassword; InPassword = Level.Game.ParseOption( Options, "Password" ); InAdminName= Level.Game.ParseOption( Options, "AdminName" ); return ValidLogin(InAdminName, InPassword); } function bool ValidLogin(string UserName, string Password) { return (AdminPassword != "" && Password==AdminPassword); } function xAdminUser GetLoggedAdmin(PlayerController P) { return Users.Get(0); } function xAdminUser GetUser(string uname) { return None; } // // Accept or reject a player on the server. // Fails login if you set the Error to a non-empty string. // event PreLogin ( string Options, string Address, string PlayerID, out string Error, out string FailCode, bool bSpectator ) { // Do any name or password or name validation here. local string InPassword; local bool bAdmin; local int Result; Error=""; InPassword = Level.Game.ParseOption( Options, "Password" ); bAdmin = CheckOptionsAdmin(Options); if( (Level.NetMode != NM_Standalone) && !bAdmin && Level.Game.AtCapacity(bSpectator) ) { // TODO: Check Login to make room for Master Admins if not enuff specs. FailCode="SERVERFULL"; // Error=Level.Game.GameMessageClass.Default.MaxedOutMessage; // Must clear error string so that client doesn't receive additional connection failed messages Error = ""; } else if ( GamePassword!="" && caps(InPassword)!=caps(GamePassword) && !bAdmin ) { if( InPassword == "" ) { Error = ""; FailCode = "NEEDPW"; } else { Error = ""; FailCode = "WRONGPW"; } } Result = CheckIPPolicy(Address); if ( Result == 0 && bBanByID ) Result = CheckID(PlayerID); if ( Result > 0 ) { if ( Result == 1 ) { Error = ""; FailCode = "SESSIONBAN"; } else if ( Result == 2 ) { Error = ""; FailCode = "LOCALBAN"; } } } // 0 - accept, 1 - sessionban, 2 - permanent ban function int CheckIPPolicy(string Address, optional bool bSilent) { local int i, j, LastMatchingPolicy; local string Policy, Mask; local bool bAcceptAddress, bAcceptPolicy; // strip port number j = InStr(Address, ":"); if(j != -1) Address = Left(Address, j); bAcceptAddress = True; for(i=0; iW!$>V!U!$=T!Z!$$?sS!Z!$@$@@s7 R S>`:$B=$BFD~ ssasu_{s^BA$Kʁ)B"!"}!$>|!$D{!$@x!$@p!:0J!Zy?tZ!$$CsAZ!$$CskZ!$$CssF%Z!$B$HCsF"Z!$@@$@s{Z!$@$@s7 >c*+Q$@QF\sqzg'@B8q$pssqqgsh'@Cq$ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)E$HB{$ FMsoss~EXB@j|%7wj*|jja| Gs|sqxGso'@FѨq$`"$ FE$HBIsossRsZ!',w*rwK*{K` UK` wU*U{V UV U GsD@LsK@LsDLsL@LsMLsNLsOLsJasI@Lsh)ss=F%&=J(9?9DJ(% GsTs&sUssVssWssXssYssss5s\ss]ss^ss_ss`ssassbsscssdssessfssgsshssissjsskssZss[g)L! )g))f))d))c))a))`) GsssomY!% GsP)e)r %)e) Gsssssussssl_)M" )_))^))Y))X))T))S) Gsm ss~ \)}&=)\))[))Z) G:svW)')W))V))U) G;sH ssV @ssy@sssstQ)Q*%)Q))O))N))L))K))J))I) Gs\wj+o\T n%Fn,;{n}nCn,ln% z~ ~ %} Gs^}_@ n% N%AN,{N}~ NNoN,zN}N%~ N}Z  GsK sM)sss@ssAssBssss|H)T2 %)H))G))F))E))C))B))A) GsCssFSsG^ sH^ sD)SsJSsKSsssPssEssR`sS`sC`sW ssXPsYPsZPs[Ps\Ps]Ps^Ps_Ps`PsFPsbPscssdPsePsfPsxssh@dszdsjdsk ssl ssm ss sson sn Unn pŪUk$>k>k>sssDU}gdrՎUoZ!$?$?ssssDBg\r](@tWB7K\#$>L$>X#${=S#$u=M#$o:L#$o:M$Q9J#$=>SL sssDOEb(v~˛ڃ@EsssDMgqc(x(K>ʁ)b#$zDA1Q/L $BM $BO/ H/CO>iqO S:$A=$AsssD[Yd(z6I[KYNbsssDse 0s| 1s} 2s~ 3s 4s@ 5sssAJg!z *rJ@J`r a%krJ@ep X &krJ@Kp X ,krJ@Ap X ,krJ@}p X $,krJ@yp X U,krJ@ep X  ~kOPENED%zk,TDM&J@% zk,CTF,J@% zk,DOM,J@%  zk,BR,J@%rJ@&,J@%J@7e&J@7K,J@7A,J@7},J@7y,J@%kCHAMPIONSHIP OPENEDk G [Kf(Db;[KQObsGqoS E⟿2ʁ)CO>soO Sssk@srnoR Geʁ)7e+F\:$=$ssC@)u B%*@) &%we 8&wK K,wA ^,w} q,wy ,we 7w%*B7w7w&wBw G sLS[i_Oo(BJcs[KH$>CS>}OydK $BVesswsDle/ 6LL uqL $BM $AQ:0CG8:$A=$BosssDsHs'O&us'cs'` G &fr(O,N&ɢzKysssDsN[ InSO[ YrS*SINGLEPLAYER LadderInfo::MakeURLFor MatchInfo invalid.[ A*Sz([ f'[ @*Sy(LpppppppS{(?Name=[ K?Character=[ )?SaveGame=[ lSw(`Su'9?%LppL?GoalScore=9USu'SB%LppL?NumBots=9SSB{StLppL?Game=StLpL?Team=1L G qJWs(B Y6RRGhqj $?+:$PBFSjS|SDSCssS@ssISsf@ssQ}(Z}(c )%S Deathmatch G&S Team Deathmatch a,S Domination ,S Capture the Flag ,S Bombing Run ,S Championship Match S  G s`ssS @sGkrDx(@Y`JGn6hCtW_ddK.CtW_dCtW_dpSXssV|( Y|( %7e &7K ),7A 5,7} A,7y M,7e  G sWssss[@ssz(@ssbs0Rf|(:`w0׿e]ssvssNss~T R wD* Z  G sB@si@)!K9:9:$-Z9:9:$-K9:9:$9:9:$GB Y7 de}Lh,e,eg _g _g _g _ p3} u u uhh u uhhh3}3} u u u u(bQ (bQ 3} u u3} u u,e,e,ehʁ),eh,e,e ҽ ҽ ҽ ҽ ҽ ҽh,eMJʁ) u3}3}(bQ 3}3}3}(bQ (bQ 3} u uʁ)3}3}hhʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ)ʁ),ehʁ)ʁ)ʁ)h,e,e3},e,e u,ehh3}h3}3}Zs,e3}Zs,eh,e,e,e,e,e,e3}Zs,e u3}ZszVGBzVGBm?4hhh,e u u,e,e3}Zshhhhh,ehhh3},e3}3}h p,e p p p p p qYh3}Zs qYh3}Zsh p,e3}hhhh,e,ehh,e,e,ehhhhhhhhhhhhh u uʁ)hh u u u u u u u uhhh qY u3}ZszVGBhzVGBhhhhhh,e,e,e,e,e,ehh,e uh,e3}Zsʁ)ʁ)hhh,ezVGBhh,e,eh,e,ezVGB3}Zs u3},e{(T,e,e,e,e,e u,e,e3},e{(Thhhh,eh3}Zshhh u u u u3} u u u3} u u u u u u u3}3} u uʁ) u u u u uhhhhhhhhhhhh{(TlFo,e,e,e3}3}Zs3}Zs3}Zs3}Zse}Le}Le}Le}L3}3}3} u u3}3}lFolFolFolFolFolFolFo,e3}Zshh3}ZsqK{DjRhoiO|Zy}{xy[xWxJJK:IhA|$zDEh[fW+Y nz$B|h$De|]SpringONSHoverBikeE|"Ow"Mj:0BIw$C|{Z!$HB$Dsei">}i">Vf]XEffects.TransEffectRedVfXEffects.TransEffectBluecg$C\y$Dtg$@~h$?wy]Onslaught.ONSOnslaughtMessage}$?Xi] in a vehicle~g] VehicleAgU\viNIv$33>x $?|v$zD{%@@P&S^&$`jFu&$?v&$?a'L[$@v$?ag:$B=$HBsAEIQi@f߄A؂u u-$;Eq E."FSss@sscZ Z k!~~ /%D*m *hDi2/a0 Cm gf|9Wm k)~  wm g10 G sssvx'w G %_G 7vUrG vx'rG vAvG &_G }rr*r x'r GKqCGx2k!e.Ke0c|CSDssrsZ}K)m=Z]|pSsy'~L)@nty'v[pSssju(l $C(7v7v&7v&vu( GsB(ssoP*."7v%Av7v&& GssN'  G sts:sus2svssssrxk*  G sys:szs2ss&GHGP {ud&ɢhhhh,eh,ehh,ehʁ)hhhhhʁ)ʁ)ʁ)&ɢ&ɢV/:0DX/$?C/Fs&MfG[)|D&ɢhh,ehh(bQ hh,eh,ehhh,ehhh,ehhhh,ehhhh(bQ E/s.IW-}.VDs.SDT-~_.VDsspS`v[|e)@~(`W=$?~$?{"y" zLZ!$$zDsw"ssdh  !E* :]* : GsAs(R=ds(T r(yq(:zdAdmin-j ' GsLsC@ssDsx(sBp({*'yVT p(e%SeEXE NeQ e Gsq)hyhuL DAy-F3T Awm *yv!3yv!`L y  w.y*c .y wa;L y c m a:L y c ya/!^.y-C-b)ya L t9:9:$p Utwp *]rp ~yp byp p S)6c %.y yc .yBL c w.y *.y Z q!b!ya L ya+c yu!3yu!` GTCrR21HTVG$?r{.h]Camera effectssFTT 0}T,(b%b}T~abcdefghijklmnopqrstuvwxyzABCDEFGHIJMLMNOPQRSTUVWXYZ0123456789!%^*(){}[]<>.,Tb&(b' G ERW~ 1JmߪE77j)ssbsEhUA1LDRE77s)*ssIS}*>'S%ISEXE NS{ SS%S]X] NSo SP GsQ@SsMw EGdaww *6E \w E qw a] \w ] qw  Gsn)GI(K -*I(a/!^.I(-C( GsO|'L _ e-j (~pp|T |pp||'|+~pp|T &|pp||'| Gw`JvR*R@?w\ݙvI-" sssCwQ[*Tʁ)sss;sDWX i 7D GsssV}'M_o m}'Zro *o * ;Two *o R}'m(l(o * GHWbO@ Yi0BHH*LaGd" ssPsb]GsJ(sso s;xydl@0]8QxxssX}"EEBw}*\}7D7D&7D&D} G'Uai@0_ 'ʁ)3}ʁ)3}Hqr$?ss^@(q-ROw@(*N%ON7DErND@(ADN& N GWRQc@0a" W7zHHd$?A$?sWTHp@0b8~`nW7zHHss`bN:.b%b7D*bD GA(WFn@0djBA(Tʁ)3}ʁ)3}Hqr$?j$k$?q$>l$n$?sss;sck(mD\Po%Ko7DAzoDdk(oDo* Gs[Ssos;WTlX @0ie"W7zHHMPssfj(\O=F%8F7D.rFDj('F( GsgsFsWZjs*@ mW7zHHssjoT,ZOb%Jb7D@9:bDy,bDb* Gsbs;W[iL@0pAW7zHHLssnVcFAD%7D GRwv*@0rRS'Gd"sHf^[@0sq|HRzGd"sHcZz@0tDH|;|;|;|;HJsHeSf@0u~QHJrsHBBy*@ vQh1HHGd"!s`YK|z*wO>|`W=M{Zy?tZ!$?$?sAZ!$?$?skZ!$?$?ssssk!sC(h ?!K* 2* 2 Gsyh(R/C(h(D(g(E(F(sF( Gsxs{!R|CG+@ };!)RS'Gd"ssze [$bwe *8K \e K e oe E\e Ee -j -s'R e T  G0u~F~@6^-0׿e] u u u u@u)ʁ)3}Zs3},e,e uhh upa u u u@u),eʁ)3}Zs_BGss~n{ 5ZWwn*K \nnEqK qnQ  GWKM+AKH@Ess@kp @Browk*8 \k kok]\k] Gg |GQ+CQg 8SNssBgo L&TQwg* \gg]q qg Gg zS+E),(g 8SNssDf(C-W DJ%AJ7G([f(mJG(J Gs|!hV+H,cʁ)7CE$ss@sTxpX+2J=TVHr{.h]FadessFe(H-_Du%Au7K(p e(muK(u Gsc@Sd(TaoY+2M2ڿTVrUXh] Triggerss@sTmn\+2O7TVrUVh]FOVssKL(L eae-s(~pp|s|pp|L(|+~pp|s|pp|L(&| GTym]+2QTVrUbh]ShakessssPXQ l -s(X%^XKXTK NX-j -s'^Xr-sssE(X%XKXR K NXT X GTel_+2TLTVrUZh] OrientationssSQ R {Q G ~Q |AG zQ Q hzQ G Q Q G &G ~pp|s|pp|z|G zsszspps|z GTlkf+2V=TVrU^h= Game SpeedsTbjm+2WjI TVrU`h] Scene Speeds[|n+X[KCS>d JPssUc(M- #-s \c( GsMasssYb(O-! k -s'Z%fZX\ NZE \b('Z( GsKLsZss]Ls\HR-}H,(X%X}H~abcdefghijklmnopqrstuvwxyzABCDEFGHIJMLMNOPQRSTUVWXYZ0123456789!%^*(){}[]<>.,HX&(X' G P`~T0a)PX Q$?g :0???ssXsPc|i0cyPX Pss`ST 8}S&([%[}S~abcdefghijklmnopqrstuvwxyzABCDEFGHIJMLMNOPQRSTUVWXYZ0123456789!%^*(){}[]<>.,S[&([' G PXy_0ePX i$?ss[sP\xA 0g-PX ssdia- -s,q%t%tKX9:K Ntyqq9:K Ntytq GstsP^r~ 0j\PX s`P@|B,k [`W=OZ!$@$@sssh`(e-K m`( Gs_@Lss;sl_(h-- m_( GsmLss;so](i-E* :&-sW](1Wk%kWXQW NkEn%nQXEQ Nnn{k8E GsYB@f Uwf *qf -C r6af  h-N('hf f f S-N(q!s GsEs:`Lx{S,u jv`W=S:0?ss\( sR\~b,@ wKRS'Gd"sPE~t @Rx9ߓډs`KAp,y6`W=n"g$@f"@ssrRl-YR%IRKXK NRERR%RX NRERP GsX( sF|,|8uʁ)7:$=$sssesFX  7F Gsss~S(j xAt* e8wt*tRS(R(lDt G$*"""? Q  " "" "Gd"s(@x@==={{{{{{==={{{{{{{{{{{{==={{{{{{===sf ssyD sOstsesn@Os@l'EBwl*\l7F7F&7F&Fl Go)] CTF-Maulp)]xGame.TeamIronGuardb$@@~)]?mutator=xgame.mutinstagibD*] Instagib!s$*? Q  " "" "Gd"s@$*???? Q  " "" "Gd"sI@$* Q  " " " " Gd"s@@\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ _$*%T7*   " " " " Gd"s@$ދvcjĀv>S$I$/Jt.Ę>C֗Ҁ/:-/j˵ͮaղ j>S֟$Ү/П빣"vSvճIҀcQܶ͘/ёJkjڦIfֹ|jҦ/&ayK Ik|"jhe/cҚIv>FIccSIvSc$vcjv°ev>>kQc>>vj$!Ivv/jI$e>vͮjv/>c瀘Iͦ $* Qec  " "@" "@Gd"sK@{TTTTUUUU{TTTTUUUU{TTTTUUUU{TTTTUUUU{TTTTUUUU{TTTTUUUU{TTTTUUUU{TTTTUUUU{TTTTUUUU{TTTTUUUU{TTTTUUUU{TTTTUUUU{TTTTUUUU{TTTTUUUU{TTTTUUUU{TTTTUUUU@KF$*.t*   " "" "Gd"s@_$**   " "" "Gd"s@_$*'j'*   " "" "Gd"sY@_$*t*   " "" "Gd"s@pF$*^a_*   " " " " Gd"s @ͱDD⹹DɹzpmmouzDȹeaNM?<.%+\tFȹjN̤a0%)pGǹkӥcaW."9nIƹl# &4@>2%+uKƹ`M$ '! '/,ZzL]2 QҰ! >,#& hT6  QW1_V8fbO Q# 7xX:&bb ˚dApY^BB$!b -ʄ4*p|sC/d2(#;SԄ=[v~3A(&-&/gR-$rrwyqfii5i5i5i5i5i5i5i5i5i5i5i5i5i5i55i55iiiriiiiiiriiiiii㻻EEEDEHJKPUVX{} qF$*jkb*   " " " " Gd"sa@ͬHH⹹HɹxspprvxHȹgeSRB?,#)auJȹlS̠e/#'sKǹmӠee~\, ;qMƹn! $3C@1#)vPƹd~R"% %.*_xQb1 Vҫ @~*!$kY7 ~ V\0c[9heT V! 8w]=$fe~ ˕fDs^bEE"e +ʂ3(sztF.f1&!>X~4`<|2D&"&-No<iW+":AGj<<<<5656565666<㻻IIIHILOPUZ[]y{} wF$*i*   " "" "Gd"s;@KKKKKKKKKKKKKPD$*``   " "" "Gd"s@PD$*0p0*kk   " "" "Gd"s@WB$*   " " " " Gd"s8@ qM$*4*   "@ "@"@ "@Gd"s@@@@_$**   " "" "Gd"s@v $*y *Z   " " " " Gd"sC@nnnnnnnnnn v $*x *Z   " " " " Gd"s@nnnnnnnnnn v $*z*Z   " " " " Gd"s@nnnnnnnnnn $*? Q  " "" "Gd"sG@sw@ssj@ssi@sse@ssf@ssw@sspssc@ssi@ss@ssssyssxssgM}u_N<#"h9?, (7h"' GsxfsX@,s_@ss@@ssssp@Lso@,sssU3@,s{ssrIqu_9:9:$'z"h9?,[q!}` q!u.(z"h9?&("h9?,h"9?,h"' Gsp@ssgLuv_9:B'r*r*@ Gszss ssP@LsissssJ$ ssTssWssp,si@ssssG @ssJ@,sssF@ssl,@ssFnHO`\SrHG*HG.HM rHG*pppWarning: 9V Couldn't dynamically load font HMHG G sunPU`' FUwF*Fa/!n.FG .F n@.F'm%P P9=,9=,9=,FFS GsssRI[`TrIG*IG.IM rIG*pppWarning: 9V Couldn't dynamically load font IMIG GsssssZWVR` @ J  Gsss_Y` ] Gss sMlssHEQ`UE9?%LKdzEL_E=LE=zEEELE Gsb// ==================================================================== // Class: Engine.HudOverlay // Parent: Engine.Actor // // HudOverlays are used to display alternate information on the hud // ==================================================================== class HudOverlay extends Actor; simulated function Render(Canvas C); simulated function Destroyed() { if (HUD(Owner) != None) HUD(Owner).RemoveHudOverlay(self); Super.Destroyed(); } sLssPnYS`S]yrJ*J.N yrJ*pppWarning: 9V Couldn't dynamically load font NJ _J GsROX`/KOKK P GhzV`lW˅ʁ)@u)O+ss'h v!@ GsOpmb`j Gs@$,so@,s`ssdss|@ssssGssgssws sw@DsSsmx~`C Gsrss@ssr ,Dss ss&sssH @sJssfsz@ss^sTs_ssssGssU@ssI@ssL@Dsso@Dsse@ssN@ssqssB@sxsQssHsso@ssYssssW@sss[s@sstss@ss\ss]sss ss s@ssy @ssa@ss`sscssdsse@ssssssssf@ss@ss}s.sd:@ss@ss]@ssz-_-:a  Gsp@ssY3ssZsss sss@EDA%@/a0 &APOwA[QA  A\10EDEDpp9V has illegal jump velocity 9XEDED#{ED Gs@ssPSv`c( r# r#* V # G@sssQTmu`k m Gszsss.smTll`ektl Gs}`|Da G sqTj{`C X`j Gsvs sg it` 9V9=9D>9?i,-T' GBsEAo`p+Evwv*kw. v*wvk*. v,-M'GG*vv  Gs| hCa m1#r*w,* th Gsxdy`iD Gs[`gFaYR>t-N O>tF gcaDqy>tF gca-ew>Q *>Q zDisconnectVDisconnect Gvs[um`#  GsTKz`3 z)%u%Qu7zG|Kuz, ,uu%u7C|KuC, &uX% Gs@ssXssSfM@aB0( Gsss]gOq`8W-M e9?& GssscgQw`f    GsssP_s`2 p _ Gs@sspju E  GsV sst~YAa<"-FY*wL*L AaY GsBqXl`a-'$wL*Ll`XW GsY[v!I?,)wd*dv![tZ GsCj^VC,)wd*dV^]\ Gs\@ss{sn`-ICozD-I r9*r9\* -I'9 n@9\E|ds%s7d s,stsds Gsc]kZm:1.wd*dZkfd` GsJsswXrx`-[A<\rJ[JUo9|Up'( G swE ss ssll|` -G-G Gsam`Vw*m` Gsqlp` GsHny`JY!y_9?wBy_9?wcy_9? wy_9?wy_9?wy_9?@w[`,w%, Gs ss ssssN ss\v ss^v ssqv ssssosspssD~ ssJ/ssgssP ssu0ssQ 0ssOR_-'!9B%6B7RBR_-B Gs sss-s ssss||r`. Gs}@ss~ssss ssssY sspssF@ssUsV$sdlay GsT@sssDsIs@sOJhaq rn*k JI GsFanab<hannh-L'eb G sDoa.z Gsoma,v<GU%GConfiguredInternetSpeedsGV%GConfiguredLanSpeed GsXQjaD$ Gs@ssPHka~$ H GsbTEiahXp{OA UE]w>*w>Q *U>Q kaEm UF Gs@ssZssss[ssVs sYssVssumss_ssTss_ssssssKssdssgssss^@sssshssbssjssssMssmSiuav<9:9:$ r\* j\Wi GBs\f{aB)f GsKeta-pppppppppppp9V Same weapon 9T-c Mode 9Re Allow fire 9T-g delay start fire 9T-h alt firing 9T-b next fire wait 9Ud G s]@ssurasv_|aHdaw*wX*XE,XK GsirassrastrasYnssyssWAss{sswssssDZzRb)|F9?wy9?:wyyFwp9?wy9?wyw9D9?w9?yw?Azw GsgpssWssAssss@ssbBYb: "* GsJw%J SJn{-j-DPrs*-Msi2 a GsdssssHssssnH_b^EH G@szFab]EF_bF GsHssqssRssXssLebkK -L' G@sQssesIsDsspD sUD sEssns sssss\@ssSssGAsbstssZssxsszssT@sscssjH[)ss_s@sss_sr~soD sossass\ssWD skD sJS[pbO_>I[;w>*>h&[m[ Gvs@sr si~rg.- GsP@ssohhob T%pp9V ServerStartFire! h G swgub)g GsU7ixb)i GsZmqb"vmaZn\ Gsss{ss|ss}ss~ssss@ss{nCrb9 GsssAssuFzbJ $ Gsss|@sssMsJssQs sRs sIssLssKssPssNsssssspsszss\~OVceS :5wi*$iVcOPNK'( GsI^MVc4 rx*(xVcMLIJ GsX@ssC@ss_sscss^ssss`@ssassqssvssss]ssPWssssfssgsshssssisskssmWl_c SLI-\bl?x kih?x gf Gsoac^-Y' GsJj`cJ^-\-j GvsJJddcX)d)])^ Gs}ssssyZrcc ] Gsenbbc:6b*-9DS  m$n$ Gsh\c^cc#c`c-_-` Gsssz@ss{@ss|@ss@@ssAssss~ssssYssVyqcD#4/wL*Lqcyz{|' GsD@ssE@@ssRssMQ@ssH@ssss`sssscWJ@d NFJ? GsBG~cLi$(%wL*L~cG-H Gs@HssQ s 0XQhd3O_0׿e]O_Szהq^h"fI"ss[s\s\@sH [w~d;9:9:$-K9:9:$-K-j9:9:$-K-j-l9:9:$-Z-j9:9:$-K-Z-jG7SzהH ,]O_O_O_O_O_O_O_[в[в[в[в[в[вygIPublicLocallp]Enable Voice ChatlpEnable local ChannellpLocal Chat RangelpLocal Chat RadiuslpAllowed VoIP CodecslpAllowed VoIP LAN Codecsop]"!Enable voice chat on the server.opݠ^Determines whether the "local" voice chat channel is created, which allows players to broadcast voice transmissions to all players in the immediate vicinity.opJHMaximum distance at which a broadcast on the local channel may be heardop21Distance at which local broadcasts begin to fadeopSQConfigure which codecs exist on the server and should be used in Internet games.opNLConfigure which codecs exist on the server and should be used in LAN games.BgUOc{YZs= CODEC_48NBssMLess Bandwidthks]=<(4.8kbps) - Uses less bandwidth, but sound is not as clear.sZs= CODEC_96WBssMBetter Qualityks]=<(9.6kbps) - Uses more bandwidth, but sound is much clearer.sz{Y  CODEC_48NBe{Y CODEC_48NB CODEC_96WBy{_gP|$zDw{$Av$b@@ssr sSs| sszssl ses}@sYsLsOsh@DTdassso@sA]eSf@hA؂ue}Lq zYMY:$B=$CFSss}ssssSsscssk!@) sses]sslssCY[d- G(sYTdysrssJssssTss[@ss`sSsLss^E#S8)Np'UNp(PqK!s Gscs smslsfs ssesKsOsssZsscsesJ@sGsIss_B>`Odc' Gsssss^s{sUsss&sB@)sU@)sessn@)sQs|sssOss\@ssussBssQssssZ@sscsOsCssssOssIsesass|seVErSd2y/^VFzVGBjh] SomeoneKd]98Invalid channel or channel couldn't be found: '%title%'Kd'&Already a member of channel '%title%'Kd('Channel '%title%' requires a password!Kd43Incorrect password specified for channel '%title%'Kd-,You have been banned from channel '%title%'Kd10Couldn't join channel '%title%'. Channel full!Kd/.You are not allowed to join channel '%title%'Kd'&Successfully joined channel '%title%'KdYou left channel '%title%'Kd# "Now speaking on channel '%title%'Kd) (No longer speaking on channel '%title%'Kd" !'%pri%' joined channel '%title%'Kd '%pri%' left channel '%title%'Kd= +cwossWssqsSscMrsmssm s=sssK@)ssAs|ssssIssJssWssisess&sNslsOsspssssAssEssossG  sHsGssssXsssssesQsssAsFssO@@)}se s=SsmssssAssssssZsskssMssTsswSfsjs`ss0Ivth2 |0׿e] u u@u)3}3}3} u ue_ .3}3}wi$=ssssn@s|sEssMsse@DTdsi@ss{ssssFs shTds@ssK@ssuJssyssses@ssWssSssssssMsOsssssI@ss`@sssss@sAss]sssFsssssvss@sss@sD@)ssOsMssEsssszssasesTs s@ssussP@QdsjsF@YdDڃ@EXgi \ei!UTClassic.MutUTClassicUnrealGame.MutLowGravUnrealGame.MutBigHeadXGame.xTeamGameXGame.xDeathMatchXGame.xCTFGameXGame.InstagibCTFXGame.xVehicleCTFGameXGame.xDoubleDomXGame.xBombingRunXGame.MutRegenXGame.MutInstaGibXGame.MutQuadJumpXGame.MutSpeciesStatsXGame.MutVampireXGame.MutSlomoDeathXGame.MutNoAdrenalineXGame.MutZoomInstagibXWeapons.TranslauncherXWeapons.ShockRifleXWeapons.LinkGunXWeapons.MutArenaXWeapons.MinigunXWeapons.BioRifleXWeapons.FlakCannonXWeapons.RocketLauncherXWeapons.ShieldGunXWeapons.SniperRifleXWeapons.PainterXWeapons.MutNoSuperWeaponXWeapons.AssaultRifleXWeapons.RedeemerVehicles.BulldogFi( BR-Anubis BR-BifrostBR-Disclosure BR-IceFields BR-SkylineBR-Slaughterhouse BR-TwinTombs CTF-Chrome CTF-Citadel CTF-December CTF-Face3CTF-GeothermalCTF-Lostfaith CTF-Magma CTF-Maul CTF-Orbital2 DM-Antalus DM-AsbestosDM-Compressed DM-Flux2DM-Gael DM-Inferno DM-Insidious DM-Leviathan DM-Oceanic DM-Phobos2 DM-PlungeDM-1on1-SerpentineDM-TokaraForestDM-TrainingDay DOM-CoreDOM-OutRiggerDOM-RuinationDOM-ScorchedEarthDOM-SepukkuGorgeDOM-SuntempleTUT-BRTUT-CTFTUT-DM TUT-DOM2s\eYfBonusPack.xLastManStandingGameBonusPack.xMutantGameBonusPack.MutCrateComboSkaarjPack.InvasionFY BR-Canyon CTF-AvarisCTF-DoubleDammageDM-1on1-CrashDM-1on1-Mixer DM-Icetomb DM-Injector DM-IronDeityDM-Rustatorium DOM-JunkyardBR-DE-ElecFieldsCTF-DE-ElecFieldsCTF-DE-LavaGiant2DM-DE-GrendelKeep DM-DE-IronicDM-DE-Osiris2s\eiXInterface.DefaultCrosshairsOnslaught.ONSCrosshairsUTClassic.MutUseSniperUTClassic.MutUseLightningOnslaught.ONSOnslaughtGameOnslaught.MutOnslaughtWeaponsOnslaught.ONSAVRiLOnslaught.ONSGrenadeLauncherOnslaught.ONSMineLayer!Onslaught.MutLightweightVehiclesUT2k4Assault.ASGameInfoUTClassic.ClassicSniperRifleUnrealGame.FemaleAnnouncerUnrealGame.MaleAnnouncerUnrealGame.SexyFemaleAnnouncerFiz> AS-ConvoyAS-FallenCity AS-GlacierAS-MotherShipAS-RobotFactory AS-JunkyardBR-BridgeOfFate BR-Colossus BR-SerenityCTF-AbsoluteZero CTF-ColossusCTF-GrendelkeepCTF-MoonDragonDM-1on1-AlbatrossDM-1on1-IdomaDM-1on1-IrondustDM-1on1-RoughineryDM-1on1-SpiritDM-1on1-SquaderDM-1on1-TriteDM-1on1-DesolationDM-Corrugation DM-Gestalt DM-GoliathDM-Hyperblast2 DM-JunkyardDM-Metallurgy DM-Morpheus3 DM-Rankin DM-Rrajigar DM-Sulphur DOM-Atlantis DOM-Aswan DOM-ConduitDOM-RenascentONS-ArcticStrongholdONS-Crossfire ONS-TorlanCTF-1on1-JoustCTF-BridgeOfFateCTF-Grassyknoll CTF-SmoteDM-DesertIsle DOM-Access ONS-DriaONS-SeveranceONS-RedPlanet ONS-DawnCTF-FaceClassic CTF-January DM-Curse4 DM-Deck17ONS-FrostbiteTUT-ONSCTF-TwinTombs ONS-Primeval ONS-Adara ONS-AridoomONS-AscendancyONS-IslandHop ONS-Tricky ONS-Urbans\eiOnslaughtFull.MutVehicleArenaOnslaughtFull.ONSBomberOnslaughtFull.ONSPainter&OnslaughtFull.ONSMobileAssaultStation.UT2k4AssaultFull.ASVehicle_SpaceFighter_Human/UT2k4AssaultFull.ASVehicle_SpaceFighter_SkaarjXGame.MutUDamageRewardUTV2004s.utvMutatorFY"MOV-UT2004-IntroMov-UT2-introssso PrAn.wQ*Q_f2wC*Ca-w w *a | -@ a *wN*puw*rxxKIxwI*rxKwr*lrrIKKwIrrrK<o  Gsdsssesgsscss`ssN@sssOsssQ@sMsassssuss]aPd sw@Vdsg\Vd sxssZssYssdssss^ssssQd sFsOsvsesssssRWHbd AwJ*%J-H u$BJ-F u9=,V-{u9=,sJ-vu9=,-Wu9=,-Gu9=, -Uu9=,@-ou9=,;I#J R#9:M9:$J +#9:JJ9:$J-vr*-l#-l #;-l9:p%u HJ-W-G-UNO9NHIJ-W-G-U-oMNOpE 9:p%DeJTJ +9?, uJJ6J ,6J ,HIJMNODeJTJ +9?, uJJ6J ,6J ,HIJMNOpE9:p%NHIJ-W-G-U-oMNOpEOI#9:M9:$ -ou HJ-W-G-UNONHIJ-W-G-U-oMNO Gss[saMeesssDssgsWsssss_ssy@scslsOsWVwhsss ss\+@ssrmssF@sssmsnssessdsOs@ssE@ssWsswssHssssGTOLG Gsssn s sZPgG GsfPfOdg( GssZssswssTss]ssIssfss]spssesXssd@ssmssu@)sJGssS8t(sssnssK@ssO$ssIssLssf@ssssfss|&ss}MSsZzki@Hz!~z  Rz Uz3@z `wU*U-l fz  U   GsssTssYssQssss~=sseds@ssc@)sJ@ssgsssSss@ssssW@ss@iKiLishs]ss\ssssZ  @sxs@ssJlssC@ssjssXsstSQeN% )SrS" G!sJ@ssssessissyssbssgs.sjsslssmssusspg]hiC 7\% GsssyssssssssGssd |a-y'%-S wF* wF f"9?&wD*rF*rF *D-^ wc*FcaDluDjl-gwDDI* a%bDDIDEI(-a wN*fasw*f fF|uDwF*Fh f9?,f FfF|uD?f%b(9:!9:$ d aF|uD Rw*f aF|uD|wF*Fh a9?,f FaF|uD?fY 9?fF|Du?%&wN*-}-a-}Hr&b(FwF*yFe }ry* wD*D-^ycuyD|w * D F|fDub?$-@6 Q6u6ub9u| Gs}@ss@ssss@ssssnssussssssHss`@ss@ss@ssZ:sssss[sZ@Qdsssbss]ss^ssss`sscsssMesrbpsDssFssissh@ssjss|sslss@ssassrsssesFsYPWd ssssisskssxssqssSFKe sCssIssKssMssAss@ss~ssSssbbpsPssDs\WHdG2"@EUwFi$ BM$L=ue$?hg$?{h$HBph$?Ii$?Jw$HB\osswNebe\dIfʁ)dhah:0a>$HBM$=ue$?+MYCS\"Sss_sst.BVg3Z)B Gsss]@s~sN@ss\ssmRqhu )R)T G$%sT@sysPss@ssQV}vO )V)X G%%sX@sWsN|fOifgs@ss[kgZhs@sGsn0@hQjxiWhMi pbi3\C pCM%k ran over %oE]%o ran over herselfW]%o ran over himselfSgg\c~eSW{r $@u$?ss@sysoss^ux.-C \rr*稨SVehicleFactory:9Vhas no VehicleClass t^a/!xg sa wr*oar  wo*soQ Gs@sot(n\ga*t(-MY)$ff?l&"`e&$=[&"?_%"ssssN@ssbssdssL@ssessgssC@ssDssjss]1ssssossss]bpspbpsqbpsBbpssbpsvssssH;G_eJ GsOs sTNLesssss@@ss@s}sF@ssG@ssI@swsv@ss@srsn@ssO@ssUssFss@ss@ss@ssxssssRssSssTssUssVssWssXssYssss\ss]ss^ssd@Pds`@Pds_ssassXssssessfssgsshssissksslssmssnssosst9ssmssyss[ssRssW@Qdsv@QdsNssHssUssd=ssdss}ss~sscsls@ssk/@sAssB@sCssD@sEssGslsH@ssKssKssssNssk@ssOssRssSssTssUssVssWss_XpdoNX##(-W(($VUNT#S(-R(($ON GB3sssZss[ss\ss]ssd^Ge X5N^#](-\(($[Z GB3sMss`ssassbsscssdssessfsslssnhYgp T7\%'w%Ow7\E9:6Zw\9:h(w' Gsgssjssksslssmss`Epi^ Bg%=g7\36Vg\E'g( Gs[ssqssrssssssstssvsswssssysszss{ss|ss}ss~ssss@ssCssDss^>E{dc_NED#(-C(($@N~}|(-{(($zy GB3sZ>ssssIsWsJsslsOsss@ssOssPssssRssTssY sst@lzfs@ssa@@^;sg@@^;si sVsA@ss>L_hsNssfBC9$w** Gs@ssAssNsZsss@ssjssPsstssn ssssssssP5ssssssssussssxssCbcdPJHCw*Qc $c $'( Gscsspd}D~K"w* D} GssscssssLssssB@sstedsss@pCeu|p GsNssHss]ssssPssssssssJzRd5w * RdUw[*w[ *[ RdyrT*rT`*,T`} Gs{ssy@sswssSsssYdd ! Ua'(U*-`'#o$-z(-A"'-@"(^-}' GssG`iej*wN*N-smN-smPG-B G Ra-x(-r(rp( GsnjD BEb"-gja+"oofoSj-<rp'j-B j-Sw.j>*H% D%Erj MawN*NU*wN*NU* GsSsslYbW2-Y! IqN(pwT*wT^*NHtT^}r *('wN*-a-NN-sn(N-Y'Na''-Oif'-O -YN-sn'N-Y(Na(((-v(e ^re^Ce^C*reReR*e-w' C'wN*N?%Naee dN^.ew^*^ V NN}de-w(Nre  * qpNN*DfUWB' GsIcC /R`-v'T$T-mSc %cc  #Adc -Xwd^*cMtNcNZfd-w'dCNaddd-w(lq+w.d*jjuT^ Hqc GsZssgcj+3F#c-T#-drc * wN*wc[*c -Xca/!@) ?%( vpc(-]cRd9:p-n-]-](C c' eec( GsR6rkH Ak. 3rk*wk#(bk-<Ufkkl@|bekkl@z"' GsXss_ss}ss^ssBssUsshs sg@)sZ@)ses sP@ss~ssUssjsssscssa@ssG@)s{@ssL@)syssw@)sN@)s@ssMss]xui('U ,U  | Gsz@\i)<U ,HpppH [U  |] G sssssq|md}&-`-H r`* Gs@ssNU@Msw 15ssPle39:9:$ wW*[P IzP[ JmP wJ*WJ[P GsN@)sv:~DY I=-[ w`*-['OS/a9 Dw.D*r.DT.D~swOD-trODct10--` w* t%t%9:E9:E-`'-Mmmd G so, sHs@ssGW@e%;;稨9WVoiceReplicationInfo created:9V}!Td Gsb\Mre' GsOssvxb[d{b ServerName%a 4AdminName&a LAdminEmail,a iMessageOfTheDay,a vb G(sss\@ss]ss^ssChVrd GspssZsstssBXgd% i Gs@ssSdJPZ%KZ7MAZMt%dZMZ* Gsi sst$ 4sh s=s] s=s^ s=s@ssvbI[d,I $bEnableVoiceChat%w EbAllowLocalBroadcast&w fLocalBroadcastRange,w DefaultBroadcastRadius,w VoIPInternetCodecs,w VoIPLANCodecs,w vI G(sw cPFew PP3bUbEnableVoiceChat%I$$Check Xv''P7bUbAllowLocalBroadcast&I$$Check Xv''P@bULocalBroadcastRange,I$d$Text4;10:3000Xv''PCbUDefaultBroadcastRadius,I$d$Text4;10:1000Xv''P5bUVoIPInternetCodecs,I$$Text Xv''P0bUVoIPLANCodecs,I$$Text Xv'' G si~qeL~7&A~%7r~*A~&~-Y( GsWeUe06   GsssdKUfL77Bfoofo]"zfoofo]"zK \]^c`UeapG^#6^oB`a^K xaZbB`'# B B Bwx*Ox-l rxef)waZbB`(# B B B*BZMa<K K GBB6K B\6K B]6K B^ GssOsdssNgNhj Gshssssnssosspssfsbe<s URP`-ZeXs iXjieXjXs oaLX_Uearo'-U|a#?No|_N|Xa<Xs G__6s BU6s BR6s BP Gs`sszsswssxq`dY( Gsss}wvhZ GsssssyssF|Fe GsksssOsPlRLd$sR "GameDifficulty% :bWeaponStay& UMaxSpectators, mMaxPlayers, GoalScore, MaxLives, TimeLimit, bEnableStatLogging,  bAllowWeaponThrowing,  bAllowBehindview,  -bAdminCanPause,  FMaxIdleTime,  jbWeaponShouldViewShake,  G s@ssss]DeeJI GsssTdCdi PIZ-w w *a | -@ a *TdddRd9:p9:p,w.d*g!s.d Usg$wh*ah  @T$ CdRd,ld9=dRdV3@@MlBt"-S(Q.duwQ*D QwQ*&-wad|Q`e GsJApg GssOs@sGsQdES|:NZcdS. awS*-Y'`S^-ZS-<xtSgYrV3V3f"9?&MlAQdwQ*3-w r *a |QHfW?% -@W-Y-w w|* *aa|Wwa*ad GsNHLg GssOs@sKssesQLieA Gsss@sOsnWMef z".e3 GsssessPss]Tvgn GsssZDf(__ lq GsRss@sVsVXEj ' GsYssvmzeWinm-sn' avma mo$ma*m D4w Gsh[Zj Gsss\`PfBj Gsss_bifj rN*(jNA#??6jN6wN6#?9?,d@#?ANA?w *  B#@  B9?%@9?++?@9?raUS @w w(j* Na  @wZraUS @w w(j* Na  @w'w *  B#@ Eh%h7cDhc   BDEED@hch1  B#@ -m 6%c9?%w#?6%c/wN6#@@ a@wwraUS@ w(j*Na @'Na @'-mh%h7c@hcNa @'m%m, m9?,?6m6jraUS@m@(j*Na @m'Na U'mh(h%h7c6%c9?%w#?6%c+wN6#@@ ahcwwwaUS@ w(j*Na @'h( Gshss@s^scssf@sskgbh GssOsisspj^d* GssOslssm@ssFz{eS ANbwT*wT^*T^r$?orN* z N}dN zN[r * w. * a  . vN. V N C3r z *zN qpNN*-v(UWB Gswnod~}* GsJ:obun-@-` F9:!9:$ J:buT rbuT??& ?%?w *z z A bUbzuz-Xs.zws*`s"Yr-a-} wN*N?%zCz dN-}HrN*z\z-Xz-@za Ub.$u3wb*/Qb@/Q*]l. s k-@a Gssstssu@ssKvTi|  G ssssQhep"W7Q%Qj Gsss|ss}ss~sss sJ;POc wN* j+O GssspdBB \(-x' Gsss|ADD m\'-r' GsssSN\1-N-r'-x' G=s@ssEM^9;-M-r(-x( G=sE_FsgTF !s GszZJcd]J -xgp(-x(-D'@-rgp'-r(-D'-D GsDss~xxh{% G sd]ILK/q5w * a/!n _LPUwP*Pa/!nr.P# PPSI-e (N_ Gsss_`LPG} GsQssssUXOK@-*-Z wN*N @K G sMss[9RUJ { GssswTT_e4XPr.T*w.eT* rT 9:T9:$ IUI|E>Tsw *# S.T EիI>Ts#?wh*ah T$ @T1-9DI= T  Eh Gs}^VHmwrH* rH 9:H9:$(H-r H-|9?, (w.H*r.eH*H8-' H  Hse( GsssGYJCex2-Z rN*(N CeJ Gs@`SSj1 Gsss[_ch w * GsssfaZi r ** Gsbssses`dJf&' GssscQfhb Gsss`d]WIf/eCr\**\*}%e%^ `e&^ we*Nae  6#@?wN*Na*`d-I-H GsssossSXntj> G sus sssPswRdBOD9:9:$ 9:p, w *ld9= Rd9:p GsssoFld\2UppF/9:U9:pMf Gs@ssxMfcT G skczBRgkcBc]BI9=,9=,9=,BAapppppSteering 9UW throttle 9UU rise 9UBwN*]c]cB)]BI$$9=,Ba--- DRIVERB)@]NRBc] Gsss|ssH}Sex  Gsra{a|# -gC r** Ab(wA*A,a+9Pa  A  AqaA Q aa GsssAss@ssEg' G sCjgE G sf @edFs@sGsKi}di pE9:9:$w. *im"9?, b$b$f"9?&wi*wi*iDu9:!9:$  [*-}(-sn(-@"(-K'-Y'Owi*iPf-z-za''9:9:$ ?%i-ai-N+#Fm-Mo$o$a**-^ (-sm-smw*,*i G s]BUjv' Gsv@k[d|k "GameDifficulty%f :bWeaponStay&f UMaxSpectators,f mMaxPlayers,f GoalScore,f MaxLives,f TimeLimit,f bEnableStatLogging, f bAllowWeaponThrowing, f bAllowBehindview, f -bAdminCanPause, f FMaxIdleTime, f jbWeaponShouldViewShake,f vk G sECd+. )C)B GsJcQZf<l[Qf"9?&U*cdhfU(-}'#+#-K(Q-aQ-Na(((-Y(QzeQ-Zb$@E-^ '-z(-@"(pQ-NQ-ZBa[Na[NJa![f~g?s6j(%%Q-aa![f G sssJw1= GsM@Hh4)@ G s\Ai'fL% r*( i'A GsS]Ns9!S]nf GslnfE@bE G sssEvAy (wL*aL  E GssssOs@* """&&&(((***...///222666888999:::;;;===>>>@@@CCCDDDFFFGGGHHHIIIKKKLLLNNNOOOQQQRRRSSSTTTUUUVVVWWWYYYZZZ[[[\\\^^^___```bbbcccdddeeefffggghhhiiijjjkkklllmmmnnnoooqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~[ZZ]\\^]]cbbihhmllonnpooBAACBBEDDHGGLKKNMMONNPOOSRRUTT433544655766877988:99;::<;;=<<>==?>>+**-,,.--/..0//100211322%$$&%%'&&('')((*)) ! "!!200(&&)'' !" soU ss^|i#KJi%Gi7L =wiL *iL #i Gs|S@aK w*@a( GsgRtdu* GsssBL{}A<wo *Wo }{6rW*o W GsssWssssdsse@ss^fIer=' Gs[iqgxKGsA#/KNp'qK!P GsLkOd"R( GsssLmOd=VT( GsssLoOdzY( GsssAn#~3Y0^--M-bNp'q!F!P GsLrOd\( GsssAq#\*^'^%Np'^%@** GsFSwsebGsLvOdb( GsssAu#Hb^Np'q!D!P GsLyOdc( GsssAx# Jc*^'^%Np'^%@** GsBS|@fNhGsA#Hg^Np'q!m !W GsIKidm9:!9:$q!id!s-g(AX9?%-b'aX]9:!9:$q!id!sAq$Xa-dwW*W|q!deAq$o$Ua-MNp( PWsGsLOd[i( GsssA~#`Ei#^Np'^%q!id!P Gs^@yj ji^Wy x7wW*WLAq$o$U_f-Mq!id!W GsssJBmgJB Gsm Aw@xk`^]^%U*^%Ww uPwW*WLAq$o$ GsDhfG}"P GsbvaeYpB)v GsD'l ^% Gs}KdepGsLJOdp( GsssAI#4p^Np'q!id!P GssRMkfuGsA#qu^Np'q!n !P GsQssMs$* ? Q  " "" "Gd"s@(())]]\RRQ&&((2244>>0uu??2  aa[^^mmPPE vv~@@@@AAQQhhf33%&&&&ggii66}}HH:xxCC4 !!^^W__,,//__``V  uu|BB__}}}PPEEyyy33%RRR+++**''~~{RRR<<<YYYww--CC5{{22--- xx@@1 888"""zzz^^WbbKKTTR```OOOJJ``ZZP  AAA<<< qqtJJmm*** ooLLuus44$&&&##44 LLL;;NNApp22,,,ZZZFFF00}}99+ ppp$$hh`YYUU(((aaa)))000UUiiXXM ```rrrbbbſ @@||SSS&&&,,,RRRiii˽OOwws.. ""%%#//.**(??>KKI   ,,%$$**..--HH:rr WWYYYYYYYYYY````\\YYYY__``[[YY\\````````````````````]]SS}}FF9  AA6``ttII;((// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00--#AA<<<9^_]^_]461GGE454BDD?@@?AA=>>@AAMOOHII?@@?@@DEEEGG ^_]^_]FHAFHA """;<>%*) ^_]^_]FHAFHA%%%-..:;;>???@@ACBIKJJLLQSSVXWY[[Y[[\^^]_`eggkmmlnnrss~|x\ccbjiW_^lwvt~~}s~hrrdmkRZZDKIBGG:>>.21  ^_]^_]FHAFHA!""566MNN\^^rstuz{syybhgPVUQWWNUT^dcW]\kvwr||_gfPVWHOO?EF8=>-21!$# ^_]^_]FHAFHA9::Y[Zvxx}mtulutdlkfoncjj[ccW__Yba`gf`kj[feakjZccirr`hhX_^Z_^\baW`^X^]S[\U__OWXLUUnxx}fonunvv`hgakjLTTIPP>CC6;;.22"$% ^_]^_]FHAFHA GHHpqrszykttjtsiss[efP[ZKUTDMLELJGQQKUTRZZZccV^_MTTR[ZOVSRWVT]\R\[[cc[dd_hhjttmutw}vviqqnxxfpo[aaRXV]dbU\[MSRLSRLRPBGF?DD/33$(' ^_]^_]FHAFHA-.._``pxx^ggQZ[OZYS\\T]\akjeooS\ZT^^YcbS]\NVUHPMPZYNVWGONFLLJRQLSROVVSZYu{zxs~~uirqirt\ddU\]JQPJPPV`_V]]KPOCGEJNM>DD5;:+/-$'' ^_]^_]FHAFHA$%%_`acjkMSSFLLDLLOWWQYXT]]XabS]]PXYW``[ccQYYOWVXbaMUTNWURZZ[geiuufqogrrkuuq{|ozzcllszxs}jwxmwvfnnZccYaa\cbSYXOUWKRQKRRU\\clmSZZQWVRXXFLL>EF9??7==5;;+//$''   ^_]^_]FHAFHA>??{U[ZIPOFONHQQBKKIQPMUURYXRYXOWWQYZ[feT\[PUVJQO[dc]gfs{wzr~fqpLRQGMLAHHAEEFLKJQQJQPMTTGNNFLLFMMCHG8<:599276055*-.*..+/.&))$'' ""  ^_]^_]FHAFHA;;;`ffDII8>=AHGJRRKSSXccR\]IQPOXYT\[OVUMXWJSSX`_XabZeexzeqqOYXIUSHRRFNODLKEKJCIG>DC@FEQVV]ghCJJ055+00+/0"%$   ^_]^_]FHAFHAhnmQ[ZPYYLTSEMMHPPKTTMUUT\]PWWNUTNTTPZZNVUYaa`ji~iqqOWVDLLAIIDLKO[YPZYKRRFMLKRPHMM=BA377/21'++   ^_]^_]FHAFHA_fe:@?AGEU]]QYZJRRGNOKSSGNNFNNNWWLSRLSQOVVS\\p}xV__IQQNUTU]]PYXKTTAHIAJJMWXOYYNXXJRRJQP6:9#&&  ^_]^_]FHAFHAFLLCIHBGFGMLELLDKJEKJGNNBKKHQPHPQJQPGMLdlk~^hfS[ZPYZRZ[S[ZNVUT^\MVUBKKISSJSST^^U^_MVV288  ^_]^_]FHAFHAJQQPWWFMKAGEAGEBIGDKJGNNIRRS\\KTTRYYnyw_hebjiblkbkjOWWQYXPWVEMMHQPKRQMUTOXXOYXPZYPZY3:;^_]^_]FHAFHAOWVT\ZPXWBHGAGEFMLJQQJQPJQQHOOLUTnxxZbb`ihfonclkS[[T\[^hgJQPEKKBIHHNMLSQNVVXa`S\\FNM$)( xzz^_]^_]FHAFHAU^^SZZQVWDJIEKJFLLHNNEKIBIHHON}[edJRR^fc_hfW`_ZccZba\ddXbcNUTDLLBJHFMLKRQQZX]ggU^]JRQ(,+676^_]^_]FHAFHAQYXSZZLRRFKJEKIGNMJQPCIIAIGXcaRZXKQPW_^_ih\fe\ecX_][ec]eeQYYENNEOPBIIIQOS\[T^\^igQYX:@?{^_]^_]FHAFHAKRROVUJPPFKJDKKEKKEKIAGELUSfpojtuAIHIRPQ[Y]ge\ddZcbZcabkjZbaMSSHPNKUUISSMVUHQONXVR[ZGOONVT=AAT^^^_]^_]FHAFHAR\]JPPEKJHMLQXW?DC?CB>B@>CBW`^W^\JPPT^^ZccXa`]ggX`aJQQGNNS\[ISRHQQJUSLUUGPQKSSEPOCKJMTTfkk_bb())688Zdd^_]^_]FHAFHAV^_FLKBGFCIHJQQFML?EB>CB@@ KOM^_]^_]FHAFHA\ddbkj]feZbaahgclk\ddaiiV[[Y_]UYWRVTOTRNTRW^]Y`_p{y¿SZX[bbX``U]]W^^SYXFKJMSRPVUS[YOWWGNMNUUZba[cb^edckiRYYQWXU[Ziqn{mrq466^_]^_]FHAFHAT[[]dcX_^X`^dmmT\[T[Z_ggRYYRYXRWWKQPOVUV]\X`^_hhRZY]dbrzx{ajjIOMRXVV\\MSRPVTLRPRZY^ijU]]U\]ZbbRYY[a^dji]dc^ff`gejrpbkkclkhombee.00 ^_]^_]FHAFHAW]\QXX]eeakjhrrY``RYWZcbU^]T[ZOUUSZZX`a]eeYa`TZYOTSPUSLSQYa^_feU\ZOVTMTRMSRQYXW``RZZW__T^^U`aSZYU[ZRZXaigell]ca]dbaiiYbbkusq}{t}|{\``')) ^_]^_]FHAFHAY`_U[ZX`_Xa`\fe[ddakmU\Z[cbS[[Ycd`jkW`_Y`_U\[U\ZLSRQWVU\ZKQQMSRjrrlyxYbaKRQNUSRZXSYXU[[Y``_ihepqbllW_^Ybb]ed_hf[a_NUTW_^Zdddnm[c`oywajiT\[hpov~}]__'(( ^_]^_]FHAFHAHNMLRQV^]`ihWaabnoX``RXVU][OVUR\\S]\T[[MRRKRPOWUQYYW``\ddV\\RYX^edT[[bjjs}{RZXFMLV]\bjiU^_[ddhqr[cdYaa_hiYa_V]]V_]MUTPWWSZZU^^V__dmnpyyXabPYZS[ZY``fmm|x|zGIH ^_]^_]FHAFHA587<@@JPP]dbW^]cmlV\]MSRIONJONJOORZXT[ZV`_Zee`hh^ffLTTPXVSYXV\ZV\[\db[ccPYYpzykwu\ecSZZ[bb^ef`jjT[\RZYTZZ\ccV]][cbV^_QXYZcc]ee\ddjuulwx^gf]ffT[[V^]W^]T[[Y_^kqrw{zuwvACC ^_]^_]FHAFHA043>DCJQP_hhajj^ed`feSYXLSRMSSPWVR][dnn`jjGNMJQQLTSQYW^feTZYXaaU]]XabRZYRZYnxvr|{RXWRXW\eeYa`SZYX_^`hgSZZX`^\edYaa^febkk]ff`jiisrYa`big`hg[edT[[V]\X``[cbKQQKPO[`_txwjmm9;; ^_]^_]FHAFHA+..CGGLQR[b`hqo_ggQXXMTTIQQRZYRZYR[ZT\[NVVKSST^`OWWKRPPXWRZZU]]SZXMUUCJH`hg]fePWUW]]OVVJPO_ee\dcY`_W`^^gfckjV^^U\\`hhisrT\[W^^W_\X`_V^]]gfYbbY``QXXS[ZOTRRYXgmm}ikk455 ^_]^_]FHAFHA'**:@?JRRRZZX_^^fdPVWQXW[cagpoV]]W_`OWXYdeT]^DKLHOOT^]V^^MUUHQQLUTSZYNVUmwvkrqSZYU[[T[Z]edgpp^geW_^^eeX`^gop[ddahfr{{Xa`X_^TZYYa`X``]dcU]\X_^XabRYXV]\W]\U[\V^^QWVjnnUXW#%$ ^_]^_]FHAFHA $((;@@LQPY_^V^\]ff\ed`kj_gfakkeooYaaYbaLTTQYXdljU[[PXWRYYW__W^^U]\QYYT\[^hfjrpYa`[aairq_hg\dc`hi[cc_gfaji]ecdomdmlaiiYaaX__V``TZZU[[[cb_hgT[[RXXJPOLSRHNLOVU_eeV\Z\bbqwwxzy899 ^_]^_]FHAFHA #%$9>=HMLYbb_ijbkj_hgZbadmmZbbhsrsiqq`iiT]^TYYT[YMTSNUVU]\V_^NTSS\\U^^t\edYbaZa`QWWOVUU\\\b`]edckjZba^feY`_dljlsq^ff\ddcjhdlkZbaSYYW`_\deJPPKRPRYYQXYR[ZYabS[\QWVdjiRTS ^_]^_]FHAFHA ')(=AAEJI[dd\ddNTSW`^Ya`]fffuukwvcll[cdRZXYbbU]]S[[QZZLTSOWWXbc\ee`ikV]]ituV[[U]]T[ZOUS\cb^gfcllhrsX``MSQV^[\b`SXVU\[U\ZYaaT[ZNTRNUTPWUOXX[efW_`YabYcdW_^W^^U]\KQOS[YY`^ous_ba"$# ^_]^_]FHAFHA &))DIIGLLW^]Z``QYXYa`PWWPYXgqolwxZcd_ijajkT\[U\[Y__W`_S[[Zbb\ddRYYOVUfpps~~SZZ[cbcmm]eepzzp{zckklttblkRZYPUTPWVRYYPXWQYVIPNJPOFKJLSSNVV[dd_iiZccNRQOVVNUULRQXaa\deLRQYa`lttloo+-- ^_]^_]FHAFHACHHJOOW_^PVVGNMQZYYcb[gghsscmmcnmmxwgrrjuudnnRYWKQPNVVMUTRZ[PWWV]]TZYozz]dd`hg[baisrgrqpz{ennV^]YbaPWVW_`V__W`^`kj_ijV^^LRRV]\bjiaiiV^\QXWNTUV]\W^]T[[]df`jlV_`T\\WaaXaairqhlk()( ^_]^_]FHAFHABFFJPOJPPOVWVa`Zdc_ijdnn`jjcmmdongrrRZZKRQLRQGMLLSROWWU_aOWWS[ZT\[Ybbw~hqpfoockkeoocnnenoQYY\dc`ihX``QXXekkahgcllU]]X^\bhhbjjQXVTZY]baQWVTZYW^^U]\XaaW`_XbbW__`ii[eeall[cc`fe^bb ^_]^_]FHAFHAFLKDMMGNNW`_^ghcmmWabMTSQZYV`_OXVMUTBGFBHGHOOHONHNNGNMHNNGMLSZZ[dd\ee_gfZa_QWW`hhfpqcllbklcll]ffZbcSYY_fdX^]T[ZU\[QVUPVUKQPKRRSZZ\ca\b`Y_^RVUU[YQWVNTSY`_\deRYY]ggnyz`jjT]]XaagonFII ^_]^_]FHAFHAJQQWbbOWWPWU\feYbbLSSGLLEKJPZXMVVMUUGMMIPPQYYRYYOWWEKKHONFLMIPOajjepobkiU\\V]]Zbblvwnwwjssgqpdlk[dcV__Y_^QXXU\[Y_]OVUXccNWVMTS^fgW__]caoutY_^NUTY_^V\[PVUZa`[bb]ee\efOUUXaaZbbSZY_ihlut~Y]] ^_]^_]FHAFHAQSSjpoU_^HMLQYYV_`KQQLSRJRQT^_PZZKRRLUUQZZQYYXaaPYZNVVOVVJPPHONZbbmvuakkekk]db_gh\ddbkjr{{fooNSRSYWV^]U\\S\[T[ZMTTPXY\ffZccW_`YbbOXYQXW[`^Za`Ya`W]^[ba[a`U\[\dd`hh`gf_ffY`^U\\S[[X`_RYXS\\qyyqwx*,, ^_]^_]FHAFHAfhfw~~PYXRZZNVUMUTGOOELKLSSKRRMUTIOOHPNOXXPXXRZZIPPJRQOVVIPPIPPW^]gonisscllcjj^fe{Ybc_hglvwajjQWWQZYQXWOVV[edW_^ahfY__KQPMTSU\[YaaZghYbcZ^\\bbhondkkfmmagfU[Zaii_fe\ba`hh^feW__gqpahgT\\OXYS\\jsts{|:== ^_]^_]FHAFHAqyzPXXJQQOVVKRRLUTQXYKSSELLEKJGNMELLNWVPYXNVVNUUFMKMUTLTSQXXU]\X___hg]febjh^edrxv[ddfpoktt_hibkkeopV__X_^_ecY__\baV\[Z`_`gfYaa]ffirsblm^feZaa`gf\dc^dd`gg^gf]ed[cbZaa\cb^ffV_^Zba[aaQXWT\\_hiXaablmipp.22 ^_]^_]FHAFHAorrMWWMUVGNNLTTJQQNVVT]\XbbOWXKSSJPQGNNLTRS\[T]\LSSJQQMTST\\Yba^ffX`_Ya`ahgcih`gg[cbeoqkvvemmkuwers^hhY``Y`_V]\X``W^^\dd`hhbii[cc\cddnoX`aV]]RYY\a_X][QXXSZZ\ec[cbY``W_^]ed^edV^^MTTPVVOUTPXW[ddhrs[edV``Yab ^_]^_]FHAFHAEGGjqrELLKTSHPOPYYNWWQYZRZZR[\JQPOXWLSRJRQKRROWWQXYJQPKSTMTSNUUQYYT[Z`hh]dd\cbZaaV]^\bcs{{bjjlvvfqqdqsYaadki_edU\[W_^W^^\cc`hg_gfZaa[cbZccXaaOUUMTSPWUY_\U[ZX``W_]T][W`_`hgV]]T]]ZddS\]PYZMSSKPP]gflww_hiU_`YbdGMM ^_]^_]FHAFHA9::FMMNTSIQPLTUNWWPWXNVWMTTPXXIONJRPLRSJRRNVWLSSNVVOVXIPPIPPLTTOVVPWVQYYXa_QYXOWV^dcY``\cc_ee]eeeooqxwryycjj\cbYa`U\[]dc\dc_fe]dd]dddllaihbhfZ_^W]\V^^lutU]\[cbV_^QXW[cbRXXPWVQYXWbajvx\efOVW^ihq||mxyclmOVWOVV032 ^_]^_]FHAFHADEELRRMTUOUUMTTOVWU]^PXXT\[QZYR[[KRQIPORZZS\]T]]QYZLSSPXYW__NTUJQQPWXLSRRYXU\ZMTRU]]T[ZPWWx[cbdjkdijemkbji_gglsraih[bcX`_]fe[dcY``]ddX__\bb\edPVVMSSOUT]deisrW]]SZY\ddX^_LRRV]]QXWSZZ]ggnz{^hiU[ZPWVV^]dnnT\]LRRRXYDJI  ^_]^_]FHAFHAhihfqq]ffV_`S[[MUUQYYZabMVVQYZS[[QXXIPOMTTJQPQYYR\\V^^MTUMXW[efT]^LSSU^^ZddW__U[[V\]ZaaT\\MTUYaadkjiro]fcfookrrqyx`hgZaaT]\dll[ddT[[RZYZbbcmn]hfW``YabXbc\cb_edPVVRYYOWVPXYMUURYYMUUS[\U[ZYabNVVNUTLQPKPO\ffhst[ccV^_NWV(,,krrJQPPWVSZZ]eeS[ZKSRNWWU]^U^_PXYMSSLTUIQQJPPMTTPXXPWXOUUMTTQZZV__R[YKRRS]\ZcdPWVV\\]ddY__SYYQWWZ`_honnts_ffdjibhfgnldjkfllW]]^ed^edW]]T[[doofqrdmm_gh\ddYa`U]\Za`V\]OVVPWVLSRTZYV\\NUUQXXS[[V_^W``LTTGONHPOQXWPWVX``\edMUT:A@RSSkuuU``SZZSZYV^^QZZU]]T]^PYZRZ[PXYLTUOWWPXYS[\SZZGONPYXLSTJQPLSRNVUNTRKPOMUTXbb[ddSXXNUUT[ZW^]V]\Y``RXWZaa[dcX`_W]]V^\jqpflldkjV^]]ddY`_]dcZa`dmn]deahh]dbY`_T\\\ffX``YaaPWWSYYRYXRXXPWWPXXQYYPWXV^^U]^Xba_ikXaaQYXSZYT]]R[ZU]]JQR$%%\ee`lk^hhU]^KQQKRQLTSOYX\ffT\\NUVJRRT]^S[[JRSU``ZbcMTTMUUU^_PXYKSRLTSQXWKRRIQPV_^]fgZa`TZYT\[T[ZW_^W]]\dc]ed]dcQXWPWU^ec^edZaaY__bjiXa`]ee_ee[bb_ggckkXa`]edZ`aT[\U^^U]^S\\PXXOWWRYYNVTOUTPVUPWVLSST^]ajieppZccQZXIONMTSKSQXbaS[[(,, ijjellOXYZcb`ii_fhU]]KQPGMLKRPU]]Ybb]ffYbcQYZU]]PWULTTU_^R\[QZYNWVU__S[\QXWLSRNUVLTTJPPPXW[dcX`_V]][dbT[ZY__`iiZa`]dcX^^NUUPXXXaa^ffZbbW__\eeZbbY``RYYPWWV^^[ab^ed^ee\cbW]]W__^hj[efPWXT\]PWWNTSPWXMUVPWWU^^U___hg^hh\deQYXGMKJPOMTSYaaU]]6<=ABCS\\GMLEKJGMLYaaW^_T[[JQPHMMIPOQYXQXW[bcZdd[ccNTUIQOMUTT[ZNUTKRPPZXT^]U\\TZYPUUIPOMTTNTSSZYU\[W_^V^]]ffQXWiqpmwuZ``V\[TZYX`_dnnakl_ih\ed_ggZaaZbaeml^edZa`W__U^^PVUSYXRXVW\ZX][\cb\ddV_`U]^U]]T]^NUVMTSWabQYXJONDJHNVT[bbV^^QXWHONHONJQPSZZNUT?EF788^ffFNNLTSCGFADB?C?NUT\dcV]\JQQNVWQXXPWWS[[^iiU]]_iiPYYPWVMUTQYXLRQIPPQYWYccQYYHMLFKJFKKMTTNUVV]\\ccX__Y`_^ffRYY]ed]fd^feX`]Zba`gfeno`ih[dcakkW`_Ya`eooX__X``[baX`_X^]ZbbU]\V^]SXWNUTPWWOWWY``SZYV``dnpNUTPXWIONBFDAEBAECT\\[dcQXXJQQPXYOWWPWWU^^CJJ.//biiU``\fhXabKRPOWWCHFADALRQRYYQXXNVV`jkV^^PWVKSR\ggT\]S\]RYYQWWIPOOWVMTTJQQKRQU^^RYZTZXV^]V`a[edU]]\cdZabNUTQVUQWXajjX_^[dbY`_\ca\edbiickkdnm^gg_hi\dc[aadlkU]^T[ZW^_Ya`ZbbX``[cbV]\SZYSYXOWVhqsbknQZYQYX^ii^giRZZNTTLSS?CAEHFNUTT[[MTTU^^`jjSZZMSSNXVCJJ///rzzV^_OWVZdc_hiZbaNTRNTTKQPHMLJPOV^_OVVV]\W^]OUTKQPU\[_hi\fgV__NUTU[[TZZMSSKTTNUTKRRcmlpzzdmmq|ziqpcml^gf_ee[dcPWVT\\LTTwW][Zb`W^]Za`Y`__gfaih]ccgrrdnnZbb\bb]dcckj\cb[ccU]\U\\V_^W_^PWUTZZQVURXX]fg\eeX``S\\]ff_hjU\[MTRMTSJONHLKNVTW__OVUX__T[ZLRQMSRZaaELM../w}|Y_^UZYOUVU]^U[[SYYOVTW__U\\OXXPXYSZ\NVVPXWOVULSRPUUMSSNUTKRQKRQPXWMUTIONIOMGLLHNMRYYT]\ZcbhttmyxnxxX_^Ya`U^][cbbji^ffbkk¿emkaig\db\cb]edU]]\dc_igW]\fopYbaW_]W^^dll]eeSZYW]^ZcbT]]W``[aaT[ZPWVZa`\cb^dbTYXRYYU\]T[[QXVQYWZbbRYYPXXQYZRY[NUURZYLSROUTMSROUUMSR7<;'((ovuQYXPWWRZYPVUGNMQYYPWWOVUV_`YbaS[[MTSKQQPWWZcbYbaQYWKPPFKKRZ[X__NTTJQOX`aJRQGNMMTROWXQYYPXXR[ZT]^blllttW^_U^]T[[S[[Ya_\dcV]\X`_PWURXWV]Z[cbZb`RYWU\Z[ca[bagqraii^ee\cdXbaXab\de`kk`ij]hi[deX^]X_^S[ZU]\V]\RYXMSRJQQRYZNUURYYXbaY`aPVWNTSJQPV]]XaaV_^NUTINLIOOX``RYY6:://0uzyT\YQXVQWVOTSPVWPVUNUSPXXU]]]ffZbaYa`V__X``SZYNUSRZZS]\RYYQXWMUUU^]XbaRZYOWVU^\hqqakjajilutajj_hg[baZcbcnnepo`hi^ff_gf^fd\cbW_^OVU}pxxQVVV_]S\[W_^RWVUZXX`_\cb[a__feaihaii_gh_hidmmjttgppbkj`iiV]]U\[T[YV]\NUSRWWOVVRWVMUSRZZXaa\ee[cbW__V__X^^QWVOVVQZZS[[PXWOWVPWXXbbS\[7<;???sxyX``ZdbV]\QYXU\[ZaaT\\U]\SZXU]\T]]\fe]ecenlgrrgqr^ffW^]S[YP[ZXa`U\[U^]U^^MWWRYYX``V^^nxynyxlwvt|{W_]X`_U]\W__Yaaeonbiicjj^ecRYWW^\S[ZkvuZcc`hh[deW_`Y`_V\[V]]Y`_U]\ahfU][[aaajjcll^eehoodkkkrq_ffV\\[cc`hgRZZSZYX`_Y_`R[ZV]\QYXU]]Wa_\fd_gfhrpeqqfpoZbaV]\QYXS]]X`^T[ZW`_R\\KSS6<; HIIv|{aig]ddT[\Ya`W^^PXWQYWRYXSZYT\[X`_RZYW_^^fdS[[T]\iutlxybij\dcRZZOVVQXWU\[X_^S[[OYXR\[V_^V__XachsqhpqX`_OWVNWWKTSS[[PXYT]]W__bjk[ba`ihenmirq\fd`kjcmm_geakjYb`^gffpoenmW_]]ffirqfonbkjdkjgpo^febjickj]cdS[\[cbRZZQXWSZYQYWSZYV_^U^]S[[Zb`[ccQYY[edlyyjsu^dd\dcOWWOWWSYYV]\V^]R[ZKTT277 TUUhppSZYOUUOUTIOMMSRKSRMTSQZYQXWNUSJQQJRQLTSR[ZPWVSZZLTUQYY\edituOVVV^]V^_[ddZbbR\[U]]W^^V_^U_]U]]W_`]fgnyx_ghU\[X`_W_^PXWT\[QZZQZZ`lmirroxxt~jtsennW^][dcgpn_fdaihcljnzxfqo[baNSRPWU`gfZa_Zba[ccW`_U[ZRYYMSRIONNUTJQQOWWPYXPWVMSRJRQLSRMUTRZYQWVPXYKSTV]\cnm`ijOUTW__V__\eeW^_QZ[W_^W__NWV*//]^^nutX``NUWQWVRXWQXXMTSV]\U\[U\[V]\T[ZPWVOVU`jj\fgR[ZNUTJPONUTKRRFLLR[[`jjajkakkhqrakkmvuW__U^\W`_R[[S[ZT][`ihfpqhqqS[YYbaS[ZPXWV`_YddYba\cc`gglttallvGNMQWVOWUSYXX^]]dcdkjr{zdllPUSMSPNTSTZXU\ZclkW]^PXXRXWRYXOVUOVUV]\T[[U\[V]\SZYOUUS[ZdopV``QYXMSSLRQMUUIPPHNMZcc`ii`iifooemogpodnnT\[Xb`IPP"&&ijjmts^eegooXabV]^SZYX^]TZZPWXU\\RYYUZYRXVS[ZQXXRYYbkkYbbW``S[[HNLKQPRYYMUTNVVZaaZba]hgiss_hhZa`T\[R\\S__T]\PYX[dbirr`jjT[[LSRV_]NWVR[ZZdbaji[ccU\\QWWQWVajjgnlQWVSZYPXWT\\SZZOVUTYX]cdY`_ekidkignmdlkfnngooS[]Y`aRXWZ`_PWWRY[SZZSZZTYWSZYQYXSYYV]\bkkW__XabNUTGLKNUTPWVMTTQYY[baZcccmmhrr]fdW^^T\\T^_AJJbccmtrhpniqp^edX^_T\]Zbb\ccRZZY^_V\\MTSPWVRXWPXWU]\U[\RYZU^^QZZS\[[edRZZLRROWWPZZS[[NUVP[[[dd\ffmxxXaaNUTJSSNYZU__PZZT]\Xa_VbaOWVJQQ[db_ihYcb\fcclkNUU^ffPVW\b`{Ya`cjhY`_SZYY__U\\RYYU[Z]cc^eeemklsqlsrhpo\abV]]T]^]edW^_T[[Z__RYYMUTRXXQWVSZYU\[SZ[S[[R[[QZZV__[deLRSOVUNVVS\]PXXMUUVa`XaaepoittPWWMUUIRT7>>fghelkclm_iidkkX`aV]]Za`Zab[bbZaaMTSRXXQWWRWVOUTLRPKRQLSST[\SZZPYYU_^[bbX`_T\\YcbW`_T]]PXYNVUNWWR[[R\\frrepqIQPKTUU`aWab\gf]ef_ijU^_BHHOXXeon^gfT\[\fd`kkMTUU\\KQQ[a`_gfclk^ee^deY__[cd_ffgonhnnbjjdnodmm^feYa`W]\]eeW]_^eeTZ[PUURXWRWVRWVNSSMRQKRRNUUT\[RZZPZYXbaY``Ya`T]][ddT]\T^]MUVOWWPYYQZ[VaalxyYccIQPHRS056^``pwvPUTOUU`jj]ff^edZaa[ba^eePVWNRRPUTT\[RXXPVURVVINMJPNKSQKSSS\\PWVMTTPXYT\\PWWKSRNUTQYZW_`QXWPWVKQPKQQQXXT]\dno]fgQYYIQSNUVT[ZT\\\efNUUAGFFMLNWWV__PYX\ffOZZT^^S[]wUZYX`_V^^U]]_ghYccS\\fnmjqqMRQX``ajk[cb^fdX_^\cd\cdKQQOUTPWVU]]OVUQVVPTTHMLLRQKRQNVVS\\LSSPXWQYYU[[MUTMTTNUUT\^U]^PWWLTSKQPLTSRZZYbaeppX`bDJJ $$*+,x||W\\5::/55377+/.2786;<6::377266045)--.11*../33155-00031)-,-00034+//+//-23,01/34+/0)..)--.22+/0-11/44,12.33)..,00-10+///44044,00,00065.23.23056+//*/.*//)..*...22065378/55EKK_ee`dcr}}]gegnmynww`ih^hggppSYW043/33/451665::0654991675:;155-114:;7;<488376256,00+./+//+//266/33.21.10*.--10044).--22,02.22-12*./),,+0/-11,00/23/34-23-11*..-22+/0,11055-22.22                 $&&                    $* # Q  " "" "Gd"sB @-on:Xr':V}?c}#[FFFRRREEE<<< }3 ...IIIaaaeee777 ...MMMkkkJJJ~= 000YYY~~~|||qqqgggMMM---KKKjjjwwwzzz9995:c777NOOooo~~~UUUQQQ^^^RRR___}}}mmmjjj%%%5QGGFrrqWWW"""6 abJJJooo ,,,444HHHiii6 QB| 111RQR~~}~~~onn<<<'''$$$ LLL6#<XDJX6***qqqg3HX>>>???}}}uuu555:::rrr~~~---X3 KKKqqqppp||||||xxx}}}wwwXXXCCC%%% ###<<>>HHHAAANNNQQQVVV444 ...]]]~~~;;; ...___{{{nnn \[[<MMMxxx---444UTUDDDRRR}}}...|GFFFqqqvvv{zzqpqpnnljknnn]]]Nx FFFiiixxxooouuu~~~xwx}||uuuVVV...---???OOOGGG(((FzAAAcccsssZZZuuu===lz///@@@}~||}zzz|}})))eO ...QQQ---EEEyyyyyykkkYXYtttxyy{{{xxypppgggcbccbaabacccghikkkllmpqqxwxyyzpqqooommmYYY3GAAAzzzpppnmnmmmoooxyytutsrsuuuwwwwwwzzzeee$$$ `G)))ooozzz~~rqrsts~~~|wutqqpstr{zzaaaYYYJJJ888)))     ,,,SSSsssz{{sts}}}yyyyyy~vuuoonihhijjmmnijjklmttt^^^UUULLLJJJQQQRRRQQQlllvvviiiUUU $$$^^^sssxxxjjjkkkwww{{{uuuqqqrsrwxw}~}|}{}||~~}yyxuvurqqnon||| ^vvvuuuwww~~~}}}www||}xxxxxxz{y<<< ^ IIIxxxrqq~}}wvvsrs~~zz{yyz}}}ddd:::^000xxxxxw|||{{{kkkPPPYYYdddHHH)))+++%%%=^'''}}}ttt```EEE,,,!!! K^ ~}}~~}(((=Nkkk <---WWW6888}|~zz{tttrrr\\\???RXXX|||}}}&&&keggg~~~uuukkk!!! ;;;xxxKKKTTUUHHH Q???qqq===+]766jijrts x 000xxxxwwwuuutu+++\f666zzz