*E< ,Qr>'p{gZR a q               *7 ,< NoneEngineCoreSystemTriggerLogEventString GetTimeStamp InternalTimeColorClientMessage InventoryTexture GameInfo TakeDamageWeapon PlayerPawn ZoneInfoPalettePawnVBitsVClampVSizeUClampUBits BeginStateUSizeDisplayMipZeroTimer MaxColorbMasked AdvancedMover MovementPostBeginPlay PlayerMoveFireTouchCollisionRadiusTick ProcessMoveCollisionHeightAltFireStatLogEventPickup LevelInfo PrunedPaths MuzzleFlashupstreamPathsDiedOpenPathsConsoleCommand ParseOption RemoteRoleAnimEnd IsRelevantSurfacebCollideActorsBumpbHidden LightingPlayerWalking SoundVolume LogPickupChangedWeapon EndEventBroadcastMessageCloseClientUpdatePositionbStatic BeginEventMenu PreBeginPlay PlayerTickReplicateMove EndStatePlayTeleportEffectReceiveLocalizedMessage ProjectilePutDown Teleporter ZoneLightBegin Decoration ChangeTeamGameReplicationInfoLanded HandleDoorFindInventoryTypeDyingFindTriggerActorBroadcastLocalizedMessageMessageInterpolationPoint SetPause PlayWaitingHandlePickupQuery KilledBy BeginPlay WeaponAI Destroyed TeamMessageRenderOverlaysFilterDoOpenDoClose bDirectionalStopLog DrawTypeSayTypingUpdateRotation SpecialEventDropDecoration LogGameEndTweenToFighter UnTrigger ServerMove MusicEvent Activate ZoneChangeSpecialHandlingWaitingFinishedOpeningBrush SelectNextReverb Collision PlayDuck DownWeapon BecomePickup WeaponChangeSwitchToBestWeapon KeyEvent TestInfoFinishedClosing LogSuicide ClientTravel NetPriority LevelSummary AddInventoryFAISoundClientVoiceMessage HidePlayerTauntDrownedUserMenuing PlayGutHitNavigationPointTweenToWaitingCarcassCalcBehindView ReduceDamageSubTestOptionalOutAllowsBroadcast WarpZoneInfo bBlockActors PostRender BecomeItem SpawnCopyGesture PatrolPointbBlockPlayersCounter DamageTypeSounds PlayerStartSuicide PlaySwimmingSetHand ChangeNameTeamSayActivateTranslatorSetDisplayProperties ViewFlashLogTypingEventGibbedSetDefaultDisplayPropertiesClientReStartArmorPriorityBringUp LifeSpanPlayModifySoundTakeHitbCollideWorld WarnTargetAllPlayBeepSound PlayRunningMutatedDefaultWeaponHitWallAmmodroppedIdle2ShouldRespawnClientReplicateSkinsMessagingSpectator PreRenderEffectsRecommendWeaponSetSwitchPriorityUnTouch PlayFiringDodge SetRespawn LiftCenterAttach CheatFlying PlayInAir SpectatorbAlwaysRelevantTweenToRunning MoverSoundsKilledBecomeViewTarget ShakeView ScoreKillHandleTriggerDoor SleepingbNetTemporaryClientPutDown TriggerLight GetItemName KillMessage ServerTravelTriggerToggleTriggerControl TriggerPoundPlayerSwimmingSpawnGibbedCarcassBumpOpenTimedFinish StartLogKeyType FindGoodViewDriversdamageAttitudeTo FlushLogSendVoiceMessageEndZoomGetLogFileNameLogPlayerConnectVector GameEnded WeaponSetSwitchPriorityTakeFallingDamageTravelPostAcceptAddAmmoCrushed AdjustAim bProjTarget PlayChattingPlayerCalcViewCompressAccelSetOwnerDisplayClientSetMusic ViewShakeIdleConsole SightRadius ActorEntered DeathMessage NextItem TestStaticTestEncroachingOnGiveTo PlayLandedPhysics ViewClass FireWeaponNetUpdateFrequencyMutatebStasis PlayDyingAudio SwitchWeaponAdjustHitLocationGetServerPort SetGameSpeed bNoDelete AnimationInitPlayerReplicationInfo LiftExitFellSetWeaponStayProjectileFire GiveAmmo Fragment Generate OwnerJumped RateSelf StopTimeDemoBotDesireability Activated Dispatcher CalcVelocity BaseChange SettingsStartTimeDemo locationid RoundRobin AmbushpointAcceptForceGenerateFallingMaxDesireability ProcessTouchPickupMessageUseAmmoPickupFunctionHUD TraceFireCheckTouchList PlayIdleAnimInterpolateEndScaleMenuProcessInput ExitMenu DropFrom SuicidedProcessMenuKeyLandingProcessMenuUpdatePrintActionMessageUpdateEyeHeightRotatorSelectPlayerTimeoutPrioritizeArmor ValidTouchstompedCheckVisibilityFeigningDeathLogPlayerInfo StopWaiting PlayRecoilPlayEnterSoundRestartPlayerPlaySelectSound AddVelocityClientSetLocation DrawScale TossWeaponDeleteInventoryTweenToSwimmingLogKill LogTeamKill JumpOffPawn SetMultiSkinCheckIPPolicy GetIntOptionLogMapParametersLogTeamChangeLogItemActivateDeadChunkUpInitforLogNameChange PlayWalkingLogServerInfoLogStandardInfoLogItemDeactivate BumpButton bHiddenEdTestNullContext NetworkingMakeGroupStop FinishNotifybGameRelevant PlayTurning SoundRadiusTestStructBoolsTransientSoundVolume LightColorLightBrightnessbFixedRotationDirMassMutatorTakeDamage StartWalkQuality AlwaysKeep AddMutatorMyDefaultWeaponServerNeverSwitchOnPickup ModifyPlayerChangeCrosshair ChangeHudPlayHeadDeath PlayGutDeath PlayHeadHitOrders StopFiring GetHumanNameServerReStartPlayer CallForHelp LensFlare LinkToSkybox ThrowWeaponClientPlaySoundHandleWalking AdminLogout AdminLogin bMovablebCollideWhenPlacingCombat CanSpectate TraceShot PlayTakeHitServerSetHandednessViewPlayerNumClientWeaponEventCdTrackFindPlayerStartAddDefaultInventoryLogPlayerDisconnectSetMovementPhysicsCheckWaterJump PlayCrawlingMakeGroupReturn ShowMenuFly GetKeyValue SpawnCarcassLogGameParametersPlayHit GrabOption ForceAddBot RespawnTime PickupQuery DrawText StartPlayerBroadcastRegularDeathMessageProcessServerTravel HomeBaseGetNetworkNumberInitGameReplicationInfoParseKillMessage InitLogging DrawTilePlayerKillMessageDiscardInventorybTravelbRotatingPickupPlayerJumpZScalingPlaySpawnEffectGetAddressURLEndGameCreatureKillMessage bNetOptional SendPlayer DelayedWarp RestartGame DispatchGainResetDelayNormalTrigger SetEndCamsDisplayMessagesProcessMenuEscape AtCapacityCheckReplacement DrawColor GetStringClientReceiveTestQLocalizedMessage RecurseTest OtherStatic BlockAll InputNumber ExitAllMenusTestOptionalOut PlayerSpeech TestSwitchClientInitialize MenuTick MaxCarcassesArmorAbsorbDamage LogPings bEnabled AnimSequence ProcessLeftProcessSelectionAddFliesAndRatsCheckZoneCarcasses ProcessYesArmorImpactEffectCheckTouching ProcessNo ProcessRightEvents ClientFire SaveConfigs TextSizeLogoutIK_1 ForceFireIK_F20IK_F21IK_F18 ForceAltFireIK_F19GetShortAbsoluteTimeGetAbsoluteTimeClientAltFirePlayAltFiringProcessTraceHitIK_F22Team GameNameIK_F24 DetachDecal AttachDecalStandOpenTimed IK_Unknown89 IK_Unknown88BotVoiceMessage* DecapitatedObjectHandleHelpMessageFromTriggerOpenTimedClientSetRotation ClientDying VisibilityTimeDemoRenderUnknown explodedAdjustDesireFor TimeDemoCalcshot gibbedBy UnderLiftIK_F15 ActorLeavingIK_F16IK_F14 PlayBigDeathTweenToWalkingPlayLeftDeathPlayRightDeathIK_F13 EncroachedByFootZoneChange PlayLeftHitIK_F12 PlayRightHitIK_F11TweenToFallingHeadZoneChangeStylePreClientTravelIK_F10PlayWeaponSwitchIK_F9 AmbientGlowGaspGrabDecorationIK_F8DrawSingleViewDrawConsoleViewRepReceiveLocalizedMessageRepClientVoiceMessageRepTeamMessageRepClientMessageGlobal PlayDeathHitIK_F6FellOutOfWorldIK_F7IK_F4tempIK_F5RiseType InitialStateIK_F3ExplodeAttitudeToPlayerClearMessagesIK_F2 IK_GreyMinusScriptedTextureIK_NumPadPeriod IK_SeparatorClientAdjustPositionActorGetBeaconText PlaySelect TweenDownServerReStartGame IK_GreyPlus SetFOVAngle IK_GreyStar ClientShakeTravelPreAccept LongFall IK_NumPad9ServerChangeSkinRaiseUp IK_NumPad7 PreTeleport IK_NumPad8SwimAnimUpdateActiveJump ServerTaunt AltFiringGrab IK_NumPad6 RestartLevel IK_NumPad2SetDesiredFOV IK_NumPad3 LightTypePossess IK_NumPad4 IK_NumPad5 IK_NumPad0Info IK_NumPad1 IK_Unknown5F PrevItem StatLogFileDoJump IK_Unknown5EChangeAlwaysMouseLookChangeSnapViewChangeStairLook IK_Unknown5DSetNameChangeDodgeClickTime IK_OEMClearIK_PA1 IK_NoNameIK_ZoomIK_Play IK_ErEof IK_ExSel IK_CrSelLightSaturation LightRadiusIK_Attn IK_UnknownF5 IK_Unknown5CUK_Unknown10FIK_Unknown10E PlayRisingPlayFeignDeathIK_MouseWheelDown PlayDodgeIK_MouseWheelUp IK_UnknownF4IK_JoyVServerUpdateWeapons IK_UnknownEAServerSetWeaponPriority IK_MouseW IK_MouseZ IK_MouseY IK_MouseXIK_JoyRIK_JoyZIK_JoyYUpdateWeaponPrioritiesIK_JoyX IK_UnknownDF RotationRateIK_SingleQuote ShowPathServerSetSloMoUpdateSensitivity UpdateBob BehindView IK_UnknownDAWalkIK_LeftBracket IK_UnknownD9 IK_UnknownD8 IK_Joy16ServerAddBots ShowLoadMenu IK_Joy15 ShowScores IK_Joy13 IK_Joy12 ViewPlayerChangeSetHandIK_Joy9IK_Joy8 IK_Joy10IK_Joy6ChangeAutoAim IST_None IST_Press IST_Hold IST_Release IST_AxisIK_Joy3IK_None IK_LeftMouseIK_RightMouse IK_CancelIK_MiddleMouse IK_Unknown05 IK_Unknown06 IK_Unknown07 IK_BackspaceIK_Tab IK_Unknown0A IK_Unknown0B IK_Unknown0C IK_Enter IK_Unknown0E IK_Unknown0F IK_ShiftIK_CtrlIK_Alt IK_Pause IK_CapsLock IK_Unknown15 IK_Unknown16 IK_Unknown17 IK_Unknown18 IK_Unknown19 IK_Unknown1A IK_Escape IK_Unknown1C IK_Unknown1D IK_Unknown1E IK_Unknown1F IK_Space IK_PageUp IK_PageDownIK_EndIK_HomeIK_LeftIK_Up IK_RightIK_Down IK_Select IK_Print IK_Execute IK_PrintScrn IK_Insert IK_DeleteIK_HelpIK_0ProcessMenuInputIK_2IK_3IK_4IK_5IK_6IK_7IK_8IK_9 IK_Unknown3A IK_Unknown3B IK_Unknown3C IK_Unknown3D IK_Unknown3E IK_Unknown3F IK_Unknown40IK_AIK_BIK_CIK_DIK_EIK_FIK_GIK_HIK_IIK_JIK_KIK_LIK_MIK_NIK_OIK_PIK_QIK_RIK_SIK_TIK_UIK_VIK_WIK_XIK_YIK_Z IK_Unknown5B IK_UnknownEBIK_JoyU IK_BackslashIK_RightBracket IK_Joy14 IK_Joy11IK_Joy5IK_Joy7IK_Joy2IK_Joy4 StartZoom StopZoom NormalFire IK_Unknown99 FeignDeathServerFeignDeath IK_Unknown9A IK_Unknown9BPlayPostSelect IK_GreySlashIK_F1 CheckBob IK_Unknown9D IK_Unknown9E IK_UnknownC7 IK_UnknownC6 SaveTimeDemo AddString IK_Unknown9FDrawLevelAction IK_LShift IK_UnknownC4 IK_UnknownC3 IK_UnknownC5 IK_UnknownC1 IK_TildeIK_F17PreSetMovement IK_RShiftPrintTimeDemoResult IK_LControlClientGameEndedIK_F23 AccelRate IK_UnknownA4 IK_RControl IK_Unknown8A IK_Unknown8B IK_Unknown8C IK_Unknown8D IK_Unknown8E IK_Unknown8F IK_NumLockIK_ScrollLock IK_Unknown92 IK_Unknown93 IK_Unknown94 IK_Unknown95 IK_Unknown96 IK_Unknown97 IK_Unknown98 IK_UnknownAB IK_UnknownAC IK_Comma IK_Unknown9C IK_MinusIK_Joy1 IK_UnknownAD IK_UnknownC2 IK_UnknownAE IK_UnknownB9 IK_Period IK_Slash IK_UnknownA5 IK_UnknownA6 IK_UnknownA7 IK_UnknownA8 IK_UnknownA9 IK_UnknownAA IK_Equals IK_UnknownB2 IK_UnknownB8 IK_Semicolon IK_UnknownAF IK_UnknownB0 IK_UnknownB1 IK_UnknownB3 IK_UnknownB4 IK_UnknownB5 IK_UnknownB6 IK_UnknownB7 ROLE_None DT_SpritebSinglePlayerOddsOfAppearingLT_None MTRAN_FadeClientHearSound bDifficulty0AlterDestinationDemoPlaySound DT_Terraform STY_None SpecialCostSTY_ModulatedbOnlyOwnerSee SLOT_Misc SLOT_NoneSetInitialStateLE_None ButtonMarker LE_FireWaverTRAVEL_AbsoluteTRAVEL_RelativeTRAVEL_Partial TriggersTriggerMarkerLT_TexturePaletteLoop PHYS_FlyingPHYS_RotatingLT_TexturePaletteOncePHYS_ProjectileInventorySpotScout PathNode LE_Shock PHYS_Rolling LE_SlowWaveDesiredRotation BuoyancyPHYS_Interpolating DODGE_Done DODGE_Active DODGE_BackDODGE_Forward DODGE_Right DODGE_Left DODGE_NonebJustTeleported LightConebBouncebRotateToDesiredPHYS_MovingBrush SkyZoneInfoLightVolumeBrightness PlayerInputMutator IK_JoyPovUpIK_JoyPovDownIK_JoyPovLeftIK_JoyPovRight LightPeriod PHYS_SpiderLE_NonIncidence PHYS_Trailer LightEffect LE_Unused LE_Rotor LE_CylinderLE_Interference LE_ShellLE_OmniBumpMapWarpZoneMarker LE_Spotlight SavedMoveLE_WarpSleep LE_Disco SetCollisionLE_StaticSpot LE_CloudCastPlayerReplicationInfoSetCollisionSize LE_FastWave InternetInfoMoveLE_WateryShimmer SetLocationLE_Searchlight SetRotationLE_TorchWaver MoveSmoothAutonomousPhysicsPHYS_SwimmingSetBase PHYS_Falling SetOwnerReplicationInfo PlayAnim KeypointDecalLT_SubtlePulse LoopAnim SpawnNotify TweenAnim IsAnimating GetAnimGroup FinishAnimHasAnimFinishInterpolation SetPhysicsLT_BackdropLight LT_Blink PHYS_Walking LT_Strobe LT_Flicker UnPossess Viewport Brightness LT_PulseTrace PHYS_None LT_SteadyAcceptInventoryExtent FastTraceCanvas PostTeleportLogin InitGame BlockPlayerDestroy SetTimerbReplicateInstigatorMTRAN_SlowFade PlaySoundMTRAN_FastFade MTRAN_SegueNoneMTRAN_InstantPlayOwnedSoundGetSoundDuration MakeNoise MTRAN_NonePlayerCanSeeMebIsPawnSLOT_Interface GetMapName SLOT_Talk SLOT_Pain SLOT_Ambient GetNextSkinSLOT_InteractBlockMonstersBitmapDemoRecSpectator GetURLMap GetNextInt bHighDetailGetNextIntDescPlayer AllActors bIsItemGoal DetailChange ChildActors BasedActorsTouchingActors TraceActors SoundPitch bIsKillGoal bCanTeleport UseSound RadiusActorsCacheSizeMegsVisibleActorsVisibleCollidingActors PreLoginROLE_DumbProxy LocalMessageConnectFailure VideoChangeNotifyLevelChangeShowUpgradeMenu bIsMoverErrorMapListTitleRenderTexture HurtRadius WalkTexture ScaledSprite ScoreBoardRole ScaleGlowSpawn GameEndingAuto PostLogin SpotlightTestObjFatnessROLE_SimulatedProxy HearNoiseSTY_TranslucentReplaceTextureEnemyNotVisible STY_Masked SeePlayerExpired bIsPlayerDrawColoredTextMayFall SpeechTimer STY_Normal VoicePack PainTimer WayBeacon ZoneTriggerLogGameSpecialLODSet PostTouchDT_SpriteAnimOnce bCanJump LODSET_SkinDT_VerticalSpriteDT_RopeSprite LODSET_WorldDT_Mesh DT_Brush LODSET_NoneUpdatebUnlitEndedRotationDT_None KillCredit bNetSpecialDetach bNoSmooth LostChild GainedChildTEXF_P8bNet bViewTarget Localize TEXF_RGB32 bDifficulty3AvgPhysicsTimeSpawnedMipMultCamera bDifficulty2 bDifficulty1 Friction+ DesiredSpeedMaxDesiredSpeedUpdateTactics GroundSpeed WaterSpeed AirSpeedROLE_AutonomousProxyJumpZMaxStepHeight AirControlROLE_AuthoritybEdShouldSnapSpawnNotificationLogGameSpecial2 Location AmbientSound SpecularHearingThresholdDiffuse-ZName PointRegion TEXF_RGB64 TEXF_DXT1 AnimFrame TEXF_RGB24LODBiasAdmin Mortared OrthoZoom FovAngleCriticalEvent DeActivated Corroded Eradicated DrawRectHealthLocationStrings DrawIcon DrawPatternSetClip SetOriginDrawTextClippedDrawTileClippedATTITUDE_FearATTITUDE_HateATTITUDE_FrenzyATTITUDE_ThreatenATTITUDE_IgnoreATTITUDE_FriendlyATTITUDE_FollowSetPos DrawPortal BRAINS_NONEBRAINS_REPTILEBRAINS_MAMMAL BRAINS_HUMAN IntelligenceBreatheDuckingZoneTerminalVelocityBigFont noise1timeZoneGroundFrictionZoneFluidFrictionMedFont noise2time SmallFontClear TimeDemo MenuTyping EndMenuing KeyMenuingOpenLog CloseLog SetMsgTick SetMsgPlayer GetMsgTick SetMsgText GetMsgText GetMsgTypeViewUp TeamTalk ViewDown IK_UnknownF2 IK_UnknownF1 IK_UnknownF3 FramesText SecondsText CombatStyle IK_UnknownF0TalkMaxTextSoundDampeningDamageScalingfpsText SetMsgTypeAvgTextPlayerReStartState MenuName NameArticle GetMsgPlayer LastSecTextPrecachingMessagePausedMessagePlayerReplicationInfoClassConnectingMessageMoveTo Watermark GetChecksum MoveToward FileFlush StrafeToFileLog StrafeFacingTurnTo TurnTowardLineOfSightToCanSee FindPathToGetBeaconAddressLoadingMessageAltNameFindPathTowardTriggerTurnsOffFindRandomDest ClearPaths EAdjustJumppointReachableactorReachablePickWallAdjustFindStairRotationWaitForLandingFindBestInventoryPathLogSpecialEventGetMapFileNameAddPawn RemovePawn PickTargetExecuteWorldLogBatcherSuggestDefenseStyleBrowseRelativeLocalURLExecuteLocalLogBatcherPickAnyTargetExecuteSilentLogBatcher NameColorMessageNoAmmo LocalLogDirAltRefireRate WorldLogDir SpecialFireCheckFutureSight AIRatingTeamBroadcast RefireRateSendGlobalMessageWorldStandardMaxTargetRange LogVersionInventoryCapsStringSendTeamMessageUseM_Deactivated M_Selected M_ActivatedIcon ShortNameThirdPersonScale FearThisSpot ServerName GetRatingPickupViewScale BobDampingPlayerViewScalePlayerViewOffset ItemArticle PlayerPathPlayAmbientSoundEffectAutoSwitchPriorityPlaySoundEffectKillInstigatorPlayersPlaySoundEffectScreenFlashScaleOtherTriggerTurnsOff NumToCountOtherTriggerTurnsOnOtherTriggerToggles FovModifierbInitiallyActive TT_ShootTT_AnyProximityTT_ClassProximityTT_PawnProximityTT_PlayerProximity RateModifierPlayReceivedMessageGameSpeedModifier WhiteColorHUDConfigWindowTypeMultiDecalLevel DrawMenuSetFontBrightness NoString YesStringEnabledString CenterStringDisabledString GetMultiSkinSetSkinElement SetKeyframe bDecorative bCoopStartbSinglePlayerStartDDAACCAAPlayMovingAttackPlayWaitingAmbushEEDDAABBTestContinueDoUntilTweenToPatrolStopTestContinueForEachPlayThreateningPlayPatrolStopTestContinueWhilesxxpppbTrue1ShowMiniScoresbTrue2 BT_AnyBump GetNextMapMaps GetOffset GetFontSizeBT_PlayerBump BT_PawnBumpMoverGlideType LifetimeME_CrushWhenEncroachME_IgnoreWhenEncroachCSG_DeintersectCSG_Intersect ScoreEvent bChaseCamAddBotPlayerWaitingPlayerSpectatingPlayVictoryDancePlayOutOfWater PlayDive InvalidState MutatorClass MaxPlayers IPBanned IPPoliciesWrongPasswordMaxedOutMessage NeedPasswordNameChangedMessageFailedTeamMessageEnteredMessagePlayTakeHitSoundDeathMessageClassFailedSpawnMessage LeftMessageFailedPlaceMessageGameOptionsMenuTypeMultiplayerUMenuTypeGameUMenuTypeSettingsMenuTypeRulesMenuType BotMenuType shaketime SetViewFlash GameSpeed bPauseablebRestartLevel AttitudeTo aimerrorNM_ListenServerNM_DedicatedServer AdjustToss NM_ClientLEVACT_PrecachingLEVACT_ConnectingLEVACT_SavingLEVACT_LoadingSummonDefaultTexture TimeDilation KillPawnsWarpUnWarp ZoneActorsMaxLightingPolyCount SetJumpZMaxLightCountMinLightCountMinLightingPolyCount CutoffHz MasterGainSloMo TexVPanSpeed TexUPanSpeedSetSensitivitySetBobGodAllAmmo InvisibleDownSpecialDamageBurnedShowInventoryGhostORDERStrLenFighter DrawActorDrawClippedActor AmphibiousDodgeClickTimeBobSetProgressTimeConBackground TimeDemoFontFrameRateTextMinTextSavingMessageSetProgressColorAddBots FlashScaleBorderFlyingTriggerTurnsOn bFirstHit SwitchLevelSwitchCoopLevelUsedUp TweenSelect UseCharge TweenToStillGetPlayerChecksum DesiredFOV DefaultFOVNeverSwitchOnPickup GetGMTRef InitialCheck Transition LogMutator shakemag shakevert InvertMouse SplashJump BatchLocal MyAutoAim HandednessSuggestAttackStyle FlashLengthProjectileSpeedAltProjectileSpeedbAlwaysMouseLookWorldStatsURLWorldBatcherParamsWorldBatcherURLLocalStatsURL bCanThrowLocalBatcherURLDecoderRingURLGameCreatorURL GameCreator LogInfoURL SetAutoAimbToggleSteadyFlashInventoryGroupDamageInstigatorDisplayMessagebStopCountDownCompleteMessage CountMessageSetDodgeClickTime SnapViewDrawCrossHair CopyMessage RightString LeftString ActivateItem AllowChunkbMaxMouseSmoothing GetWeaponInterpolateTo bNoFlashCreateReplacement bMessageBeepDrop FollowHolder skinnedFragActivateInventoryItemSetMaxMouseSmoothing MaxDist2DPauseSetMouseSmoothThreshold describeSpecKickTestContinueForAAMouseSensitivityKickBan TestLimitorTestX QuickLoadSTestMouseSmoothThreshold QuickSave MoveTime GetColorAssembleStringxnum NextWeaponMV_MoveByTimeMoverEncroachType ReplaceWithME_ReturnWhenEncroach TempScale PostScale PrevWeaponRegisterDamageMutator CSG_SubtractCSG_Add ResetGame PlayerFlying HasOption bLocalLogServerLogName bWorldLogbCanViewOthersAutoAimMaxTimeMarginMaxSpectatorsSpeech CauseEventQuickSaveStringNoPauseMessage ViewingFrom OwnCamera FailedViewNM_Standalone bNoCheatingbHighDetailModeKillAll SetSpeedShowSpecialMenubMoveProjectiles SinglePlayerAmbientSaturation FormatFloat ZoneGravityResetKeyboard UpdateURL LogGameStartSetProgressMessageClientAdjustGlowGetDefaultURL ViewSelfGetEntryLevelGetPlayerNetworkAddressCopyToClipboardPasteFromClipboardPing MuzzleScale CheatViewInventoryCapsFloatLocalStandardDrawStatusIconAt PlayersOnly bFirstFrameClientChangeTeam ItemNameDropInventory StairLookProfilebAffectAllPlayers bAmbientGlow ClearMessageHUDLocalizedMessage MenuInitSShot PlayerListAlwaysMouseLook ActorClass HelpMessageClientReliablePlaySound FunctionKey SelectionClientInstantFlash StayOpenTimeRenderComplexMessageMV_GlideByTimeNumKeys ClientFlashME_StopWhenEncroach MainScale CSG_Active GetRulesGetInfo PlayerWakingDefaultPlayerStateDefaultPlayerName StatLogClass Difficulty GetLocalURLbCanChangeSkin GetFreeMoveClearProgressMessages RandSpin MaxSpeedCalcDrawOffsetFragbEndPointOnly ExtraCostMoveAutonomous bChangesYaw ActivateHint ToggleZoom LocalTravelFOV LEVACT_None RememberSpot SetFriction SpeedOfSound LargeFontSwitchLevelMessage realbDuck bRealJump realbRunMapName CurrentMoveOldLocDirNewLocYPrefixCarriedNewVelZNewLocZAdjPColNewVelY maxPitchViewYawNewVelXNone newAccelnewFOVNewLocX OldTimeDeltabForceAltFirebFired TotalTimeNone OldDodgeMove SoundPlayer OldbDuck NewbDuckOldbRun CurrentSkin OldBobTimeNewbPressedJumpOldBase NameEndingOutTeleporter bSaveDefaultNewMove NewOptionSpawnRotationOldMoveTargetWeaponViewOffset LastMove aMenuClass NetMoveDelta SpawnOwner ViewPitchTargetViewRotationTargetEyeHeightngWorldSecret BuildAccel DeltaRotLocDiffProgressTimeOutAccel OldAccel OldTimeStamp clientErr AccelNorm InTeleporterCurrentTimeStamp LoudnessRadius DeltaTimeViewOther newPhysicsMinRate ClientRoll TweenTime DodgeMove SavedMoves realWeapon bAltFiredaExtra3 bForceFireaLookUpfogNewbJumpStatusaMouseY bNoOverrideASound SmoothMouseYBorrowedMouseXIP Sequence bInterruptbVolumeControl ZoomLevel bUpdating ClientLoc bFixedCamera NewOwnerNewbRunNewBase DeltaSecondsInAccel bJustFired bIsTyping bNoVoices TimeStamp SkinName SkinDescDelta BaseClassNumNewBlockPlayersResultEntry CommandLinebDelayedCommandOption bShowMenubWokeUpSpeed2D bShowScores MatchTagSkin4OldTeamSkin3Skin2 bIsTurning EventTypeSkin1bClientDemoNetFuncHitLocHitNormaClassNewSongVolumeshake InstantFogSlot bIsCrouching bShakeDir NewSectionbLookUpStairsConstantGlowFog bNetFeel NewCdTrackbNetSee NewValue ScoringTypebItemsNewTransition TravelType ViewTargetMisc2 bNetOwnerLandBobbLoopLastPlaySoundURLDodgeClickTimerusealt NewTimerRatehandMultiply_FloatColorSpawnLocationdepth newHeadZone StepLocation DemoViewYawMsgAdd_ColorColorDemoViewPitch MeshName SpawnTag RelatedPRI_2PKiller PhysAlphanode ngSecretSet SmoothTime FOVScale MouseScale AbsSmoothX AbsSmoothY MouseTime SpawnClassbound bTraceActors EDodgeDir WeaponNameN actualDamage TraceStartshooterbActorShadows VolumeFogAimSpot BestTargetClientUpdateTime bLeadTargetProgressMessage damageScale projSpeedProgressColorPTarget TraceEnd MomentumIndex goalscale FullNameRollMag NewWeaponLastUpdateTime TimeMargin bUpAndOutServerTimeStamp Callsign HitLocationDamage bSaveJumpbTypingTransientSoundRadius MultiSkins FreeMoves PendingMovebForcePhysicsUpdate bCarriedItemNewZone HitNormalEventInstigatorbNeverSwitchOnPickupaExtra0bHitSlopedWallspot DesiredDist WallOutDist bAlwaysTick cameraLoc cameraRottriesbesttrynewdist startYaw S_CameraadjZmaxZ PlaybackGRI bOwnerNoSee bShadowCastVisibilityHeightVisibilityRadius ECsgOperaExtra1aExtra2 prevGroupaExtra4 TraceDirrealHitUnusedLightMesh PostPivot bFoundWeaponPrevaUp BrushColor PolyFlags bColoredEMoverEncroachTypeaStrafeaTurn aForward StartTrace nextGroupEMoverGlideTypeRateaBaseZ bCanStrafebUpdatingDisplayaMouseX bFixedStart MutateStringaBaseYbCanDoSpecialbCanFlyaBaseXBorrowedMouseY bDrowningMouseZeroTime SpecialMenu SmoothMouseXEncroachDamagebTriggerOnceOnlybSlavebUseTriggeredbDamageTriggeredDelayedCommandWeaponPriority bFromWallaPawnbAutoActivatebPausebStopAtLedges Follower ReturnGroup DelayTime bMeshCurvy OpeningSound OpenedSound ClosingSoundbCheatsEnabledbNeverAutoSwitchKeyPos bJumpStatusBasePosOldPos OldPrePivot SavedPosInvItemOldRot SavedRot bIsFemale bIsHumanTriggerActor2bJustAltFired bOpening bDelaying bClientPause bPlayerOnlyRecommendedTrigger SimOldPosSimOldRotPitch SimOldRotYawSimOldRotRollSimInterpolate RealPosition RealRotation ClientUpdatebMeshEnviroMap bRandomFrame NewRotation bReadyToPlaybTwo bZoomingDP2Dist1 bMouseZeroed NewLocation NewKeyNumDefaultSkinNamebIsMultiSkinnedNewWeaponClassbRisingSprite ERenderStyle bCenterView bTempEditor bReducedVis LastItem NewHeight bMemorized bSelected Acceleration Velocity ColLocation NewRadius ParametersNewBlockActors SurfList OldLocationIdSoundLocationbUpdatePositionL S_Keypoint bPressedJump NewColActors S_Interp bSpecialMenuM OtherPawn PainTime SightCounterbSkipNextPath HeadRegionItemSeconds bInvertMouse SpecialTag GameClass bTeamGamebBadConnectionAlertbFrozenRenderInterfaceCommandRenderIteratorClass SecondCount NumPlayers EInputKey UpdateTimerbAnimTransition MinHitWall NewVelocity AdminEmail MOTDLine1 MOTDLine2 EInputAction MOTDLine4 ETravelType PRIArrayFragAcc PlayerNameOldNameEnemy LastSeenTimebClientDemoRecordingTeamIDScorefirstHasFlag PacketLossbIsABotbFeigningDeath bIsSpectatorbWaitingPlayerbFoundEndPlayerLocation StartTimeTimeAccMinDistContextbWorld bEdgeRight MessageTypeWait bEdgeLeft bEdgeBack bEdgeForward bWasRight bWasLeft bWasBack bWasForwardbKeyboardLook bSnapToLevel CarcassTypePRI shaketimerbAdmin RecipientNext CollisionTag JumpSound InstantFlashWalkBobbSimulatedPawn verttimer maxshake SongSectionGameSongbDemoRecordingbQuietDesiredFlashFogDeleted AbsoluteTimeGMTRef Touching LatentActor LatentFloat LatentInt LatentByteNetworkNumber SpecialIDConstantGlowScaleSpecialParam2DesiredFlashScale bNetHearbestAim AttachTagRegionBase KillerIDHUDTypeKillerWeaponNameVictimWeaponName InstigatorTargetScoringInstigatorStringmyHUD FlashFog bNetRelevantZoneRendMap AnimRate MinWeightbPredictRespawnsArg2Arg3Arg4 TimerCounterMisc1 TimerRateReasonbExtra3 AppliedBob ShowFlagsbobtime bNetInitialNewDestinationspeed NewTarget NewFocus FilenameSimAnim bClearPaths HitSound2 nextPawnZoneTag OldAnimRate ZoneVelocity Passwordnoise2loudnessStart noise1otherLoc NumCarcassesbIgnoreHiddenFloorEIntelligence checkNorm SpecialPause EntrySoundrating EntryActor ExitActorSubtract_ColorColor checkpointSpree WallNormal AnimMinRate bGravityZone bPainZone bDestructive bNoInventory splashSizebBounceVelocityOwnerAmbientBrightness AmbientHuesplash FogColor FogDistanceEnvironmentMap AnimLast newFootZoneViewFog ENetRole bReverbZonebRaytraceReverb StepNormal PendingTouchMultiply_ColorFloat EPhysics bSimFall bClientAnimLensFlareOffsetLensFlareScalebBeepSeen NoiseMaker PhysRate RelatedPRI_1bTrailerPrePivot TempSkyZone OtherSideURLThisTag bNoTeleFrag iWarpZone WarpCoordsOtherSideActorOtherSideLevel DestinationsnumDestinations bAlreadyDeadVelOptionalObject nextPickbTrailerSameRotation NewClassNonesmooth TimeSecondsYearMonthDay DayOfWeekHourMinuteSecond MillisecondIdealPlayerCountRecommendedEnemiesRecommendedTeammatesLevelEnterText LocalizedPkgPauserSummary bLonePlayer bBegunPlay bPlayersOnly DodgeDir bDropDetailbAggressiveLOD bStartup bHumansOnly DamageAmount bAllowFOVPlayerDoppler ScreenshotHubStackLevel ELevelAction DamageRadius DamageName bWarnTargetcarcVictims LevelActionbNeverPrecache ENetModebCoronabInterpolating bLensFlare VolumeRadiusNetMode ComputerNameEngineVersionMinNetVersionDefaultGameTypeNavigationPointList PawnListNextURL bNextItemsNextSwitchCountdown AIProfile AvgAITimebCheckWalkSurfacesCameraLocation bForceStasis ItemGoals KillGoals SecretGoals ViewDist bNoMonstersbMuteSpectatorsCameraRotation ViewActorbCoopWeaponMode bLowGoredist bVeryLowGore bDeathMatch bGameEnded bOverTimebAlternateModevertmag LightPhasegoalFogDefaultPlayerClassDefaultWeaponposNumSpectatorsAdminPassword GamePasswordScoreBoardType GameMenuType HitActorT2T1 ELightEffect LightHue NewTexture MapListType MapPrefix BeaconNameSpecialDamageStringlookDir SentText NewStyle bEnviroMap bLightingMultlandVolS_Pawn Palette3 bJustLanded impactVel bBehindView ELightType bNotForward CurrentID bIsWalkingEMusicTransitionDMMessageClass MyAnimGroup BaseMutatorDamageMutatorWaterZoneType ESoundSlotGameReplicationInfoClass OldDodge LocalLog WorldLog OldRotationAnimGroupName bBatchLocal bLoggingGameLocalLogFileNameWorldLogFileName currentRot DemoBuild DemoHasTutsbIsSecretGoal bTimerLoopbDynamicLightNewRot ResultSet bHurtEntry NextMutator NextDescEnabledMutatorsbLightChangedbTicked bAssimilated FirstHit bDeleteMebSuperRelevant bAnimByOwner bAnimNotifyPairKeyValuePlaybackActorInKey bAnimLoopInOptLeftOptMClassbAnimFinished LocalPlayer Palette1Address FailCode InPasswordS_ActorLastMatchingPolicyPolicyMaskbAcceptAddressbAcceptPolicy FontColor ParseString CurrentValuePortal StartSpot NewPlayer TestPlayer PawnLinkInNameInSkinInFace InChecksumInTeam bWarpingTextTexExiting bMessageVL WeapClassUL incomingNameDestTelaPlayer foundStartU KillerWeapon OtherWeaponbSpecialDamageYLXL KillerName VictimName LocalTimeJunk3Junk2ViewerCsgOperJunk1injured EndTrace EventName EventActorSourceTexture NotifyActor CompFormat CompMipsweapMips bNameChange Accumulator MaxFrameRate MinFrameRate PrimeCurrent PrimeCount IncomingbOutbSound AnimCurrent AnimNext broadcasterELODSet bHasCompNextDamageMutatorbRealtimeChanged bParametric bRealtimebHighTextureQuality EBumpType aClassNamebHighColorQualitybResultbX7bX6VictimbComplexString bIsSpecial bIsUniquebIsConsoleMessage bFadeMessage bOffsetYPosbReducedSpeed ChildMessage bFromBottombX5XPosYPosbCenterdotpMessageStringbX4 bCanWalkbX3 bCanSwim HitVec2DClipYHitVec BumpTypeMapNumbCanOpenDoors CurrentMapRegFont OwnerHUDKeyNum PrevKeyNumbFalse1 bLOSflagbFalse2bBool1bBool2BrushRaytraceKeyWorldRaytraceKey OtherTimeMyArrayv1v2 TestRepStrPieStrLotusbDynamicLightMoverb1b2b3STbX2 bMirroredo TempActorbPortaltooo bAvoidLedges bResourcebHighShadowDetail bHunting bGouraud bSpecialLit SavedTriggerPlayerBumpEvent BumpEvent bJumpOffPawn bHighLedgebDirtyShadows bCloudWavy bNoMergeTC PlayerOwner LeftListbShootSpecialLeaderDamageThresholdnumTriggerEvents ClosedSoundbLowShadowDetail messageIndex bWaterWavy S_Pickup ownerTeamtaken bSmallWavy bBigWavyVisNoReachPathsvisitedWeightbestPathWeightnextNavigationPoint nextOrdered prevOrdered startPath previousPathcostMoveAmbientSound bEndPointKeyRot bSpecialCost bOneWayPathbNeverUseStrafingBaseRotiSpec ReachFlags DistanceSeekerSourceLiftTagMyLift LiftTriggerLastTriggerTime MaxZDiffAdd TriggerActor LiftOffsetdist2dmarkedWarpZone markedItem S_Player TeamNumber myMarker WaitingPawn bAutoVPan S_TeleportProductRequiredbChangesVelocity bParticles bReversesX bReversesY bReversesZTargetVelocity LastFiredoldYawmagoldDir survivecount bSnipingS_Flag S_Patrol Nextpatrol pausetime PatrolAnim PatrolSound numAnims AnimCountNextPatrolPointEffectWhenDestroyed bPushablebOnlyTriggerablebSplash bBobbing bWasCarried PushSound numLandings contents content2 content3 EndPushSoundbPushSoundPlayingbOneDP1newVel HitNormall decorMass2 tempClassDist2 FragType FragSkinDSize NumFragsToucher OldKeyNumoldZ S_CorpsebPlayerCarcassfliesratsbReducedHeight PrePivotbSlidingCarcassCumulativeDamageBugsSkin bAutoUPan bTwoSided EDrawTypebFakeBackdropbSeen bModulate bSemisolid ParentMenuTeamNum MenuLengthbConfigChangedbExitAllMenusNewSkin MenuListSkinNo FaceNamebEdSnap SkinActor bHighlighted MenuTitle bEdLocked bCountJumps bEnvironment bNotSolid bTransparent bInvisible HitSoundFootstepSound MacroTextureDetailTextureBumpMapFormat InputStringETextureFormat IDC_WAIT IDC_SIZEWEKeyNo IDC_SIZENWSEbAdvancedTacticsLastRenderedTime IDC_SIZENS IDC_SIZENESW DecalDirbBright IDC_SIZEALL ActionNumHudMode Crosshair MainMenuTypeTraceDistance Rotation MainMenu HUDMutator LocationName RelatedPRI EndOfLife bDrawing numLinesStringMessage StringFont NextLocation PositionM1M2 IDC_ARROW decorMassStartXStartYSelectedCursorCriticalString instigatedByPNamePZoneConfiguredLanSpeed S_Trigger ETriggerType SpeechTime OldWeapon FootRegionLink bEndOfPath TriggerTypeNewItemClassProximityTypeRepeatTriggerTimeReTriggerDelay TriggerTimeConfiguredInternetSpeedCurrentNetSpeed DesiredClass MoveTimer bWasActiveScreenFlashFog bKeepTiming S_Counter S_Ambient bShowMessageNonebClassicDeathMessages OriginalNumWindowsMouseY S_Dispatcher OutEvents OutDelaysWindowsMouseX bSilence bOnceOnly DestinationS_SpecialEvent bBroadcastbPlayerViewRot MoveTarget FaceTarget MeleeRangeInvFocusRemainingTime ElapsedTime S_InventoryRemainingMinute SumFrags bActivatablebDisplayableInvbActive bSleepTouch bHeldItem bTossedOut AlertnessbInstantRespawnbSuspendPrecachingbShowWindowsMouse StimulusPeripheralVisionbWindowsMouseAvailablePlayerLastTouched LastSeenPosPlayerViewMeshASpotLastSeeingPosPickupViewMesh AdminNameThirdPersonMesh MOTDLine3 StatusIconProtectionType1ProtectionType2ChargeArmorAbsorption bIsAnArmorAbsorptionPriority NextArmorvfExecbSteadyFlash3rdGameEndedCommentsvfOutbMuzzleFlashParticles bNoSpeakbSteadyToggle FlashCountOldFlashCountMuzzleFlashStyleMuzzleFlashMeshMuzzleFlashScaleMuzzleFlashTexture PickupSoundActivateSoundDeActivateSound RespawnSoundbroadcasttype TeamName PlayerID ExtraTagPickupMessageClassItemMessageClassDeathsBot AlreadyHasdesire bCheckedCurrentTickRate bUseAltModeSender DrawOffset WeaponBob PawnOwner ClientCycles GameCycles TickCyclesRenderCopy CylinderNetworkDevice AudioDeviceGameRenderDeviceAStartLocationPendingWeapon TalkTexture PlayerZone MessageIDD FirstArmorReducedAmount ArmorDamageX InsertAfterCYWPitch NewStateRollKeyNamejibHint ScriptText S_WeaponLocalBatcherParams AmmoName ReloadCountPickupAmmoCount AmmoType bPointing bInstantHitbAltInstantHittbAltWarnTarget bWeaponUpbChangeWeapon bLockedOnbSplashDamagebGlobalbRecommendSplashDamagebRecommendAltSplashDamage bWeaponStaybOwnsCrosshair bHideWeapon bMeleeWeapon bRapidFire bSpecialIcon FiringSpeed FireOffsetProjectileClassAltProjectileClass MyDamageTypeAltDamageTypeCurrent ViewRotation SelectedItem OtherTag LightingTag FireSound AltFireSound CockingSound SelectSound Misc1Sound Misc2Sound Misc3SoundNetTag EventString AdjustedAimbSetFlashTimebDrawMuzzleFlash bMuzzleFlash FlashTimeBaseEyeHeightFlashYFlashOFlashC bestDistFlashS MFTexture MuzzleFlare FlareOffset bPlayerOwner projStartSFireDir ChecksumOldAmmoVAlphaBbTempYawbSwitch bHaveAmmo Recommended oldRating oldFiringoldMode SpecialParamRG ReturnValueLenGetEnumDynamicLoadObjectSetPropertyText ProjClassbWarnGetPropertyText AccuracyTimeCoordsMusicAudioSubsystem RenderBase Description RenderDeviceRenderIteratorFontLevelMeshStandingCountModel PrimitiveNetConnection NumCopiesbCanHaveMultipleCopies bCanActivateExpireMessage MiscNumberAmountClient VictimIDS_Ammo AmmoAmountMaxAmmo ParentAmmoUsedInWeaponSlotPAmmo NetDriver AmountNeededHeight AmmoToAdd KilledIDMomentumTransfer SpawnSound ImpactSound MiscSound ExploWallOutExplosionDecal TestLocationAuthorWall ClassNameXLevel spinRate FragmentsnumFragmentTypesanActorColorsExplosionSizeArg1DamS_Light ChangeTime bInitiallyOn bDelayFullOn RemainOnTimeInitialBrightness Direction poundTimeiLeaf ZoneNumber TweenRate DamageEffect EffectSound1 EffectSound2 ConsoleBackNoneShadowNonevtblOut MaxBorder MaxLines MaxHistory TextMsgSize HistoryTop HistoryBot HistoryCur TypedStrHistory ScrollbackTopLine TextLinesMsgTime MsgTickTimeMsgTextMsgType MsgPlayerMsgTick BorderSize ConsoleLines BorderLines BorderPixels ConsolePos ConsoleDestFrameXFrameY bSinglePath bNoStuff bNoDrawWorld bTimeDemobStartTimeDemobRestartTimeDemobSaveTimeDemoToFile ExtraTimeLastFrameTimeLastSecondStartTime FrameCountLastSecondFrameCountMinFPSMaxFPS LastSecFPSaPoint EyeHeight RouteCacheOldMessageTime VoiceType VoicePitch AlarmTagcarriedDecorationSharedAlarmTaghome NextLabel NextStatebExtra0bExtra2bExtra1 bWatermarkbFire bFreeLook Language bAltFirebDuckbStrafe bSnapLevelLogAr StatLogFinal NewMsgTextbZoombLook NewMsgTypebRun WaterStep NewMsgPlayerLand HitSound1 NewMsgTickOptionsExitActionTag BigMessageClassYStartYEndLineiLinePackageConst TypingPromptShortMessages ExtraSpaceSwitch NextMoveLastPainSound PlayerMenu S_ZoneInfo noise2other bSaveToFileRotDie PropertyAvg AvgString Subsystem TextBufferATextLTextH noise2spotnoise1loudness Texture0None noise1spot Texture1None EAttitude Texture2 Palette55Skill Texture3 Palette57SpaceXSpaceYOrgXOrgYClipXCurXCurYCurYLSizeXSizeY FramePtr RenderPtr SpecialGoalCRUnderWaterTime WireFrameClearZZonePlayerEventZonePlayerCount bCheckHotKey DamagePerSecXBYBDropWhenKilledWidth CamActor CamLocation CamRotationReducedDamagePctReducedDamageType SpecialMeshSelectionMesh DamageString ZoneNameRectXRectYEnumGroup Function ExitSoundStatePlaneStructSkyZoneString StrPropertyStructPropertyArrayProperty SecretCountClassProperty NamePropertyObjectPropertyFloatProperty DieCount BoolProperty KillCount ItemCount bWaterZone bFogZone IntProperty bKillZone SplashTime ByteProperty bNeutralZoneNoneSetMeshPostNetBeginPlayAttachToSurface ReplaceTextbTwoWayWith Palette9InputReplace bAutoBuiltNoneNoneProcessKeyEventSpriteProjForward GetNGSecretRegisterHUDMutator SetNGSecretbFilterByVolume newSecretNextHUDMutator bHUDMutatorNoneMutatorTeamMessage!MutatorBroadcastLocalizedMessage PreventDeathHandleEndGameMutatorBroadcastMessage ModifyLoginHandleRestartGame LinkSkelAnimMoveCacheEntry MaxItemsRegisterMessageMutator ActorBufferGetCacheEntry ActorNode bAllowPickupGuidAnim ActorProxyNextMessageMutatorPaddingbWorldBatcherErrorFrame NewFilename ReceiverbScriptInitializedReceivedSecretChecksum NextNode ObserverMessageMutator SkelAnimNoneNoneNone ClipMarkerNone Palette59NoneNoneNone bProscribedNoneNone S_ClipMarkerNonepkg SkinItemNonebExternalBatcherNoneNonebLowResNoneNoneNoneNoneNoneCheckValidSkinPackage SkinPackNoneVisibleGroupsS_ClipMarker3LastMessageWindow Palette61 Palette65 Palette29S_ClipMarker2S_ClipMarker1 Palette63 OldScoreNoneNoneNoneNoneNone AdminActionDO_KickBanPlayerPlayerViewDelayPlayerTauntDelayMaxFOV DO_NothingDO_KickPlayer KickBanMeDO_LogDO_DisableLogin KickListKickMePlayerSpeechDelayKickIdMinFOV KickBanId ActionToTakeNextLoginTimebLoginDisabled ELoginAction ViewDelay SpeechDelay bCyclingViewbLogTypingEvents LastSpeechLoginDelaySeconds LastTauntMaxNameChangesLoginAttempts LastViewbLogAdminActions TauntDelayMaxLoginAttempts NameChangesNone ServerUTraceUTrace SetUTracing IsUTracingiMJ":::$-b ::$-b--O ::$-^-b ::$-^:i:$-^-Q-N ::$-^-Q-N ::$-^-Q-N"::$ a/! ::$::$ 7\TԝXPГX'P1111P 11111P11Г111ГPPP11111111111ԝX1111P T{#UP +=$:ePTTTP ԝXP P P ГTTTTTP P +=$:e-yrүԝXX'<G<G<G<G<G<G<G<G<G<G<G<GPPTT{#U{#U ԝXPԝXPԝXԝXԝXԝXԝXԝXԝXԝXԝXԝX{#U{#U{#UPP mQ23%ГГГPP {#UPTTTԝXԝX<GԝXԝXԝXX'X'X'ГX'X'ГX'PP P ԝXԝXԝXГԝXГГГГГГГГГГГГГГX'11PPPTTP T{#UT{#UTTTTP P PTTTTTP PTTT{#U{#UTTTX'X'X'X'X'ГX'ГX'{#UX'p$=y$?{$C|$HCJ $C$C@$AA$L=TI$@EI$?V$@GW$B]"dJ rw$ {$ V$?W$?[?]] a bdWK7hvl D=cy @{$@;}ag@lc :LP L$@w4|ORR V::$-b ::$-S :i:$ ::$::$-b -TwM* ::$-b -T-^::$-B-H ::$-W "-O-k  :i:$ ::$-W :@:$ :@:$"-O-k  :i:$ ::$:i:$-c-:i:$-O-k -v-c$:i:$-O -k :i:$ :I:$-O:@:$1:i:$-b -T-^::$::$:@:$ -M-p-b ::$:@:$ ::$:@:$ ::$::$:Q:$ ::$::$'ԝX<,ԝXԝXԝXԝXԝXԝXPTTTPP P +=$:eTTTP PTTTPP P +=$:eTTTPP z7S$?} $?Auto| kenn QF\$?{$?BB3$BYy @b@{$?&$A)$Ai$BL$?U$Bw4MNdT. ::$@`6P1  [$?t] UntitledF4]Noneybp$?Zl1rw4w4pw4PNqE rO!::$-b::$3rГԝXГԝXP TTTTTPԝXP P xP P xTTГP ԝXP TTԝXГԝXTTP ԝXԝX111111ԝXГГГГГГГГГГГГГГTTГГГP P xP P xTP P ГГГГГTTTPPԝXTTTTcҗOTГTГTГГxxPԝX+ԝXTx[Az]Snagged an item.h]af$?e$u?d$?`$?x$ ף;Tn]] activated.\= selected.[] deactivated.7n ACs\@&$A)$A;~c :L_:L0uL$33?U$ Aw4_MfQ-b ::$-b ::$-^ ::$::$::$::$::$::$ -^::$::$::$ -^:i:$ 6l +TTTԝXԝXP R~R~R~R~R~R~ԝXԝXPTTTTTX'TTTԝXPP PP P {#U{#U{#U{#UP {#U{#U{#U{#UP 1PP1111PP{#U{#UГX'11X'11ԝXԝXPTTTTTX'TTTP T{#UTTԝXԝXTTPP ԝXԝXГГX'ГPPPP P P P P{]H{]H{]H{]HP 0eГГГX'ГPPX'PP0e0ekkbPPPPPԝXPPTPԝXԝXPP1PPP P P g0NiPPPГѸBѸBГPX'ГГГГPPPP X'X'PPPPP P \R@GW^w P\R@GP\R@GPPPP PPPP ԝXTT{#UT{#UԝXPԝXTT{#UT{#UԝXPTTT{#UTP T{#UԝXPPPP {#UPPTT+T{#UP P {#UP PP P ГԝXPX'P{#UX'X'PX'P{#UX'X'PГPГГГГГГГГГГГX'ГГX'X'ѸBTX'X'X'ГPP X'X'ГГX'0e0e0e0e0e0ePГPГГPPP PTTT+T{#U+P P P P P P {#UT{#U+P P {#UT{#U+TTPTTT{#U++P P P P P P {#UT{#U+P P {#UT{#U+TTPTTT+T{#UP {#UT{#U+TTPTTT{#U+P {#UT{#U+TTPTT+T{#UT{#UTP P {#UP P P P P P {#UPP PP PP +=$:ePГX'X'X'X'ѸBX'X'X'X'ѸBX'X'ГX'ГX'X'X'X'ѸBX'X'X'ѸBX'ГX'PГX'X'X'X'ѸBX'X'X'X'ѸBX'X'ГX'ГX'X'X'X'ѸBX'X'X'ѸBX'ГX'PPPX'P +=$:eX'X'X'PPP P PTTT{#U{#UTPP P +=$:eTTTPTT+++TPP PTTTPP P +=$:eTTTP P xP P xP P xP P xP{#UX 4P TPTTT{#U{#UTTPPPԝXP{#UP +X'PԝXԝXԝXԝXP 0ec OXR~R~R~R~1<GR~PR~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~PR~R~R~R~R~R~R~X'TTTTTTR~TT{#UR~R~R~R~R~R~\R@GR~R~R~R~R~R~R~PR~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~R~TTTTTTR~TT{#UR~R~R~R~R~R~R~R~ԝX<G<G<G<GX'X'PPPP\R@GP\R@GԝXP{#U\R@G{#UX 4\R@G\R@GW^w 0e\R@G\R@GW^w 0ehEl{#U{#UP PP PP P P {#UPPPPPPPPP{#UP TT{#UPTTT{#U{#UT{#UT{#UTPTT{#UT{#UPX'0eX'{#UPP{#U{#UVz$>{$oI$ EWS@L$@@w4[ \MR-K"f ::$ {#U[ YQZ1pFzԝXpFzpFzpFz++PTDU$@w4FLTIZ-b ::$3LX'ГԝXTԝX++TTTTTѸBTTTѸBTTTTTѸBTTTԝXTTԝXTTԝXTTԝXTѸB+TԝXѸB+TԝXԝXTTTԝXTTѸBѸBԝXTTѸBГTTTTTX'TTTX'TԝXѸBTTѸBTѸBѸBѸB++X'X'++++++P ГГГГГГX'X'X'TX'X'ѸBГTГГX'X'X'ѸBѸBX'TX'ГTP P xP P xГTГTГГГГГГѸBTTX'X'ѸBX'ѸBX'X'ѸBX'ѸBX'ѸBX'ѸBTTX'P ____+++P+TPxPPxxxxxxxxxxxxxԝXTxTTTTѸBѸBѸBTV$Eg`$zDa$zDP$ DW$CJ$=X$@Q$=S$?M$?K] has no ammo.K]%o was killed by %k's %w.J*N$@_$=koz]You got a weaponV]Weaponr$Ag:wAx$?^c& c&gw4w4 #!w4G+w4 w4&!!wJpNu7 6L JU[PTTTTT+=$:eԝXxxxxxxxxP+P++PP+T{#UxxxxT{#UTT{#UTTTГГԝXԝXԝXԝXTГTTX'P +=$:eTX'TTX'TX'X'X'TX'X'TTTГГГ+=$:eTTГPГT1+=$:e+=$:eTT{#UTTT{#U+=$:eTTTX'TTTxxT{#UT{#UTX'T{#UxxxxTTTTTTTTTTX'TTX'T{#UT{#UxT{#UT{#UxT{#UT{#UxT{#UT{#UxT{#UT{#UPP+++PPTw4w4Tw4TTTTTTTTw4w4TTTTTUEx8[ h[ h[ hTTT+=$:eTTX'X'TX'X'X'X'+=$:eT{#UTTPPPT{#Uxx+PPPPPTTT+TTTT+TTT{#UT++++++++T++++++PP+=$:ePT++++{#U{#UP+{#U+TP+w4w4+w4++{#U++P+{#U+P+++{#U+++PP+{#Uw4xx++Pxxxxxx+++PPP+++++PPPPP+=$:e+=$:e+=$:eԝXԝXԝXԝXԝXPԝXPPԝXPTԝXԝXԝXԝXPԝXԝXԝX1PPxxxxxxPxxPxxxxxxxxxxxxxxxxxxxxxx+PP+{#UPP+=$:e+=$:e+=$:e+=$:ePxg0Nig0Nig0Nig0Nixxxxxxxxxxx+=$:ex+=$:exPPxxxxxx+=$:ex+=$:ex1111111111111PP+++{#U+++++{#U++{#U+{#U+{#U++{#U++{#U++{#UvNMxxlm${n?L$?o"I]UMenu.UMenuBotConfigSClientH]UMenu.UMenuGameRulesSClientG] UMenu.UMenuGameSettingsSClientF]UMenu.UMenuGameMenuE]UMenu.UMenuMultiplayerMenuD]UMenu.UMenuOptionsMenuL]Switching Levelst]PlayerB] left the game.A]Failed to spawn player actorC]HFCould not find starting spot (level might need a 'PlayerStart' actor)}] Could not find team for player|]Name changed to ~] entered the game.E]Gamez] Server is already at capacity.y]('The password you entered is incorrect.{]10You need to enter a password to join this game.w]10Your IP address has been banned on this server.v"@hu+s?j= server.logikuaW4$?a4$>X4$@c4$BY4$Cx] ACCEPT,*w4w4L w4w4 w4JELa8 ::$@`21JU[TԝXԝXԝXԝXTԝXԝXԝXԝXԝXԝXԝXCO>PA:wmx$Ay$?u$@Ed"}i$?h$?J$Efde"pNN"LLFcbd"`"G^W A0U$@w4w4W"w4w4Y w4!YOHQxx<,Z!Z!Z!Z!Z!Z!L$?nU*|K)zaOvgOKdOw4JdL[DR~JU[w4JVLi+IxJU[{#U{#UГT{#UTГT{#UГГT{#UГT{#UT{#UT{#UT{#UT{#UT{#UT{#UTTX'T{#UT{#UT{#UT{#UT{#UT{#UT{#UT{#UT{#UT{#UT{#UT{#UTTT{#UT{#U+T{#UT{#UPPPPP P g0NiP g0NiP g0NiP g0NiP g0NiP g0NiP g0NiP g0NiP PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPQ]ngLogU]ngLogW]1.2l]#"http://www.netgamesusa.com/ngLog/E]Unrealk]Epic MegaGames, Inc.j]http://www.epicgames.com/i]:9http://unreal.epicgames.com/Unreal_Log_Decoder_Ring.htmlh]*)../NetGamesUSA.com/ngStats/ngStatsUT.exef]32../NetGamesUSA.com/ngStats/html/ngStats_Main.htmle]65../NetGamesUSA.com/ngWorldStats/bin/ngWorldStats.exed]/.-d ../NetGamesUSA.com/ngWorldStats/logs -g UTc]http://www.netgamesusa.comL] ../LogsN]&%../NetGamesUSA.com/ngWorldStats/logsw4w4= w4 w4i w4xw4w'w4{'NPLg RZ!Np\J$?H$?\$?v$?r$?Uw4w4h w4 w4Qw4w4h w4w4w4urOCJD/-b ::$3*ѸBu^ГГГѸBГTГP ѸBГГѸBP P xP P xГTГTГГГГѸBГГTTѸBѸBѸBѸBz]You picked up some ammo.r$Ax$L> rI;Sw4wMbYw4ԝXP ԝXԝXԝX1"111111111 1 1 1 1 114"444444444 4 4 4 4 44/"///////// / / / / //G=Z@&$8B)$HBw4w4Cw4w4N #!w4k w4w4ow40w4jw4w4Ww4w4M w4!w4Z! w4w4XEw4w4)#Aw4B#Aw4drJxMiQr4+=$:eJU[T++0e+0e+=$:e+=$:e+=$:e+=$:e+=$:e+=$:e+=$:eԝXԝXԝXԝXԝXԝXԝXГГcҗOГГԝXԝXԝXԝXГԝXГГԝXԝXԝXԝX+=$:eP +=$:eP +=$:e+=$:e+=$:e+=$:e+=$:e+=$:e+=$:ew4w4F<w4@ |MN- b ::$ @I-yrү@ TԝXTTTTԝXTTԝXTTԝXԝXԝXԝXԝXԝX-yrүTԝXԝXTԝXTTԝXԝXԝXԝXԝXԝXԝXԝXԝXԝXTTTw4Tw4T-yrү-yrүԝXTTTTTԝX-yrү-yrүP -yrү-yrү-yrү-yrү-yrү-yrүPPPԝXԝXԝXPTTTTTTTTTTTPTTTTTTTTTTTTTTTTTTTTTTTTԝXMWԝXMWԝXTԝXTTTTԝXTTԝXTTTTTԝXԝXԝXԝXԝXԝXMWԝXMWP]fkW$?h$@GS=SqWR 7G k@{$@@&$ C)$ C;agL$,@w4w4{!Dw4w1 @w4YNmQ}0eԝX+++V]UMenu.UMenuHUDConfigCW~*=u7w4w4g,w4w4xw4w4~!w4Rw4w4H w4w4b w4w4;w4y w4 UB*<GԝXԝXԝXԝXԝX1rrԝX1rrrTTPԝXԝXԝXГԝXTԝXԝX<GԝX1111111ԝX1111TTTGW $w4w4["w4lw4w4w4T!w4j @w4w4sw4w4s* w4w4 w4 w4e=" w4 w4 w4cw4w4t@w4w4a w4w4#!`VNs JU[ԝX=U$@w4JRL@;H%K# JU[+PK# K# K# K# K# K# K# K# K# K# K# K# K# K# ԝXԝXs7K# \^Z" [$H@Z]Tim=SW7w4w4`w4\w4PF!Bw4*rw4U0w4K w4w4Dw4w4Uw4w4V)w4w4`w4w4^w4w4X w4w4u w4w4| w4?w4hw4tw4w4VEw4Rw4x w4{w4w4^Iw4w4Ew4Dw4w4@w4w4Y@w4w4Aw4w4Q:w4w4kw4w4] _Ak [ cNh1W$D!::$-O ::$ g0Ni[ YQZPPPP{#UPP PPrb]Another UT Demo Server_] UT Server7w4w4Rhgfedcbw4|D!txw4cw4DNq?I2kkbԝXxxxxx0e++\R@GW^w P+0e0ekkbf"c)(This menu has not yet been implemented.z]Lefty]RightF]CenterE] EnabledG] DisabledD]yesC-no=w4w4Zw4+w4Rw4w4j+w4w4\ w4w4U6w4w4Vw4w4w4F)w4uw4w4{!w4z?w4kw4Fw4w4Tw4INx;a@x!w4Tx!TTTTTT-yrүTTT-yrүTw4w4w4w4~1 @w4w4t!w4U'@ w4Vw4w4N$! w4X C)w4Sw4w4k< w4Xw4vw4w4QGw4w4UCw4gw4Uw4w4MD!Mw4Uw4-w4A w4w4l4w4w4sw4w4gw4w4vPM"lJM l M"D L" LOL{)a@2#MWLPԝXԝXPPԝXTTPPԝXԝXԝXTTԝXTTTԝX_TԝXTԝXTTTTTTTTԝXuG O r@w4w4aw4Rw4^w4w4_! w4[Sw4w4s l w4mw4w4u w4w4\Sw4w4[w4w4xw4w4Rw4w47w4w4\) w4m w4`MPJZ\R@G<,w4w4^w4w4Ww4w4[ w4NN]`hDԝXG= {.@&$ A)$ Aw4w4i !! w4@C"w4 w42w4w4w4w4|Iw4w4BAw4w4ew4JGNZ9l hElJU[++0e++++\R@G+\R@GW^w g"U*w4w4o w4+w4cw4w4aw4w4o w4w4Uw4w4o@w4tw4@w4t`FN|.r2 pFz`hD111pFzpFzpFzpFzw4w4rw4w4l%w4w4Mw4w4cw4w4oJYIG-o::$ 9a w4xw4w4w4w4mw4w4i@@w4w4Fw4<XOx>[B{]H<G1111TTKGSWSRz$4ChiQ$fff?n X>&$A)$@;}@$4C`$Bw4w4DEw4`QNV,_}`hDTԝXԝXTԝXԝXԝXԝXԝX}}}}}{$?}$?t$?o$?GSl K,w4w4`!!uLB&P"_ԝX-yrүԝXPԝXԝXԝXԝXԝXԝXTԝXԝXԝXԝX|$D`Rz$ Cln \'w@&$)$;}L$ @w4w4@{  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ՋսJw4w4w4w@w4w4[w4z;w4w4w4w4dw4w4w4hw4s!Aw4@w4w4hw4w4k hKLRLPԝX=&$ B)$ B;w4w4!QGw4ow4w4{ w4z w4|w4w4F@w4w4O@!w4Mw4SLE=R6a!::$-O ::$@ @;UEx8w4TTw4Tw4TTTTԝXTԝXTԝXԝXP UEx8UEx8ԝXUEx8ԝXԝXԝXTԝXԝXP ԝXԝXԝXԝXPTTԝXTTPTTPTTԝXԝXԝXԝXԝXԝXԝXԝXԝXԝXԝXԝXBg7l a<@&$A)$ B;w4w4`w4vMNJWfT<,w4w4w4]L}-a  ::$YmԝXPPPYmYmYmYmYmPYmYmPPb=W`w4w4Xw4w4Qw4w4}w4w4Dw4w4Qw4w4qw4w4w4w4^w4w4w4w4dw4w4K@w4w4|6n6K w) w4Jw49w4w4zw4w4d@w4w4QC D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s wu v w x y z { | } ~  @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ L } y u r t k m p q i ` b ] Y W P M O r s L H B D A vrpkie`]_C {}yzCI FKJM N O P Q R S T U V W X Y Z [ l o p _ u v { } E G L K h i j k l m \ ] b d r s t o u v w x y p e q n ^ ` f g B A c  ~ @ x w a g B h e { f y x z d u t c r o n m j l a b d b a _ ^ ] \ [ Z Y ` U W _ S Q N M SNMOT K J G F E D C B A @ w4{w4w4Kw4w4vw4w4t'w4[>d*| w4sw4w4G=w4w4ww4w4w4w4hw4\w4w4_w4w4yw4w4w4w4kw4w4Hw4w4w4+w4w4w4uC!w4Ew4w4rw4w4$!.w4\ w4w4i w4w4aw4w4iw4w4w4w4gw4w4w4Yw4@w4w4@w4w4w4w4w4-w4Ww4w4N w4w4|w4w4w4w4w4w4R w4w4lGw4w4p w4w4pw4w4OD!M^ w4s w4w4G!! w4w4w4r!w4ow4w4@w4tw4w4w4uw4w4@w4w4i w4w4 w4w4]w4w4zJ w4Ww4F5@w4w4I !Mw4f @w4w4OC w4Tw4w4p<w4w4m w4@w4w4w4w4DD!w4HD!w4Aw4jw4pw4w4w4w4SOV*@PbIx UV*i~x .Aix x i,x  sNxJf"r_P1P1111ԝX11T1H`SGR7z$A&$A)$@;Sk~L$33?w4w4w4w4w4w4dw4w4HJPw4fw4w4sw4w4Ow4w4e w4w4Q Dw4G)w4w4r w4w4w4w4X,w4w4U!Mg w4m*w4w4V@w4w4T @w4w4w4}w4Jw4w4w4w4_w4w4Sw4ILe1` ::$@`2#IkgX1PTTTTԝXTԝXԝXԝXԝXԝX+ԝXԝXIkgXԝXԝXTԝXPTTԝXTTTTԝXԝXԝXԝXIkgXd"w4w4Jw4w4w4w4B2@w4w4f  w4w4w4w4bw4w4Rw4w4bw4w4dw4w4lAfj w4:!w4Kw4w4j3w4hw4B@ w4w4w4J w4w4@D w4s?w4w4y w4Xw4w4|w4w4z w4Uw4T w4w4w4w4w/w4w4K@w4w4]7w4w4l w4w4"w4w4iw4w4Zw4w4Sw4w4gw4w4^.w4w4w4pw4w4y' w4w4w4w4w4Yw4Ew4w4Ew4w4w4w4\Gw4w4Pw4w4w4w4l/w4w4@w4w4w4ew4w4X@w4w4aw4w4Iw4w4@D w4w4w4^w4w4Z'w4w4w4w4{k*w4E w4-w4w4w4e w4w4Fw4w4r!w4w4p%w4w4 @w4w4]w4w4Gw4w4w4w4w4w4w4w4s w4w4[w4w4g w4w4R@w4w4w4w4^w4UOqH:{W^w <,xxxx+Pxxxxxxxxxx+PPPPPPPP+P++P++0e+0ekkb++0e+0ekkb++0e+0ekkbkkbkkb++0e+0ekkb++0e+0ekkb++0e+0ekkb++x++0e+xxxxx++xxxxxxxx{#Uxxxxx{#Uxxxxxxxxxxxxxxxxxxxxxxxxx+P+Pxx+P++P+P+P+Pxxx++0e}uKE^*~K)r] LOADINGA]SAVINGc= CONNECTINGa]PAUSED`= PRECACHING= Frame RateZ]Avg_] Last Sec@]MinU]MaxX]fpsQ] seconds.P]frames rendered inw4w4Mw4[w4N@w4w4T0w4Tw4w4w4w4@w4w4}w4w4v:w4w4Kw4w4Kw4Rw4X'w4w4| c2m cD::$ppppV client damage type WE by Vg -s3%g:I:$f:I:$6~6~>~rg~?~~?J ]mEgS-t!J%PEw*J]JEePJmwg*?ga/ a/gJD?J?h33>t!t!w4 tEJD?J?&hgw o * o @Jge~EZ~3Jw8*se#e 3%wg* wgqgo?JeE~-sl!w4~?JeE~P?J?3Jswg* wgqg2gEe-Sq![ab? w4lw4w4~w4w4B  w4w4I w4w4W-},YZ( w4^ w4w4d w4w4O4w4w4}w4w4o w4Pw4w4bCw4cw4F w4w4tw4w4y1w4QLRQAs7<,w4w4w4w4w4w4Zw4w4w4w4['! w4Kw4w4U<w4`<!@Rw4Zw4w4w4w4B@w4w4w4w4VAw4w4|w4w4_ w4w4QF*+-^'-]{z ::$n::$ w*-^ @F-]zz /`( w*-h'O *F w4Pw4w42w4w4w4w4S2 w4z'w4B w4w4m@w4w4w4pw4\w4w4Lw4w4Hw4w4qw4w4q @!w4]w4w4P,E$M-O'-]{z ::$n::$ w*-O sE-]zz /`( w*-h'O $E w4w4w4w4w4w4w4]w4w4w4gw4iw4w4w4w4nC w4Mw4YM\17w4w4w4w4Dw4w4Cw4w4w4w4O @w4w4{w4K@w4w4s@w4w4[Ew4w4cw4w4Tw4w4w4w4Bw4w4{K} ~  @ A w4fV$aB1M-i'Dn'!XKKwP* }n%P  n w4w4w4w4w4Dw4w4q9Hw4uEw4v9w4w4|9w4w4[w4w4w4w4w4w4I:w4sw4Pw4w4F/_w4w4w4|&w4w4w4w4w4w4%w4w4d w4w4gw4w4r:w4Kw4lw4w4pw4-w4w4w4w4w4cw4w4P)w4w4nw4w4w4w4vw4w4w4w4u w4w4Nw4w4q1 w4w4w4w4B*!Rw4H w4w4w4w4lEAzl w4X @w4H w4w4B=w4w4I w4w4]w4w4w4w4qA8vh w4w4w4{hw4w@t@{m w4v*w4w4yw4w4Vw4w4I=@w4w4{!w4D w4Qw4w4nbw4Yw4w4aDw4w4w4w4R w4w4tIDw4~Dw4w4x w4w4q&w4w4Qw4w4H@w4w4w4w4j)ew4~w4w4p&w4w4w4w4w4w4fAcA'7k w4w4w4zCA%l w4w4w4Tw4w4w4w4bw4w4k*w4w4nw4w4q4@w4w4@w4w4I.@w4w4N w4w4Dw4}w4w4w4D w4w4_w4w4}w4hw4~ w4w4w4w4Ew4w4yw4w4p_%G&$Tw46"*T46"A3:_%:^%fM'g:^%:$(:_%:$NN?q!pq!w4'( w4Tw4w4~w4w4q w40w4}5w4w4i@w4w4K| w4Ww4w4y-w4w4fH@ o w4`w4w4z w4w4@w4w4d@w4w4p5w4w4I&w4w4w4w4U*w4w4n5w4w4Sw4w4A @w4w4w4Cw4w4w4Gw4w4};w4w4~w4hw4j5w4w4Nw4w4Qw4w4A w4w4mw4w4M w4w4}Ow4w4w4w4V Hw4Y Hw4w4JJLG;PX 4JU[7z$ Aw4w4[ Hw4})w4w4W*Hw4w4w4B9YG)Yw4xw4HNo_ %8x.ԝXG=^ FKYS&$A)$An }@H I @w jp@w4w4w4w4@w4w4c w4w4w4w4Jw4w4mw4w4f w4w4|@w4w4LN"bO p N"N K% w4}PJ"`YORaJ"Nl p E D N E NE E  w4w4w4w4w4FSw4w4d w4w4w4w4ew4w4xw4w4w4w4\w4w4Dw4w4w4Yw4\ w4w4m>w4w4w4w4Yw4w4A w4w4Ow4Ow4P*w4w4s/w4w4o w4w4ww4w4Qw4w4w4w4yw4w4WNw4jw4w4w4v w4|1@.w4G@w4w4tw4w4Uw4w4f w4w4@ w4+w4Y@`w4QCw4w4}w4w4w @w4w4w4w4w4w4Ew4-w4w4w4w4w4mSw4w4X-w4w4Ew4w4i#w4w4X w4w4ew4w4Q'w4w4jw4w4fw4w4g EOHEGw4w4w4w4w4Ww4w4w4bw4w4P w4w4d w4w4Ww4w4w4w4w4w4w!w4hw4^ w4w4vw4w4k w4w4sw4w4] w4Mw4w4m w4w4^/ (w4t  w4L) w4Fw4w4w4w4z w4w4j. w4X w4J w4w4&CHEH$Z9B{&q!k Mw.*.\YZd-h'O-i \ ?%. V\ -b&~dJb-F$-MR w4\>w4w4x&FHJH*soD{&q!g Mw.*.\YZd-h'A-i \ ?%. V\ -G$~dc ]-H$-MR w4u$w4pw4w4jOS0~@ ԝXnZB???aZB???`ZB???G=^Cn~w4w4kw4w4Z*w4jw4w4w4M w4w4Z w4Vw4w4kND}9\.e aլfff?\_~\ ::$.::$:i:$e \7#?1e \;#?nY\ Y6nff> ?Y6\ Ye ne  w4I@w4yw4w4O w4w4w4w4t0w4Kw4w4`Aw4w4^w4w4w4w4w4rw4w4{w4ow4w4Fw4w4w4kw4Cw4w4w4w4nw4],V 7$wV =:V %,&:V :|:X:|`?`ez:XH{ a<R:Xae {  `o$ -M '|XXV K?O* ף;C s)eu)6{ t)6{ v)6{ 6B`6B #<K6C<|<X w4]w4JtL[[ YQZJU[Ww4w4~Mw4w4Aw4w4iw4w4[w4w4m;w4w4Kw4w4`w4JaLAQyc OXJU[w4w4@wwwkkkccc[[[SSSOOOGGG???;;;333///+++'''###˿÷ǻwwkwkck_WcWO[OKWKCOG?G?;C;7;7/7/+/+'+'## ӫ˟×sk{cs[gW_OWGwSCkK;cC7[?3S7/O3+G/'C+#;'7#/+#  ߯sӣgǗ[SK{GsCo?g;_7{[3sW/gO+_G'S?#K7C3?/;+3'/#+#  wg[OKGwCo?g;_w7[o3Wg/O_+KW'CO'?K#;C3?/;+3'/#+#  ;;77'' wkc[SKG?;3/'# sg[OGw?o;g7_/W+S'Ks#Ck?c7[3S+K'G#?73 +# Ϸۯ_ߟ/Ӌ'{k_OC 73{+s#kc_WO GC;3/# _[_w4@w4w4\w4w4w4w4NEw4w4w4w4w4w4^w4w4\w4w4Mw4w4@w4w4w4w4z5w4w4gw4w4s)w4Mw4w4w4Gw4w4} @w4w4w4w4@w4w4hw4w4@w4w4}w4w4| @w4w4}w4w4jaw4G w4w4Aw4w4w4w4w4w4C  w4w4(w4w4w4w4zw4w4P @w4w4mw4w4vw4w4GRw4o w4w4@w4w4K w4w4ww4w4GF w4w4uw4w4Z w4w4PPw4O,l; c* Xw4cq2PD iM3q w33& O-[ 3%3B VwB *B Zq B B Uqw8*s Zq *!w4/a0 y*y q10 6 ff?ou jl-SoaX w -V :i:$S wq![ w4jMw4w4O*w4w4vCw4w4r*@w4w4w4w4u1w4w4w4w4fw4w4w4z)@ w4cw4w4 w4w4jw4w4P1JT1/a%J!ef JaJ333?L> w4E$w4k w4w4ww4w4Mw4w4jTw4w4m w4w4X<!w4hT@w4w4X@w4w4w4w4|@w4w4w4rQw4+w4N w4w4C*w4Iw4] w4w4_ w4w4tw4w4t,w4w4Fw4w4F@w4w4\ w4w4Y w4w4w4w4w4pw4xw4w4qw4w4rw4w4w4w4EJw4w4aC!|ZLk1V 6B'-+PPPP PTT+++TP {#UP {#UVm}$CTJ \] Spectator=;S}SaSgS@Sw4w4Tw4Mw4o)w4w4fxw4Gw4w4yw4w4mw4Mw4Qw4w4c w4w4w4Jw4w4Gw4w4Pw4w4|w4w4{w4w4w4w4w4w4Ow4w4e w4w4W w4w4Dw4w4y w4w4N&w4w4Mw4w4Lw4w4E<w4w4_w4w4d9w4w4zjw4Sw4w4@ w4w4Ww4w4XGw4ON~YcҗOw4rZS&$A)$ Bw4w4w4w4v w4w4vxw4w4rw4w4w4jw4w4C=w4w4lw4w4w4OOn.^mQ23%ԝX@"X`G7naw&$)$w4w4R Pw4w4w4yw4w4{*w4w4w4w4w4qw4o w4w4Q+wZ|"?-]{z -V Lr* w*w*~ Ew~*r~*~ Ewr~* r*~B  w~~ Q* Xw4Kxw4~w4w4n w4w4m  w4 w4kw4w(w4w4y( w4 w4w4w4F6w4w4Jw4w4B w4w4s$!R w4Sw4w4[k6N7X W8I -i Q6 q HBGa=6 {-h' w4w4w4H w4w4T Cy 2 /9j T y z {  w4w4X w4H(w4w4w4w4w4w4Aw4w4bw4w4w4kw4~w4w4uw4w4@8w4w4Nw4w4w4w4G"w4w4w4w4w4w4y)sw4F?w4w4S w4xw4w4Iw4w4HFw4w4_ w4w4u<w4w4w*w4w4@* w4w4J2 w4X w4`w4w4fXLD!c Q;3%2D!!F  w4Ew4w4Rw4w4gw4w4L- w4w4hw4w4uw4w4w4w4nw4w4^#w4w4Qw4w4i'@rw4f[Avk w4lw4w4pw4w4mw4w4T#w4w4t?u]w4Gw4hw4a(w4w4}Cw4@w4w4I w4w4] @@aw4Z-KVs_|[: o VKz -]: o[2*!w4  Xw4H w4w4w4w4aw4w4f w4w4w4w4w4w4sw4w4w4w4p w4w4wGw4w4r;jw4Iw4w4aw4w4Jw4w4Lw4w4Uw4xq  4:z%x q <z?o:4xx o:6E?v,6E?,6E6E?,6E?D?v,,6E?,6E6E?,6E?D?v,,96E?,6E6E?,E?,-Sv,@%-Qv, %-F v,%-F -W-nv, %f$ &f$ ,f$ ,f$ ,f$ Px x-S-Q-F fE"xx H|S,|HH?,EE?, -F -W-n-W-n-H-G w*x:v%$v$v$M-A+-B w*|BB:x%*x$Ux$Pq xh ?%m PG?$h m k m Pm ?k k k ?Pxq h $6r:C6rS[:I:$ :I:$M,bM&HM6: HM6:H6rM6:6rM6:6rHha= r6H6S6%a+rO=zz P?%PP-M-D-F FEh$sC?Le]@F88$s4C?LeU Z]UU]?,sw.-=*Z =  ~Z s$Q q aI6Z6Z6Z6 6 6 = Bcw4w4X w4_w4w4N;w4w4n$w4w4w4w4o w4pw4w4rw4w4r w4w4w4w4Rw4w4Hw4w4@w4w4Vw4w4Uw4w4w4w4w4w4@0w4I*!w4w4w4w4w4rw4w4dw4w4w4Uw4uBw4w4zw4w4y#w4w4Nw4w4jw4w4z w4w4w4w4w4w4Yw4w4aEOw4pw4w4w4w4g!w4w4w4@w4w4w4w4aw4w4i w4fw4w4`w4w4fw4w4w4w4w4}w4mJw4w4Fw4w4w4w4w w4w4_@w4w4\ w4Yw4w4~w4w4hw4w4R)bw4v/w4w4v!Bw4w4w4tw4w4w4w4k w4w4\@ w4U  w4w4j*@w4w4g@ w4q'@w4w4d5w4w4Pw4w4[w4w4~w4w4g'@w4w4N@D w4e!!w4] I/I w4^ JIORPNLw4G @w4w4Cw4w4v @w4w4BIEC B@w4w4w4P$@w4w4nJw4w4rw4w4GCw4w4w4w4T9w4w4@w4w4_/ w4gw4O@w4w4u^5J"cbu-[ %~ lL>hw *R < tR R @@D FFa(FF)FF3D?3FFI-wJ* aJ #"C a  #"`-r7?%7L?);7:g%g=:$x,,zm m cVz~~V{ w4x'Nw4{Jw4w4w4w4tw4^$w4w4E@w4w4MEw4w4w4w4| w4w4x(w4w!Aw4w4w4w4w4I w4w4u/@w4Z w4w4|w4w4x'@w4w4w4w4M !!w4w4w4ow4w4_@w4w4w4w4Tw4w4]@w4w4^w4w4@w4w4\w4w4TDd1p%p Gba "bNNb**q!_wbbfb-Q'b Pb w4Kw4w4 w4w4DJw4w4h w4w4}w4w4L  w4w4C2w4w4Q!Aw4l w4w4@w4w4~@w4w4y@w4w4e@w4Q5`t42z / / ~ w4g&@w4w4VOqA w4tDw4w4w4w4C@w4w4F@w4w4p:w4w4w4w4@w4w4C$@w4w4krw4w4w4 w4k'xFw4w4mw4[w4w4w4+w4`&@w4w4w4w4w4w4w4w4x@w4w4w4w4HRw4n:Ock w4Zw4w4XF@w4w4O$ w4X@w4w4i4w4w4t:NrDw4u%@w4w4Ww4w4w4w4`*@w4w4`%@w4w4`)w4w4w4+w4G4w4w4W:w4w4w4w4w4w4sw4fw4w4vw4w4}@rw4P6@w4w4D*w4w4DQ"QKhD[ w4|3w4sM\=fpFw4l U=@w4w4g*@w4w4w4w4w4w4Y5@w4w4J@w4w4w4w4w4w4D gw4I<w4w4R<w4w4w4w4L @w4w4nrw4w4w4SGb f1`wL*La'::$ bb cwb *b ab b 5**-w * vw * ac V wc *c Z*!w4c c US  w4Zw4w4Iw4w4H#Aw4W<kw4w4w4w4w4Vw4w4_<!! w4j<w4w4H@w4w4 w4w4{w4w4w4w4x@ w4K3 c w4Ew4w4yw4w4rCQw4Ow4w4|@ w4S w4w4w4^ @ w4U&@w4w4w4w4m5XB~UXr.r*FQQa!Cykw*vB* r*qw*??, w8*sw*vBw* _ Xw *: t&b=< t* w4Rw4w4[Mw4w4w@ w4^At2~N w4Zw4w4l* w4_@ w4`@ w4E*z(N: & Nz(-G*( w4a@ w4ew4w4w4w4e@w4w4K@ w4@!!w4Aw4w4w4w4 hw4j@hw4gw4w4Uw4w4W w4Caw4Dj"|&z||cVD w4~ w4w4w4w4r<w4w4bw4w4sw4w4B w4w4vw4w4w4w4l@hw4zhw4R4w4w4w4w4^=F=OcV w4w4w4aw4w4}'Yw4^S w4w4)w4w4P w4vw4w4w4+w4w4w4mUw4@(@.w4A@w4w4a=[ ~ w4Ow4w4V@w4w4M'w4w4ew4w4cBw4w4rRw4w4@w4w4@w4w4w4w4|CYkKmef?, -\'yY Zewy*yPP-i-\yY Zwy*K?&?yPy_7K?P ף;K?_ #<KK w4`@w4w4s w4w4_w4w4CDw4w4w4w4ln1V>XefaQ6 [6 33ab6 aC-h' w4w4w4hw4w4w)w4w4yw4w4v @w4w4@w4w4fw4w4x#w4w4jUw4w4w4E7w4w4jQ!w4{@w4w4S'! w4lUw4SKDfBwo*o~*@w.*.^ w4pUw4Xw4w4OHw4w4i=g=hQA w4C Uw4Eefghijkw4nPqw4Yw4F*w4w4w4w4eotm w4Sw=F fr?w.=*r.=8.=swd*-Cg dwj* >g jwl* >g lF ag F i$F o$F -H'w.F *.F q!-!ER*!w4/a0 y*Qy*10j-C ap$S w4Pw4w4g w4w4Nw4w4h$w4w4Dw4w4w4w4~;@w4Bt^zxw.t*.t-xW% a !w4/a0 }a w}v.t10 w4T=w4w4S%w4Qw4e(IJ,fK-x(Ia/! rI*IU? w.I*.I-W& a !w4/a0 @a @.I10d-v(H#:II:$I  HddIa/!K:II:$Io$I  H w4c0B 8z -[ 33BZZ?ZZx-M u| -M'ju-Sxa w4Q w4w4uy0JuS w4M>T Y4S~)T )S )R )Q w4R w4w4D(w4w4RCm0.-M-M'm+-S.a w4sRw4@w4w4Mw4w4gw4w4dNw4Qw4Ow4Cw4w4w4q@w4w4w4w4^>w4w4G w4kw4F*w4E Iw4{$w4w4o?I!Fw)I!)H!)G!)F!)E!)C!w4x)w4w4rw4w4m}#kU]G$&#-i (-^(-P(-N (-B(-N(-q( w4Yw4w4^w4w4_w4w4w4w4j @Dw4Bw4A"L@Apn w4}Nw4jw4o'mw4w4w4B"{@<_m w4jw4w4w4p!@DW w4kw4w4` w4w4w4w4G DU!W:I:$i${O$FT'-p(-M(-W (z33?a'(( w4w4w4B+w4jw4v w4c w4A(!@DW w4n  w4c w4}w4w4l w4w4rw4w4F#w4w4c w4w4p!@DW w4j w4w4K#w4w4}w4w4K w4w4\ w4w4|w4w4s,!@DW w4XDw4w4n)Bbf)>rB''r*( bB w4^Dw4w4T{w4SJw4w4~!@DW w45jB}MT1I 7G oB'-Vw4w4iGw4w4H@w4Pmw4Lw4w4B$w4w4w4w4e$w4w4w4w4Ew4w4tGw4w4w4w4{w4w4_D{&E+a {& fo$i$Dz @BCA-H'pw.*.^*q!-!E w4O&Pw4L%w4w4UPw4Vw4w4[w4w4L@w4w4{Dw4w4Nw4w4Xw4w4ew4w4@w4w4jnOPRw4ow4w4z6w4w4P w4w4Ow4w4u w4w4m w4h w4Bw4t/@w4w4IFw4[ w4w4qw4LTOuAh@2lAo8LPTԝXTqt]Only %i more to go...s= Completed! oAw4w4w w4w4w4w4BFw4q w4w4W@w4w4LJPw4M&Pw4oF0w4w4w4HYw4s' w4pw4L@w4w4\&0w4ew4w4w4w4w4w4Zw4w4| w4w4Aw4w4m2w4w4@w4w4Iw4w4-w4w4w4w4w4kw4w4bw4w4w4w4B@w4w4w4w4@w4w4w4w4Pw4w4p w4w4`@+w4xIw4w4B-w4w4ew4w4\w4w4vEw4Rw4w4a @w4w4dw4Yw4kw4w4[,T::$ rr*2r iB-o   9?#\C-b']r*F Xw4gw4w4[w4w4m'@+w4^Ew4w4]w4w4d w4w4e w4w4S/ w4w4N@w4w4Zw4w4A1!@DW w4N/|*t5-pppp, game_end, |* w4w4w4Iw4w4lw4w4{w4w4mw4w4iw4w4E!@DW w4l#w4w4H7w4w4A8w4w4I@w4w4K!w4w4t@w4w4nEw4w4v@w4w4x@w4w4]&l)VU[ )l)w4T&w4w4sw4w4R& w4w4w4w4w4w4}d8`}!} -f-5 w4w4w4w4w4vw4w4w4w4h@w4w4w4w4_*w4w4w4w4w4w4w4w4w4w4W P-" z){F  F -'k#???x::$q N w4w4gqOKJTNp\<,*@@*w4w4W'w4w4nw4w4fw4w4{ w4w4Qw4w4y0w4Z.lv !#la/!pppppppppp, player, Connect, l /, Sl B, T.l-5pppppppppp, player, Connect, l /, Sl B, T(Tl w4@ w4w4yw4w4@w4w4i t_]igwt*at?tJK?trK?tJ?tr w4@w4w4w4w4w4w4jw4w4Dw4hw4aF@w4t w4w4ep+`<A6t.`-::$ rt* S::$t- {::$`??,  X!w4/a0 t Xt t104wt*t- y !w4/a0 t y t t104rtPtP* w4Dw4w4Iw4w4X w4Hw4w4a @w4w4w4w4rw4w4Qw4w4kw4w4l@w4w4dw4w4Qw4w4w4w4w4w4R0A w4z@w4w4Cw4w4Xw4w4@w4w4M w4w4x  w4o_IZ)dPq -EoZ)EPPE w4`z kC~Bw4n)iEyLG>w.* {g. p|gq!Y w4vw4w4M#w4w4zw4w4f w4w4dEHJD-H'#-QaA(HH-C-M'BCA w4E w4w4qw4w4Gw4w4Fw4w4|w4w4nw4w4Zw4w4Cw4hw4Bw4w4Aw4w4Zw4w4JcwR:9rw*rw`*rLb* vaw`wv*vbw_^] w4w4w4hB@w4w4Dw4w4vw4w4F w4w4Rw4w4Iw4w4^6w4w4B@w4w4@w4w4VHKOnJ: w4ty7gm|9 w4[w4w4y5wgJ #&#77;7a6'[-O y!?6'a-OhYo$q!iqy tw4J/@w4w4`6w4w4A~8JR w4Kw4w4vw4w4]w4w4^w4w4Fw4Pw4ML5\V)Lw4Xw4w4Vijg9;wLb*Lb^jklU-d-u @~w"*"^jkl w4w4w4lSw4w4pw4w4w4w4sw4w4tBf 8 rL* 'a !w4a !,bwLb*Lb^ fa |-K-u @w"*"^ fa  w4kw4w4g@w4w4w4w4Pw4w4@w4w4sw4w4w4w4w4w4gw4w4rw4w4sLjL l9 w4w4w4uw4w4L9w4w4ow4hw4rw4w4w4w4ww4w4{w4w4|w4w4}Ew4~w4N9w4w4@w4w4UE.xO]7&xWosrg w4_6~sB*$A @-v'>A$mVwm*"ma/!-vH!} -]mR~r ] A:~o:m omR~r ] Arrrm r ] !t rr *mL] AmmUR B/w4#w4w4Aw4w4w4@w4w4mw4w4Nw4^ w4C]6R(E w4Lw4w4w4w4yBC D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s wu v w x y z { | } ~  @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ L } y u r t k m p q i ` b ] Y W P M O r s L H B D A vrpkie`]_C {}yzCI FKJM N O P Q R S T U V W X Y Z [ l o p _ u v { } E G L K h i j k l m \ ] b d r s t o u v w x y p e q n ^ ` f g B A c  ~ @ x w a g B h e { f y x z d u t c r o n m j l a b d b a _ ^ ] \ [ Z Y ` U W _ S Q N M stuvT K J G F E D C B A @ w4pw4w4L^^ + OzN6Opd Kp6KrKO6d6 ?)r?%L^X^ r5?X^)r5L^)rpzrh^)j^ w4hOQPw4mC!>lw4lLTNPR^MJI\GECy@A~}|w4eEw4w4w w4w4w w4JEN_9sVJU[w4w4x@w4w4pw4w49w4w4H:w4w4w4w4_w4w4p2o2oW w4T Z2uC( w4w4w4Qw4w4cw4w4w4w4w4w4bw4w4w4w4aw4w4fw4w4w4w4[:w4w4t5s5L>CN"rC*C WwC*CClCrC*C B/w4q5w4w4@w4w4z w4w4w4w4T5w4w4qw4w4w4w4A/@w4w4w4w4zb\% ?,<6 4Co$ w4[Gg!::$ $[>[$e:I:$b?mb>-6'N-O*G-O ::$w6'Nz *a6'Nz $?*w6'N{ *a6'N{  )#?G-O ::$Z 7??,?6 ?@<wGP*_a_ y ծ)?,(#L? )#L?(r_*aGP$@Z <ay$??Z wGO*]aGO  )#?w]*]FZ 6'N-CG-C6'a-OhG-Ch #< w4Mw4w4B2}1Kժ w4p1w4w4_ w4w4lFN[3%2*!F  w4^w4w4}w4w4w4Fw4w4w4w4w4w4w4D@w4w4{0w4w4w ~ ^ ˄JN!cV{H -j*c~ EJ! Xw4~@w4w4J!@w4w4w4w4_5\ f_ w4aw4w4\w4w4X f!xfiw4Pw4w4Mw4w4Q!w4w4Lw4|NpKKOGԝX`nw&$)$w4w4Vw4hw4d!iw4`@w4w4h!iw4G1m  w4TwQB -] rX*X3% wVww*w-*:w o: owPwwUV BMw4Ww4w4w4w4cw4w4E1h `r8*us Xw4w4w4\w4w4]w4w4Gw4w4Zw4w4tw4w4w4w4bw4w4P0qo6W -5zq&#qq}q&zVwz*za/!.zz.z |@.z Eq%zzUF VT$ _}qzVwz*z-za/!Iw *w rQ* rQK3z q!o'zg q!o'zg q!o'zzU  Xw4w4w4`w4w4l:w4w4w4B@w4w4E0j z75-5::$K?restart$( Xw4ww4w4@w4w4nw4`w4q:w4w4l;w4w4fw4w4jw4w4hw4w4w4w4w4w4}w4w4w4w4rw4w4uw4w4n@w4w4v@w4w4o;jw4Fjw4@w4w4w4w4Ow4w4|Eav w4qnopqw4w4w4Iw4w4A<w4w4@w4w4w4w4B<w4w4w4w4s@w4w4Dw4w4Qw4w4N@w4w4H@w4w4Kw4w4Lw4w4oWMlh73!w* hl  w4C-w4w4TExy u= w4w4w4w4w4Vw4w4w4w4w4w4Xw4w4dw4w4dw4w4Yw4w4\Ew4U@w4w4pDUX{I6 ?,aU ;U!NJU  {Py6{rK tr6tk t{6K6 ?)k ?%JUKU  k 5?KUGk rP<k cUGdU w4[w4w4w4w4Kw4w4w4w4w4w4]w4w4zw4w4w4w4w4w4gw4w4w4w4ew4w4J,_v Q"-]{z DrC*C wC*_Cw_*r_*_-x[ ___l_w_Cr_*_-x[ ___Ow[ *C[  pC|Cx Xw4w4w4wAw4w4hw4w4hw4w4@3~2yQC^Nrc*a LCcccmCm*C w4mw4w4N w4w4lw4w4ow4w4q<w4w4vw4w4w4w4tw4w4w4w4pAw4w4w4w4z<w4w4w4w4rw4w4w4w4|w4w4w4w4F w4w4w4w4~w4w4w4w4Bw4w4@ w4w4Ew4w4@w4w4Fw4w4@w4w4Hw4w4[w4w4IDy[s56kkyyի>(k2a%t!t {z 6 >)26yz 6k?%(Sz 6y6k6yz 6y6y6kS6y6y6kS2y ((' w4Dw4w4Ew4w4sPw4w4w4`w4w4w4\vŗ2UUdd-m-m-l-l w4w4w4w4w4Tw4w4@w4w4Uw4w4Ww4^ w4o+Zv bVnwb*Wb-|b /ZnbbUwb* \b Bb /!,'rb!*!b P-Ew!*-E![ Xw4b@w4w4k9w4w4~Xr42UXdW-m-U-l-T w4f w4w4`=[ w4Ow4w4p9w4ULP:w aDxT{#UTT{#UT{#U+T{#UT{#UP P w ]$#../Logs/unreal.ngStats.Unknown.logw4w4s-cS `5w * -]$ rDTr$ETDT -CT -CTET$Q*/a0c@ .rQ* w@ @-5r * \@ Q@ -|'-r@ !Q*10wQ*-VQa/!.Q-!{.Q / B.Q /!,' BVQ!,'!Q70-V-| Bw!,'0 P!,'!*-Ew!*^-E![ Xw4Vw4w4zw4w4Xw4w4ew4w4t9w4LNLQM2hv?<,w4w4bw4`GLr/R j`hDԝX+ԝXGS=SH7z$@n\$?s(;n }}H }w4w4w4w4F ~ tqjmli_WTw4w4w4Cw4w4@w4w4Ww4kw4@w4w4nw4w4\!Aw4rw4w4tw4w4w4w4^BXB\$i w4Aw4w4uw4hw4\Bw4w4xw4w4h=w4w4u@w4w4J3dAAI w4YBw4w4nw4w4^U2m|0pV should never call base spawncarcass* w4|w4w4w4w4q=w4w4Dw4w4b.k sr -l 3-5::$ YY You feel much lightera'''-H'q!T Bcw4s=w4w4Tw4w4Gw4w4d.k .&-5::$ A Bcw4y=w4w4Kw4w4wCw4Aj w4w4w4Ow4w4Zw4w4w4w4w4w4P/Ui 6 %-E-U Xw4w4w4Pw4w4w4w4Vw4w4w4w4bw4w4w4_LSFN R\Z!w4w4w4w4V:w4w4w4w4Xw4w4w4w4w4w4w4w4w4w4Jw4w4^w4w4sI_\Yw4fw4w4SBw4w4Dw4w4dw4w4_:w4w4kw4w4mw4w4w4w4w4w4sw4w4pw4w4nw4w4rw4w4r1w4w4Nw4w4tw4w4w4w4xw4w4yw4w4zw4w4wl3W Kx ^:I:$ -hE? AW @;;6 6N ?&Ea7ED);D;DD)6N 6 i ;D;DcE AW @33>?-h(;;?&E7aE_b_b__@fff?W _b__fff?W _b_b?, _b\-} oW ?7offf?offf?bBoB?*C w4{w4w4}w4w4~w4w4z|N w 3%2*!F  w4Y@ B 'Y%w* nR w4w4w4B w4w4n3o Q"r4::$R-q_R` V -'S>S;7z@@A w4w4w4E w4w4w4w4dw4w4t1P dWS FP xpppx /S|m  w4G w4w4I o1q֬ w4_!K w iU w4w4w4M w4w4N w4w4xw4w4@w4w4Q @w4w4R w4w4S @w4w4K>w4w4U @w4w4n}6" *6n/{F  F ::$v  W$q NTT V-'S>SYY?*CbY;74 a/!~::$k# w4_1l [u iw4Z w4w4\ w4w4@w4w4] w4w4[ @w4w4uemU1!::$ 6'a-Oe-Op- h?% h?,tw*]%!s -z(6'N-Che-O6'N-ChYw*]%!U  w4Z w4w4] w4w4` @w4w4PBw4w4`1w4w4a @w4w4S>w4w4gw4w4Rc{ ]^[ZDWw4|w4w4e @w4w4w4w4h w4w4q;Z a>( w4i @w4w4w4w4p w4w4Sw4w4oHk w4B?w4w4q Ck w4w4w4t w4w4u w4w4q,PL Xw4v w4w4z w4w4{ w4w4w4w4w4w4w4w4E@w4w4x w4Bw4A!w4w4oLw4w4 w4w4w4w4w4w4C!w4w4E!w4w4F!w4w4G!w4Bw4H!w4w4N!w4w4iw4w4w4w4pLoB S>Fw!*o!i!  ^ !  x.!&wx*::$x-x cx;dwx*x ~ex-^ x &-E6ix;D-E\i^ 4C oi y-E\i^ C^ 6i;iY w4@w4w4L!w4w4O!w4w4V w4Fw4P!w4w4w4w4j w4w4}w4w4M@w4w4p,[1e VB8-]zz /`(@-e' w4R!w4Bw4X!w4w4]Diw4w4w4[!w4w4RXACQl w4}Qiw4]!wcl w4w4w4}?w4w4^!iw4w4w4b!iw4w4w4w:9 o$S w4a!w4w4Qiw4w4w4g!w4w4w4w4j!w4w4w4w4l!w4w4?w4w4k!w4w4o!w4w4w4w4w4w4u!w4w4i w4w4A@w4w4Nw4w4v!w4w4x!w4w4w4w4y!w4w4{!w4w4Siw4|!w4w4S w4w4J@@ n o$a w4tN@fJn w4AA|@NCm w4vz@Sm w4GBw4w4k(w4w4w4w4F"w4w4w4w4H"w4w4Nw4w4w4w4w4w4L"w4w4K%w4w4Q"w4w4O"w4w4w4w4T"w4w4R"w4w4P"w4w4W"w4w4U"w4w4S"w4w4w4w4hPw4w4X"w4w4Z"w4w4["w4w4w4w4\"w4w4`"w4w4a"w4w4b"w4w4c"w4w4d"w4w4e"w4w4f"w4w4g"w4w4h"w4w4i"w4w4j"w4hw4YPw4w4m"w4w4k"@w4w4w4w4w4w4n"@w4w4r"w4w4p"w4w4w4w4t"w4w4u"w4w4w4w4q"w4w4v"w4w4w"w4w4x"w4w4|"w4w4z"w4w4w4w4w4w4}"w4w4~"w4w4"w4w4@#w4w4A#w4w4w4w4C#@w4w4B#w4w4G#w4w4w4w4w4w4yw4w4H#w4w4zw4w4^"w4w4yOw4w4w4w4N#w4w4K9w4w4SMw4w4TMw4w4W#w4w4U#w4w4V#w4w4w4w4w4w4w4w4w4w4w4w4Z#w4w4NMw4w4_#@w4w4dw4w4@w4w4]#@w4w4`#@w4w4lL@w4w4b#@w4w4a#@w4w4g#@w4w4w4w4c#@w4w4w4w4x w4w4jKw4w4kK@iw4w4w4k#@iw4hKw4w4@w4w4o#w4w4cKw4w4w4w4r#w4w4G&iJICw ? II v -Sv?-S(-e'-@(6~%6~D?6~%6:D?6:@?6:D?6:@?6:D?6:@?0v?,<6I333?o$-h(q![v?,2|?aW$?? CY?>aU$?? CY?> w4Sw4w4u# fw4rw4w4TJw4w4YJw4w4{#@w4w4YI@w4w4w4w4@[I^b#r^e-R&}uw * A^.w * A^.r^K*. ^g!-3.%O^K%**^^a^Y @^Q-['P^PP^Pw * A^.4w * A^.rr^K*. ^g!-.%O^K%**^^a^Y @^Q'r*( b^ w4@$w4w4~#w4w4QHw4w4L 0w4w4w4g @w4w4bw4D$w4H$ew4F$w4Bew4J$@w4w4zE@w4w4qC w4K$ w4Y! w4M$! w4T' w4R$@w4w4Uw4w4T$@w4w4w4w4X@w4w4~@ w4Hrw4JB 0w4[$xw4Z$w4w4Q3w4w4xw4Lw4w4`Sw4w4`$w4w4w4w4]$w4w4b$w4w4u'w4w4N?@.w4@Iw4w4w4g$w4w4G(w4w4Ow4w4{w4w4i$w4w4l$w4w4](w4w4[=`w4d=Uw4q$fw4o$fw4W=w4w4t$!R w4r$!R w4w!R w4Pw4w4w4v$w4w4w$w4w4x$w4w4y$w4w4bw4w4V;w4w4w4w4O} w4\|:~$N~w4w4w4B%w4w4|/w4w4@w4w4H%I)fg)I)w4MBw4w4w4E%Cw4G%C%e,)C%w4J#@w4w4L#w4w4w4w4w4w4Ow4w4y@w4w4lNw4Qw4w4w4P%w4w4Nw4jw4\Nw4w4t8w4w4w4w4w4w4U%w4w4W%w4w4X%w4w4Y%w4w4Z%w4w4w4w4w4w4fMw4Qw4^%w4jw4w4w4]%w4w4aw4w4w4w4Y#w4w4HMw4w4@w4w4f%w4w4i%w4w4j%w4w4M8w4w4\%@w4w4N8@w4w4yLF 9q!p w4@w4w4xL@w4w4q%w4w4e#@w4w4s%w4hw4t%w4w4B8w4w4d#@w4w4w4w4w4w4`Kw4w4\Kw4w4XKw4w4TKw4w4}%@w4w4w%@w4w4|%w4w4Y7w4w4mbw4C&@w4w4`JT{cj n~a@6:DT?,T6:DT?,T6:DT?,T w4w4w4E&w4w4A&@w4w4w4w4]!ZJjCP; r::$jw.-T*.-T-x T* Ds% ?M& !w4b?I  O&jjwJ*::$aJ  Pj w4_ QJW%4H/8Wa/!\C W  W -W-w$W-sW-\xaPy# N 'rxWW-w!.W[P  yWP-yWW  W( W   "w4J&w4w4K&w4w4w4w4D&w4w4rPw4O w4w4JPw4D@-w4z#@w4w4XI-w4z-f5SY w4w4w4i5w4w4W&w4w4X&w4w4Y&w4w4Z&w4w4w4w4w4 w4A$0w4t-[&TT+ )[&w4Y 0w4]Fw4k w4w4}4INN w4G$WQ" " " " *k*"Fow4L@S?$Ƣ>ISSIA>ĘҀjpVNVS>Įc/V'666,6'[ec$SM/'/''''',3'6Vjcj[?VM???6V;L[;6VvjIV?NVVVe,V;NVvͦeN?6NV;$,$V;6NvjSVI?Ne> >$/pVrN;jpNN,$$vLN;cp/I;N?V>ypv͎0vN,VNr,ޮ;NN?VcM^eV;N,Vc3?BrV,N6VV>^?#6VV$V63>/$jNV w4w4w4@w4w4l&ylEMw4@w4w4k&e&I e& w4_ YE`%eBP`Ww * A.`w * A.`d.`rK*.` g!-.`OK%**aYS: t&`"b=< tr.`A.`K-br`.`-ba w4m)@w4w4o&rE w4SEfE-I`D$-V' :I:$o$6-X'Z=,E-U o E$Tw49Hw4_4m; w4w4w4m&m@T w4JEw4w4CEw4w4T w4w4w4w4rDv&E0'r**% Ev& w4@w4w4vDw4w4w4w4&qD*/ w4w4w4ZT@D+w4w4w4}&w4w4~&w4w4w4w4iDoD$l/ w4A'w4w4B'w4w4C'w4w4D'w4w4E'w4w4F'w4w4G'w4w4H'w4w4I'w4w4J'w4w4K'w4hw4q-w4w4gw4w4L'w4w4z&@D+w4w4w4q3@+w4r w4w4J  w4i w4VC w4f@ w4g w4w4w4ICw4iw4+w4Ww4w4v d " " " " **"1 pw4V@                                     w4P'@+w4w4w4o w4w4I@w4w4`'@w4w4a'@w4w4w4w4b'@w4w4w4w4d'@w4w4f'@w4w4]'@+w4_Brw4Q@+w4X$xw4w4w4j'@+w4Nw4w4lmw4s@ w4p'@ w4_ TAn%/+)9nOo ?%;$] o  ] $*!w4/a0 P*Pnn%10na/!r.nP.nP*{{n%  {-X a()){?%a{( w4k2 w4w4{w4tw4w4e w4w4c@w4w4Y2@w4w4v' w4w4@GXWVUw4z'wRQTw4L2Yw4|'Yw4uw4w4d$@Iw4c$@.w4w!@W w4RH>xap$-C ( w4W>w4w4Zw4w4Hw4w4E(w4rw4w4w4I( w4w4M(w4w4K(@w4w4L(w4w4w4w4hw4w4O(w4w4P(@w4w4v0w4w4w4pw4w4w4T(w4w4U(w4w4V(w4w4w4w4w4w4Y(w4hw4Z(w4w4[(w4w4\(w4w4w4w4w4w4j$w4rw4K=w4w4A*w4w4w4w4c(@w4w4d(w4w4w4w4fE}0b%-C' w4g(w4w4h(@w4w4w4w4m$!`w4h0Sw4l(w4w4m(w4w4w4w4A!R w4p(w4hw4q(w4w4r(w4w4s(w4w4w4w4j(Sw4oedkjw4]0w4w4w4v(w4E w4 w4G*w4w4}( w4 d " " " " * *×"Mwe2pw40a@LJKJEHKMMPPU6LIGJKKKJFIPSKIIJHDGGEBGLOPMKJJIGEGFHFILLLMJJIHGGHFHHJLKLMKIIIGHHGHHKMKLOMKIIHHHFFHKKILOLJHIHGHFFIJIHLROMJJIHIKJKLJKPQOMMKKKKKLJJMQOMNLKLLKKJLQQMMMKLLJJHMNLJLKJGIKOINQPJL w4z*w4w4T:w4w4m_hiw4w4w4r \jw4@)w4w4A)de_w4@w4w4H)D)j)D)w4y9YTw4X/ w4D%hw4@w4w4Q/_w4_O@$+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%U797w4f w4m8w4w4k8w4w4v%w4w4y w4w4w4w4@&bw4wRw4w4cIw4w4{6w4w4Q w4BJw4w4S)w4w4w4w4dIw4w4Q&@w4w4])Yw4^)Yw4_)Yw4vYw4e6w4w4T.Y.@w4@w4w4b)@w4w4c)@w4w4@w4w4y@w4w4DGw4w4W@w4w4@w4w4k)ew4YFew4w4+w4]E@w4w4ZDyR'-xRw * h.w * h.{M. p|Mq!l w4@w4w4oqO'hc r* Y::$/a/!r.L* a   G a+. O'a(  w4U^L,7(w*L^w)5^* w4o@w4w4t) w4w4u) w4w4v) w4w4 w4w4JDw4w4r)@w4w4O sw4|)w4w4B"]ArN%XV9rV*!w4/a0 *Uvrr%10 w4T w4w4w4B w4w4~).w4` w4w4w4w4g!R w4L<w4w4JRw4h;` u-nr-x` a  #A]-x`   #` a+ N` '-x w4L0@w4w4w4w4w4D0w4{( @w4 w4J* @w4 w4H*w4w4iw4w4w4w4w4w4@%w4w4R*w4w4S*w4w4w4w4X0w4J w4w4[Ow4w4Fw4w4O%w4jw4r8w4w4uNw4Qw4H,w4w4BMw4w4{ rsS""""* * "kpw4r@                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              @@                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    @@@                                                                                                                                                     @                                    @             $ 4 w4hw4w4w4w4w4w4w4w4F.K.u w4a*w4w4i)w4w4w4w4Y@w4w4{w4w4N w4w4]w4w4zyxwvw4u w4b2w4w4o*w4w4^+w4w4k@@w4w4@w4w4iw4w4o @w4w4f*w4w4U+w4w4Ww4w4w4w4y*w4w4w4w4| w4w4w4w4@w4w4M+w4w4~%w4w4e)@w4w4A+w4w4w4w4AOw4Qw4| g>v 8L-| -r (o$K:I:$6q?%6q? ?,q??,{*!Zv >Sv v ,a?SL???v >?6 ?,ajv -|  # w4S+w4w4w4w4~4DP w4Vw4w4-w4w4fZ+x*E>Sx*%y*0wS*SHq!Q!3 w4hD+Y[K^D+ w4R+u+gMtZ?%-M'aZja-}SCJ-mq!w4ka-I EK3w4\w4fO+@+HlS@+%A+0wS*SH^:X%:X:|q!f!3jq!f!E w4w4w4I+F -m ( w4h}*YbH^}* w4D~+K"6F 9a(((a  #@F-M'\-E /a0 -KNK-E Kq!w4Ka*10rR *R /a0 -KwKKE E KR KEEEK10 w4+L,euE w4[+L+fIpZ?%-M'aZja-}EwS*SCka-I EF3w4@Xw4w4w4fJ+t*KEQSt*%f*7wS*SHq!g!3 w4w4w4}w4w4_,}X0| -}b w4x+\+kyU|v!<#Z?%-M'aZja-}at J-mq!w4ka-Iu!< EJ3w4dw4hu YcxST&::$u -(<u [u u K  @' w4hu*YvE^u* w4d+N+QF|v!#Z?%-M'aZja-}at J-mq!w4ka-Iu! EJ3w4@dw4aY+T  w4w4w4fy+L*3O+QSL*%H*q!h!3 w4uB~Ar* rB*#w*rB SwS*rSB.Sw*.%.$ p|_* Q SSL X@" " " " *4E*"ow4@汩 };+zՖq,Lggdz z[[pȠ,}R#^Ȉz#N;Ȉr;,rr#^r߽ѶʽӽZP8("   ("-87(!.AC{{tk]TC88"  "!8:PZ{l]TAA=<-$ "-8:T]PPCF8SSc/!288 -/<38/jڮ7-.|j "-8 $- I$A Z---"$PÙ "|A "߇  ! . :8  ә ZK  FZ % Zlfltt~ʓѽ w4w4w4J)_w4T,Pv+:X%PVwP*rP=PUrPPrPP^PP*rP[[*PPU w[*[Ur[Pr[P^[P*[* w4C\,x 3 w8* 1-F :I:$P-iXF$?'D?w *: t%b=< tU-s ::$ w*h6 a,w= w=*6 6=  o$ w4i{>"-]{z <wC*Cy Xw4Y Q*J[';X=:Q*%,&:XHR*:XaS* w4K/Yh A OYo= w4W,j  -} ( w4aQ,V+Ae(}||X`C _:X%:X:}Y =:X&s :X:G)&:X:}Y =:X&s M*C %::$f B   w4R/_gQ  f _ w4ai/JAC-J)w.J*.J-J-H'J-M (.J3%Ja'''Jo$JM*Ja/!Jq!? w4Y,i no-} ' w4w4w4\D Ybti  WQ" " " " *6H *"@ow4Z@汩};+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~ʓ w4hjE#20-5::$Kj$' w4w4w4D a+{!-x 5-F r**d-Y'Tv$x$::$-* w4S uaz -ub w4b,{{ +-I-{ w4^,wz  -H-w-H-H ( w4u(~w4`,yv%R{ -yb w4oI,d,v:P5Q3Q%Q%S*%*q!h!E w4k,w4w4{/w4w4W+| 63 -H --H -H( w4lw4w4K0~w4f,Au= Ab w4c,E]Q Q% w4w4w4]+TG'-`-Tb w4QJ a w4g/ca` @ -l 3-5::$ ac w4`0E"z\X IGwq*:q:$qRE"k(l(m( w4CV!|uAMkV! ?wM*-{'pMj w4r,} _ك,R} *w* nR Xw4^1n  Xw4`  @w4w4w4w4DK*"1nO::$hhpwpE~H$aL>' w4X+K-qY|v!<#Z?%-M'aZja-}B-mq!w4L-E ka-Iu!< EL3w4dw4wx,Y \:K6] Z 6] BY 6] B\ Z ]  w4y,j Z ?C6j V  #<6j CD6j V  #<6j T  #<6j FǎT  Bw4z,pFz!spvo:q w4~,qdu&Uq-s-n w4hSYAW5&::$S-(<S( w4X1w4w4`+w4w4,Q Ug ~e$-w!*G!4GGaQ $A-Z GaQ $A-Z GaQ $A-Z GaQ $A-Z  Bw4@-dg^}l dc o:b Bw4x1ZlX|n Zk o:b Bw4i,C C S>C w4w4w4w4w4a{,T<X"::$r.T* M::$.T- u::$T??,  8<TST%.Tq!q!3 w4jT2Lb  Bw4QM2F2$ -`-E-D+r!*-E( w4w4w4gTO`+8w *  `-O Xw4X2w4w4q D-HsY -E ' w4s J-CY-E (%*q!q!E w4m w4w4a2f54zw"*"a4wo*oabwc*caccm4wj*jajjmb  w4v,Y-I^|v!S#Z?%-M'aZja-}at J-mq!w4ka-Iu!S EJ3w4dw4fTJP -5 NVwN*:rNN-|N /Jw.N*w..NL*|.N[: d|||~|:pAdding IP Ban for: |X%WXMzX WXXX pDENY,|" -}Sp /bannedN /.N[duringV~V..unr!U4 b -}Sp /kickedN /.N[fromV~V..unr!U4Na NNU! Xw4D i2o F-'S>S;7z@**k w4D/",As'D$a@'-v'.-t w4RQ-|71|$tIw*wm*mm~ wm*H   m  H m]* H |wm|H mm{ 1ff&? w.*oJ.5GETPING/w.*y'=J.5GETLOSS w4RC)j! #-N ( ::$C %-N mf ?,a fxf a+B -N (f -N '-N (f B   w4|2~L|^a  w2*2U$Oa? a? ay2]~2 &~a2]2 &y:2G:$2G^2-^:A%2-P:Z%2-B-e2-B2-i 2-i -O :v%2-N2-N-O2-N 2-N -^ :x%2-q2-q-O2]yowj*#jraw#m*#-B-:#G:$:#G,9# &a# &r33s?j###m.o#-B-:#G:$:#G,9# &a# &r33s?j#@##n#]~a? a? a# &a#G^#U$#-^:A%#-P:Z%#-B-e#-i -O :v%#-N-O#-N -^ :x%#-q-^w*-h:v% :x%-O(-^(/a0 QwQQ  #Q-\[SQ    [S?%Q  [S?%Q   Q((#]WQ)oQ  ?? o10(#]# &#GDo#]~r2*2##mcc#c[#2I B?LeX94<@2-N2-q2-B2]I d  rd ?%2]I d  d 2]I rj*j2@m22*wj*WC$jU?~ L=j &#???vCD6~ ,CD6~ ,CD6~ ,j-^v,@j-Pv, j-Bv,v:jGA=:=6 ,, #-B-W-Ww#U# &?,  #-^#-P-W#-i #-N #-N#-q#GA6,6,CWv w4ZQa ~ YM}a ,a a ,ZQa  _oa b"Namea 'b w4bw2ySoc1"-5zyS&#ySyS}yS&zSVwzS*zSa/!.zSz.zS |@.zS EyS%zSzSUF }yS,?ySyS,?  -aDpp /:yS' w4S-O\}*V*/a0 OO*N(Oa/!Oa/! Oa/!hOa/!-}'0 r}*}OrV*VO10r}*-}::$ -}}a/!:.M}D:$-} wV*-}Va/!:.M}D:$-}O}}VVO w4w4w4C"g+mS\Q.m-::$ rQ* S::$Q- {::$m??,  S*q!I!3 w4l+IohDBIT% LTITLT oI( Xw4D3@w4w4XI3wLE #&#77;7q!T w4[-@w4w4_-S| &T VS w4n+QmZ| Qb w4UY3Q16 Bw4@D` @ -M' w4ua-_3g w4Y]O7 -l 3-5::$ \*/a0]f ur\* wf \f -}'rf !\*10Cw\*\a/!.\-!{.\ / B.\ /!,'5 BV\!,'!\g-} Bw!,'x P!,'!*-Ew!*-E![ w4e-Vnw Vb w4^-S<::$ -E-E Xw4N'@D+w4bTGLV -5 sVTws*:rs==s-|s /G.w.s*w..sL*/ -}Sp /kickeds /.s[fromV~V..unr!U4sa ssU! Xw4o-Ss+JH::$ -sK?load=9$( w4w4w4G w4w4Dj-t " it kCwt *,rt  t t GGkk w4QNSB4$;::$ $-cV 99a?%a?( w4d4w4w4b f4n&T 3%8Tn& w4v-Vhaca3%::$ -s k5SaveGame 9 w4u-kFA --{ -k Xw4A4w4w4y4w4w4c-H)-E(!* Bw!,' Xw4F+q*FQ )q*$w4bR8 jB-q--{ -F-@::$b Xw4~-CVa۪B::$  i VC Xw4Sk-qf!2rkkGG*qkwq*wqG*rqGqGGG* qqGF  w4P5M.wj*jajjmLw2*2a2* #&#-E(-L(-O(-^(-e(w.{!*!* w4^w4w4ze*OV )e*)i)$w4s+oIL 64-5La/!o eo( Xw4{-qJR N64-5La/!o eq' Xw4w-H+D6H+  w4.L[:"-]{z 5r*F L,dW^w**LwL*R.LwR*":R\:\rR-W '-W 1rR*R.%R:R\:\1rR*R.%:R\LL:R\RLLp-W (L:\Xr*LXwL*R.LAwR*:R\:\xrR-W 'uwU*U-W  r*1rR*R.%URAA:R\L1rR*R.%L:R\RLLWpr* Q Xw4w4w4IV5-c(-L'-e( w4ow4w4J@; w4h5l5~|aSWOs, appa.0Sspappa.Ssu, appa.0Suappa.Sux, appa.0Sx&appa.Sx`H, appa.0SHappa.SHB, appa.0SBappa.SBIa w4@w4J.w4H.z`5TPlayer List:/a0 zQpz/( pingSzo)10 w4C.G./h UIh h ~h .,h  w4h @w4w4P.\__4\L5get ini:Engine.Engine.ViewportManager Brightness5set ini:Engine.Engine.ViewportManager Brightness 15flush5shot5pset ini:Engine.Engine.ViewportManager Brightness U\5flush w4w4w4w4w4@w4w4] c*E+'IE+ w4|+w4w4L.o%<I-ipppppp, info, Log_Standard, `pppppp, info, Log_Standard, Qpppppp, info, Log_Version, m'pppppp, info, Log_Info_URL, j'pppppp, info, Game_Name, Qpppppp, info, Game_Version, cpppppp, info, Game_Creator, h'pppppp, info, Game_Creator_URL, ]'pppppp, info, Game_Decoder_Ring_URL, P'pppppp, info, Absolute_Time, :-i|$5get UdpServerUplink douplinkT'pppppp, info, Server_Public, 1:pppppp, info, Server_Public, 0 w4N.Zn)Z ypppppp, info, Server_ServerName,  Dhpppppp, info, Server_AdminName,  Dhpppppp, info, Server_AdminEmail,  Dppppppp, info, Server_Region, S DA(pppppp, info, Server_MOTDLine1,  Dwpppppp, info, Server_MOTDLine2,  Dppppppp, info, Server_MOTDLine3,  DEpppppp, info, Server_MOTDLine4,  D~pppppp, info, Server_IP, Zpppppp, info, Server_Port, S \ w4u5W 4 W Xw4O.*T46pppppp, game, *, e) w4|-s X -L-L w4R.j] TY#-]'Lbq!WR::$`' w4Q.d)ECpppppppp, game, d), c), b) w4S.q g j w4U.vCl  p v w4}+tz it%gt,tX6ta =,6ta =,6ta =,t w4].C| cjC$ w4@w4w4a)XfOXa)pppppp, map, Name, Xpppppp, map, Title, Ipppppp, map, Author, @(pppppp, map, IdealPlayerCount, c$pppppp, map, LevelEnterText, F  w4W.}E u,uX} w4^d6bu 'V"b!N b!Z(R33 ?'( w4[.@B n,na @ w4@w4w4X.p  w4p.L`F)5 -M -] L%d.!wd*d-d \L!*-E( dV}wd*fwd **:d o: od -Md \Ldwd!d-E' ddU ::$DT-CT$ETDT S '-CT'3w!*9.!-.! -MS '-CT(xw!* B.! /!,' Bw!,'ET$ Xw4j6Y)ey'Rpppppp, player, Disconnect, SY) B w4_.y @ -l 3-5::$ Y#tI w4a.L&`#g(`pppppppppppp, kill, SL&, E&, SD&, A&, WC& w4FHc y&-5::$  -u-H/a0 TvT-B(Tc10 w4z+G _w4D7XoE6O %Q%N{6O %O ,X BT&XN&PX PNNPQO 6O @6{Q w4W V 5 x,XVw*?a/!.M  Xw4c.~*a(x)dpppppppppppp, teamkill, S~*, |%, S~%, }%, Ww% w4y  w4S^QfGS  w4G7w4w4k.r.` w4\7w4w4q.~ t 0&[[_.z ?, _L>~ V_~ >333?z WYWff&?Oz @_m m ?&?A~ q  #<m ?A~ q q ?&?,~ +z ?, 6Ym O?,@A_Y6Ym Oz @A_ w4g7gH(&BpppppppGetting Vg, Vf, Va, Vc  w4w4w4F,kr  -l 3-5::$ ^w*p Weapon: Vkwk*pppInv: Vk state WkakkiwC*稨Selected ItemVCChargeSCP Xw4v.har$!w* ah w4f7BlA,mpppppppp, player, Rename, B /, SB B w4kTM#* Current ping isS o w4u.AgFi-rpppppppp, player, Teamchange, SA B, RA o w4@o! w4w.a%tK>.VT-ZTpppppp, typing, T-a%, S]% B w4G,Rn d -l 3-5::$ O-R-M'z$b-M(zz @" " " " */?*"욷ow4F<@汩};+zՖq,Lggdz z[[pȠ,}R#^Ȉz#N;Ȉr;,rr#^r߽ѶʽӽZP8("   ("-87(!.AC{{tk]TC88" "!8:PZ{l]TAA=<-$"" !-8:T]PPCF8C-E\{e4C ebYS-E\{e4C{ 6{7 w4u^8W8Z0 w4@/Ub"-]{z 5r*F U%i]w**DwD*Q.DwQ*9:Q\:\rQ-p 'wD*D66-p 1rQ*Q.%DQ:Q\:\1rQ*Q.%:Q\UU:Q\QDDo-p (U:\Wr*DWwD*Q.D@wQ*:Q\:\yrQ-p '-p  r*1rQ*Q.%Q@@:Q\U1rQ*Q.%U:Q\QDDior* Q Xw4C/nl vnlnB-B-5::$YnJTKTbYb w4@w4w4f8Q%p`^1]pppppp, item_deactivate, Q%|, SP% B w4[/qF4 l q w4el8V%K-kF#V% w4w4w4H/_w4bE/cڭ w4M,_w4w4w4@w4w4TWk; _h Wb w4v8Lfx3l/a0 Lipppppppp, player, Ping, SLB, SLo10 w4O/BN w4L/D~4"pp, game_start w4LRK!)R)`)F nw4z.l#  -l 3-5::$ ct!t!w4 God mode off t! God Mode on Xw4\/_w4Z/]g L Cx] w4H9 w4,w4BR@w4V/O K F. w4b8P J .. w4s  w4W/ w4e/F%K~-kF#F% w4R,[jF g [b w4S,t-} (bY w4]/_w4j _w4 A)w4T/@Dw4jw4w4o&n9m4 rG% w4k&a/r:YH) w4h&b/M?'-MH%ME)Mr w4`/w4w4c*c/f/uHHN w4@w4w4U,af V tr-5::$ ]a b Db Xw4d/w4w4Dj/"6_D w4o_do/a0 }j N:9j __&:10Vwj *j D/a0 }DND__&10rD*/a0 }DND_%10wD*Dj  w4Dr" ELDrUnreali.Lamp4 Jwr*{r{ w4zw4w4n/qC w4o/w4w4@w4w4m/q/S l w4S:w4w4_ k/N*% <:rN*7a/!.e a w4Ow4u @w4w4gw4w4b w4w4Zw4w4!w4w4x/w4w4y/w4w4C0~w4f9w4hw4a:w4w4w4w4rI0A%(x&B%o&A% w4H!@" " " " *HF*"ڠ]ow4mN@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 w4w4w4a,~w4:w4bw pX.* -]ow  B|w HelpQ  _}w FVwF*F-*:F o: oFa/!gw *w rQ*d rQK3F w !p'Fg w !p'Fg w !p'FFUy Xw4B0w4w4F0w4w4{N0}$Vj  V}$ w4QH0~/$oڧ#!::$`-E' w4w4w4e,~w4~ @^w4J0w4w4Cb<O0*c)-E(!* Bw!,' w4w4w4popE!-X-o-oVw * t'w * t'Aw * t(w * t( Xw4g;w4w4Y[pLb`$AMTGa ``wG*G`[\] Xw4Z0~u(w4fp;c w4V0w4T*w4h,w4w4Cw4w4w4W0w4wNCL[0Bog"ew4w4o,o(yb NLwq*:q:$qOo(p(q(r(s( w4^0w4_0!Sw4@<!Sw4k0f({VS DBwq*:q:$qgf(g(h( w4b0!Sw4c0Sw4d0Sw4e0!Sw4t(!Sw4iqJ( |J(K(-L( w4Ji0S(RzS(T(U(V( w4K<!@w4cf0N(g\{N(O(P( w4d<@w4m0b(|PyECwq*:q:$q b(c(-d( w4e;w4w4] w0|0'&\ ::$rq*/a0 p p La/!oqp ywV*qOVpAttached to player Vp 10rV*/a0 gMVMwq*qOV10wq* wV*v!'v!' w4o0@w4p0 Rw4q0 Rw4r0 Rw4s0w4t0w4u0w4w4w4w4Bg0X(O !yX(Y(Z([(\( w4n,eIj ON&-5::$ /a0 JKJI*e10 w4h<H SyFi/a0 CH !w4!OH 10/a0 CH !w4feH -V-vOH 10 w4Zw4w4z0w4w4p w4w4{<w4w4x0I{r Y -l 3-5::$ WWIGGI w4GD1\  w4w4w4h!@DW w4w4w4S=w4w4T L1C12 w4K UjqwjXj w4V=w4w4b s!f [Y$NTOTa%s!!eas!333?L>NT$ Xw4w4w4F=J=2W w4]w4w4F1w4w4]N1K1~ w4w4w4fM1cE w4_k$]&=)k$)l$)](:w4W!iqj -l h-5::$ i!w4/a0 kigk10 w4H1w4w4~0jz~ l -l 3-5::$ /a0 DihaDjDa10 Xw4O1f$^')f$)g$)G(;w4L" \L-( w4c=w4w4w4w4V1w4w4Y1w4w4W1w4w4pw4w4w4w4I>gR wu* v  w4\1vZ i!~_/%u*]*gup/a0 I]fe|W]i(_ w]f10  w4w,k E.Nk Lh M|Q!} w4a1L>F r*(Lf gBr*Or*(`r*B~wQg% B/w4e w4w4b1c g< w8*(p9 6pVpp (VY(#??6Y)e amXp 'Y8we *r.e *c ?XF  6F ̌?i pF ի?,(Ve amXpF '8re *'( w4d1Q Q|&3%::$ 6'N-CQ >k6'[-CQ >6'a-CQ L>(6'Nb%a/! ~6'NF* D?6'NbQ * #6'NUhh3333D?3Q ?6'Nb~3%h?6'a-O ,* )#?#!U3%h@ w4Q>[^7[5[a/!.[-| ( w4^ Nq w4c1f1Iw4] g1'vVvwv*_v-| r6'v [-Z'JvvvU-Zq!w4 w4vw4w4Ru,]Fl::$$H@y(cE%|EE%|% -z*|H@X%X, X` *XX%/a0 ]X, X` ]10M(X%NX, DwX` *DX` _X I(w *H( B w4w4w4i1w4w4cI2|,  oS""""*z*ε"sow4͢@\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ݧmݲ@@bpμĻ˻v^q}1]ۨmrND@F4н˽ĽķïBlϜC1|=r50'WķȒxv{zR DnH8Y88u@5w{ĻĻss|s~ݱzmhTDcӋC џ<_zTDAu_SywƹսĻįxݨ{bc@Db b@n6D_zuk}Ȼv~z<@\'߮c$5tuҽ~}Tɶ}fmD1#r±}]ò~~~e}ٿyJakJ1'޺@68μ˩~x}ص\1HO'zOH!ب*׿~~ʐbTLTCCkfx[ؿuy~{{ǰ]O]]D8SiNBimm1Ž~siw]bbH:-mYzc11H~tX@*)-ئAŽp C"{O15^~weJ:*%-+ǏyGhŽp:uu5">@J>BPvs`H7--) _笆u8G}<rL10NT14s{C40VӡYYs[pLG!4Ck:ӆ:=u_V.*SwnwKOpSQ2Steeb$ӆ@ǿ~K~7WfY}}mXQ=km]4GϋOyʿ;>s5fAurm_LGGfGb cϿ۾ƿż4RwTTT{G!AcVQA(AOۘH!zˆHGɿCɪDH@!@GYYVLmmrk@ cuVSAظ`"$ͣɿ1eܗSuopapL@$ XB mŒ;Ƽu:eؿy}ءmYO88}X~5m'Q] /ŹXb@Cb}_؋tXG@m__mttH OM5yfYz/e{H]NƋ'Ƣ6=6}cO@LhG==Lakn</'԰͜{'7<{<]í~XԸcϵ}85cG=V}Y=222L]e"9 $A՝ʰJ1JJ$JŚtV+zG.YucA+cV=2++@T`5^F>ԅǵeHbapƜbJ}AQmrhmcư}smcG2++@JW-.yfָmګtLtb{ҫ}༓h}rŮ~TzVA8=GHW0*VS.j8iS}]JXݢuϓrrGƼtpnNycQSJKR>uӗ}k@i>GLO*<ήDϏyrºuYr]{bX['O{pbW` ~ 'ῈkSJ1HJz}}mhkˇw/JL!ǶhYYOtXOW/W~sspH ^we x~lCsk'C{eN{zrR Dnb$]npT16_hc_YY1rhzXddd`5wkJ;ݱzmhOCcӋC yh;J.1LYYVY6}cmiI^^iR:t}sC7ݨ{bc@Ab *}V~K5bOYOup.ǾzL5HB^x~:{4tk[;0z<@b'߮cO~pSi]c`1V{X}f5$9M%e~1]]C;/]'GbG͋}Ӹ]1b{//X<)BPvlص\~ki;e>-`~x9IU99^b5e. NrX:'"vqlqʐbTCd̎giN{nŇ|Zw{@~f5KCJS@'?|^xǮ]J]d^vxixs*Hxds{yTdXX8X/OfbCMMdx]bHstͶxvg7NPLݾy<|suaO5}S~eRPgdvmuwc۶mJxi Fs%ӪN5uJ@*sNF>Ildn[ӗBWxȐ~ Huu04>l|}zz[Jn IíxswN¦rmbacϜO UrC*<~{]J1%)-红um\Xr֋@ ;`Xt:YY.ܵƜu'Fwb@5`|~sTB/)-4qlkCaDcш\S«T˹4T]Ϗ@*XHb@obutѳp\ư]wdZgx[3g{ի~n¢]آXşR5{}{}uԿ|vdvdl^|TPBƪyΣwJ}ϣzĻ||vqUvql͍ƦŐɫNض}af̻|vld^Ivllw֪zaykŤūHԙXTwĻdgKgvdggvdьX]yK'թtbչi]enN]ĻȠ^Zd^gdlgq]OTӶD=.}rptȳrkfȷMIZv#dó{`}fmr}z@@@Wҿȯ^]}r:m1wĽ|54`r*V}zȻ|uXppC֕1]}ijC{ur0:p:˳wԦcX']Ƕ=}ų~Ѽf]He~JǺJ~w{]t<{KCLrǁŽCXxn7%(mǵpcuz}~}_2=RkDSO}k1JƋyaeNkX> rDkmukbO]Tc8yT:;]X]NNnDwb}Vmzr__Te1~5~]`5/X}G=buJVhYOwk>F|xH5s:}54/r@JOVc!hT^v{-Jn;uXmeab@~.te:7C]HT]C{X{HT;~k3lWH<'FwԦe]g)N0~n7,?O@p4^qѼfs~iګep~wG/Cu@;q{TNZ-CzCbiIlsp%@~4mCip5{wC-Z|rD{HtCTu`b``;-ZCJbzteXkyTֺ~NZxWTجwɚb|vlinۈfxggdv|݂p'ԂtfķUdPwec @eνįw˽c]btkkeνw]bJ{;mhɽ:5OOƼk`ShYhbOzYr/u}bmpu8;pwzsnYOi]4nccp[R{CWuH{C,xH];RntCpU}wwcW~eTBeinxv|uxvquyM@{Ҹ{pkɹ]a}p}m`}pkkewy]kKXb{wnXnvluhypsbvu{w4L k>wr w4w4w4S@w4w4x w4w4w4w4uw4w4p>s1ZrrXuX* w4Gw4w4w4w4B @w4w4[2SX SD| _S Bw4ew4w4WAMAޣ0u2 -M( -f (a''' w4wv1z w4z@.w4w4w4pSw4hw4@2.w4Ew4w4w4w4O?A2I w4D2w4w4Cw4w4w4w4w4w4w4w4E2w4w4CF-G2*t )-E(!* Bw!,' w4o w4S)PtE w4Ww4w4j2w4w4n2w4w4]fS' w4w4w4q2w4w4@ \-NV3%2*!E  w4r2w4w4w4w4u2w4w4Ys2h \ w4v2w4w4x2w4w4w4w4iw4w4npC^_<p%pp,4pD?p,,p w4v@w4w4Cw4w4G6w4w4C3wF!W-k(T:Ae:Z-H-ewj-i'pww*wUxjwmwmccwc[wjmb?%/a0 UwUU  #U-\\SU    \S?%U  \S?%U   U((w]WU)oU  ?? o10bw]Pw]w-^w-Pw-BwGw &"wwm@-i(Z=eA=T-e-H w4eR3_$K"F-kF#_$ w4w4w4P^Q SVx^ x^6\n6\f6\p6 h6 s6 }a*Ow.-O*\O  K8U -w(a \-w'0wK*8K8a \8  U8o$8a*okLa[q[-k' Bw4w4w4B3w4w4E3w4w4F3w4w4G3w4w4CM3]-^ G w4w{(a<6 33ab6 aC96 ?a6 ?a t! * #!b::$ D6 ?a* #!b\333>̒86 Y6 o6 __6 ?ab33> w4L3 kw4vA@ w4FP3k=(Ya(((-H'q!Tw Bw4}A@ w4w4w4S T3l9| w4BBw4hw4~S3a w4rRBY$(&Z$o&Y$ w4\`-T5[ w4w4w4w4w4}@w4w4VBw4w4b Z3U3T- w4{[3e'V(  Ve' w4T\3c'i :/-E-c'-D-E-r!*-E( w4JgQk   Bw4w4w4^ b-]3m w4w4w4f2Re &-5::$ RbHlwR*found patha j!w4R  didn't find path Xw4e3Zu r8*Z9 6ZM 7#?ZL?(GMZ?(waJ f GM'rw*MGկ7)?,#?waJ f MG'``rwGJ ZMGկ7)?,#?waJ f MG'rw* rw6e (6e (6e )waJ f  Z?( 'e w.-w*.-w-vww.<w*!r*??,8.<w8-[8??,(:8X%8* 6Z8-a  ծ?(8(Z8o$8a*8* w4f!g3uQtZ6mv$x$a(((-L'-c'`-po-E'a?(o$/a0 uQuQ  #uQo$10 w4{kBS$V   VS$ w4w4w4f3smkw8*8-y'8a**8o$8   ?, 8%8* w4CCt w4R@4E -c( w4n w4w4tA b p!% ?,<6 Bo$ w4Y'w4hw4`3H  H  Xw4k3Cq -] w"*Gw"u*"u cC-^(-a(-`(-f(-w (-z (-J (-O (mS@d -a-a(5W-^-w x?%-a-z x?%-`-J m?%-f-O m?%-w x?%-z x?%-J m?%-O m?%vL>@@C@Nb6<TxNzTHTe Bd vP $@y-` z?% P yB?yP e yFB>B?% z?%B?%z?%BzF3B?BzF!B?%z?%z?%B?!BFBze B-` H?% P yv?yP d yGvav?% H?%v?%H?%vHGVv?vHGDv?%H?%9H?%v?DvGvHd vz?% H?%$dNSN:j%m| B| S| NB| E:j%-H :^%6-ZdvBdvQ@vBe vd :o%-b '-O (d?%-b (-O '-I -H-b '-O (:m%-O 'd?xN@xxV w4D q ` $OM::$q $M:q ,2X q :q Lq  w4y i3| !3%33 w4w4w4w4w4r3@D+w4u3@D+w4t3O[ w4XCUQˆJw Uaw  ף;?w w aF$Aw  w4w3@D+w4x3B' w4y3@D+w4{3U w4f-@D+w4m3H X $w:H LdOuwO*^Od.OMOO Xw43l w4oC@w4w4~3w4w4o3w4w4xCsއ w4E4[ ov6r %\%_O6r %r ,nw!*[ !  y[  BW'[ Q'S[  S__S\r 6r @6O\ w4i-w4w4w4w4upCJz)]^ -~)-q'-B-p'FTFT?CHTHTFT*Cwx*DaxDa gz w4z3n %MpV being unpossessed1w"*"a-(;L?) w4uI4@'whX~8w@'A'B'-C'-D'-E'-F'-G'-H'-I'J'K'6,6, Bw4yC{|{#"-Q-YInitiating local logging...ao-i(monf{iw{* z{{{lnx)u!::$::$  -q-YInitiating world logging...ao-i'monf]&{iw{* z{{{lnr)u w4Ow4w4RF4' }% w4V4a#6|&}&~&-pdu>Su>6DBaS6DBad666PF6d?%6PF6w!*!  Fasa^::$La#$"(a#$"-e( w4S x4l w4GDL4y?r*w4@w4w4K4N4qI@+:w*-GR\\worldlog\trueQ\\worldlog\falsew*\p\\wantworldlog\true\p\\wantworldlog\false\ w4\@w4w4Sw4w4M4Q4p^-c?zfSK il?wK *} %@ FEngine.Mutator%@ d({@  } ,2|@ VK q~d,qddq{fSfSpfS, fSpfSd(} FEngine.Mutator} @ dcK K l(k{fScppc\mutators\fScppppc\listenserver\T::$\password\T{c w4c@w4w4@w4w4t4w4w4U4TZ! w4[DajW~ Xa w4e\4y&K,-kF#y& w4[4zLM^~ Xz w4w4w4P4Z4\u1CkD]~k: ]%Jk]& w4kw4w4\X4XH}EError - play gut hit must be implemented in subclass ofV w4Cl-w&*' $w& w4@w4w4o{2d/ aA' w4R^44f w4Ye4]4v  w4nD>ny3 r>* >Bpppppp>, game, GameName, I>Dpppppp>, game, GameClass, V>Npppppp>, game, GameVersion, c>Ppppppp>, game, MinNetVersion, x'>Fpppppp>, game, NoMonsters, T-c>Jpppppp>, game, MuteSpectators, T-a>Fpppppp>, game, HumansOnly, T-`>Gpppppp>, game, WeaponsStay, T-u>Ppppppp>, game, ClassicDeathmessages, T-\>Cpppppp>, game, LowGore, T-w>Gpppppp>, game, VeryLowGore, T-y>Dpppppp>, game, TeamGame, T-]>Jpppppp>, game, GameSpeed, SD^ ?,d>Hpppppp>, game, MaxSpectators, SS>Epppppp>, game, MaxPlayers, SX w4w4w4a4s&]::^ s&=@^ a@' w4w4w4bn-m-Sf w4\J4T w4k4b4d`z w4w4w4w4Cw4o4w4w4IEh4c5z w4Pw4w4w4w4BEepTBze&?f e&E~f ?%f f ~f ?ee&}~e?%ee~e?e'( w4w4w4w4w4w4w4n4ll)IDYD~l=%{l~l=yl~l=&W{ly w4Pp4ay w4w4w4z4W5y u= w4r4j&h;E@<pj&zlz~g&9|~m)'( w4j4w4w4FA5w42 w4S4w4w4{4pZx up w4{EFUx uF w4r-w4w4h&GM w4a&[Oz $w4FI5}32 w4yEw4w4cN5|4 q w4w4w4G5B5X x u= w4gEc{]FHInitGame:cX, ecMaxPlayersX@6cDifficultyp{@t=J@@6cAdminPassword{@[@@6cGameSpeed{@GameSpeed@]L@iaY'pBase Mutator is Vi@6cMutator {@Mutators@ {@g ~@,g %j @g @@}@g &j @@pAdd mutator j N+j iDaNR@6cGamePasswordX{@@GamePassword@@6cLocalLog|@true-Q'@6cWorldLog|@true-q' w4w4w4@@w4w4H5E5uw w4NFQwa w4cJ5  w4@5w4w4D5L5S MPppppppppw' I, U$ SB/SX w4@w4w4w4w4bM5c! w4J_8b3x iw4l @.j77;7.r.{!*-E'-c'-e(-O(-^(ou::$ -MIa?(wj*jajjm~w2*2a2* w4kF^I8oQ:^:$:^:$ {Xw^{*ES^cV^{ES^cV^{KS^ cZDSZ}Z}KS&-FSiSDSESQ-FSpppAttempted to use illegal skin from package DS for ESl .Z -FS wl *W^ }l 'pppFailed to load Z so load X{Xl .X W^ }l (  w4OFS5SSX% BX w4\F@w4w4O3w4hw4R5GjUg L 6GPasswordX::$ SGg H{{L z[{L [zL g R$|NEEDPWg P$|WRONGPWdC$g T$ w4Cg.V& ,*-MCV&W&X&Y&Z& w4j7A>oS ow4Yw4w4X5@w4w4]Q_c&mHF{tY.t FwY*_I Y  w4U5od W]~o:1]oo]-P 'a%a{a]~a,]wCa]G a]&|CACCEPT-A '|CDENY-A (w]~G *P]MzG ]o]-P -A DawwzG o-P -A Daa@-P pppDenied connection for o with IP policy D-P  w4[QD rkea?%-J'-H'-F(-E(cM:n:$-@'c:n:$-F ' w4aw4w4H@1c)H)a)b)X)c@ w4va5Eo]*#r=* :I:$o$(w.=*=M D?D?&6 ??=? ? !Qb((w.<=*6 ?pE.<=??=F D??E6 ? ? !Q "w4w4-w4t`5\I] w4G@w4w4A"g5LfZw.L*[L w4w4w4[5h)e=[?y 6h)W7{y Wy Jy U& w4@w4w4tYzOYV(wzt*w.@ z*'R--| w.z*'( w4S&b5a] mGSWOs, GppG.0SspGppG.Ssu, GppG.0SuGppG.Sux, GppG.0Sx&GppG.Sx`H, GppG.0SHGppG.SHB, GppG.0SBGppG.SB_, GppG.0S_7GppG.S_tS&GppG.tIG w4y w4w4xw4w4e5f)z[^s::$laA Bi|S"::$ B%G H*X% BXG H*iP3A f)y@6yName,v =eyTeam,A6yPasswordM6ySkinV6yFace`6yChecksumLogin:@|{APasswordA[c*v f)r[*G d'* Vw *`. w`*r`L*w` *`-({` / /::$9|` /@|``AT`  U{rT*'-`-)A -vaA BA |)TaA [  [  {wT*T [  rT*pCouldn't spawn player at V[G f'*TcTMVv T BZ'TRT  .z@@~y::$zT /~oT@(VT:v G b'*Ta/!V::$|T`AT-5{[zA[T -fT-5hT-5Administrator logged in!TOD::$::$DpT /`'([ NT'w* vT)w*vT`T-BR|`NoChecksumkTa/!VBT w4a@w4w4o5M ^wTrM *,rM CC*xwx*vrxM xM xx3M a* w4I w4w4r5E NaQ2rE *ptried to add none inventory to VI pwI *YrI E (I I =E aE E ' w4[w4w4}w4w4jkZSEPO}Kw}*4r}k}}} * w4w4w4w5L]3FMe r*  LOe7E իL?(Lի?(O w4h6GX0t%$PT-QT  XGU-5GT% GTPT$ aTrGT \T ST $XTToo many login attempts.r $RTToo many login attempts.r #$-QT'r o$稨SGTincorrect admin login attempts from /[  Xw4CGw4w4x5v5X,L w4XH $L q!x tw4|5\S IX\_q![ tw4w4w4k5wtow2EA}'|'$::$yVwy*y- wywy-vwHH%y }&y },y },y }wHyI wy *y -f ya/!w-v.yHH%w }&w },w },w }.yHwI yyUfwDT]TwMT^TwOT_TwJT?DFT&wKT?DHT,wIT`T w4C6p R8I-p 6p %6p %a+p  tw4w4w4{55n t w4w4w4~5A6q't w4w4w4@6t vt-T'`t a/!Yt a/!V-T(V::$|`B-T.::$::$Dpt  /g'(w* et w* et  w4D6T[vGw 66:66:r66w 6:6w 6:6w %a+w a T tw4I6UZrFZ:I:$o$L6 ?|6U?%6U? U w4B6nu?yKdn稨All inventory fromn /is accepted w4Kw4w4Hw4w4E6vdL{8vavaB;va/!V i iB"wi *rv Zi *_ai v  "w_*_%v_cv N__y_ ev_ Mv_ yvi Gv w4K6NHc0FzD w4w4w4Q6J6a F w4H6M6cm~>{l/a0 UM=<|WMNl0M10/a0 [X|{X-CX-z0X10WARNING: All single player starts were disabled - picking one anyway!/a0 [XX-C0X10No single player start found* w4N6w4w4lw4w4w4w4Xw4w4W6O6PE w4w4w4L6pXd =-_::$::$'Jcp=,|rJ* Player start not found!!!(-Jpa J  -JJ Np'pa+J  p p  p &#p  #p3p3pa'''p"[J  J  p-M(pDpDps ps dppVJ Player start not useable!!!-J w4R6w4w4Jw4w4T6w4w4JV6LrE w4S6IulwY::$::$ -_IqIyuIK?restart$( w4w4w4X6cZJA-wc*c-ucdsADu(!Kw*JAs*w*JAs* 0s!p {~D{c /A /c|~(!K-s'A @*?&ZrcA rc*s!w4w*JA!Vcw*JA!Vcw*JAscw*JAscW-sVs!b]W,A *Ws![]W,A *Ws!U]W,A *Ws!q]W,A *Ws!Z]W,A *W<s!U]W,A *W]W&A *c-JNonewc*Jc|KNonewA*KA|:c o:A orw*Cac BA BJKsw*Cac BA BJKsz#w*C`c BA BJKszw*C`c BA BJKs-s wA*vcAs]cA w4Y6w4w4[6w4w4\6w4w4w4w4a6mY@!s mPR!D w4w4w4c6QT!@!s QIZ!} w4Z6bv*rA]W%b `) b w4m6dRr</|d&@dd}d&-g'W|d&.dpp.Red -g -] _}dKVwK*K-Ka/!IKg d!oKKU  _}dKVwK*K-*:K o: oKa/!Kg d!pKKUW B/w4AD4g6m &IaCrI**IkGwL*I-C(' -Vr.{!*!II w4w4w4b6[){0)[))Q&)z#){#$w4Iw4{w4i6ST303-5B5S1{B B Xw4`.Yx[.Average AI TimeUm*p < 5% S% Ap < 10% S& Ap < 15% S, Ap < 20% S, Ap < 25% S, Ap < 30% S, Ap < 35% S, Ap > 35% S, A w4UAT#~pppppppp, player, TeamName, SA B, A s*pppppppp, player, Team, SA B, RA opppppppp, player, TeamID, SA B, SA \pppppppp, player, Ping, SA B, SA opppppppp, player, IsABot, SA B, TA -epppppppp, player, Skill, SA B, UAR  w4L l2w 7U w4f6S]4g EJrSg  rS*g  _?&wS*SBwS *S _?&i]Sg  w4JJX; w4w4w4l6p6dF  died.  w4q6w4w4r6w4w4@w4w4o6t6\R' w4u6w4w4v6w4w4w4w4s6ccW-!cZo o c w4\Iw4w4fRU)]f~*"6'T) [-T*%U) w4w4w4T)w4w4N\.R j (FR aCDwR *R kR j3 w4QeJ )-'Q w4w4w4y6@7lp? w4A7w4w4AJw4w4e}.F&Ktm-kF#F& w46fGwH::$(w.f*.ff w4B7B #~ W?-c'-e$-e(I&J&K&du>Su>6DBB S6DBB d66 6PF6d?%6PF 6?::$LB #$"FB sB  w4w4w4C7csRf+ibcx#vQ:vQ&Drc*'dc bx# w4J7w4w4I7w4hw4w4w4Ew4w4w4w4eJK7VL; w4U7w4w4w4w4A k78pm w4XJQ7B? w4w4w4P7} oz` -w* l} Lw* l} }  /`-`*} $ pa'}  / w4kJw4w4S7w4w4l.w4w4R7bV`b o=%=w* gb\w* gb' w4T7w4w4M7w4w4w4w4V7[7C> w4lJw4w4X7w4w4o.w4w4_7w4w4`7w4w4R@w4w4h.b7R @ -B w4w4hw4SKw4w4Pa7xC - w4@w4w4i.t J0*" rt * ht  BDr_**w NonePw Selfwt *pppppppppp, suicide, Sh, t |, WG, w  pppppppppp, suicide, Sh, None, WG, w  w4Nt.Fh$@w* hF>w"*" hF  w4cJw4w4[Kw4w4gLeFT w4ci7 P w4w4w4_KJe?Restart( w4m7o7_hkS.o7wkS*[$kSlS?,$?,(kSlS@?kSlS>$}j#} w4j#w4w4r%w4w4FsO 9,s-r*sr w4n7_E5{ 0iN3P_-^$' -V'/a0 Q!E_Q*10w* t_m-g*a&a* w* t_mF+a* w4w4w4s7w4w4r7v7PVkOVgwO*PO-Oq!xOH OOU' w4w7@w4w4Ow4w4t7@w4w4x7w4w4w4w4z7w4w4ulJ w4|7~7b w4w4w4w4w4@w4w4w4qw47w4w4p7w4w4TLE8BQHdPwl*C lBMrC  TC E\C EC  w4C w4w4uP8h%w)-8wh%i%j%(((((((r%s%t% Bw4C8w4w4G8w4w4qLFDf /rl*lF-l DF w4H8w4w4J8w4w4pQ8A w4K8w4w4sw4w4w4w4b L8O8Tµ w4CT8c%* b $c% w4w4w4M!S!K cB-h-S! w4QV8R8$_nJ::$ -sA-c q ll-c aP w4EMD qm M~6DBD d666PF6d?%6PF66DBD SFD sD K 6K66K6?6KM ?6:(?6K?M ?6:66KDM ?6:6KD?M ?6:a+K w4w _SPܲ5-c a::$  Xh m X* uw{*awRestartplayer failed w4w4w4iSM22 w4VM]MT' w4y.lAQ.l{l|pppppp, item_get, l|, S~ Bpppppp, item_get, Vl, S~ B w4w4w4w4w4Y8k%V&$wl*lVk%\% w4b[8c w4X y8x-[  iw4]8[%@:8wZ*Z$@[%Z%Y%X%W%U% w4c8I -^6%a( 7;a@@(-^' w4d7mG .A w4D/b #'sb ?[a?%6Db ?.[6%6%q!?::$Lb #$"(b #$" w4j8e8LN!w4@w4w4Z8|hYE00rs*rs * r|* pppppp, item_activate, ||, Ss B w4h8w4w4i8w4w4N)w4w4}8lK !)lw4M)w4w4Rs8J 77 w4n8w4w4o8w4w4p8w4hw4Y*w4w4w4w4T%w4w4uG/q8Z# w4w4w4g8eMi [ w4B/N%g2IN%/{yIppI, yS{xIppI, xw{vIppI, v{tIppI, tpp, I w4x8w4w4[Nw4w4@>a8r iw4{8w4w4|8w4w4bNw4w4a[r5 )rw4@w4w4@9w4w4A9w4w4kNw4w4M/AC)A)D)~"w4@w4w4jNE9Y3  w4F9w40w4G9w4w4tNw4w4e w4,w4@w4w4P#w4w4JMw4hw4w4w4O9}H+ 2)})|){)ww4w4w4]9NC*1)N)E)A)@w4FOQ9XQ Y*  w4R9w4w4S9w4w4GOw4w4fw4w4P9ZObVM T%  w4`9\I -M' -f '-L'{*a(((;7o$ w4X9w4w4Y9w4w4w4w4U9[9cY  w4\9w4w4w4w4^9B'1w4xPA&0w4z^O`Cb#{C7|C,.unrCCJCpC.unrT %T , |CT z]T T Q]], &]%z]z]%b]z w4a9M0 -M( -f (u2a''' w4Y/]#ͩXVL%@=m=du>Su>R=&@XmVR#?q]?::$L]&$"(]&$" w4KM~Ot S w4rCPJ9(H(sT#U#&P#c s&?%-is&?%%6&?%6-i6'[-O gV#6 C?,(Bq!? w4Xw4w4LU/[T S/+rrի?(r>77'v 6 ;>)'6v 6r?%(ev 66r6v 666re666re' ((' w4w4w4ec!K Q2pV invalid state%-kF#c! w4SPM-O( -u( w4cPMrY#-F( w4KQ}#\0 w4w4w4[Pp#f[ sX!@>m>du>Su>S @smX6S :Y:$n $n $S:Y:$oYY$-^-w Y$-a-z Y$-`-J Y$7-f-O Y$S:Y:$Yo:Y:ojS?pn Y:Y:$jpj33Y$jS:Y:$ :Y:$jpj?%Y$jSVa%tm:I:$ V!P-O  :^%x-H 6b p-b 66666D?6?&?, 1=p?6?6%r6 6 6 6 j-]t prX-]_YY?&?Ap} qp?-e V!P-C'-e(-C(*::$LpS n a=} L(pS n a=} -e-C w4w4w4m&E)Im $bm~-iIppppppppN'/Q.Q.m.S \fpI.tmpNpI.logIppppppppz&/Q.`.m.S \fpI.tmpNpI.log-M'E% w4s9m9{!/w4w4w4r9w4w4@@w4w4u9`z.)`w4w4w4}9gyX.)g w4r@w4w4U 3.14w4w9"Tim"w4x9 vect(1,2,3)w4Ue/zvMp-i2z -ee IsABotza/!pppppppppppp, player, Connect, z /, Sz B, T.z-5, e bpppppppppppp, player, Connect, z /, Sz B, T(, e TzUze  w4w4w4Zw4w4~9{9x- w4A:wk- w4w4w4F)wX#6w@6w@@6w@ &w#@@@@ '6w?, (6w?, )6w?, w4K:Yv?-)Y w4@:N.4 K Z#?@@@  w4DB:D:"5!!BEGINZ#@@@@ 8Z#@@@@N :Z#?@@@DWNDWNDptest WN ?a/!R  @a/!H Aa/!s  Ba/!. Ca/! !!END w4E:w4w4w4w4C:zL L-6Yr( M-6Zr( N-6[r(-6Yr' Q-6Yr' R-6Zr( S-6[r(-6Zr' V-6Yr' W-6Zr' X-6[r(-6[r' [-6Yr' \-6Zr' ]-6[r'-6Yr(-6Zr(-6[r( w4oF:]dhvj] s] s] s]!w4 s]!w4% s]Nz w4w4w4w4w4G:^Rtp-w*A-^A-^@%A-^@ w4Y:`t,)`)Q)Zw4h/w4w4J:N:Z{ -W*'( w4w4w4M:B)QR @)B) w4iz9Jt^\ h[-i-M(D%Bppppppp, game_end, J, BfiJ w4L:w4w4O:~([ # ~(, V +  w4@w4w4w4w4R:eM 6 e,{ V  [e,+  w4w4w4w4w4U:uM TestContinueu%uu,piteration Sudu, u,  u,k...uDoneContinue w4]:hp b,)h)f)^w4X:Y Yf mTestContinue[Y ,piteration SY QY , Y , X...DoneContinue w4w4w4Z:`T/ }TestContinue`piteration S`X`, `,  `,_...`,DoneContinue w4b:io +)iw4\:UV aTestContinue/a0 UNpactor VUFr._ U*1N...10DoneContinue w4w4w4^:M*^'M*?,ii,ff w4w4w4c:ln P+)lw4e:om*)o w4`:]_d5]&u,\,^]u\ ], u, \,^]u ], u, \,^ u\ ], u, \, ^ ], u, \, ^]u\ ], u,  \,TestOptionalOut ok! w4f:slR*)s w4g:T!k* )T!)j  w4i:p!i) )p!)k! w4d:Rs7.-MR-MR-M-M w4k:^gh) )^)Z w4h:SaSTimx,x %% (? 5,-l '? (? -l S [ (z lxyzzy (z -l (z -l testswitch succeeded w4dd) )d)` w4A@w48Mw4] j:o:'ptime=U$_ss*aZ#?@@@X#@@@ #ZX $ZX %Z#?@@@ &X#@@@ '#?@@Z (Z?,X )ZX?, +H@H@ ,H@?, -zTimTim .{TimBob /#?@@@#?@@@ 1zsxxTim 2{ppp123 3zbogusVY 5zxnum345xnum999 7V 8V :-U ' ;-V ( <-Y ' =-[ ( ?-U ' @-V ( A-Y ' B-[ ( D K-U ' E K-V ( F K-Y ' G K-[ (g Jg-U ' Kg-V ( Lg-Y ' Mg-[ (f PKf-U ' QKf-V ( RKf-Y ' SKf-[ ( UV M,{gM,{KfM,{-FZ [-F(zXAll tests passed w4fw4w4m:Mw4s w4w4w4w4lw4w4V| C jH| %@| ,| P*L| &@%| C  w4s:[w4z/w4w4T M;~:2 w4u:w4w4x:w4w4\{:Svdw4VOua w4\z:}:Ozw4Oy w4}/w4w4a w4$$A;Rw4~$O w4C;bW w4D;w4w4E;w4w4F;w4w4w4w4B;H;` w4I;w4w4J;w4w4w4w4xYw4y:w4w4]k;G0~ w4O;w4w4P;w4w4Q;w4w4R;w4w4S;w4w4T;w4w4|$w4w4w4w4W;w4w4X;w4w4Y;w4w4Z;w4w4[;w4w4\;Yw4];Yw4^;w4w4_;w4w4`;w4w4a;Yw4`QYw4K;z$K%)z$)y$)x$)w$)v$w4U;w4w4c;w4w4d;w4w4M0w4w4f;w4w4b;i;F& w4j;w4w4w4w4cT0Q0  w4L;w4w4n;w4w4w4w4Aw4w4w4w4[IY0Xo$ w4yjw4nw4w4s;w4w4t;w4w4u;w4w4D} "Z)} !w4/a0 -j} ((10Rp!w4/a0 MCpQQ10D w4D w;D{ wrD=j wj*p6  6D  D)DbDP*D ~P D  j YDrDPjrDP*DPj^DP w4v;w4w4w4w4y;w4w4{;w4w4|;w4w4t@w43w4w4a0!Sw4;w4w4Bw4w4DJ "@J !w4/a0 -GJ G^a*Gs G  GW!kppWarning: VG is BumpOpenTimed. Bots don't understand this well - use StandOpenTimed instead!10U!w4/a0 MHU10D w4D C<,{,y rG*r,=GwH*rGS*$m?,,PHm$Hw.x,A* w.x,AC*$.x,A} J 2$.x,AT?,rGS*D6,  6,A  ,(D6,  6,A  ,(D6,  6,A  ,).x,AT$,P.x,AC.x,ACa G  sa*GZ¯6 6,  ¯6 6,  6 )D*6,  ,),i ?6 )6,  ,)?ZJJ:G:$,-*,P*Ar.x,A*rG+4wr*ra/!a.xr} J ;6,  6r  ,(;6,  6r  ,(;6,  6r  ,)wr4rr|$Arw*G Y,Gr *r,PGr,P*,P,P w4_w4w4Zw4w4[w4w4Xw4w4H<w4w4yPw4j0@w4w4w4Dq ""q Y&\D w4M<s\3C/a0 qs@?s*q GC*s0 10 w4J<Pw4D N<z{' 51r6'z [q q Jz w4O<Pw4w4w4Q<w4w4Ckw4S<w4d " " " " * *߷"l;?pw4\@mooomoqmmttqttqtmottottttoommq060# # ##88 6`m068 0  8660086 0 688806686 0888888888888888668888686888 w4zkw4c!! w4fT<Z<-z-z w4[<w4w4w4w4bY<{NJ -s{a/!.{ X C )N{-w( -s w4a!! w4S I1l[# w4]<!! w4n(R@" " " " *(s *"!cLEpw4a@ܠ̱eػ2['2JIﱱq,Ż/NVN֭ՍgRRYd}}u}pT' w4C^<l0s_ Bw4W[w4e<@w4f<@w4n0@w4c<w4w4G`(_q )`()A*4w4g<w4w4i<w4w4Hw4w4D{"?O +|{a(((#-w\D w4l<D \K tg*I */a0 D qpD *NIw.lD *0 brg*gD pI D 0 10 w4Nw4w4E*m<ZufA Dv!%Z  -A]Z  66 wt*66Z  6t  w.Z*::$@ Vw@ *r@ XZ@  yZ  @ @ U.Za  ::$$U?.Za+.Z U$.ZK.ZANZ(Za  u!%(-AZa+u!%A-n(Z  B*@-Am:ZI:$6]%`9]aZ  `Z  Z  a`a9Z  -s$6Z  -r$6Z  @-t$6Z  ' w4n<w4w4qw4w4w4w4Yw4w4s<w4w4aw4w4t<w4w4v<w4w4w<w4w4bo<vNKIva/!vb? Nv-a(' w4x<w4w4w4w4fy<}<%Y-w-wW-wS %WS ,MwS |*%S |S  w4~<w4w4S w4w4Jw4w4_ |<V%[1 -w /V-wVa (~{/%~{#%::$w.V* H.V{//a0 U`|W`N{ w`z 10z z /a0 U`87|W`N{ w` z %810w`*iVa/!N.V(` uV*!w4Va/!/a0 }*}VV%10//::$.V4 ppTeleport destination for V not found! w4<Mw4A=[w4{ w4@" " " " *m*"ow4^m@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>$ w4D @=q{z-ww&q@*&q@a/!R"|W&q@N{6 6q  )q)i q  6ii(q(%qrg*\rg**rwI *CI   q  g  q  I g w4@w4w4H=w4w4iw4w4j @w4w4P=w4w4L=w4w4M=tw4tw4u_(J_(?9 u w4R(xw4B1w4@" " " " *c*"VzPpw4s@,E,+;xi+;2K\Biiiy˥}X;, LikQiӬ;;;;,zyXdL;;;LzS̐B,,܊^EB;;Bz,aՊdOB;;;;iXL}}}zd^OL;6,\\,zz}zgzd\;;,,#iO }zzgddzdO^dir6izggdz;r}z'#O,OOOd,#d#Lzr^E,EO;;O;##  w4uO=J R(?,9 u w4@1w4w4w4@" " " " *i *"Upw4Jx@ 'Ӈa \՗VjIv<vήvvk/jƦecƮ/qϱ*~}L}}'v*Ie}g}} i컡tjR }_}HRR  w4w4w4X=fw4Y=fw4Z=fw4Q(w4w4J1w4w4up$JiB o$q$?,9 /a0 pQ(p$9910u w4[Uw4^H cjXj ~H .Pj H H }H j &j ~H .H  w4w4\w4y _=uL w4YQiv* -g -g'/a8 _bXw_y_  Xp?yyyp|?p_(b_l D|i%_  ի?_)_(yի|eyf10-g( w4DK*-}Q'!W!w4qW(q!~  w4Q1w4w4dw4w4f=y]}?)CV'wC*C-Ca/!Iw *w rQ* rQ%L3CyutrnCOyutrnCOyutrnCCU w4uhDdćKx!w4x!,I _}h@VIw@*2@-@a/!Iw *w rQ* rQO3@h-{x@ hx-{2@ hx-{@@UQ w4w4w4w4w4r=BMKW )B)|(4w4]=k=D w4w4w4j=m=C w4w4w4ll=o=X.-y a  gw%*/%   (%(a %   % #??!W-y(-r ( w4w4w4zn=iz,Wi-O-m6'[-O ?T 6 ?,d ??% L=b-m(o$vv6'[-O6 ?8Z8??,?6 ?@@,wiP*aiP$ZvwiO*IaiOvwI*IFZ-m'6'[-O T?-r 'Ť??T33s?TT ׃??Tp}?TUi-Cib% ,d* #iU "w4w4w4x=EwJ )E)D'4w4w4w4fp=u=RC <%W( % #??!W w4W(w4w4U1w4w4vt=OoZ KO??-r (e6 ?  D?&6 ?,% #!~r=*-[ a/![ :I:$o$Ijw.=*w.=8=Q D?D?&6 ?O=?% ? !~6 BS?6 ?,Fb6 ?,Fo$IBw.<=*6 ? u.<=??=C D?&Ou6 ?,% L> !Q6 B+?6 ?,F:6 ?,Fo$I%* "w4z=IMIń )I)G&4w4w4w4{=LKH| )L)K%4w4|=`iD˃)`)X)V)P)O8w4}=nhC)n)m)k)d7w4B>wfB)w)t)r)p6w4w^(E -H O*!w4/a0 |*N|D.D10k6'[-[a O%Oh$Q a^(Q ni$?,dQ I j$Q F{?333?{Ora w4cv= Wݥ w4W5V9pG ow4z1IL{*4w * -M' -f 'a(((;7o$ w4D>aA #))~)}){)z)y)x5w4ES1J+nEgY%FY,;{YL YCY,lY% z__%L  w4E>C `@H )C )B 3w4F>F _? )F )E 2w4G>J ^> )J )G 1w4cRO [=()O )N )M 0w4~=F(~ -H O*!w4/a0 L*NLM.M10k6'[-[a Z%ZD(gaF(gnE(gFH?333?HZra w4e(C>J>@ Y% p%Ap,{pL _ppop,zpL p%_pL v w4Z1w4w4@w4w4f w4w4O>V W3} )V )U w4@w4w4P>N>V2}#w4T>d Q1n})d )a )` )] )[ !w4B]1`JuF PB`N`-YgNw]*`v!%`v!ND`  `a/!P.` P`  a;D`  P]a:D`  P `a/!.`-| -m$`a D::$RVwR*rRX`R y`  RRUL6P%.` P.`[DP.`K q!I.`a D`a+P`u!%`u!N w4eB(g <-[w.g *g ??,(-r (R6 @g    g   BA@@:I:$6 A-C an$$>-C '6 Ro$a>(%.g  w4@w4w4om M0|)m )i )e w4w4Uw4w4w4Y>[@" " " " */t"*"`pw47@3[ӎ<ye$VS"j'KȏjIзVepvNI=33'eNSKjKBc$Nv3Vk3Vr>3cSI)py$I?I>?Qc/>$2V[w4| [w4l>U>y'{ w4Sw4w4w4w4 w4w4]>w4Uw4C(AQw * a w4w`>b>f w * aw w4w4w4a>d>k)< w4w4w4c>f>j-ia w4w4w4e>h>|2' !w4i>w4w4j>w4w4w4w4j1w4w4@?_>a &{ w4n>w4w4qw4w4w4w4{1G. w4C+r>[Nx$aL>q!i Tw4w4C+s> Ls w4t>w4w4u>w4w4v>w4w4w>w4w4w4w4q>>ivaa@la@m-|  -M6'[-O6'[-Ck Tw4pw4B(z>[JE6'[{$6'[u$9baBa@(Ha w4{>w4w4|>w4w4w4w4y>kh w4}>ll w4~>p:"-| U aA( w4A?o>J  {w4C?n Hsz)n w4w4w4E?r Gy)r w4F .w4XB!C x)B!) )x )v )u )t @ w4G?@Iw4H?@Iw4I?@Iw4J?@Iw4K?@Iw4L?@Iw4M?@Iw4'@Iw4D?.w4R2H2D w4TQ?j w4w4w4P?S?i, w4w4w4R?U?q K w4w4w4T?W?m!h w4w4w4V?Y?p" w4w4w4X?t# w4Z?Y$ w4[?{% w4\?W& w4]?_?t ', w4@w4w4^?a?I(f w4@w4w4`?R) w4b?d?G* w4e?w4w4@w4w4c?g?c+ w4w4w4f?^, w4h?j?A. w4w4w4i?^2@;9w.0u*.0uD w4k?m?D8.0uT(-E trT*W-](WLbq!w4::$W`(a w4w4kw4l?Z BHpQ-})6Z k=,6Z k=,6Z k=,nZ kZ k w4r?Y!Av)Y!)X!)R!)P!)O!)L!w4N2.w4n?\CTk:\:$WD ZS:\:$&YG PG &G VZ:\:$(YG G VG &Z:\:$ -E 'jWZ:\:$%-E 'i{Z:\:$'-E 'q{Z.|:\'&-E '+m{ZZ|:\d$&-E 'Zp{i-v*^ w4|?\!~tu )\!)[!w4w4w4u?@w4w4v?@w4w4w?}kw4~'@}w4d2g2Dvw4w4w4{?w4+w4w4w4~?y?}tw4w4w4@@n!|s)n!)l!)j!)g!)a!w4w4w4B@q!wq )q!)o!$w4w4w4| ~!r%q)~!)|!){!)y!)x!)v!w4w4w4C@w4w4D@w4w4E@w4w4dw4w4F@w4w4w4w4abn w4t[\( |6u[*6G[%6I[*6J[*6L[6^[6c[~'6d[-6Y[( w4w4w4K@nx56un6uo6Gn6Go6In6Io6Jn6Jo6Ln6Lo6^n6^o6cn6co6dn6do6^n6^o6_n6_o-6Yn-6Yo6\n6\o6]n6]o w4w4w4w4w4M@Q@JG$ w4w4w4P@S@bHR w4w4w4R@U@]I{ w4w4w4T@W@IJ w4w4w4V@Y@HK w4w4w4X@[@wL w4\@w4w4]@w4w4w4w4Z@_@^Q w4`@w4w4a@@w4w4w4w4^@c@YR  w4d@w4hw4e@w4w4f@w4w4g@w4w4h@w4w4@w4w4b@p*|V F.  p*D.-u .@ w4w4w4l@@w4w4w4w4i@n@Q` ( w4o@w4w4w4w4\w4w4O@w4@" " " " *-=*"#1rpw4@Ic>v>$V/Ӧ>$>$ڀ>$cҘN$u' ΦS<Ęҋ/,S$v6z+jSccSSI>NcjcjjvSSccjvIIIISIIII>>?>SSSSII>cĮcS/'>>/ScjjS3)'  '    '        !''      '%    !''   '%'.   "%)=J)2   )=JMa   u w4w4w4s@w4w4w4w4y2w4w4y@u@dm w4w4w4C"x@fm w4w4w4w4w4w4w4DD"0?-n\7:D:$-M(-w'@$D w4}@b \@tj*d */a0 b qpb *NIw.lb *0 brj*jb pd b 0 10 w4w4w4D ~@f{U> -X  -B*>:D:$f-*-nZrj*\grj**wd *Cd   f  j  f  d jZ:D:$f-F rf**fdf-Y'fTfv$fx$f9fW %W ,rW |f%fW o w4_ @Vl w4W w4w4w4w4@A^ a A^ %?^ ,5w^ |*%^ |^  w4w4w4DAONw4FAHAs@@w4fIA -n-n-n w4JAw4w4w4w4GALArL@w4fMA(-d-n-n'&-d w4NAw4w4dw4w4w4w4KAQAp@w4fRA -n( w4SAw4w4w4w4PA@9 -n(D @$w.@*.@- q$w.@*:.@n:$ $a@t' $' $w.@*.@sf  w4w4w4w4w4A3k#-\Ne$@=m=du>Su>R=&@\mNR#?qk?::$Lk&$"(k&$" w4UAw4w4w4w4Rr'@Zy-@(B %eB ,[wB |*9B |-@'%B |B w-@a{( w4YAw4w4w4w4| ZAi* -n :D:$?i*f wN *yo ?%e$] o  ] $*!w4/a0 T*TN N 10{{N %  {-X a( w4~}2SFژ w4\Aw4w4aAw4w4bAw4w4Tw4w4w4w4H3w4w4w4w4iAeAhk w4r'l % G9l i*!w4/a0 \hg\G*\l l %10{{l %  {-X a( w4w4w4kAhAij w4{)gAkN$kki9ki*!w4/a0 lhglG*lvkk%10 w4SJj w4mAqj w4nAPhj)Pw4sRgi- @" " " " *:I#*"]{pw4@Ic>v>$V/Ӧ>$>$ڀ>$cҘN$u' ΦS<Ęҋ/,S$v6z+jSccSSI>NcjcjjvSSccjvIIIISIIII>>?>SSSSII>cĮcS/'>>/ScjjS//3vڋ''$>vvS'vVc'-3ڀ$'$ٸj  / IIv  v''vc'> '%Ě lI!)j~3f €ct 2>"%23<3 2:B)2  '-  :BMa  u w4w4w4rAxfsh)xw4xAerQh w4oC d2 jC  w4sAM" C j w4ftAn'/M:C %:C %E-{ {lN  l*!w4/a0 D*Dn'N10-{ {zC $Bone- $Btwo- $Bthree- $Bfour- $Bfive- $Bsix- BRC -~z~~%i%V~~%i~pp~VB~V,8N  ~ w4N3@ w4w4w4zAkdq h)k%w4w4w4{AyAcpgw4|Afbog )f)g&w4AS`nlg)S)V)X)dw4HB@ @" " " " *7F!*"cpw4@Ic>v>$V/Ӧ>$>$ڀ>$cҘN$u' ΦSĘҋ/,S$v6z+jSccSSI>NcjcjjvSSccjvIIIISIIII>>?>SSSSII>cĮcS/'>>/ScjjS3)' j' 禮$'ڦަͮ '-$/ " '$  v2    :J)2   22BMa   u w4DBA\mf)A)I)Qw4fcAB%l'q!K w4l'w4w4w4w4@BK!v!l%yl,olc!w4alo'/a0 dlcnd %10lu! Tw4w4EB@Zg f)@w4FBtXfe)t*w4OBfVce)fw4w4w4IB@ w4W$@ w4NB Vw4oEd<rE*EA:-k'f=,v=, w4fKBMB#~-[$bV{wb*dba/!.bEEfvKbbUL.\$rL* LEEfvK-X$a(((v! w4\$w4w4U$@ w4QBD"UbHe)D"w4w4w4WBb Sa e)b +w4CpBV3*1 -g' w4w4w4fVUB@O V!w4/a0 {O VF{ h*10O ,O V!w4-y)O %a((( w4h*w4w4w4w4[BiQ`d)i w4X3w4w4w4@" " " " *8F*"4 pw4*@Ic>v>$V/Ӧ>$>$ڀ>$cҘN$u' ΦSĘҋ/,S$v6z+jSccSSI>NcjcjjvSSccjvIIIISIIII>>?>SSSSII>cĮcS/'>>/ScjjS^EL3/O)b' }Y  ' g  '  .nY "  }Y "%'    sn!' kf.  "%%'O9 %%'.  }R '%)=B)2$YH )=JMa   m w4]BO_d) w4w4w4`BdL\:d )d)zw4a3N"" w4rw4bB_H[c)_)K)Lw4Pw4w4gBFXMc) w4w4w4Rq)w4dBfBp5B@w4R]0]x8h=]a/! ~k]0 V$hh  #H w4aTrRb)Tw4@w4w4eBjBmB@w4R_'<m8o =_'a/! ~kkwo *o 2*Ho    w4S MClg w4 w4wQw4iBnBlLq @w4RoBI, 8^'a} w4^'w4w4Qc3d3$ -g' w4mBrBn[ @w4RsBU 8Q$UVwU*lU-Ua/!.U U}UUU  w4Q$w4w4h3w4w4lBwQw4qBwBje @w4RxBbG "8rrMM w4rw4w4P} ~  @ A w4vB{Bi@w4R|BnX 8FwF*F-::$/a0 }d*  d_%Fq!w4Fa'((F-H(FddFo$FK?F`F-M 'FMM10 w4Fw4w4k w4w4}Bw4w4~Bw4w4Bw4@" " " " *.` *"5ow4c@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# w4Otw4JCtBg!$n> .r^* n$w?a^$?n Q?n @az$?n Q?n @ w4mw4w4DC w4w4ECw4w4FCw4w4w4w4V' w4TCHC_ w4h>w4KC>w4W!4p3e C w4LC>w4~w4w4NC!>w4xw4w4w4w4PC>w4s3RCq w4@Dw4w4WC! w4R'! w4v3hA w4SC!>w4YC!>w4ZC>w4[C!>w4\C!>w4[TDXz[ zo)[D-5'D -fD-5-}S稨D /logged in as administrator fromD[!TAdministrator logged in.DD /became a server administrator. w4]C!>w4_C!|w4`C!|w4cC w4w4dCw4w4eC0w4fC0w4gCw4w4hC w4w4iCw4w4jC0^ w4kC0w4lC0w4Y0w4A!>Rw4L$ w4fS@w4w4^CU WtrU -5U -5(U  -fU -5wU t!U t!w4U AmSU  _U lU  _mS-}SU  /logged out as administrator.1Administrator logged out.DU  /gave up administrator abilities. w4M w4(Qw4Q!Qlw4sC!Qlw4tC!Qlw4Fw4w4Vw4w4~Crl w4DC4|" +-`$-w'-y'*-y-w'wM */a0 ||-Or|O*|OM Or|{ *|{ M { r|P*|PM Pr|z *|z M z 10|D w4~p){COU'| w4@w4w4zCNRoPgg?NL?M'?L'NYR'g w4pw4Oqy u= w4H4}#'Hw*tserverquitma*w*tserverquitma* w4gw4Zw4ADw4yw4w4lQw4lw4EDw4Cz9w)WD-{(-]DK*IDJ*VD-}(-\ w4FDw4T4P ]baaP ub|'w.a*@P .a[P b|a.a]P ub@a w4w4w4Kq)[ 'KP.%-vy w4BD!w4LD w4w4e w4w4d!Xw4}! w4w4PD w4w4QDw4lc"_i${N$FM$-p'-M'-W 'z33?a(((o$a(Z$ w4SDmP%<$*%mcmNq!F w4RDw4w4UDw4w4VDw4w4bw4w4WDw4w4oQF&+& Gq!_)a w4W4jhR~ Xj w4YDw4\Dw4w4w4@`Ds*Y7-x5{x. p|xUw*W* w4w4w4 w4w4w4w4TWn- w4cDeDPX. w4fDw4w4gDw4w4hDw4w4w4w4dDjDX. w4kDw4w4lDw4w4mDw4w4@w4w4Y4u&`2~-l*@-5::$h-u&z@ /yz'( w4w4w4g4bDKz w4w4w4x&sDZ/ w4w4w4w4w4c4f; w4w4w4t&k]2 k%%R kP OkY[wP * R %R P eR Y[P P i3R  w4  w4w4xD w4w4yD w4w4P w4w4 w4w4zD w4w4w4w4wDr&O42w*HOr&T q&9H*-iVrH*i*H xT xT iHFHwFi*+Fi xT xT FFiiFiFiH w4uD_ ];}Z-v/a0 _ YX_ -V_ -o_ a10/a0 [z[S10 w4}D w4w4@EI9`=i CI'Fi9IPC:P&'H(:t%I-}! :t&I-S!:t,I-h!!:t,I-Q+I-d!::$DI-b!.::$::$+I-^!::$(-cw.I*.I-(IZ!(I-Fu'I-~a$I-b$' w4Hw4w4AEw4w4|w4w4Dae%8Z !Unp&MZ !w4J Z  DZ %bZ !Ua` a_,d` P` PaP` a`  w4EEw4w4GEw4w4s4m4J z w4` w4w4HEw4w4FEh x :Ph !U%Hh !w4J h  Dh @BS' w4KEw4w4w4w4LEPEn; w4w4w4OEh&;w*h w4QEB/<w*B w4RED6)=w*D w4u4X oya w4zc zD}>c -O6'[-Ob7??,?6 wc P*ac P$bwc O*fac Owf*fF@b "w4X!w4w4w4WEw4w4UELPWz@L-w.L-.L3%$ s.L*!w4/a0 I*ILL%10'( w4w4Iw4w4eRw4w4zw4w4Uw4w4li&`EX_E5G 6G%BCBCa+Ga@( w4Gw4w4aOw4_EFosFe-U (F%cF,YwF|*F|a/!%F|F w4Tw4w4RbEGzJ:i:$z33?i$H-Q?-bapA(Ha B( x-Qo=baxa@@' w4cEw4w4~MI-H(-U ( w4v4I$6JFE@pI$BlBCF=|CJ$F w4]KK-v'I.- J !w4.tJ  w4hEML]-v([w.*.- J !w4.t!w4 w4Sw4f&mE_NHafaK$a Cq!- Tw48w4ND-M' w4lEW MnN\-U (W %ZW ,PwW |*W |a/!-U 'W  w4jEw4kEd&qO" w* q-d& w4w4w4oEF Pw4Ww4ww4pEw4w4nw4sEw4}w4wEw4tEw4w4B@w4w4C5qbSx Xq w4WFm9vA w4xEw4ww4w4@F w4w4oew4~Ew4w4CFew4Bew4AF w4w4O w4DF w4w4iew4FF w4w4\ w4w4[w4w4JF w4w4KFw4w4LFw4w4~P^wA w4K5OwN?Gw*tmapchangema*w*tmapchangema*ProcessServerTravel:O/a0 k w.k L*k KO$-`&k k o10::$ w*X ppppppppppX ?Skin= ] Skin?Face= ] Face?Team= ] Team?Name= ] Name?Class= ] Class=::$::$i w4MFd " " " " * #'*"V!A ow4@                                                             w4Mw4TFxu)x)v)u)rw4UF|F9)|w4VFML)M)L)K)H)Dw4`Fbt)b)])[)Uw4}Av w4l w4w4ZFw4[Fw4_&w4w4w4^Fw4_Fw4_w4iFM}B2)M)D)B)~)|)r)o)m)h)ew4bF@w4q w4 w4w4cF w4w4WI" ;7o$am w4dF w4w4fF w4w4gFN w4hFw4w4w4`w4Z5iH!nwViI n  w4c5J[Za::$  .J?r * J%32 !u  w4w4w4jFw4mFw4pF0w40w4y rE|ey r.* wW*.. ZWr*aW. Nc.nq!Fr.yq!F w4kqFf{,HkFw.*r..* w4p)rFHh-O  r* v.wv*VvbvY -k'qDvR::$ q,-O ' -krvL*. Y#3:Y %-^&-v wt*ZZHw Do-g-g'~$A$~$Y $0:Y %Rq%HLHw?,?Z?L HwL6fyHf?,?Z?L HfT\&HLHw?,?Z?L Hw?q6fyHf?,?Z?L HfTHJ $HYtZHJ $;-g(a   G A . q%6A 6 6A 6 qa+A Ha(  w4w4w4nFw4tFw4uF w4w4vF_w4wF_w4qsF"qcm?X QwJ*bJvE$Jrwc *]c vD$c r w4yF{FZ\( w4w4w4zFc,-B-B -u w4U|Fu k\ mu XA.u ZwA*f?, R-MrA*1A.A{-Q-b-BrA*>\ A.%>\ Am?>?A{?A.L=ru *u X >@\ \  w4xF w4w4Aw4w4~F_w4@G w4w4}Fg)i#J'w*.%g)A>X L= w4w4w4w4w4BGFG^# w4w4w4EGHGE.$ w4w4w4GGJGJ!$ w4w4w4IGLGb"$ w4w4w4KGNGa$ % w4w4w4@MGCb+m%c?rCe.C-B0.C-Q.C-b'n.w*P.}.Cn P%(wnCn-{ yn`w * AC.w * AC.rCK*n Cg!-n%OCK%**CCaCYCQ'Lr*( bC w4AG_w4Pw4w4PGBgw4RGw4w4OGh nLZ):h ?,6~6f-O ' B-O (h ?%6~6~Ga?6~L6~6~6~)\?6~6~6~6~h 6~6~~?,d6f6fh  w4SG w4w4t&TGbEl,:\:bw*.%Gr*_ *a_  Ebr_ *. p|__ r** Eb w4UGw4w4_ w4w4WGw4w4oVGud/Y{ GTau "TNNT**x-Bq!_TTfT-Q'T-b(T Pup.Tp%up eup Mu@u-{ p yupZ$p w4YGBw4Tw4w4[GBw4]Gw4w4ZG\M2><w.\*j%gj,2]j.\Lj=j jP j:j<j,2j.\L!w4j.\LP  22j,2&cj.\Lj.\LP P cj w4^Gw4w4`Gw4w4aGw4w4bGw4w4_GHe 5 rW* .H ZWNw* }naWH Nc.nq!F w4cGw4w4dGgGz~7z%a/!ib*xqw*.%hr.nx<j w4hGw4w4b*w4w4qw4w4fGRy<9rR(NrR*RRB'RzzRRRq!w4RQ'RR(q!w4( w4eGw4w4mGw4w4nGw4w4oGw4w4Rw4w4kGw4w4q)jGK L;#a/!K zK iQr.w.X*r*.%K = W>w*cLEOwc* EK K EQOc w4pGw4w4rG:w4cw4w4sGw4w4uGw4w4Ow4w4vGw4w4TqGME)>ea M X X Y $M*Xw*n..%TM w4xGw4w4lyGD9W?$lrUd-m-l w4{GN=? w4|GpRH@p.-Mp3%!:pz:pz-M(pzpz w4zG:w4}G@HsRA' w4AHw4w4w4w4GxUA w4BH|VB w4~Gw4w4w4w4{ GH@n7D' w4HHw4w4w4w4DHw4w4w4w4} OF w4KHAF w4LH#d{GK .bK s K  nm{j  G 6fn6fm6f{q K  ~#jDg'-@$a# jq  w4w4w4w4w4e]J|#K-kF#|# w4jw4w4IH:w4RH:w4SH:w4TH:w4UH:w4MHt~tI[ .b[ s [  S x \ f   G 6fS 6fx 6f\ q [  $tIf D?,g((Wf իt?x ?իt?\ ?S 9q W?'S j[ ]r}Wf Bjr}S x \  w4VH:w4XH:w4YH:w4ZH:w4[Hw4w4\H:w4]Hw4w4^H:w4_H:w4`Hw4w4WHcHBL w4dHw4w4eHw4w4fHw4w4gHw4w4hHw4w4w4w4bHklL-sq!C k.r.*w*.%kNkF-sq!C:kv% j)8$:kx% k)8*kNq!G ?w*.%wkq!Gb:kv%8$:kx%8*q!G w4aH w4iHnHk Pal Tw4 w4{ mH$P w4w4w4} lHoH*P w4w4w4kHsHg Qal Tw4 w4{ rH$aQ w4w4w4} qHtH*Q w4w4w4pHwHG R-h(=w*.%.Fb:.v%$:.x%*v!8@ Tw4w4A 8WR@ w4vHxHQ R q!C' w4w4w4uH@Id 2UU<a-sq!C-B'q al Tw4,w4{ {H$PT w4w4w4} zH}H*"wT w4w4w4|HHQ&T0$-B {@?q!C,-s'' w4w4w4~H/7U -s( w4yHHICPnW0U a.B Tw4 w4{ CI$AAV w4w4w4} BIEI*AJV w4w4w4DIGIQEoV,.a.' w4w4w4FIKV:-s(Y $.a. w4AIJIaVW w4w4w4IIyZ XXAa/!n.R.t-B(T q!d  w4KIMI_ fXy w4w4w4LIOIQkY -s'' w4w4w4NIU qYYN:t!w4a%t!Ma&t{>La!o?L= w4PILyZa&!Mo: w4QIT ~UZ:a!M?a_&$.s  w4RIq Z w4SI@Z w4}w4w4jH w4PH~#BKLB$@=m=du>Su>R=&@KmLR#?q~?::$L~&$"(~&$" w4P&-w4@w4w4VI w4y UI|y |. w4w4w4ZI w4w4w4}#`IMJ"  w4aIw4w4w4w4]I w4~6w4w4Ew4w4bI w4l&wjI-r( 9w4i&l%Z PlKd.lmw * A.lw * A.l-xr.lC*.lCK/-x-D.l-xKy[rK*.l g!-.lOK%**aY @.uK|.l w4eI w4hI w4~gIo ~}% w4fIlI|vU  w4w4w4kIK} |fw.*-x(.Lr.C.Lr.C.C*w * p.w * p.Mwk*.Ok%**f.  P&aL$a w4f&mIoIlw4yyKCw.*.-x-D P% y w4iI w4pI WQ" " " " *.V*"뇞ow4@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$ w4qI w4uI Dw4w4w4U.Rk -wQ *t.R ZQ Lt.R Zdrt*33>m~t.%mt.t{m?>?{?t. w4`w4w4tw4w4wIw4w4}#vIeb0re6ae r.eQ c.{'w * Ae.w * Ae.;reK*. eg!-n.%OeK%**eeaeY}.e.eQ'r*( be w4yIw4w4w4w4zIC{L_!.C(.C' w4{I w4w4w4}IW)}VQ ;.{(.W)7.{.{' w4w4w4w4w4w@J@d`& wQ *EaQ @ "ENNE**E%@.E..Ec@ NEEq!w4 Gq!_aEEw@.E..E w4~I w4Ew4w4Jw4w4FJw4w4sPw4GJ Ww4OJx6P;' w4IJw4`w4WPw4w4w4w4MJw4L7Og; w4RJ6w4tvDO'D,(wDt*w.@ D*'( w4UJ5w4w4w4tRw4w4VJ4w4WJ3w4^J2w4F7XwXs*RaXs X  [.Ryw[*[f[DwR*Ri$Ro$R-H'R  X  ?w[*[ q!-!EdwX*;wX iBX-os X  QXs ?%Q  X  s ?s ?16Q  6Q  6Q  X]dQn%Qn&X*XC*[Xw[*[a[[ w4w4w4H&[JyL w4\Jw4w4w4w4rO7w#(,&r r?,ow# w4_J1w4EK0w4G&aJI ^" a w4bJw4w4w4w4fJw4w4w4w4@"jJ@ w::::$ 3o$*2*!b  w4w4w4dJ@w4w4Dv#" A%6'[-[a#D w4hJs#n1 r#CBs#?,P w4^U[rp: -q' w4w4w4w4w4gJ@w4w4w4w4t#wJFt 1w4R8 q![ w4H&pJQ%>/0r.Q* ..Q-a w4e w4w4zqJdzHqDd-O L> lo:?,?6 ::$wdP*adP$lwdO*^adOw^*^F@l*-S-S(-e'-@(6~%6~D?6~%:a L>:q![od-Cdb%a "w4rJ w4w4tJw4w4uJw4w4sJjG B&$GE6:6:'6:'6:6:'6:'{D?u#v#::$UA?,(a@' w4oJCK[w4t#SCz  ? SS v -Sv?-S(-e'-@(6~%6~D?6~%6:D?6:@?6:D?6:@?6:D?6:@?.6 ?,26S333?o$-h(v?,Pz?aW$?? CY?>aU$?? CY?> w4vJ w4w4w4w4| yJ}J a w4~Jw4w4Jw4w4@Kw4w4AKw4w4w4w4R|J  ba w4BKDa?'a'(( w46w4w4DKw4d " " " " **"capw41@ `` `` ` ` ` `mo`oooo`0 o # o0 0   6% 0 06  6 0 8 8 w4Z7^7~yR was killed by R  w4W7w4hw4pw4IQw4w4JKw4w4KKw4w4LKw4w4oL dUv!'m<A5-nh?z?Khz@$ w4] NKQ)'-hzQ)L Xh?h?v!'UwF*FChhv!'wF*FC-R)AChmz?% h?& h?%A$ACm w4GKc7F0 was killed by a   w4OKRKGSr@w4f{%LHwF*FCF{%FHz?u!' w4e7w4w4w4w4QKVKua @w4fz%ZHwF*FCFz%FHzu!' w4PKp#Hp#Ko#$' w4w4w4UKZKfo @w4fy%h JwF*FCFy%FHz?u!' w4h7w4w4w4w4YKaKg w4fx%v# _wF*FCFx%FHK-nzVz?u!' w4WKiKN ^ w4w4w4o^Kq#v9 _wF*FCFq#FHK-nz?Vzu!' w4fLo$am w4w4w4]KfKh`@w4RI :c@&v!cL z?aL ( w4feKn#"cwF*FCFn#FHz?cL aL (u!u!' w4l7w4w4w4w4gKw4w4kSw4w4lKiw4mKiw4iOw4m#oKK?m#k#  w4@w4w4qKKw4rKKw4Kw44w4w4sK6nS"@""@"**ZRR"{pw4 x@&&#&&#&&&#&++(,+(+++(+#(*+(+#+#(&+&+&&#&+&#&&+&++#+(++(*(,*(*+*++(*,,%**%,%,,%*%,(%+$+(*(%++*+(+++(++#+#++*(+((((*((,$(*(,(*(*(%%,%%(*,%%.,(*(,(,*,((**++(((*+(((((*(,(*(,(*(*(,*%$%%,%,%%%%*%%,,.,%(,*%,*+,+(+++*+(*(*+,((%%,$,(,(,(,(,%,,%,,%%,%,%%(%%($(,(,*((+,(+*+(+*+(+((*.*%%$,*,(**,(,%%%,%%%,%%,,%,%%%%%*,%*,((,+,*,*(++(((+*+((,%$,$,(*(((*+,%,%,,%%%+(%*%(*%,%(%*(,,,(,,%%,+((+,+((+(*,*,*,(%,,,,(,%,,%%%,%,,,*%%%,,,$%,.,(*%,(*,(,(,*(+*+(*+*(+*%%((%(*,(*(*,(*%,**,%,,,,,,$(,%%%*+%*,*%*,(,(,,*(,,*+((+,(**(*%**(*,%*(%,(*,,*,%%*(,,,%,%,%,%,,%*%%%%,%,%,%*%,,%,*(**+(*(,(($%(,(,,(,,*,,((*,(,,(,***%*%*%,%%*%*%*%**%*,(,%+,(((((+(,*%**%%,(,$%%,*(%(*+,(,*(*,(,,%,%,*%,%,$%*%*(%,%,%,**(,+*((*+,.*%,%,*%,(,,%,,(,,*(,*+(,,*,$,%$,*,*%,%%%%(%,,,*,*,,,%+*(++((,,(*.*,(,,,%*,*,*,*,%,%,+,*(,%,,%*,*%%%,$%%*$,(%%%%,*.,%*,,(+(*+%**(,$,($,$,*%%(,(,,,*,**%%%%*%,%%,$,%*%(,%*%*,$,,*%%,(+(*+(,((,($,*,$(,,,%,,*(%%%,(%,,%,,%,%*(,%%%,*(%,%%,,(,(,,*,,*+*(*(,*,*%%(,,%*,*%,*(,,,,%,%,%,,(,%%*%%%(*$,*,*$%*,%,%*(*(,(,,*.%%*,*,%*%%%,*(,,%*%,%*,%%%*,%%%%$%*,%,%*%,%,(,%,*,*(*%*,*%,%%,%%%,%,,,%,%%,%,%,%,%%%%%%,,%%%%%$(,*.,*,%(*%%*,((,(*(%,%%*,,$%%*%,,,%,%,%,%*%%,,,,,%*$,(%%,%(,%,*%,,$,*,*,*,%$,%*%,,,,%%,%,,,%%,%,%,*,%%,%%%,,$,*,(%,$**(,$,*,*,(*.%,%$,%%*,%%,%*%%*%,,%,%,%,%,,,%,%*%*%*(%,$,*,%(,$**(*%(,%$,,(,%%%,%,%%,%,%,,*%%,,*%,%%*,%%,*,(%,,%,%**,%,,*%%%$*%%%*%%,%,%,%,,%,*,%%,%,,%*%,,%*,$(%,*,%,,(%%,,,%%,*((,$*%,%$,%*%%,*,,(*%,%%,%,,*%,,,$,%,*,%(,%(,%$,$,$*(,(,,*,%$%%%%%,%%,$%%,%,,%,,%,,,%,$,%,%,%%**,.,*(,$,%%,(+(,*((,(%%%*,$%$%,%,%,$,%,%%,%,%,%,%,%*%*,%,%,(%,%(,*,,,,%,%,(*%*,*(%*%,%,%*,,*,%,,%,%*,**,%*,%,%%(*,*,$,,%%,*(%(,*(,*,(*(%%*%%%*%$%,*%%*%%,%,%*,%%,%%,,,%,*%*(,$(,(,$,$,%,,**((,*((+,**%($%*%%%,%%,%,,$,,%,,,%*,*,%$,%$,*+,*(,,%,*.,%*(*%,(+(*(,(%*,%*$,%%%,%**,*%,%%,,%%%,,,$,%,*(,,,,$,%%*,,$,*,(+,,(,+*(,*%*%%%%*%$**%%,,(%%%%,%,,%*,*%*%,$,,*(,(*%,$,%*%,%*(*,*,(+*(,%,$,$%%%%%%%%,$,%,%*%,%,$,,%,%,,%,,$,(%%,%%*%%%%,(*(,%,(,(+,,*.,($,%$*%*,%,%,%,%%%,,%*%*%,$,*%,*%,*,%,%,+,%,*(*,,*(,(*(,(*%,$%%,$,*%*%**,$,*,%,,%,*,%,$,%*%*,(,**,%,,(,,%,(,%%*+,(,%*,%*%*%*$,%*(%,*%,%,%%%,%,*%*%,,%,%,*%,,*(%(,%%*,%,%*,*,,(%,**,$*%,*(*,%%%,%*,%%,$,%,%,,(%,*%%*%*%*,$(,%%%%,%,%*,,(*,,*,,(,,$(,*((,*(,%,%,*,,%,*,%%,%,%*%,%*,%(,,(*%,$,*,,*,*,*,(,(,*(,*,,((,(,(,%*%,$,%,%,%,,%,%*%,*%,$,*(%*%*,,*+,(%,,(,*,(*+%,*(%(*,$,%*,*%,%,%%%*,%,%,*,*,**%,%,$%,*%,*(%%,*((,*,*,*(,+(,(,,*,$(%(*%(%%,%*%%,,%,$,%,%%*(,*%%%,*%*%*%,*%,*%*,*((,(,*(,*,,(%%*%%,*,%*%*,,,,(*,%,%*,%,,%,*,$(,%,%,(,%(,(,(,((*(+,(+,(,$,$,*%,$%%%%%%%%,%*,%**,.*%%%*,(%$,$,,*,,(,*(*,(,,*,,*,*,%*%,$,%,%,*,,(%%,,*,,,,(,%,$,*(%*,*,,$,(%,$(,(,***(,(*(,,$%%,,%,%,,%$,%,%*%,*%*,%(,$,(*%%,*(%,.%(*%,*(,(*(,,*,%,$,%%%*%%%%,%,$%,%,%,,,*%,,*,(,*,*%*(,%,*,%,(*,*(,,((,%*(,,%,%*%,%%%%*,(*,*(%%%,,%*(,,%**((*.,*(,**%,%,%*(%%*.%,**,,(,*,$,%%%%%,*%*%,%%*,%*,(,,%,%%%,%,*(,,(,%%%,$%,,,*,(,,*,(%*,%(,%%*,$,%,%,*%$%,(,(*,,%,%,,*(,,%,,%,*%,*%,,%%(,%,%**,,(,*,*%%%%%%,%*%%,%,%*%,,(%**,*,%,,*,,*%*,$,*%%,*,%,,,%*,*,((%,*%,$(,*%*%,%*%,%,$%(**%,*(,*,*$,(%*%,%,%,%,%,%,*%,%%%,,*,*(,*(,%%%,%,%*,,%*,$,,,(,%(,,(*(,((%,%,%%,%,,%,%*,%,%%*,*%%*,$%**,,(*%$,$,,$,%,%%$,*,,*,(+,+,*,%*,,,%%,*%*,%,*,*,,%,,,**%,(,%,%,%,%*%,,%%,*,((%((+(,++(,,*,%*%,,,%%,,%,%,(*%*%%,%*%((,,%,*%,,%*,%*%,*%,%+*(,(+**%*,%,%,%%%*%,,%*%*%%,,%%,%,*%(,,**%*%,%%,$,%,%,%,%(*(,+*(*(,*,%,%,%%,*,,%%,%,%,$,%***,(,$(%%,%,$,$,%,%%%*,%*,+(*+++(,(,,%**,,*,%,%,%,,%,,%,%,,$*%%*%+(,%$,%,%,,,,$%%*%*+++(++,%(*,,%,*,%,%,%,,%,%,,$,*(,,%%$(*%*%*,%$,*%,%%,,%*,%+((*(,(*,+,%,*%%,%,,$,*,%,%,%%%(,$,*%%,*.,%$%%%%,%%%%,($(+,(,++(***,%,%,*%*,%*%,%%,%,,*(,%%%($(*%,,%,*%*,%%,$,*(,(*+*+(*(*+,%,%,,,*%,*%,%,%%,%,$,%%*%%*(,($%%,%%,%%,$,%,(%,%(,(*(+,,((,%,%%*%,,*%,,*%,%,%,%*(,%,*%,$((,%,,,%*%,%%*,%(+*%(,(+,*((,(,*%,%,*%*,%%%%,($,$(,$,(**,$%,$,(%,*%,,%,%(%%(*,(,*,*,*%%%,%%%%%%%,%,%*,*%(**,(*(%(,%$,%%*,,$*%*(,,$((,*((,,(,,,%,%%,,%,%%,%%(*(,(*$((*(%*%,$,%,%*%,,%%.,(,,(,,,(,(*,%,%%%,%%%%,*.,%*(%%*.,*%,%%%%,%*%%*(,%,*(%(,(*%,(*%,%%,%%%%%,,%,$,*(,*%(*(,(%,%,$%*%%(%%.%,%(,(,(,,,%%,,%%%%%%,%*.,,(%**%%**%%,,%,,,*%,%%%%,%,*,*,(*(*,%%%%%%,%,,$(%%(%,%(,%%,$,%*%%+$%%**%$(,(,(,,%,%%%%,%,*%,$,(,*%**%*%,%%,$,,$%,%,*%*%,(%(,%,(,*,(,%,%,%%%,%,%*,%*%,%%*%*%$,,,*%%%%*%#%*,,$(,(,(,,,(,%%%,%%%%%,%,%%*%%*%*%*%,*,,%%%,*%,((.%%,,%%,*%,*%,%%*%%%%,,(,*(%%%%,%%%,$%,%,,%,%*%*%,*,%*(,,,%%,%%%%%%%,*%%*%,,,$,%%*%$%*%%$(%,,%*,(,*%%,,%%%%%%%,%%%%,,$,%,%,$%$%%%%%,.,,%*%(,,,$(,,$%%%%%%%%%,%,,%$*%*%%$,%%%%,$.,%%$%%*(%,.%,,*%,,,%,*%%%%%%%%%%%%%*%%%%%,%*%,%%%,%,%%$,%(*%,%%,$,(,$%,*,%%%%%%$%$$%*%*%*,%%%%$%%,%,%**%$$%**(%%%,,$,(,,,,$,%%%--%$%%%,*%*%%%%,%%*%%,$$%%%$%%(%*,%*,*(,,$*,*,%,%%-%%%-%%*%,*%*%%$,$,%%,%%,%%.$%%%$%%*($,$,%%,*,%,%(,*%%%%%%%%%%%%%%,$%,$%%%,%%,%,%,%%$%%%%%$%(%*,%,,,*(,%,(,%,%,%%%%%%%$%%%,,,$,*($%*%,%,%%%%$%%%*%$*,%$%%%*,,%*,*($%*%%%-,%,%$,%,**$,%%,%%%%*%%%%%$%*,.,.,%%%%%,,%*(,,$,%,%,%%%$%$%%,**((,$,*%%,%(%%%%%$,%$%*.,.,*,$,*,,(*,%%,$,%%%%%*%%%%%%,$,(%$.,%,$%%%%%%%%$%$%%*%*%,,*,,$,*(*%%*,%%%,%%*%,*(**%(,$,%%(%%%%%%$%$%$%%*,*,%%,$(,,*.,,$,%$%%%%,%%,%*.%(($%*.%,%,,%$%%%$,$,%*%*%,.*%,,%,$,(,(%%*,%,%,$%%%*,%%,.($(*%,%%%%*(,%,%%%$%*%$%(,*(,$%*%,,,*%,%%,%,$,%%$*%,$,$%$(%,(%*,%,*,,%%$%%$,%*%$%%*%,,%,,%,.,$%**%%$,$%%,%*,$,$,.*%(*.,%,%%%%,%%%%$,%%(%*%(,(%,%,*,*%%*%,*%,*%%%$*%*%%%$%*(%%(,*(%%%*%%%$%,$%$*(,%(,,%,%,%(%%%*.,%,$%%*%%,*%*%$,$(*(,*%(%%,%$%$%$%$%,$,$,$%,$(,$(,*,%(,***,%*%*%$,$$*.(*%,*%,%,%$,(,,$%%,%%%,%*%*.,.,,$,(,%,,*%%%%%,%*%*%%%%*%%,$(,*%*%%,$**%%,*%,%,$%$%*.%$,$,,$%*%*%*,*%,%,%,*,(,(%,**,%*%$,*%,%%,%%,,*,%,*%%$%%%%,$%(%,*%%%,(%*%,*,%%,%%,*(*,*$,*%*%%*%$,$,%*,*,$*%%*%(,*%$*%%*,%$*$,$%$,$,%,%*,*,*,%*%,(*((%*%*%$,$,%,(%%*%%,,%,,*,,%*%$%$%%$,$%%%*%*,$,***%(%%,%,*,(,,*,(,%(%*%(%$%,%*,*%(*%,%*%(%(%%%%$%%*%**,**(,,$,,,%%%%,(,(*(,.,%*,*%(%,%,$,($,(%%,,%,%,%%%%*%*(%*$,%*((,$,*%*,%,*(,(,*(**(%%*%**$%,%*(%,(%%,%*,*%%$%%*%,%$,$*%*(*.,*,%%*%,%,%,(*,(,,%,.,$%%%,,%,*%,,$,,%%,$%,%%*%%$%*%$%*$,$,*,%*,*%,%,%*%,*(,,$(*,*%*,%*.%*%,*%%,(%,%,,%%*%*%$%*$,%%%**.,*,%,,$,,%,*(,*((*,%($,$,$,,*%*,*,$,%%,,%,*%%%%$%,$,$,*$,%%((*(,,$%*,*%,%,*,$,*(%*,$,.,%*,.,%,*%,,*%,*,%*$,$*$,$(,$%**%*(,(,%*,%%%,%**(%*(%$(,*.,%,*%(,%,%%,,$,%%%%$%*%$%,$,%,$,**(,+*(,%,%,,%,,,*.,%*,%,,(**%,,$,*%*%,,%,,%$,*%,-*,$%($,*$($,((*(,%,,%,$,*(,*(,*((*(*$,%,$,%,,%,%,,%%,%,%*,%$%**%$($,*,$*%*(%*,,%*,,$,,(,%*,(,,(,*(,%**(%,$,%%*,%,*%,%,%,$%,%%,(,$*%*(%(*,,%%,%*(*(,,*(%*%(%(,$,%,,%,,(,,%,*%%,$,**$*$($*%(,.*,*,$,,%,%,,,,,(,*,$(,%%,$*%,$,$,%%%%%,*,%,%,$,,$,*%,,$%*,$$(.,,(,%%*,$((,*,.%*,*%*%,%%%%,,,,((,%%*,$%%*%$,,$,$,$$(%(,%,,%,,,%,%,*,(,,*%*(%%,%,*%*,%%*,%,*%*,%,*,*,%*,$.%,%($(%,,%*(%*,((%,*,(,,%%%*(%,%,,%%*%,,%,,,*%,,(%***%*(%,,%*.,,((.*.,,%,,%,%*,%,*%*,*%,%,%%,$(%,%*%,(,%,,*(%*,%***%(%,$$($(%.,$,$%(,*(,,$,,$(%,%$*,**,,*%%%(,,%,%,%$,,%*(,(*(*,$(,,%,(*.,%*(%,%(,$,%%%%,,$(%(%%(,%,*,*%,%,**,((*,(*+%%,,%%(%.,(%%%,%%,,,*,,%,,$,%%(%*%,(,*(%,*,,,%,,(,+++(*(*,*%%,%*(%*(*%,%,%%%%*(,%*%$.%**%$,%*%*,%,(,%(,*,%*%%*(,+((*%(%%,*$(*%*,.%$,(%,%,,%,*(%,*%,%,%(,%*,%%*,(,,*(,*%,,*,++(*+(,$**.*%$*..((.,%*(*%,*,*(,%%%,%,*,%*(%,*(,%**,(,,(,*%,*,+*+,**,(,$,.,%($.*(%*(,*,*(,,*,%%$,*%*%,%%(%(,,(((,(+,%,,%*(,(+*(,,(*%$($.$.$($$(,(,,*,*%%(%%%,%,,%,*,$,(,*%(+(,*+**,$,,(,*,*(,(*%*(%*%.$.+%(*(,%(%,(,,,**,$,%*(%*,**+*(,(,,*%,$,,,,,*,%%(%.%$.%(,,,,,%,%,,*,*%,%(%,,(,%*,,%$,(,(+(+**(,*,*%,*%*,,**%(*-$$.$%*%%,*,%*(,%,%%,%,(%,$,%*(*(,+(*+,%*.,(,(*(,,(*(%,(%%%.%,$(%*%%*%(*(%,%,,%,%%%,,((+(*+(,,(*(,$,*,*,(,,*%%,%%-$%*.%%%%,%%*%,*%%%%%%*,$(*%+(*(+,((*(,,**,(%%*,%%*,*%*%%$$%,(%*%%,,%,(%*%,%%%,(%%,*(%*+++((+(,(,*(%*,%,%,**%$,%%%$.%%($,$%%,$,$(,.,,,*,$%(,*(*+(,,+*,((,,,%,,,$(,,**,%*$,$%$*.(,%%,(,(,*%,%%*((+%(,(,(+**((*(,$,%%,$,$(%%%$*.(,.,%%*(,*(,(%,$,%%%%+(%%*+%%(**+(,,*(,,,%%%%*(,,,%*$(%%$,$,$(,,%,%(*,%,%%%%,(,%((,%((*(,(,,,*,$,%,%,,(,,%%-*%%*%,(%%,*(,$,,%*%,%%,%*%*,%,$,((,(,*((,*,%,%%%,*,$.*%..,$(%,$%%%*,,%*%%%%%%+%,%%(,.(,(,*,(,(%,%%%,%,*%*(,.$%*($(%$%%,**,%,,%,,,%,%*%(,%%(,*(((,,(,,,%,%,%,(,%,(%*$*$.($*(,*%*((,,$,%%%%,%%%%(%%,%%,(,(*((*,%%,%***,%,*%(%.(*.,%$%$(,$,,%%,%,%,,%,%%%%%$,*%+,,*+,,%,%,,,%,,**(*,%%%.(*.$%*%(,%,%*%%%*%,%+*%%,(%*(*(,(,*%,%,%%*%,$,%(,$,*%$(.%$%$%%*%%%%%%%%,%%**,$%,*%($,((,(,,(,%%(,,$,,%*%,*%,$$*((%$*%,%,%,%,%%%%,$+%(,*%(,,%,*%,*,,,,*,%*%**,*%,%$*.,$%$%$,%%(,%%%%%,*((%%%*(,*(,,*(,,%,.,$%,%(,,,%*%%(.*$,%%%$,,%,%%,%,%%$%(%($,%*,%,,,(,*(,,$,$%%,%*,*,($%*.,%$%,%%,%%,*%,%%%%%*%$(%*,(%*,,(*%,%,,$,,($(*%,$%$,$%%,*,$,%%%%%%%%%,%%$%(%,%%,*(,,%*,$,%*%*%%,,*.,*(%$%*%$%%%,%%*,%%%%$%%%*.,%,-*%*,,($,,,%,%*%*,($%*$%%%%$%*%,%*%,$%%%%%%%$$%**%*%%,,(,*(,*,,%,$,%,%%*(%(%,(*.,%%,,,%,%%%%%%%%%%%((%%%**(*%(,,%*%*%**%%%$%,%,$%*%,(%%%%*,*%,%%%%%%$%$$%,(%*,,%%,*(,*%*,%*%,%,%%*,$*,(%*(,%,%,%*%%%%-%$%%$%$%%*.$**,,%,*+,(,%%,$%*%$,%%,%*.,%((*%%,**,*,%%%%-%%%%%$%%$%$%(,,*%%,*,*,$(,%*,%$,%%%%,%%,$,,*%%%%,$,,$%,%%%%%$$%*%**%$(%%%%,*(,%,,(,(%,$%%%%%*(,%,%*%,(,,%,$%%%%%%%%$$%,.,(*.,*,*%,,(,*%*%$,%,,,,%*+(%*%%,%%,,(,(*%%,%,%%%%%%,$%$(%*%*%%,(*(*,%%,,*%,$%%$,.*,,$,%,,%%,$,*%*%,$,%%%,%%$*%%%$(,,%,$,(,%*,%%*%*%%,%,$,*(%,**%,,,%*,((*,$%,%*,%%%%$,%%.,%*,$,,*,*(,,*%,,%%,%%(,(,(%,%(%,*.,,(*%%*,%%%%%$*%%*%%%(,(,*%$,,*.,$,,%%,*%,**,.*,$(,%,%,,(,,*,,$,%%*%,%*%%,$%%*%$%%(,*%,,$(,*,(%*%%,,,%,%%,(,%,*,%,$,*,*,($(%%*,%%,%%%$%%,*%$,*(,,%%*,%*%*,%%,$,$,(*(%,$,((%,$%%,$,(,%,%*,%,%%%%%,%%*%**%((,,%%,*((,*%,%,%*,$,(,$*%%*,,%,(%*%*%*%,%*%%*%*%$%(*(,*,*%*(,%,%,%,%%,*,%,(,,%*,%*,,$*,*,$,$,$*,,$,%%%*%,$,$,$$,(*%,,(,,%*%*%%,,$%*,$(,(%,%,%,*%(,%$*(,%%,%*%%$,$,%$,$%*(,$,,%,%,*,,*%,%%%*,%+,%(,,%,.,%*%%,,$*(,%*,(,$,$%*,%*%%$*,**%,$,%$,%*,$,%,,$*%(%,*%*%,,,*%,,(,*(%*%*%,%,$(%,*%%%,.%,*,*(,(*,*.,,%%,*%,%%,*(,,%,$(,%,,%,$*,(*.,%(*%*,%,$,$%**%%*,(*%(%,,*,(,(%*%,,*%,,$,$,%*,%,%,%*(,,**,(,%*,%,%%*%,$,$,(,%,,*%%*,(,%*,%%%(,*(*(,,%*,,*,**,%,%,((,($,*(%*%$%*%*%,*,(*(,**(%*,(,*,*,%%%%,*%(,%,%*%,%(*(%*%,*(*(*(*(,(,,,*%,%*,$%*%*(*,%,*,*(,((,(%,%,*(%*(,%%*(,$,,%,,%,(,+,(,(,(*(,$,$,$$,*.,$,,**%,(,**,*,*,%%%(%,(,%*%,*%,%*,*%*,%*(*(,(*(,(*(,,%*%*%$,$,*,(,(*,*(,(,(,(%%%%,,,%,%,*%%%,*(*(%,,*(,*(,(,((*+%%*(%*,%%*%(%((,(,(,((,*,*,,,%$,(%%,,(+$(%,,*%(,(,****+(*%**,$%**,*(,*(,*,(,%,,*%%%,%*,,*%,%,(,%,,(,,%,(,*,((,(,*+,,%(*,,$,$,(*(*(,,%,$*,,*(,*%,*%,%*(%(,%%%**,%%,,%*,(,%*,*,,%%*,,(,%%*%*$(+(,(*,*,*(,(,$(%%%,$,%(,%%,%%,,*,*%*%,**(%(,*%,*,,$,*$,*$*(,((,*,,(%(,,$,,,%%,*%,$,*(,,$,*,,,,*%%,,,,%*,,,*%(,*.,%*,$,$,%$(%*(,%,%*(,((*,%,$,,*%,,(%,%*(,*%(,*,(*(,(*(,(*(,(,*,$(,.,*(,$,,,*,,,*(*,(%*%*,$,%*%**%*,,%(,,*,,%*(,,,,(*,(%(*(,(,%*%*%(*(%,,(*%,(*(,(*,,$,,$,*%*%,%,%*(,**(,$,(,+(*(,*,*,,+,,,%,$,.,$,,(%(,*(%*,,,*(,*%%*,.,%,%*,%,,(((,(,,(,*,,(%*(%*,(,%*(,,$,$,$%($(*,*,*,,*.,,*(,%,,*,%,*,,(,*(*,,(,*(**(,(,,,*%,(,$,*(,%%,$*.,(,,(*(%(,$(,,*%(,%%%%,*,%*%,$(,,%((*(,*,,,,***,,(%**,%(,*,*%(%*($.*.,%,%(,*,(,*,%$,*,$(%*(%,,%**,(,*(,(*.,(,%%$,*(%,,(,$(%,$,(,(.(.*%%,(%,$(,$,%%*%,,%%,%%,(*,((,,(,,$,,%,%,$%,%,%,(%,$,.,$%,*(%%,$,*%,%,*(,%*,*$,,*,*%(,%(%,*(,%(*,*,$,(%,%,*(,%,%,%(,.,((%,%,%%,,,$,%,,*%%%%,%,,*,*(%,%*,,*(,%,%,%,,*,(,%*%,%%*(%(($**%,,$,$,,*%*%,%,%*,%,%(,,*%*,$,,%(,%*,.,%*(,*,*,$,*(%**'.,(,(*%,%,$(,,,%,*%,%,*%,,,%*%,*,(,*(,*,%*%$,%,%*,,,$,.*$%$,.(($(%,*,*,*%,%,%%*%%,%,,,%,$%,%*%,%,%,,$(,*%,%,%*(,.,*,$,%*.%.*(%*%(,(,$,,%*,*%,,,%%*%%,,%*,,%,$*,$(,,(%$%,%,*,*,,%(*$*.%$.$.$+*(,*%,%%,(,,%,%,,,,%*,,,,$%,,,%*%*,*,%,%*$,(,,(*%(*%%*%$$$(*%,%,*%*,,*%,%,,%%%,,%%,(,%*%%,%,(*%*%,%%,%,,$(,(%,($$%$.($.,,*,$(,%,%*%%$,%,%,%*%,$,%*%%*%*(,(,,%%*,(*,%%,$%%%$$%.,%%%%,,%%**,,,,,,%,%,%%,%,%,%,*,%%,(,*,*%,%*,%,(,*,%,*%%.%,*($,*%$(,,%,.*%*%%,,%,,%,,%*%,$,$,(%*,$,%,,%*(,*(,$%,$,%%$$(*%.%,%,,%*,,%%%,%%,%,%$,$,,*,$,%**(,,%,%%%%,*(%,,*%(%,$,%,.,%,,*%,%*%,%,%,,%,%,%*(*.,%%$(,(%$%%*,,*,,*%*,(,*%$(**,$$,%%,,*,(,$,,%%%%,%%,%(,%,$%,($*(,$,%%,*,*%,%*(,*$,*%*(,(,$%,(%*(%*,%%%,%%%,%,%,*%%*%,%(*(.,%,%,%*((,,%,$(,(*(,*(%*,*,$(,%,(,,%,,,%,%,%,*(,%%%%*((*(**(%,%*,(,,$,$,,(,*(%*(*(,%%**,,*,,(,,%%,%%%%,$*,**%%$((*.,$,(**,*%,,%,(**(,(*((,*(,$,(,*(*,,%%%%%,((,$(%*,*(*(((,*%,%*,*$,*,,(,(,(*(+(,(%,%*(,,(*,%%%%%,%,*.,(,(*((((*(((%(*((,(%,$,(**(,(,*(**,(*(,*%,%,,%%%%,%%(,$,(*$(*(*(**(*(,%(*,%*(%*(,,*(*(*+(%(,*(,(*%%%,%%,*%,*%(%%(((*(%(,(,%*,(*(,%,,,(*((,*,%,*(,(,,%,%%%,%%*.,(%*%**(((*(*(*,%,*%,,*,($%,$,((%%,%,$,%*(,$%%%%%,%,,**%,$*%%*(*(%,%,**(,,%,%*,*,.*,(,*%*.,,(*,%,,%%%%,,*%%*.(,$,(%,,(,**,*(,,(,$,$,,*%,*%((**(,,%(,(*,,%%%%,%,,,,,$,%*(%*$,$,(,%(,*(%,*,(,%*(*(**%(,,$,%$,*(,%%,%%%,,%$*%%*%*%*%.,$,(,*(%,*,,*,(,,,(,,(,,*%,(,(,*,,%*%%%%,(%*,%*%(%**%*(*%(,*(,*,((*(,*,(**%,,*,,,**.,*%%-%%,%*%%%,,*%,*%*,**(,(,%,,,(%*,%(,$,%(%%,%%,,*%%-%%%,%%%*.,(,(,*(,*(*(*(*(,,(%**,,%,(,*,%%*%%%%%%%%%%,%,,*%*%$%%*(,%,*%,(,*(,,,,,,,*%**%*(%,,*,$(%*%,%%%%%%%%*%*%,%%%%,%(,%,$,(%*(,((*(*(,(,%%,*,,%%%*,%,,(,%%%%%-$$%%%*%*%%$%,%*,**%*(,,*(,*(%,%,%,$%%%,*,,%%%$,%%%%%%$%,$,%*%%,$,%,%,*(%(,%%,*%*%*$,%,,,%*(,*,*,%*%%%%%%%%*%*(%,%%%*,%,%*,(,,%**,*(,*%*%*$%*%*(,,%$,$,,%,%%%-%%%%%%-%,%%,%$%$*%%%,,%,%**,$,%,%(,%,%,$%,,,,*.,,$,$%%%%%,%%%%%,$,,$,%%%*%,,,%*%*,*%(,($,*%,$,$(*%,$(,,$,,$,%%%%%%$%%%,$,%***$%,%*%,,%(%,,(%,*,(,,$,,,,*(,*%,*,%%%%%%%%$%%*%%,,*(,$,%(%,%,,%*,*,**,*%(,,(%*%%**%(,%*(%*(,$,%%%%%%%,$%%%%*,%(*.%**%*%*,$(%,(,$,**%*%,%(,,,*(,(,%,%,%%%%%%%%%%%*.*(%%*(%,%,,(,,*,,%*%(,$(,%,,%%*%,(,%,$,$%-%%%%%%*%%%,,%,(%$(*,,*%,%,$,(%*,%,*.,,,%%%*,%*(,*,%*,%%%%%,%%%%*%%$$.*,.%(%,%,%,*,(,**%%,,(*,*,%,(%,*,*%,%,,*%,%%%%,$,%%$,,*,%,%.,*($,%,,%,%%,%(%*%*($,,*%%%%%,,(,(,%%%,%%%,%%*%$%%*%*%*.*%*.%*(%*,%,%**(,*(%,%*((,%,%,,%*,*,%***,$,%,%%%,*%%,*%,%%,%$,$,%($,%*%%,%,(,$,%%$,*.,$,%**,*,*,*%,%,,%,*,%$%%,$%%*$,$,$%($,.*(%*%,,,$,*%,*%%*.,$,$,%,%,%*(*,%,*%**%*%,%%%$%(*,%%*,$,*(,,(,,,%,,*((%,$%%(*(%*(%**,*(,%(,%*,(,*,$,%,%$%,$,%%(*,%,%,%(%$*(*%*,%%,,(,*%%,$(,((%,*%,(*,%*%,%,*,*%(,*%*%%,$%$,$,,%%,$,$,*,(,(,%%%*%*(%*(*,$(**($,*.*%*,*,,*%*(,(*(,,%*$($%%%,%%%,%*((,.*,$,$,*,,(**%(,.,$((,(*(,,(*(,(*%,%,(,*((,**,*%,%,%,%,%,%*(,*((,(,(%,.,*((,$,(*(,(*(*(%.(,%((,%*(,*(,(,*(%*(,%%,%%,%,,%*,%$,*((*(,%*,*%,*,.(*%(*(($,((**,*,(*,%,$,,(*(%*((%,$,$*%,%,*(,(%(*,(%*(,*%(%*%,*$%*.,*.,$(*(,%*,%,,*,(*,(**+,,(,*%%%%%%%%*$(*(*.%,%,%,,%(,*(%,*,(.*((,((*(,((*,%,%*,(*+,*(*,%%%%,%%,(,(*((%,%,*%%%*%*.,*(%$*%%(,*$,$*,*,(,*,$,(,(*((%(*(%%,%,%,,*.,(*,%,%,*,,%,,(,%,(%%**(,*,((,(,%*,(*,(*++*(,(,*,%%%,$*(,(*.,*%,%,%,$,$,$%*%*%*%,%%((,,.**(,,,(,(,(((,$(*%,%%%%,,%,%,.*(,*%,%,%,%,%,*%%*%*%*%$%*,*%,,%%%*,,**((,$,*%,%%%%%%,*%%%%%(%%%%%%,%%%%%%%%,%%"  "         "   !   !      !         !   //              /             /,$,,%%,%%%%*,$,.*., "#&+++(+++*(++(+'&+(&+(+,,,%*,%,%,$,%,*((***$+**+++(((++*+++++#&#(&#&###&&#&&&+#(((*+(*+#*++,*(((*(+(++&+&##+#&&+&&& #&&&&+#+++&+&++#((*+++++&#&&& &&&+#+&+#&++&+#+++(#+&+&&#&&& &&&&&&##+&+#++++&+&#++#&+&&&&&&@@@####+####(*,((***((+(+(##+##((((((*((((%%%$%%(*(**((+((((($%*(*(,%%%%%%%%%%$*((*((((((*$*(*((%%%%%%(%%,$%($(,(,*(((*(%(**((**,%*,,%$%%%*%%,,*,,*(((*(%(*%,*(((***%%*%%%$$*%,,(((((($,*,,,*,*,(,*%%**%%$(%%*,%*((((($*$,%,(%,*%%%%%%%%*%%,**%*(((,*%*,$%%*,%%%,%,%%%%%*%*$*%,*(**%%,%%,%%%%%%%%%%%%%(%%*%$%****%%%%,%%%%%%%%,%%%,$*$*****%*%$*%%%%%%%%%,%,,%%*%*,,%%,$*(*$%%%%%$,*%%%,%,%%%*%($%(,*($%*$%%%%,,%%%%,,$%%%%,*%%%,,((*(*%$%%%%%%%%,,%,%,%*(*,,%$%*(,((($%%$%$%,*%%%%%,$%,(,$%%,%***((*%$%%%%%%%%%,,%%%,*%,%%,,(,*((**%$$%*%*%,%,%*%,%%*,**%%*%*,*,***$*(%,%%%%%,,%$%****%%,,***(***(*,**%%%%,%%,**%%$*%*%*%(,*((*,*$%**%%,,%%%,%,*%*%%%*%**(((,**$%$%%%%%%%%,%*%$%***$*,((*****%%%%%%%%%%,$,***%*%*%,**,(,(,%%%%%$,%*%%,%%%*(**%$%%%**%****,%%%%%%%%$,,%,,%*,%,*%%,%,%,***,(%%%%,%%%%***(*$,%%%%%%,%%,%,$*,,%%%,%%%%(*((+(*%,%%%%%,%*,%%$,*%,%%,%%%%((((*,%%%%%%%%%%%%***(%%$%%%$%*(++((,*,,%%%,%%,*%%(%$%%%%%%$((((*,,%,,%*%%%(%%*($%%%,%%*,(((((,%%*,$,%%%%$,%*$(,%%,%%%%%($*(***%%%%%%*$*(($%$%%%%%,((*((,%%%%%%(**$(*%%%%%%$%$%((,*%%%%%$*%*%*%%%,$%%%%**(*%%%,(%*$%%%,%%**%,(,(,(%%%%%%$%%,%%%%,%%%%%,%*%%%%,%%$,%%$%%$%,*,*%%%%,%%%%%%%%%$%(%%*%,,%%%$%$%%%%%%%$%$(%%,*,**%%%%%$%%%%%%%%$$%%$$*%,*%(,%%%%%%%%$*%%%%%%%%$*$%%%%*($%%%%%,*($%%%%%%$%$$$,$,,(%%%%%%%%,*$*$%%%%%%%%%*%,,*($%%%$%,$$$(%%%%%%%%$%$%*,%,,*%%%%$%$$$$$(*%%%%$%$*(,%%,$%$%%%%$$%$$**(%%%%$$$%$%(%*%%%**$%$%$(*%%$*%*%%%%$$*%$*$,,%%,(*$*%%$$%%%%%,*,$%%%*%$$$$*%*,%%,((*%$$%$%*%$%,%%%%%$$$**($,%%((*(*%$*%%(,%%%$%%%%$$$**,,$%%%*****$%$%,%%%%,%%$%$$$$**,$%,*,(*($$$,**%%,%%%$%$%*%**((*%%,%*$%*,(*%*%%%%%%,$$%*$**$$$*%,%,(*(*((%*$%%%*%%%%%$$$($*(*,%%,*(*$*%*$%,%%,%%%%$*%$$$$%%,%%(*,$*%%%%,%,,*,,**$$%%$(($,,%%*,,%*%%%%%%,%,%%*%****$*$$$%(%,*,$%$**,%%%,%%,*(((*%%$$(%%%%,*%%$%$$%$%(,(*%%(((*$$$*$($**%,*%%%%,,*%**(((,%*((*($$$$$$*(**%$%%,%,$%*(((**,*,**%($$(,*%%*,%**%*%**((***,*,*$%$$%$$%*$(%%%%%((((*(****,*%%%$%$%%%*%%%%$%(*(((*(*%%,*,*%$$%$*%%*($%,%((((*((,%%*$%%$$$%$*,(*%%%(%(%(((***%%%*%$$$%$%*,,%%,%%%$((,(,%%%*%%$$($$%**%,%%%%*%,*(*(,%%%***%%($%$$%,%,%%%%*$((,*%%*%,$%*%$$%$$%%%%*$*$*,*,*%,*$%*,%$($%%%%%%%$$%%,,,*(,%%%,*(%%$%,%%%%%%%%$%%*(%,$%$%*$$%$$%%%%$$%$%%*(*,*%$%%$%%$(%%,%%%%%%$%,%***%$%%%%$$%(%%**%%%%%$%$%$*$%%*(%*$%%%%$*%%%*%%%%%%$*$$*,*(,%$%%%$($%%%%**%%%%$%$*%,**,%,%%%$(%*%%%*(*%,%%%$%$%(*%$**$%%,,%(%*%%,***%%%%%%%%$%*(%%*(,%%*,%*(%%%**%$%%%%%$**,**%%,$%*,*%%**%$*%$%%%$$$**$%%*,%%*(%,%%%%,(***%%*%%%$**,**(%%,*,%$,%%*(****%%%$%%*(**%***%%%*(*%$,**%,(((*(,$%*$*(*%******%(%%*%,%,*(((((*%$$*$*((*((**%%%%%,%,(*%*((**(,$*$%$%(*,**,*%%%*%*%*,%,%****,*,(,$$((*****,%%%%(%,%,%,,****,*$*$$(%*,,*((%$,%,*%*%,*,(,*((((*$$*(%%(*****$,$%%%%***(**((**,,*%$$$*(****,(%%*%****((**,*,*****%$$(*(%%***%%**%%%***(**$,%,%,*$%$$((%%%,%*,*%%%%,%(,*,*,%%,*(%%%($(**,%$*,%,%%%%%,***,*$%%%*,*$$$($$***%,%%%%,%,%,%$%*($%**,*$$$$$*,*%,*%,%%%,,%,%%**%%$,*(%$%$$$%%,%*,%%%%%%%%%*%(*,%%(*%*%$%($%$,%*%%%%%,$,$%**%%%*(,%$%$*$%,,*%%%%$*$%(*$%%,*,$(*$*(*$**%*%%%%*%%%((*%%,(*%,((*((%*,*,%(**%(((****,,(((((*%*(*,%%%*$(*(((((*(%****(*,((,%%$*$%(((((%**,,$*((%$,*,%%%%($%$,(*,*(,%,****(,%**%,%,$$$$$*,(*,*(,(**,,,**,%%*%%%$*$*(*,*(***%(%,%*%%%%%*%*,(******$*%%*%*%%$%%$%%%%*%$(,(((*,%%%%*,%%%%%$*%*%%*,*%**$$%%,*%$$%%%%%%%%%$%%,%***%$%%$,**%,%%%$%%,*$%%%%,****,,$%,**(*%%%%%%%*($*%,**,$*$*%%%$(,%*%%%%%$$$*%%%***%,(,%%%,*,%,%%%$%%$%*%$*$,,%$,(%*(,%,**$*,%%$%%$%%$$%(%%%*%%$*$$%,**,***$%%$$%*%%%*$(,,%*($%$($*%*,*,**(*%$$%%%%$(***%***($$((**(((%,((***%%%%%%*$*((%**($((((($***,**(*((*%%%*((*%*,%**$*((*(**(,%*(((*%%%*((%%%%%**%*%***((*,((((*(,%%%%((*,%%%*%$$$%%(%%$%%%                 *((,,((((((,%,%,%,%##&#(+(#+(((+##&####+###+##& @#+((((%,%,*(((++((***,%%%%%%**(((*****,*,,%%*,,(((*,,,*,%,%%,,,((*%%%,%,,%%**,,*%%%%%%%%%,%**,%**%%%%,%%,%%,*%%*(*%%%,%,,,,*,,**(*$%,,%%,,,,%,******,%%%,,%*,,,(**%%%%%,,,,,,,**,%%%%%,,,**,%****%%%%,,**,,%,,,*,%%%%*((,%%%,%,,*%%%%(((,,,,%%*$*%%%,((*,%%%%%**(%%%%*(*%%%%**%%,%%,**%%,%%%%%%%,*%%%%%%%%%*%*,%%%%%$%%%%%$%,,,%%%%**%%%%%%*%,*%%%%*(%%%%%$*%,%%%%$$,%%%$%$*,%**%$,%%,%%%$**,%**$*%*%,%%%$*,,%***%,,,%%%$***,%****,%%,%$***%,***%%%,,,*****,,,%%%,%,,*(*%$*,,*%%%,*(*,**$$$*,,%,,%*(****%%$%,,%%$(((,%*%$$%,*%,*((*%%,$$$%*%%%%%*(*%,**$$$%%%%%*,*,%*,$%%%%%%%%*,,%%$%$,%%%%%%*,*%%%*,%%%%%**,*%%%*%%*$%%%%%*%*%,,*%,,,%%%%$*,,%%,,%%,**%%$$***%%*,%*,(*,%$****%%,%,*,(**,$*(**,%*%,,,**,*,*%,**,,,******,*$***%,%,***,,,*$**,,,%%,,**,%,*%(**,,,%%,,*,%**$$$,,,%%%,,*,%,,%$*,,,%%%,%**%*,**(**,,**(**,*(*,*%%%**(**,,**,*%%,%$**,**,,,%%%%%*****%,,%%%%%%%%,***%**,%%%%*$%,**,%,,%%%%%%$*,%*,*%***,%%%%$*,,*%*,*****%%%******(**,*((%%**,,****%%,*,%%%%%%     &++++#&&@@+((%%*(+(***,%,**%%%%%*,($%,,,*,**,%,,,,*%%,,*,**%%**,,,*%%(*,%,*%%*,,%%%%,%%%%%%$,,%%*%%$,*$$,%$*,**,,%**,**%,***,,%,(**$,%%*(%*$*%%**%*$%%%%**%$%%%$**,*,%%%*,,,,*%$**,,,***,*,******,,,*%*$*,%%*,***,%*(***,%%****%%%$,*,*%%%*,*****%*,*(,,*%%% @(*,(*%,**,,****,%,%%%$,%%*****,,**%%**%%*,***,***%**,%***%**0****$%***%**%*%%C***%T**d*w4}7h#G!wl*l Gh# w4tK64w4yK16w4zK128w4MKw4w4|Kw4w4}Kw4w4~K@pw4K@pw4@L@pWw4AL@pw4BL@w4w4H//============================================================================= // 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 ); } } w4Gc//============================================================================= // 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 nativereplication; #exec Texture Import File=Textures\ZoneInfo.pcx Name=S_ZoneInfo Mips=Off Flags=2 //----------------------------------------------------------------------------- // Zone properties. var() name ZoneTag; var() vector ZoneGravity; var() vector ZoneVelocity; var() float ZoneGroundFriction; var() float ZoneFluidFriction; var() float ZoneTerminalVelocity; var() name ZonePlayerEvent; var int ZonePlayerCount; var int NumCarcasses; var() int DamagePerSec; var() name DamageType; var() localized string DamageString; var(LocationStrings) localized string ZoneName; var LocationID LocationID; var() int MaxCarcasses; var() sound EntrySound; //only if waterzone var() sound ExitSound; // only if waterzone var() class EntryActor; // e.g. a splash (only if water zone) var() class ExitActor; // e.g. a splash (only if water zone) var skyzoneinfo SkyZone; // Optional sky zone containing this zone's sky. //----------------------------------------------------------------------------- // Zone flags. var() bool bWaterZone; // Zone is water-filled. var() const bool bFogZone; // Zone is fog-filled. var() const bool bKillZone; // Zone instantly kills those who enter. var() bool bNeutralZone; // Players can't take damage in this zone. var() bool bGravityZone; // Use ZoneGravity. var() bool bPainZone; // Zone causes pain. var() bool bDestructive; // Destroys carcasses. 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 //----------------------------------------------------------------------------- // Zone light. var(ZoneLight) byte AmbientBrightness, AmbientHue, AmbientSaturation; var(ZoneLight) color FogColor; var(ZoneLight) float FogDistance; var(ZoneLight) const texture EnvironmentMap; var(ZoneLight) float TexUPanSpeed, TexVPanSpeed; var(ZoneLight) vector ViewFlash, ViewFog; //----------------------------------------------------------------------------- // Reverb. // Settings. var(Reverb) bool bReverbZone; var(Reverb) bool bRaytraceReverb; var(Reverb) float SpeedOfSound; var(Reverb) byte MasterGain; var(Reverb) int CutoffHz; var(Reverb) byte Delay[6]; var(Reverb) byte Gain[6]; //----------------------------------------------------------------------------- // Lens flare. var(LensFlare) texture LensFlare[12]; var(LensFlare) float LensFlareOffset[12]; var(LensFlare) float LensFlareScale[12]; //----------------------------------------------------------------------------- // per-Zone mesh LOD lighting control // the number of lights applied to the actor mesh is interpolated between the following // properties, as a function of the MeshPolyCount for the previous frame. var() byte MinLightCount; // minimum number of lights to use (when MaxLightingPolyCount is exceeded) var() byte MaxLightCount; // maximum number of lights to use (when MeshPolyCount drops below MinLightingPolyCount) var() int MinLightingPolyCount; var() int MaxLightingPolyCount; // (NOTE: the default LOD properties (below) have no effect on the mesh lighting behavior) //============================================================================= // Network replication. replication { reliable if( Role==ROLE_Authority ) ZoneGravity, ZoneVelocity, // ZoneTerminalVelocity, // ZoneGroundFriction, ZoneFluidFriction, AmbientBrightness, AmbientHue, AmbientSaturation, TexUPanSpeed, TexVPanSpeed, // ViewFlash, ViewFog, // Not replicated because vectors replicated with elements rounded to integers bReverbZone, FogColor; } //============================================================================= // 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; foreach AllActors( class 'SkyZoneInfo', TempSkyZone, '' ) if( TempSkyZone.bHighDetail == Level.bHighDetailMode ) SkyZone = TempSkyZone; } //============================================================================= // Engine notification functions. simulated function PreBeginPlay() { Super.PreBeginPlay(); // call overridable function to link this ZoneInfo actor to a skybox LinkToSkybox(); } function Trigger( actor Other, pawn EventInstigator ) { if (DamagePerSec != 0) bPainZone = true; } // When an actor enters this zone. event ActorEntered( actor Other ) { local actor A; local vector AddVelocity; if ( bNoInventory && Other.IsA('Inventory') && (Other.Owner == None) ) { Other.LifeSpan = 1.5; return; } if( Pawn(Other)!=None && Pawn(Other).bIsPlayer ) if( ++ZonePlayerCount==1 && ZonePlayerEvent!='' ) foreach AllActors( class 'Actor', A, ZonePlayerEvent ) A.Trigger( Self, Pawn(Other) ); if ( bMoveProjectiles && (ZoneVelocity != vect(0,0,0)) ) { if ( Other.Physics == PHYS_Projectile ) Other.Velocity += ZoneVelocity; else if ( Other.IsA('Effects') && (Other.Physics == PHYS_None) ) { Other.SetPhysics(PHYS_Projectile); Other.Velocity += ZoneVelocity; } } } // When an actor leaves this zone. event ActorLeaving( actor Other ) { local actor A; if( Pawn(Other)!=None && Pawn(Other).bIsPlayer ) if( --ZonePlayerCount==0 && ZonePlayerEvent!='' ) foreach AllActors( class 'Actor', A, ZonePlayerEvent ) A.UnTrigger( Self, Pawn(Other) ); } w4D//============================================================================= // Parent class of all weapons. //============================================================================= class Weapon extends Inventory abstract native nativereplication; #exec Texture Import File=Textures\Weapon.pcx Name=S_Weapon Mips=Off Flags=2 //----------------------------------------------------------------------------- // Weapon ammo/firing information: // Two-element arrays here are defined for normal fire (0) and alt fire (1). var() float MaxTargetRange; // Maximum distance to target. var() class AmmoName; // Type of ammo used. var() byte ReloadCount; // Amount of ammo depletion before reloading. 0 if no reloading is done. var() int PickupAmmoCount; // Amount of ammo initially in pick-up item. var travel ammo AmmoType; // Inventory Ammo being used. var bool bPointing; // Indicates weapon is being pointed var() bool bInstantHit; // If true, instant hit rather than projectile firing weapon var() bool bAltInstantHit; // If true, instant hit rather than projectile firing weapon for AltFire var(WeaponAI) bool bWarnTarget; // When firing projectile, warn the target var(WeaponAI) bool bAltWarnTarget; // When firing alternate projectile, warn the target var bool bWeaponUp; // Used in Active State var bool bChangeWeapon; // Used in Active State var bool bLockedOn; var(WeaponAI) bool bSplashDamage; // used by bot AI var() bool bCanThrow; //if true, player can toss this weapon out var(WeaponAI) bool bRecommendSplashDamage; //if true, bot preferentially tries to use splash damage // rather than direct hits var(WeaponAI) bool bRecommendAltSplashDamage; //if true, bot preferentially tries to use splash damage // rather than direct hits var() bool bWeaponStay; var() bool bOwnsCrosshair; // this weapon is responsible for drawing its own crosshair (in its postrender function) var bool bHideWeapon; // if true, weapon is not rendered var(WeaponAI) bool bMeleeWeapon; //Weapon is only a melee weapon var() bool bRapidFire; // used by human animations in determining firing animation (for still firing) var bool bSpecialIcon; var() float FiringSpeed; // used by human animations in determining firing speed var() vector FireOffset; // Offset from drawing location for projectile/trace start var() class ProjectileClass; var() class AltProjectileClass; var() name MyDamageType; var() name AltDamageType; var float ProjectileSpeed; var float AltProjectileSpeed; var float AimError; // Aim Error for bots (note this value doubled if instant hit weapon) var() float ShakeMag; var() float ShakeTime; var() float ShakeVert; var(WeaponAI) float AIRating; var(WeaponAI) float RefireRate; var(WeaponAI) float AltRefireRate; //----------------------------------------------------------------------------- // Sound Assignments var() sound FireSound; var() sound AltFireSound; var() sound CockingSound; var() sound SelectSound; var() sound Misc1Sound; var() sound Misc2Sound; var() sound Misc3Sound; var() Localized string MessageNoAmmo; var() Localized string DeathMessage; var() Color NameColor; // used when drawing name on HUD var Rotator AdjustedAim; //----------------------------------------------------------------------------- // Muzzle Flash // weapon is responsible for setting and clearing bMuzzleFlash whenever it wants the // MFTexture drawn on the canvas (see RenderOverlays() ) var bool bSetFlashTime; var(MuzzleFlash) bool bDrawMuzzleFlash; var byte bMuzzleFlash; var float FlashTime; var(MuzzleFlash) float MuzzleScale, FlashY, FlashO, FlashC, FlashLength; var(MuzzleFlash) int FlashS; // size of (square) texture/2 var(MuzzleFlash) texture MFTexture; var(MuzzleFlash) texture MuzzleFlare; var(MuzzleFlash) float FlareOffset; // Network replication // replication { // Things the server should send to the client. reliable if( bNetOwner && (Role==ROLE_Authority) ) AmmoType, bLockedOn, bHideWeapon; } //============================================================================= // Inventory travelling across servers. event TravelPostAccept() { Super.TravelPostAccept(); if ( Pawn(Owner) == None ) return; if ( AmmoName != None ) { AmmoType = Ammo(Pawn(Owner).FindInventoryType(AmmoName)); if ( AmmoType == None ) { AmmoType = Spawn(AmmoName); // Create ammo type required Pawn(Owner).AddInventory(AmmoType); // and add to player's inventory AmmoType.BecomeItem(); AmmoType.AmmoAmount = PickUpAmmoCount; AmmoType.GotoState('Idle2'); } } if ( self == Pawn(Owner).Weapon ) BringUp(); else GoToState('Idle2'); } function Destroyed() { Super.Destroyed(); if( (Pawn(Owner)!=None) && (Pawn(Owner).Weapon == self) ) Pawn(Owner).Weapon = None; } //============================================================================= // Weapon rendering // Draw first person view of inventory simulated event RenderOverlays( canvas Canvas ) { local rotator NewRot; local bool bPlayerOwner; local int Hand; local PlayerPawn PlayerOwner; if ( bHideWeapon || (Owner == None) ) return; PlayerOwner = PlayerPawn(Owner); if ( PlayerOwner != None ) { if ( PlayerOwner.DesiredFOV != PlayerOwner.DefaultFOV ) return; bPlayerOwner = true; Hand = PlayerOwner.Handedness; if ( (Level.NetMode == NM_Client) && (Hand == 2) ) { bHideWeapon = true; return; } } if ( !bPlayerOwner || (PlayerOwner.Player == None) ) Pawn(Owner).WalkBob = vect(0,0,0); if ( (bMuzzleFlash > 0) && bDrawMuzzleFlash && Level.bHighDetailMode && (MFTexture != None) ) { MuzzleScale = Default.MuzzleScale * Canvas.ClipX/640.0; if ( !bSetFlashTime ) { bSetFlashTime = true; FlashTime = Level.TimeSeconds + FlashLength; } else if ( FlashTime < Level.TimeSeconds ) bMuzzleFlash = 0; if ( bMuzzleFlash > 0 ) { if ( Hand == 0 ) Canvas.SetPos(Canvas.ClipX/2 - 0.5 * MuzzleScale * FlashS + Canvas.ClipX * (-0.2 * Default.FireOffset.Y * FlashO), Canvas.ClipY/2 - 0.5 * MuzzleScale * FlashS + Canvas.ClipY * (FlashY + FlashC)); else Canvas.SetPos(Canvas.ClipX/2 - 0.5 * MuzzleScale * FlashS + Canvas.ClipX * (Hand * Default.FireOffset.Y * FlashO), Canvas.ClipY/2 - 0.5 * MuzzleScale * FlashS + Canvas.ClipY * FlashY); Canvas.Style = 3; Canvas.DrawIcon(MFTexture, MuzzleScale); Canvas.Style = 1; } } else bSetFlashTime = false; SetLocation( Owner.Location + CalcDrawOffset() ); NewRot = Pawn(Owner).ViewRotation; if ( Hand == 0 ) newRot.Roll = -2 * Default.Rotation.Roll; else newRot.Roll = Default.Rotation.Roll * Hand; setRotation(newRot); Canvas.DrawActor(self, false); } //------------------------------------------------------- // AI related functions function PostBeginPlay() { Super.PostBeginPlay(); SetWeaponStay(); MaxDesireability = 1.2 * AIRating; if ( ProjectileClass != None ) { ProjectileSpeed = ProjectileClass.Default.Speed; MyDamageType = ProjectileClass.Default.MyDamageType; } if ( AltProjectileClass != None ) { AltProjectileSpeed = AltProjectileClass.Default.Speed; AltDamageType = AltProjectileClass.Default.MyDamageType; } } function bool SplashJump() { return false; } function SetWeaponStay() { bWeaponStay = bWeaponStay || Level.Game.bCoopWeaponMode; } // tell the bot how much it wants this weapon // called when the bot is trying to decide which inventory item to go after next event float BotDesireability(Pawn Bot) { local Weapon AlreadyHas; local float desire; // bots adjust their desire for their favorite weapons desire = MaxDesireability + Bot.AdjustDesireFor(self); // see if bot already has a weapon of this type AlreadyHas = Weapon(Bot.FindInventoryType(class)); if ( AlreadyHas != None ) { if ( (RespawnTime < 10) && ( bHidden || (AlreadyHas.AmmoType == None) || (AlreadyHas.AmmoType.AmmoAmount < AlreadyHas.AmmoType.MaxAmmo)) ) return 0; // can't pick it up if weapon stay is on if ( (!bHeldItem || bTossedOut) && bWeaponStay ) return 0; if ( AlreadyHas.AmmoType == None ) return 0.25 * desire; // bot wants this weapon for the ammo it holds if ( AlreadyHas.AmmoType.AmmoAmount > 0 ) return FMax( 0.25 * desire, AlreadyHas.AmmoType.MaxDesireability * FMin(1, 0.15 * AlreadyHas.AmmoType.MaxAmmo/AlreadyHas.AmmoType.AmmoAmount) ); else return 0.05; } // incentivize bot to get this weapon if it doesn't have a good weapon already if ( (Bot.Weapon == None) || (Bot.Weapon.AIRating <= 0.4) ) return 2*desire; return desire; } function float RateSelf( out int bUseAltMode ) { if ( (AmmoType != None) && (AmmoType.AmmoAmount <=0) ) return -2; bUseAltMode = int(FRand() < 0.4); return (AIRating + FRand() * 0.05); } // return delta to combat style function float SuggestAttackStyle() { return 0.0; } function float SuggestDefenseStyle() { return 0.0; } //------------------------------------------------------- simulated function PreRender( canvas Canvas ); simulated function PostRender( canvas Canvas ); function ClientWeaponEvent(name EventType); function bool HandlePickupQuery( inventory Item ) { local int OldAmmo; local Pawn P; if (Item.Class == Class) { if ( Weapon(item).bWeaponStay && (!Weapon(item).bHeldItem || Weapon(item).bTossedOut) ) return true; P = Pawn(Owner); if ( AmmoType != None ) { OldAmmo = AmmoType.AmmoAmount; if ( AmmoType.AddAmmo(Weapon(Item).PickupAmmoCount) && (OldAmmo == 0) && (P.Weapon.class != item.class) && !P.bNeverSwitchOnPickup ) WeaponSet(P); } if (Level.Game.LocalLog != None) Level.Game.LocalLog.LogPickup(Item, Pawn(Owner)); if (Level.Game.WorldLog != None) Level.Game.WorldLog.LogPickup(Item, Pawn(Owner)); if (Item.PickupMessageClass == None) P.ClientMessage(Item.PickupMessage, 'Pickup'); else P.ReceiveLocalizedMessage( Item.PickupMessageClass, 0, None, None, item.Class ); Item.PlaySound(Item.PickupSound); Item.SetRespawn(); return true; } if ( Inventory == None ) return false; return Inventory.HandlePickupQuery(Item); } // set which hand is holding weapon function setHand(float Hand) { if ( Hand == 2 ) { PlayerViewOffset.Y = 0; FireOffset.Y = 0; bHideWeapon = true; return; } else bHideWeapon = false; if ( Hand == 0 ) { PlayerViewOffset.X = Default.PlayerViewOffset.X * 0.88; PlayerViewOffset.Y = -0.2 * Default.PlayerViewOffset.Y; PlayerViewOffset.Z = Default.PlayerViewOffset.Z * 1.12; } else { PlayerViewOffset.X = Default.PlayerViewOffset.X; PlayerViewOffset.Y = Default.PlayerViewOffset.Y * Hand; PlayerViewOffset.Z = Default.PlayerViewOffset.Z; } PlayerViewOffset *= 100; //scale since network passes vector components as ints FireOffset.Y = Default.FireOffset.Y * Hand; } // // Change weapon to that specificed by F matching inventory weapon's Inventory Group. function Weapon WeaponChange( byte F ) { local Weapon newWeapon; if ( InventoryGroup == F ) { if ( (AmmoType != None) && (AmmoType.AmmoAmount <= 0) ) { if ( Inventory == None ) newWeapon = None; else newWeapon = Inventory.WeaponChange(F); if ( newWeapon == None ) Pawn(Owner).ClientMessage( ItemName$MessageNoAmmo ); return newWeapon; } else return self; } else if ( Inventory == None ) return None; else return Inventory.WeaponChange(F); } // Either give this inventory to player Other, or spawn a copy // and give it to the player Other, setting up original to be respawned. // Also add Ammo to Other's inventory if it doesn't already exist // function inventory SpawnCopy( pawn Other ) { local inventory Copy; local Weapon newWeapon; if( Level.Game.ShouldRespawn(self) ) { Copy = spawn(Class,Other,,,rot(0,0,0)); Copy.Tag = Tag; Copy.Event = Event; if ( !bWeaponStay ) GotoState('Sleeping'); } else Copy = self; Copy.RespawnTime = 0.0; Copy.bHeldItem = true; Copy.bTossedOut = false; Copy.GiveTo( Other ); newWeapon = Weapon(Copy); newWeapon.Instigator = Other; newWeapon.GiveAmmo(Other); newWeapon.SetSwitchPriority(Other); if ( !Other.bNeverSwitchOnPickup ) newWeapon.WeaponSet(Other); newWeapon.AmbientGlow = 0; return newWeapon; } function SetSwitchPriority(pawn Other) { local int i; local name temp, carried; if ( PlayerPawn(Other) != None ) { for ( i=0; i 0)) ) rating += 0.21; // tend to stick with same weapon } if ( inventory != None ) { Recommended = inventory.RecommendWeapon(oldRating, oldMode); if ( (Recommended != None) && (oldRating > rating) ) { rating = oldRating; bUseAltMode = oldMode; return Recommended; } } return self; } // Toss this weapon out function DropFrom(vector StartLocation) { if ( !SetLocation(StartLocation) ) return; AIRating = Default.AIRating; bMuzzleFlash = 0; AmbientSound = None; if ( AmmoType != None ) { PickupAmmoCount = AmmoType.AmmoAmount; AmmoType.AmmoAmount = 0; } Super.DropFrom(StartLocation); } // Become a pickup function BecomePickup() { Super.BecomePickup(); SetDisplayProperties(Default.Style, Default.Texture, Default.bUnlit, Default.bMeshEnviromap ); } simulated function TweenToStill(); //************************************************************************************** // // Firing functions and states // function CheckVisibility() { local Pawn PawnOwner; PawnOwner = Pawn(Owner); if( Owner.bHidden && (PawnOwner.Health > 0) && (PawnOwner.Visibility < PawnOwner.Default.Visibility) ) { Owner.bHidden = false; PawnOwner.Visibility = PawnOwner.Default.Visibility; } } simulated function bool ClientFire( float Value ) { return true; } function ForceFire(); function ForceAltFire(); function Fire( float Value ) { if (AmmoType.UseAmmo(1)) { GotoState('NormalFire'); if ( PlayerPawn(Owner) != None ) PlayerPawn(Owner).ShakeView(ShakeTime, ShakeMag, ShakeVert); bPointing=True; PlayFiring(); if ( !bRapidFire && (FiringSpeed > 0) ) Pawn(Owner).PlayRecoil(FiringSpeed); if ( bInstantHit ) TraceFire(0.0); else ProjectileFire(ProjectileClass, ProjectileSpeed, bWarnTarget); if ( Owner.bHidden ) CheckVisibility(); } } simulated function bool ClientAltFire( float Value ) { return true; } function AltFire( float Value ) { if (AmmoType.UseAmmo(1)) { GotoState('AltFiring'); if ( PlayerPawn(Owner) != None ) PlayerPawn(Owner).ShakeView(ShakeTime, ShakeMag, ShakeVert); bPointing=True; PlayAltFiring(); if ( !bRapidFire && (FiringSpeed > 0) ) Pawn(Owner).PlayRecoil(FiringSpeed); if ( bAltInstantHit ) TraceFire(0.0); else ProjectileFire(AltProjectileClass, AltProjectileSpeed, bAltWarnTarget); if ( Owner.bHidden ) CheckVisibility(); } } simulated function PlayFiring() { //Play firing animation and sound } simulated function PlayAltFiring() { //Play alt firing animation and sound } function Projectile ProjectileFire(class ProjClass, float ProjSpeed, bool bWarn) { local Vector Start, X,Y,Z; local Pawn PawnOwner; PawnOwner = Pawn(Owner); Owner.MakeNoise(PawnOwner.SoundDampening); GetAxes(PawnOwner.ViewRotation,X,Y,Z); Start = Owner.Location + CalcDrawOffset() + FireOffset.X * X + FireOffset.Y * Y + FireOffset.Z * Z; AdjustedAim = PawnOwner.AdjustAim(ProjSpeed, Start, AimError, True, bWarn); return Spawn(ProjClass,,, Start,AdjustedAim); } function TraceFire( float Accuracy ) { local vector HitLocation, HitNormal, StartTrace, EndTrace, X,Y,Z; local actor Other; local Pawn PawnOwner; PawnOwner = Pawn(Owner); Owner.MakeNoise(PawnOwner.SoundDampening); GetAxes(PawnOwner.ViewRotation,X,Y,Z); StartTrace = Owner.Location + CalcDrawOffset() + FireOffset.X * X + FireOffset.Y * Y + FireOffset.Z * Z; AdjustedAim = PawnOwner.AdjustAim(1000000, StartTrace, 2*AimError, False, False); EndTrace = StartTrace + Accuracy * (FRand() - 0.5 )* Y * 1000 + Accuracy * (FRand() - 0.5 ) * Z * 1000; X = vector(AdjustedAim); EndTrace += (10000 * X); Other = PawnOwner.TraceShot(HitLocation,HitNormal,EndTrace,StartTrace); ProcessTraceHit(Other, HitLocation, HitNormal, X,Y,Z); } function ProcessTraceHit(Actor Other, Vector HitLocation, Vector HitNormal, Vector X, Vector Y, Vector Z) { //Spawn appropriate effects at hit location, any weapon lights, and damage hit actor } // Finish a firing sequence function Finish() { local Pawn PawnOwner; if ( bChangeWeapon ) { GotoState('DownWeapon'); return; } PawnOwner = Pawn(Owner); if ( PlayerPawn(Owner) == None ) { if ( (AmmoType != None) && (AmmoType.AmmoAmount<=0) ) { PawnOwner.StopFiring(); PawnOwner.SwitchToBestWeapon(); if ( bChangeWeapon ) GotoState('DownWeapon'); } else if ( (PawnOwner.bFire != 0) && (FRand() < RefireRate) ) Global.Fire(0); else if ( (PawnOwner.bAltFire != 0) && (FRand() < AltRefireRate) ) Global.AltFire(0); else { PawnOwner.StopFiring(); GotoState('Idle'); } return; } if ( ((AmmoType != None) && (AmmoType.AmmoAmount<=0)) || (PawnOwner.Weapon != self) ) GotoState('Idle'); else if ( PawnOwner.bFire!=0 ) Global.Fire(0); else if ( PawnOwner.bAltFire!=0 ) Global.AltFire(0); else GotoState('Idle'); } /////////////////////////////////////////////////////// state NormalFire { function Fire(float F) { } function AltFire(float F) { } Begin: FinishAnim(); Finish(); } //////////////////////////////////////////////////////// state AltFiring { function Fire(float F) { } function AltFire(float F) { } Begin: FinishAnim(); Finish(); } //********************************************************************************** // Weapon is up, but not firing state Idle { function AnimEnd() { PlayIdleAnim(); } function bool PutDown() { GotoState('DownWeapon'); return True; } Begin: bPointing=False; if ( (AmmoType != None) && (AmmoType.AmmoAmount<=0) ) Pawn(Owner).SwitchToBestWeapon(); //Goto Weapon that has Ammo if ( Pawn(Owner).bFire!=0 ) Fire(0.0); if ( Pawn(Owner).bAltFire!=0 ) AltFire(0.0); Disable('AnimEnd'); PlayIdleAnim(); } // // Bring newly active weapon up // Bring newly active weapon up state Active { function Fire(float F) { } function AltFire(float F) { } function bool PutDown() { if ( bWeaponUp || (AnimFrame < 0.75) ) GotoState('DownWeapon'); else bChangeWeapon = true; return True; } function BeginState() { bChangeWeapon = false; } Begin: FinishAnim(); if ( bChangeWeapon ) GotoState('DownWeapon'); bWeaponUp = True; PlayPostSelect(); FinishAnim(); Finish(); } // // Putting down weapon in favor of a new one. // State DownWeapon { ignores Fire, AltFire; function bool PutDown() { Pawn(Owner).ClientPutDown(self, Pawn(Owner).PendingWeapon); return true; //just keep putting it down } function BeginState() { bChangeWeapon = false; bMuzzleFlash = 0; Pawn(Owner).ClientPutDown(self, Pawn(Owner).PendingWeapon); } Begin: TweenDown(); FinishAnim(); Pawn(Owner).ChangedWeapon(); } simulated function ClientPutDown(Weapon NextWeapon); function BringUp() { if ( Owner.IsA('PlayerPawn') ) { SetHand(PlayerPawn(Owner).Handedness); PlayerPawn(Owner).EndZoom(); } bWeaponUp = false; PlaySelect(); GotoState('Active'); } function RaiseUp(Weapon OldWeapon) { BringUp(); } function bool PutDown() { bChangeWeapon = true; return true; } function TweenDown() { if ( (AnimSequence != '') && (GetAnimGroup(AnimSequence) == 'Select') ) TweenAnim( AnimSequence, AnimFrame * 0.4 ); else PlayAnim('Down', 1.0, 0.05); } function TweenSelect() { TweenAnim('Select',0.001); } function PlaySelect() { PlayAnim('Select',1.0,0.0); Owner.PlaySound(SelectSound, SLOT_Misc, Pawn(Owner).SoundDampening); } function PlayPostSelect() { } function PlayIdleAnim() { } w4A //============================================================================= // WayBeacon. //============================================================================= class WayBeacon extends Keypoint; //temporary beacon for serverfind navigation function PostBeginPlay() { local class NewClass; Super.PostBeginPlay(); NewClass = class( DynamicLoadObject( "Unreali.Lamp4", class'Class' ) ); if( NewClass!=None ) Mesh = NewClass.Default.Mesh; } function touch(actor other) { if (other == owner) { if ( Owner.IsA('PlayerPawn') ) PlayerPawn(owner).ShowPath(); Destroy(); } } w4B//============================================================================= // WarpZoneMarker. //============================================================================= class WarpZoneMarker extends NavigationPoint 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; } */ w4_N//============================================================================= // 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 Pawn P; //if ( Other.Role == ROLE_AutonomousProxy ) // return; // don't simulate for client players Super.ActorEntered( Other ); 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( Other.IsA('PlayerPawn') ) R = PlayerPawn(Other).ViewRotation; else R = Other.Rotation; 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 ) { P = Level.PawnList; While ( P != None ) { if (P.Enemy == Other) P.LastSeenPos = Other.Location; P = P.nextPawn; } } R.Roll = 0; Pawn(Other).ViewRotation = R; Pawn(Other).ClientSetLocation(L, R ); Pawn(Other).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 ) { Super.ActorLeaving(Other); If ( Other.IsA('Pawn') ) Pawn(Other).bWarping = false; } State DelayedWarp { function Tick(float DeltaTime) { local Pawn P; local bool bFound; For ( P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.bWarping && (P.Region.Zone == Self) ) { bFound = true; ActorEntered(P); } If ( !bFound ) GotoState(''); } } w4Y //============================================================================= // VoicePack. //============================================================================= class VoicePack extends Info abstract; /* (exec function to do ServerVoiceMessage, and use in OrdersMenu) (voicepack configuration for players and bots) */ /* 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); function PlayerSpeech(int Type, int Index, int Callsign); w4X//============================================================================= // Event. //============================================================================= class Triggers extends Actor native; w4N//============================================================================= // TriggerMarker. //============================================================================= class TriggerMarker extends NavigationPoint native; // OBSOLETE - to be removed w4f=//============================================================================= // TriggerLight. // A lightsource which can be triggered on or off. //============================================================================= class TriggerLight extends Light; //----------------------------------------------------------------------------- // Variables. var() float ChangeTime; // Time light takes to change from on to off. var() bool bInitiallyOn; // Whether it's initially on. var() bool bDelayFullOn; // Delay then go full-on. var() float RemainOnTime; // How long the TriggerPound effect lasts var float InitialBrightness; // Initial brightness. var float Alpha, Direction; var actor SavedTrigger; var float poundTime; //----------------------------------------------------------------------------- // Engine functions. // Called at start of gameplay. simulated function BeginPlay() { // Remember initial light type and set new one. Disable( 'Tick' ); InitialBrightness = LightBrightness; if( bInitiallyOn ) { Alpha = 1.0; Direction = 1.0; } else { Alpha = 0.0; Direction = -1.0; } DrawType = DT_None; } // Called whenever time passes. function Tick( float DeltaTime ) { Alpha += Direction * DeltaTime / ChangeTime; if( Alpha > 1.0 ) { Alpha = 1.0; Disable( 'Tick' ); if( SavedTrigger != None ) SavedTrigger.EndEvent(); } else if( Alpha < 0.0 ) { Alpha = 0.0; Disable( 'Tick' ); if( SavedTrigger != None ) SavedTrigger.EndEvent(); } if( !bDelayFullOn ) LightBrightness = Alpha * InitialBrightness; else if( (Direction>0 && Alpha!=1) || Alpha==0 ) LightBrightness = 0; else LightBrightness = InitialBrightness; } //----------------------------------------------------------------------------- // Public states. // Trigger turns the light on. state() TriggerTurnsOn { function Trigger( actor Other, pawn EventInstigator ) { if( SavedTrigger!=None ) SavedTrigger.EndEvent(); SavedTrigger = Other; SavedTrigger.BeginEvent(); Direction = 1.0; Enable( 'Tick' ); } } // Trigger turns the light off. state() TriggerTurnsOff { function Trigger( actor Other, pawn EventInstigator ) { if( SavedTrigger!=None ) SavedTrigger.EndEvent(); SavedTrigger = Other; SavedTrigger.BeginEvent(); Direction = -1.0; Enable( 'Tick' ); } } // Trigger toggles the light. state() TriggerToggle { function Trigger( actor Other, pawn EventInstigator ) { if( SavedTrigger!=None ) SavedTrigger.EndEvent(); SavedTrigger = Other; SavedTrigger.BeginEvent(); Direction *= -1; Enable( 'Tick' ); } } // Trigger controls the light. state() TriggerControl { function Trigger( actor Other, pawn EventInstigator ) { if( SavedTrigger!=None ) SavedTrigger.EndEvent(); SavedTrigger = Other; SavedTrigger.BeginEvent(); if( bInitiallyOn ) Direction = -1.0; else Direction = 1.0; Enable( 'Tick' ); } function UnTrigger( actor Other, pawn EventInstigator ) { if( SavedTrigger!=None ) SavedTrigger.EndEvent(); SavedTrigger = Other; SavedTrigger.BeginEvent(); if( bInitiallyOn ) Direction = 1.0; else Direction = -1.0; Enable( 'Tick' ); } } state() TriggerPound { function Timer () { if (poundTime >= RemainOnTime) { Disable ('Timer'); } poundTime += ChangeTime; Direction *= -1; SetTimer (ChangeTime, false); } function Trigger( actor Other, pawn EventInstigator ) { if( SavedTrigger!=None ) SavedTrigger.EndEvent(); SavedTrigger = Other; SavedTrigger.BeginEvent(); Direction = 1; poundTime = ChangeTime; // how much time will pass till reversal SetTimer (ChangeTime, false); // wake up when it's time to reverse Enable ('Timer'); Enable ('Tick'); } } _ MLdKbNLy_ %8x.ԝXԝXԝXԝXԝXԝXԝXԝXԝXԝXԝXԝXԝXԝXGS=S7Yw4w4Ar//============================================================================= // 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 Flags=2 //----------------------------------------------------------------------------- // 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 that class only TT_AnyProximity, // Trigger is activated by any actor in proximity. TT_Shoot, // Trigger is activated by player shooting it. } 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; //============================================================================= // AI related functions function PostBeginPlay() { if ( !bInitiallyActive ) FindTriggerActor(); if ( TriggerType == TT_Shoot ) { bHidden = false; bProjTarget = true; DrawType = DT_None; } Super.PostBeginPlay(); } function FindTriggerActor() { local Actor A; TriggerActor = None; TriggerActor2 = None; ForEach AllActors(class 'Actor', A) if ( A.Event == Tag) { if ( Counter(A) != None ) return; //FIXME - handle counters if (TriggerActor == None) TriggerActor = A; else { TriggerActor2 = A; return; } } } function Actor SpecialHandling(Pawn Other) { local int i; if ( bTriggerOnceOnly && !bCollideActors ) return None; if ( (TriggerType == TT_PlayerProximity) && !Other.bIsPlayer ) 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.bCanDoSpecial || (Other.Weapon == None) ) return None; Other.Target = self; Other.bShootSpecial = true; Other.FireWeapon(); Other.bFire = 0; Other.bAltFire = 0; return Other; } // can other trigger it right away? if ( IsRelevant(Other) ) { for (i=0;i<4;i++) if (Touching[i] == Other) Touch(Other); return self; } return self; } // when trigger gets turned on, check its touch list function CheckTouchList() { local int i; for (i=0;i<4;i++) if ( Touching[i] != None ) Touch(Touching[i]); } //============================================================================= // 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 ) { if( !bInitiallyActive ) return false; switch( TriggerType ) { case TT_PlayerProximity: return Pawn(Other)!=None && Pawn(Other).bIsPlayer; case TT_PawnProximity: return Pawn(Other)!=None && ( Pawn(Other).Intelligence > BRAINS_None ); case TT_ClassProximity: return ClassIsChildOf(Other.Class, ClassProximityType); case TT_AnyProximity: return true; case TT_Shoot: return ( (Projectile(Other) != None) && (Projectile(Other).Damage >= DamageThreshold) ); } } // // Called when something touches the trigger. // function Touch( actor Other ) { local actor A; if( IsRelevant( Other ) ) { if ( ReTriggerDelay > 0 ) { if ( Level.TimeSeconds - TriggerTime < ReTriggerDelay ) return; TriggerTime = Level.TimeSeconds; } // Broadcast the Trigger message to all matching actors. if( Event != '' ) foreach AllActors( class 'Actor', A, Event ) A.Trigger( Other, Other.Instigator ); if ( Other.IsA('Pawn') && (Pawn(Other).SpecialGoal == self) ) Pawn(Other).SpecialGoal = None; if( Message != "" ) // 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 int i; bKeepTiming = false; for (i=0;i<4;i++) if ( (Touching[i] != None) && IsRelevant(Touching[i]) ) { bKeepTiming = true; Touch(Touching[i]); } if ( bKeepTiming ) SetTimer(RepeatTriggerTime, false); } function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType) { local actor A; 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. if( Event != '' ) foreach AllActors( class 'Actor', A, Event ) A.Trigger( instigatedBy, instigatedBy ); if( Message != "" ) // Send a string message to the toucher. instigatedBy.Instigator.ClientMessage( Message ); if( bTriggerOnceOnly ) // Ignore future touches. SetCollision(False); } } // // When something untouches the trigger. // function UnTouch( actor Other ) { local actor A; if( IsRelevant( Other ) ) { // Untrigger all matching actors. if( Event != '' ) foreach AllActors( class 'Actor', A, Event ) A.UnTrigger( Other, Other.Instigator ); } } w4d0//============================================================================= // Texture: An Unreal texture map. // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class Texture extends Bitmap safereplace native noexport; // Subtextures. var(Texture) texture BumpMap; // Bump map to illuminate this texture with. var(Texture) texture DetailTexture; // Detail texture to apply. var(Texture) texture MacroTexture; // Macrotexture to apply, not currently used. // Surface properties. var(Texture) float Diffuse; // Diffuse lighting coefficient. var(Texture) float Specular; // Specular lighting coefficient. var(Texture) float Alpha; // Alpha. var(Texture) float DrawScale; // Scaling relative to parent. var(Texture) float Friction; // Surface friction coefficient, 1.0=none, 0.95=some. var(Texture) float MipMult; // Mipmap multiplier. // Sounds. var() sound FootstepSound; // Footstep sound. var() sound HitSound; // Sound when the texture is hit with a projectile. // Surface flags. !!out of date var bool bInvisible; var(Surface) editconst bool bMasked; var(Surface) bool bTransparent; var bool bNotSolid; var(Surface) bool bEnvironment; var bool bSemisolid; var(Surface) bool bModulate; var(Surface) bool bFakeBackdrop; var(Surface) bool bTwoSided; var(Surface) bool bAutoUPan; var(Surface) bool bAutoVPan; var(Surface) bool bNoSmooth; var(Surface) bool bBigWavy; var(Surface) bool bSmallWavy; var(Surface) bool bWaterWavy; var bool bLowShadowDetail; var bool bNoMerge; var(Surface) bool bCloudWavy; var bool bDirtyShadows; var bool bHighLedge; var bool bSpecialLit; var bool bGouraud; var(Surface) bool bUnlit; var bool bHighShadowDetail; var bool bPortal; var const bool bMirrored, bX2, bX3; var const bool bX4, bX5, bX6, bX7; // Texture flags. 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 private bool bHasComp; // Whether a compressed version exists. // Level of detail set. var(Quality) enum ELODSet { LODSET_None, // No level of detail mipmap tossing. LODSET_World, // World level-of-detail set. LODSET_Skin, // Skin level-of-detail set. } LODSet; // 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, CompMips; var const ETextureFormat CompFormat; w4p//============================================================================= // TestObj: A purely scripted object for internal testing. //============================================================================= class TestObj extends Object; function Test() { log( "TestObj.Test" ); } w4uk//============================================================================= // For internal testing. //============================================================================= class TestInfo extends Info; var() bool bTrue1; var() bool bFalse1; var() bool bTrue2; var() bool bFalse2; var bool bBool1; var bool bBool2; var() int xnum; var float ppp; var string sxx; var int MyArray[2]; var vector v1,v2; var string TestRepStr; //var string[32] teststring; const Pie=3.14; const Str="Tim"; const Lotus=vect(1,2,3); var struct STest { var bool b1; var int i; var bool b2; var bool b3; } ST; function TestQ() { local vector v; v.x = 2; v.y = 3; v.z = 4; assert(v==vect(2,3,4)); assert(v.z==4); assert(v.y==3); assert(v.x==2); } static function test() { class'testinfo'.default.v1 = vect(1,2,3); } function PostBeginPlay() { local object o; local actor TempActor; log("!!BEGIN"); default.v1=vect(5,4,3); assert(default.v1==vect(5,4,3)); test(); assert(default.v1==vect(1,2,3)); BroadcastMessage(Tag); BroadcastMessage(string(Tag)); BroadcastMessage("test "$string(Tag)); assert(IsA('Actor')); assert(IsA('TestInfo')); assert(IsA('Info')); assert(!IsA('LevelInfo')); assert(!IsA('Texture')); //o=dynamicloadobject( "UnrealShare.AutoMag.Reload", class'object' ); //assert(o!=None); //assert(o==None); log("!!END"); } function TestStructBools() { assert(ST.b1==false); assert(ST.b2==false); assert(ST.b3==false); ST.b1=true; assert(ST.b1==true); assert(ST.b2==false); assert(ST.b3==false); ST.b2=true; assert(ST.b1==true); assert(ST.b2==true); assert(ST.b3==false); ST.b3=true; assert(ST.b1==true); assert(ST.b2==true); assert(ST.b3==true); ST.b1=false; ST.b2=false; ST.b3=false; } function BeginPlay() { local testobj to; local object oo; to = new class'TestObj'; to = new()class'TestObj'; to = new(self)class'TestObj'; to = new(self,'')class'TestObj'; to = new(self,'',0)class'TestObj'; to.Test(); TestStructBools(); } function TestX( bool bResource ) { local int n; n = int(bResource); MyArray[ int(bResource) ] = 0; MyArray[ int(bResource) ]++; } function bool RecurseTest() { bBool1=true; return false; } function TestLimitor( class c ) { local class NewClass; NewClass = class( c ); } static function int OtherStatic( int i ) { assert(i==246); assert(default.xnum==777); return 555; } static function int TestStatic( int i ) { assert(i==123); assert(default.xnum==777); assert(OtherStatic(i*2)==555); } function TestContinueFor() { local int i; log("TestContinue"); for( i=0; i<20; i++ ) { log("iteration "$i); if(i==7||i==9||i==19) continue; log("..."); } log("DoneContinue"); } function TestContinueWhile() { local int i; log("TestContinue"); while( ++i <= 20 ) { log("iteration "$i); if(i==7||i==9) continue; log("..."); } log("DoneContinue"); } function TestContinueDoUntil() { local int i; log("TestContinue"); do { i++; log("iteration "$i); if(i==7||i==9||i>18) continue; log("..."); } until( i>20 ); log("DoneContinue"); } function TestContinueForEach() { local actor a; log("TestContinue"); foreach AllActors( class'Actor', a ) { log("actor "$a); if(light(a)==none) continue; log("..."); } log("DoneContinue"); } function SubTestOptionalOut( optional out int a, optional out int b, optional out int c ) { a *= 2; b = b*2; c += c; } function TestOptionalOut() { local int a,b,c; a=1; b=2; c=3; SubTestOptionalOut(a,b,c); assert(a==2); assert(b==4); assert(c==6); SubTestOptionalOut(a,b); assert(a==4); assert(b==8); assert(c==6); SubTestOptionalOut(,b,c); assert(a==4); assert(b==16); assert(c==12); SubTestOptionalOut(); assert(a==4); assert(b==16); assert(c==12); SubTestOptionalOut(a,b,c); assert(a==8); assert(b==32); assert(c==24); log("TestOptionalOut ok!"); } function TestNullContext( actor a ) { bHidden = a.bHidden; a.bHidden = bHidden; } function TestSwitch() { local string s; local int i; local bool b; s="Tim"; i=2; switch( i ) { case 0: assert(false); break; case 2: b=true; break; default: assert(false); break; } assert(b); switch( s ) { case "": assert(false); break; case "xyzzy": assert(false); break; default: b=false; break; } assert(!b); log("testswitch succeeded"); } function Tick( float DeltaTime ) { local class C; local class TC; local actor a; log("time="$Level.TimeSeconds); TestOptionalOut(); TestNullContext( self ); TestNullContext( None ); TestSwitch(); v1=vect(1,2,3); v2=vect(2,4,6); assert(v1!=v2); assert(!(v1==v2)); assert(v1==vect(1,2,3)); assert(v2==vect(2,4,6)); assert(vect(1,2,5)!=v1); assert(v1*2==v2); assert(v1==v2/2); assert(Pie==3.14); assert(Pie!=2); assert(Str=="Tim"); assert(Str!="Bob"); assert(Lotus==vect(1,2,3)); assert(GetPropertyText("sxx")=="Tim"); assert(GetPropertyText("ppp")!="123"); assert(GetPropertyText("bogus")==""); xnum=345; assert(GetPropertyText("xnum")=="345"); SetPropertyText("xnum","999"); assert(xnum==999); assert(xnum!=666); assert(bTrue1==true); assert(bFalse1==false); assert(bTrue2==true); assert(bFalse2==false); assert(default.bTrue1==true); assert(default.bFalse1==false); assert(default.bTrue2==true); assert(default.bFalse2==false); assert(class'TestInfo'.default.bTrue1==true); assert(class'TestInfo'.default.bFalse1==false); assert(class'TestInfo'.default.bTrue2==true); assert(class'TestInfo'.default.bFalse2==false); TC=Class; assert(TC.default.bTrue1==true); assert(TC.default.bFalse1==false); assert(TC.default.bTrue2==true); assert(TC.default.bFalse2==false); C=Class; assert(class(C).default.bTrue1==true); assert(class(C).default.bFalse1==false); assert(class(C).default.bTrue2==true); assert(class(C).default.bFalse2==false); assert(default.xnum==777); TestStatic(123); TC.static.TestStatic(123); class(C).static.TestStatic(123); bBool2=RecurseTest(); assert(bBool2==false); TestStructBools(); TestQ(); log( "All tests passed" ); } function f(); function temp() { local int i; local playerpawn PlayerOwner; local name LeftList[20]; for( i=0; i<20; i++ ) PlayerOwner.WeaponPriority[i] = LeftList[i+1]; temp(); } state AA { function f(); } state BB { function f(); } state CCAA extends AA { function f(); } state DDAA extends AA { function f(); } state EEDDAA extends DDAA { function f(); } w4|v///============================================================================= // Teleports actors either between different teleporters within a level // or to matching teleporters on other levels, or to general Internet URLs. //============================================================================= class Teleporter extends NavigationPoint native; #exec Texture Import File=Textures\Teleport.pcx Name=S_Teleport Mips=Off Flags=2 //----------------------------------------------------------------------------- // 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() { if (URL ~= "") SetCollision(false, false, false); //destination only if ( !bEnabled ) FindTriggerActor(); Super.PostBeginPlay(); } function FindTriggerActor() { local Actor A; TriggerActor = None; TriggerActor2 = None; ForEach AllActors(class 'Actor', A) if ( A.Event == Tag) { if ( Counter(A) != None ) return; //FIXME - handle counters if (TriggerActor == None) TriggerActor = A; else { TriggerActor2 = A; return; } } } // Accept an actor that has teleported in. simulated function bool Accept( actor Incoming, Actor Source ) { local rotator newRot, oldRot; local int oldYaw; local float mag; local vector oldDir; local pawn P; // Move the actor here. Disable('Touch'); //log("Move Actor here "$tag); newRot = Incoming.Rotation; if (bChangesYaw) { oldRot = Incoming.Rotation; newRot.Yaw = Rotation.Yaw; if ( Source != None ) newRot.Yaw += (32768 + Incoming.Rotation.Yaw - Source.Rotation.Yaw); } if ( Pawn(Incoming) != None ) { //tell enemies about teleport if ( Role == ROLE_Authority ) { P = Level.PawnList; While ( P != None ) { if (P.Enemy == Incoming) P.LastSeenPos = Incoming.Location; P = P.nextPawn; } } Pawn(Incoming).SetLocation(Location); if ( (Role == ROLE_Authority) || (Level.TimeSeconds - LastFired > 0.5) ) { Pawn(Incoming).SetRotation(newRot); Pawn(Incoming).ViewRotation = newRot; LastFired = Level.TimeSeconds; } Pawn(Incoming).MoveTimer = -1.0; Pawn(Incoming).MoveTarget = self; PlayTeleportEffect( Incoming, false); } 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; } // Play teleport-in effect. return true; } function PlayTeleportEffect(actor Incoming, bool bOut) { if ( Incoming.IsA('Pawn') ) { Incoming.MakeNoise(1.0); Level.Game.PlayTeleportEffect(Incoming, bOut, true); } } //----------------------------------------------------------------------------- // Teleporter functions. function Trigger( actor Other, pawn EventInstigator ) { local int i; bEnabled = !bEnabled; if ( bEnabled ) //teleport any pawns already in my radius for (i=0;i<4;i++) if ( Touching[i] != None ) Touch(Touching[i]); } // Teleporter was touched by an actor. simulated function Touch( actor Other ) { local Teleporter Dest; local int i; local Actor A; if ( !bEnabled ) return; if( Other.bCanTeleport && Other.PreTeleport(Self)==false ) { if( (InStr( URL, "/" ) >= 0) || (InStr( URL, "#" ) >= 0) ) { // Teleport to a level on the net. if( (Role == ROLE_Authority) && (PlayerPawn(Other) != None) ) Level.Game.SendPlayer(PlayerPawn(Other), URL); } else { // Teleport to a random teleporter in this local level, if more than one pick random. foreach AllActors( class 'Teleporter', Dest ) if( string(Dest.tag)~=URL && Dest!=Self ) i++; i = rand(i); foreach AllActors( class 'Teleporter', Dest ) if( string(Dest.tag)~=URL && Dest!=Self && i-- == 0 ) break; if( Dest != None ) { // Teleport the actor into the other teleporter. if ( Other.IsA('Pawn') ) PlayTeleportEffect( Pawn(Other), false); Dest.Accept( Other, self ); if( (Event != '') && (Other.IsA('Pawn')) ) foreach AllActors( class 'Actor', A, Event ) A.Trigger( Other, Other.Instigator ); } else if ( Role == ROLE_Authority ) Pawn(Other).ClientMessage( "Teleport destination for "$self$" not found!" ); } } } /* 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 int i; local vector Dist2D; if ( bEnabled && (Other.RouteCache[1] != None) && Other.RouteCache[1].IsA('Teleporter') && (string(Other.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 ) Touch(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; } w4dRO)]GA&$wl*l]O)v% w4b(//============================================================================= // Logs game events for stat collection // // Logs to a file. //============================================================================= class StatLogFile extends StatLog native; var bool bWatermark; // Internal var int LogAr; // C++ FArchive*. // Configs var string StatLogFile; var string StatLogFinal; // File Manipulation native final function OpenLog(); native final function CloseLog(); native final function Watermark( string EventString ); native final function GetChecksum( out string Checksum ); native final function FileFlush(); native final function FileLog( string EventString ); // Logging. function StartLog() { local string FileName; local string AbsoluteTime; SaveConfig(); AbsoluteTime = GetShortAbsoluteTime(); if (!bWorld) { FileName = LocalLogDir$"/"$GameName$"."$LocalStandard$"."$AbsoluteTime$"."$Level.Game.GetServerPort(); StatLogFile = FileName$".tmp"; StatLogFinal = FileName$".log"; } else { FileName = WorldLogDir$"/"$GameName$"."$WorldStandard$"."$AbsoluteTime$"."$Level.Game.GetServerPort(); StatLogFile = FileName$".tmp"; StatLogFinal = FileName$".log"; bWatermark = True; } OpenLog(); } function StopLog() { FlushLog(); CloseLog(); } function FlushLog() { FileFlush(); } function LogEventString( string EventString ) { if( bWatermark ) Watermark( EventString ); FileLog( EventString ); FlushLog(); } // Return a logfile name if relevant. function string GetLogFileName() { return StatLogFinal; } function LogPlayerConnect(Pawn Player, optional string Checksum) { if( bWorld ) { if( Player.PlayerReplicationInfo.bIsABot ) Checksum = "IsABot"; if (Player.IsA('PlayerPawn')) LogEventString( GetTimeStamp()$Chr(9)$"player"$Chr(9)$"Connect"$Chr(9)$Player.PlayerReplicationInfo.PlayerName$Chr(9)$Player.PlayerReplicationInfo.PlayerID$Chr(9)$PlayerPawn(Player).bAdmin$Chr(9)$Checksum ); else LogEventString( GetTimeStamp()$Chr(9)$"player"$Chr(9)$"Connect"$Chr(9)$Player.PlayerReplicationInfo.PlayerName$Chr(9)$Player.PlayerReplicationInfo.PlayerID$Chr(9)$False$Chr(9)$Checksum ); LogPlayerInfo( Player ); } else Super.LogPlayerConnect( Player, Checksum ); } function LogGameEnd( string Reason ) { local string Checksum; if( bWorld ) { bWatermark = False; GetChecksum( Checksum ); LogEventString(GetTimeStamp()$Chr(9)$"game_end"$Chr(9)$Reason$Chr(9)$Checksum$""); } else Super.LogGameEnd(Reason); } w4J//============================================================================= // Logs game events for stat collection // // ngLog, ngStats, and ngWorldStats are registered trademarks of // NetGames USA, Inc. at http://www.netgamesusa.com All rights reserved. A // ny and all occurrences of code related to supporting their products and // services appears with their express permission. //============================================================================= class StatLog extends Info native; // Internal var int Context; // State var bool bWorld; // Time var float TimeStamp; // Log Variables var() string LocalStandard; // The standard this log is compliant to. var() string WorldStandard; // The standard this log is compliant to. var() string LogVersion; // Version of the log standard. var() string LogInfoURL; // URL to info on logging standard. var() string GameName; // Name of this game. var() string GameCreator; // Name of game creator. var() string GameCreatorURL; // URL to info on game creator. var() string DecoderRingURL; // URL to log format decoder ring. var() globalconfig string LocalBatcherURL; // Batcher URL. var() globalconfig string LocalBatcherParams; // Batcher command line parameters. var() globalconfig string LocalStatsURL; // URL to local stats information. var() globalconfig string WorldBatcherURL; // Batcher URL. var() globalconfig string WorldBatcherParams; // Batcher command line parameters. var() globalconfig string WorldStatsURL; // URL to world stats information. var() globalconfig string LocalLogDir; var() globalconfig string WorldLogDir; var() globalconfig bool bLogTypingEvents; // UTPG - Allow admin to control whether server logs typing events var globalconfig bool bWorldBatcherError; // An error occured last time we tried to process stats. // Object function BeginPlay() { SetTimer(30.0, True); } function Timer() { LogPings(); } // Logging function StartLog() { // Implemented in subclass. } function StopLog() { // Implemented in subclass. } function FlushLog() { // Implemented in subclass. } function LogEventString( string EventString ) { Log( EventString ); } // Batching native final function ExecuteLocalLogBatcher(); native final function ExecuteSilentLogBatcher(); native final static function BatchLocal(); native final function ExecuteWorldLogBatcher(); native static function BrowseRelativeLocalURL(string URL); // Special native final function InitialCheck( GameInfo Game ); native final function LogMutator( Mutator M ); native static function GetPlayerChecksum( PlayerPawn P, out string Checksum ); // Time native final function string GetGMTRef(); // Return absolute time. function string GetAbsoluteTime() { local string AbsoluteTime; local string GMTRef; AbsoluteTime = string(Level.Year); if (Level.Month < 10) AbsoluteTime = AbsoluteTime$".0"$Level.Month; else AbsoluteTime = AbsoluteTime$"."$Level.Month; if (Level.Day < 10) AbsoluteTime = AbsoluteTime$".0"$Level.Day; else AbsoluteTime = AbsoluteTime$"."$Level.Day; if (Level.Hour < 10) AbsoluteTime = AbsoluteTime$".0"$Level.Hour; else AbsoluteTime = AbsoluteTime$"."$Level.Hour; if (Level.Minute < 10) AbsoluteTime = AbsoluteTime$".0"$Level.Minute; else AbsoluteTime = AbsoluteTime$"."$Level.Minute; if (Level.Second < 10) AbsoluteTime = AbsoluteTime$".0"$Level.Second; else AbsoluteTime = AbsoluteTime$"."$Level.Second; if (Level.Millisecond < 10) AbsoluteTime = AbsoluteTime$".0"$Level.Millisecond; else AbsoluteTime = AbsoluteTime$"."$Level.Millisecond; GMTRef = GetGMTRef(); AbsoluteTime = AbsoluteTime$"."$GMTRef; TimeStamp = 0; return AbsoluteTime; } // A less verbose version... function string GetShortAbsoluteTime() { local string AbsoluteTime; AbsoluteTime = string(Level.Year); if (Level.Month < 10) AbsoluteTime = AbsoluteTime$".0"$Level.Month; else AbsoluteTime = AbsoluteTime$"."$Level.Month; if (Level.Day < 10) AbsoluteTime = AbsoluteTime$".0"$Level.Day; else AbsoluteTime = AbsoluteTime$"."$Level.Day; if (Level.Hour < 10) AbsoluteTime = AbsoluteTime$".0"$Level.Hour; else AbsoluteTime = AbsoluteTime$"."$Level.Hour; if (Level.Minute < 10) AbsoluteTime = AbsoluteTime$".0"$Level.Minute; else AbsoluteTime = AbsoluteTime$"."$Level.Minute; if (Level.Second < 10) AbsoluteTime = AbsoluteTime$".0"$Level.Second; else AbsoluteTime = AbsoluteTime$"."$Level.Second; TimeStamp = 0; return AbsoluteTime; } // Return a timestamp relative to last absolute time. function string GetTimeStamp() { local string Time; local int Pos; Time = string(TimeStamp); Time = Left(Time, InStr(Time, ".") + 3); return Time; } // Return a logfile name if relevant. function string GetLogFileName() { return ""; } // Track relative timestamps. function Tick(float Delta) { TimeStamp += Delta; } // Standard Log Entries function LogStandardInfo() { if (bWorld) LogEventString(GetTimeStamp()$Chr(9)$"info"$Chr(9)$"Log_Standard"$Chr(9)$WorldStandard); else LogEventString(GetTimeStamp()$Chr(9)$"info"$Chr(9)$"Log_Standard"$Chr(9)$LocalStandard); LogEventString(GetTimeStamp()$Chr(9)$"info"$Chr(9)$"Log_Version"$Chr(9)$LogVersion); LogEventString(GetTimeStamp()$Chr(9)$"info"$Chr(9)$"Log_Info_URL"$Chr(9)$LogInfoURL); LogEventString(GetTimeStamp()$Chr(9)$"info"$Chr(9)$"Game_Name"$Chr(9)$GameName); LogEventString(GetTimeStamp()$Chr(9)$"info"$Chr(9)$"Game_Version"$Chr(9)$Level.EngineVersion); LogEventString(GetTimeStamp()$Chr(9)$"info"$Chr(9)$"Game_Creator"$Chr(9)$GameCreator); LogEventString(GetTimeStamp()$Chr(9)$"info"$Chr(9)$"Game_Creator_URL"$Chr(9)$GameCreatorURL); LogEventString(GetTimeStamp()$Chr(9)$"info"$Chr(9)$"Game_Decoder_Ring_URL"$Chr(9)$DecoderRingURL); LogEventString(GetTimeStamp()$Chr(9)$"info"$Chr(9)$"Absolute_Time"$Chr(9)$GetAbsoluteTime()); if (bWorld) { if( Level.ConsoleCommand("get UdpServerUplink douplink") ~= string(true) ) LogEventString(GetTimeStamp()$Chr(9)$"info"$Chr(9)$"Server_Public"$Chr(9)$"1"); else LogEventString(GetTimeStamp()$Chr(9)$"info"$Chr(9)$"Server_Public"$Chr(9)$"0"); } } function LogServerInfo() { local string NetworkNumber; NetworkNumber = Level.Game.GetNetworkNumber(); LogEventString(GetTimeStamp()$Chr(9)$"info"$Chr(9)$"Server_ServerName"$Chr(9)$Level.Game.GameReplicationInfo.ServerName); LogEventString(GetTimeStamp()$Chr(9)$"info"$Chr(9)$"Server_AdminName"$Chr(9)$Level.Game.GameReplicationInfo.AdminName); LogEventString(GetTimeStamp()$Chr(9)$"info"$Chr(9)$"Server_AdminEmail"$Chr(9)$Level.Game.GameReplicationInfo.AdminEmail); LogEventString(GetTimeStamp()$Chr(9)$"info"$Chr(9)$"Server_Region"$Chr(9)$Level.Game.GameReplicationInfo.Region); LogEventString(GetTimeStamp()$Chr(9)$"info"$Chr(9)$"Server_MOTDLine1"$Chr(9)$Level.Game.GameReplicationInfo.MOTDLine1); LogEventString(GetTimeStamp()$Chr(9)$"info"$Chr(9)$"Server_MOTDLine2"$Chr(9)$Level.Game.GameReplicationInfo.MOTDLine2); LogEventString(GetTimeStamp()$Chr(9)$"info"$Chr(9)$"Server_MOTDLine3"$Chr(9)$Level.Game.GameReplicationInfo.MOTDLine3); LogEventString(GetTimeStamp()$Chr(9)$"info"$Chr(9)$"Server_MOTDLine4"$Chr(9)$Level.Game.GameReplicationInfo.MOTDLine4); LogEventString(GetTimeStamp()$Chr(9)$"info"$Chr(9)$"Server_IP"$Chr(9)$NetworkNumber); LogEventString(GetTimeStamp()$Chr(9)$"info"$Chr(9)$"Server_Port"$Chr(9)$Level.Game.GetServerPort()); } final event LogGameSpecial(String SpecialID, String SpecialParam) { LogEventString(GetTimeStamp()$Chr(9)$"game"$Chr(9)$SpecialID$Chr(9)$SpecialParam); } final event LogGameSpecial2(String SpecialID, String SpecialParam, String SpecialParam2) { LogEventString(GetTimeStamp()$Chr(9)$"game"$Chr(9)$SpecialID$Chr(9)$SpecialParam$Chr(9)$SpecialParam2); } native final function string GetMapFileName(); function LogMapParameters() { local string MapName; MapName = GetMapFileName(); LogEventString(GetTimeStamp()$Chr(9)$"map"$Chr(9)$"Name"$Chr(9)$MapName); LogEventString(GetTimeStamp()$Chr(9)$"map"$Chr(9)$"Title"$Chr(9)$Level.Title); LogEventString(GetTimeStamp()$Chr(9)$"map"$Chr(9)$"Author"$Chr(9)$Level.Author); LogEventString(GetTimeStamp()$Chr(9)$"map"$Chr(9)$"IdealPlayerCount"$Chr(9)$Level.IdealPlayerCount); LogEventString(GetTimeStamp()$Chr(9)$"map"$Chr(9)$"LevelEnterText"$Chr(9)$Level.LevelEnterText); } function LogPlayerConnect(Pawn Player, optional string Checksum) { if (Player.IsA('PlayerPawn')) LogEventString(GetTimeStamp()$Chr(9)$"player"$Chr(9)$"Connect"$Chr(9)$Player.PlayerReplicationInfo.PlayerName$Chr(9)$Player.PlayerReplicationInfo.PlayerID$Chr(9)$PlayerPawn(Player).bAdmin); else LogEventString(GetTimeStamp()$Chr(9)$"player"$Chr(9)$"Connect"$Chr(9)$Player.PlayerReplicationInfo.PlayerName$Chr(9)$Player.PlayerReplicationInfo.PlayerID$Chr(9)$False); LogPlayerInfo(Player); } function LogPlayerInfo(Pawn Player) { LogEventString(GetTimeStamp()$Chr(9)$"player"$Chr(9)$"TeamName"$Chr(9)$Player.PlayerReplicationInfo.PlayerID$Chr(9)$Player.PlayerReplicationInfo.TeamName); LogEventString(GetTimeStamp()$Chr(9)$"player"$Chr(9)$"Team"$Chr(9)$Player.PlayerReplicationInfo.PlayerID$Chr(9)$Player.PlayerReplicationInfo.Team); LogEventString(GetTimeStamp()$Chr(9)$"player"$Chr(9)$"TeamID"$Chr(9)$Player.PlayerReplicationInfo.PlayerID$Chr(9)$Player.PlayerReplicationInfo.TeamID); LogEventString(GetTimeStamp()$Chr(9)$"player"$Chr(9)$"Ping"$Chr(9)$Player.PlayerReplicationInfo.PlayerID$Chr(9)$Player.PlayerReplicationInfo.Ping); LogEventString(GetTimeStamp()$Chr(9)$"player"$Chr(9)$"IsABot"$Chr(9)$Player.PlayerReplicationInfo.PlayerID$Chr(9)$Player.PlayerReplicationInfo.bIsABot); LogEventString(GetTimeStamp()$Chr(9)$"player"$Chr(9)$"Skill"$Chr(9)$Player.PlayerReplicationInfo.PlayerID$Chr(9)$Player.Skill); } function LogPlayerDisconnect(Pawn Player) { LogEventString(GetTimeStamp()$Chr(9)$"player"$Chr(9)$"Disconnect"$Chr(9)$Player.PlayerReplicationInfo.PlayerID); } function LogKill( int KillerID, int VictimID, string KillerWeaponName, string VictimWeaponName, name DamageType ) { LogEventString(GetTimeStamp()$Chr(9)$"kill"$Chr(9)$KillerID$Chr(9)$KillerWeaponName$Chr(9)$VictimID$Chr(9)$VictimWeaponName$Chr(9)$DamageType); } function LogTeamKill( int KillerID, int VictimID, string KillerWeaponName, string VictimWeaponName, name DamageType ) { LogEventString(GetTimeStamp()$Chr(9)$"teamkill"$Chr(9)$KillerID$Chr(9)$KillerWeaponName$Chr(9)$VictimID$Chr(9)$VictimWeaponName$Chr(9)$DamageType); } function LogSuicide(Pawn Killed, name DamageType, Pawn Instigator) { local int KilledID; local string InstigatorString; if (Killed == None) return; KilledID = Killed.PlayerReplicationInfo.PlayerID; if (Instigator == None) InstigatorString = "None"; else InstigatorString = "Self"; if (Killed.Weapon != None) LogEventString(GetTimeStamp()$Chr(9)$"suicide"$Chr(9)$KilledID$Chr(9)$Killed.Weapon.ItemName$Chr(9)$DamageType$Chr(9)$InstigatorString); else LogEventString(GetTimeStamp()$Chr(9)$"suicide"$Chr(9)$KilledID$Chr(9)$"None"$Chr(9)$DamageType$Chr(9)$InstigatorString); } function LogNameChange(Pawn Other) { LogEventString(GetTimeStamp()$Chr(9)$"player"$Chr(9)$"Rename"$Chr(9)$Other.PlayerReplicationInfo.PlayerName$Chr(9)$Other.PlayerReplicationInfo.PlayerID); } function LogTeamChange(Pawn Other) { LogEventString(GetTimeStamp()$Chr(9)$"player"$Chr(9)$"Teamchange"$Chr(9)$Other.PlayerReplicationInfo.PlayerID$Chr(9)$Other.PlayerReplicationInfo.Team); } function LogTypingEvent(bool bTyping, Pawn Other) { if (bLogTypingEvents) LogEventString(GetTimeStamp()$Chr(9)$"typing"$Chr(9)$bTyping$Chr(9)$Other.PlayerReplicationInfo.PlayerID); } function LogPickup(Inventory Item, Pawn Other) { if (Item.ItemName != "") LogEventString(GetTimeStamp()$Chr(9)$"item_get"$Chr(9)$Item.ItemName$Chr(9)$Other.PlayerReplicationInfo.PlayerID); else LogEventString(GetTimeStamp()$Chr(9)$"item_get"$Chr(9)$Item.Class$Chr(9)$Other.PlayerReplicationInfo.PlayerID); } function LogItemActivate(Inventory Item, Pawn Other) { if ( (Other == None) || (Other.PlayerReplicationInfo == None) || (Item == None) ) return; LogEventString(GetTimeStamp()$Chr(9)$"item_activate"$Chr(9)$Item.ItemName$Chr(9)$Other.PlayerReplicationInfo.PlayerID); } function LogItemDeactivate(Inventory Item, Pawn Other) { LogEventString(GetTimeStamp()$Chr(9)$"item_deactivate"$Chr(9)$Item.ItemName$Chr(9)$Other.PlayerReplicationInfo.PlayerID); } function LogSpecialEvent(string EventType, optional coerce string Arg1, optional coerce string Arg2, optional coerce string Arg3, optional coerce string Arg4) { local string Event; Event = EventType; if (Arg1 != "") Event = Event$Chr(9)$Arg1; if (Arg2 != "") Event = Event$Chr(9)$Arg2; if (Arg3 != "") Event = Event$Chr(9)$Arg3; if (Arg4 != "") Event = Event$Chr(9)$Arg4; LogEventString(GetTimeStamp()$Chr(9)$Event); } function LogPings() { local PlayerReplicationInfo PRI; foreach AllActors(class'PlayerReplicationInfo', PRI) LogEventString(GetTimeStamp()$Chr(9)$"player"$Chr(9)$"Ping"$Chr(9)$PRI.PlayerID$Chr(9)$PRI.Ping); } function LogGameStart() { LogEventString(GetTimeStamp()$Chr(9)$"game_start"); } function LogGameEnd( string Reason ) { LogEventString(GetTimeStamp()$Chr(9)$"game_end"$Chr(9)$Reason); } w4b//============================================================================= // A directional spotlight. //============================================================================= class Spotlight extends Light; w4I q7@!d C:>p ~@!A!  / _ WL@YLv_ %8x.l{ w4w4n6//============================================================================= // Spectator. //============================================================================= class Spectator extends PlayerPawn; var bool bChaseCam; function InitPlayerReplicationInfo() { Super.InitPlayerReplicationInfo(); PlayerReplicationInfo.bIsSpectator = true; } event FootZoneChange(ZoneInfo newFootZone) { } event HeadZoneChange(ZoneInfo newHeadZone) { } event PainTimer() { } exec function Walk() { } exec function BehindView( Bool B ) { bBehindView = B; bChaseCam = bBehindView; if ( ViewTarget == None ) bBehindView = false; } function ChangeTeam( int N ) { Level.Game.ChangeTeam(self, N); } exec function Taunt( name Sequence ) { } exec function CallForHelp() { } exec function ThrowWeapon() { } exec function Suicide() { } exec function Fly() { UnderWaterTime = -1; SetCollision(false, false, false); bCollideWorld = true; GotoState('CheatFlying'); ClientRestart(); } function ServerChangeSkin( coerce string SkinName, coerce string FaceName, byte TeamNum ) { } function ClientReStart() { //log("client restart"); Velocity = vect(0,0,0); Acceleration = vect(0,0,0); BaseEyeHeight = Default.BaseEyeHeight; EyeHeight = BaseEyeHeight; GotoState('CheatFlying'); } function PlayerTimeOut() { if (Health > 0) Died(None, 'dropped', Location); } exec function Grab() { } // Send a message to all players. exec function Say( string Msg ) { local Pawn P; if ( bAdmin && (left(Msg,1) == "#") ) { Msg = right(Msg,len(Msg)-1); for( P=Level.PawnList; P!=None; P=P.nextPawn ) if( P.IsA('PlayerPawn') ) { PlayerPawn(P).ClearProgressMessages(); PlayerPawn(P).SetProgressTime(6); PlayerPawn(P).SetProgressMessage(Msg,0); } return; } if ( Len(Msg) > 63 ) Msg = Left(Msg,63); if ( !Level.Game.bMuteSpectators ) BroadcastMessage( PlayerReplicationInfo.PlayerName$":"$Msg, true ); } //============================================================================= // functions. exec function RestartLevel() { } // This pawn was possessed by a player. function Possess() { bIsPlayer = true; DodgeClickTime = FMin(0.3, DodgeClickTime); EyeHeight = BaseEyeHeight; NetPriority = 2; Weapon = None; Inventory = None; Fly(); } function PostBeginPlay() { if (Level.LevelEnterText != "" ) ClientMessage(Level.LevelEnterText); bIsPlayer = true; FlashScale = vect(1,1,1); if ( Level.NetMode != NM_Client ) ScoringType = Level.Game.ScoreboardType; } //============================================================================= // Inventory-related input notifications. // The player wants to switch to weapon group numer I. exec function SwitchWeapon (byte F ) { } exec function NextItem() { } exec function PrevItem() { } exec function Fire( optional float F ) { ViewPlayerNum(-1); bBehindView = bChaseCam; if ( ViewTarget == None ) bBehindView = false; } // The player wants to alternate-fire. exec function AltFire( optional float F ) { bBehindView = false; Viewtarget = None; ClientMessage(ViewingFrom@OwnCamera, 'Event', true); } //================================================================================= function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType) { } w4v;//============================================================================= // SpecialEvent: Receives trigger messages and does some "special event" // depending on the state. //============================================================================= class SpecialEvent extends Triggers; #exec Texture Import File=Textures\TrigSpcl.pcx Name=S_SpecialEvent Mips=Off Flags=2 //----------------------------------------------------------------------------- // Variables. var() int Damage; // For DamagePlayer state. var() name DamageType; var() localized string DamageString; var() sound Sound; // For PlaySoundEffect state. var() localized string Message; // For all states. var() bool bBroadcast; // To broadcast the message to all players. var() bool bPlayerViewRot; // Whether player can rotate the view while pathing. //----------------------------------------------------------------------------- // Functions. function Trigger( actor Other, pawn EventInstigator ) { local pawn P; if( bBroadcast ) BroadcastMessage(Message, true, 'CriticalEvent'); // Broadcast message to all players. else if( EventInstigator!=None && len(Message)!=0 ) { // Send message to instigator only. EventInstigator.ClientMessage( Message ); } } //----------------------------------------------------------------------------- // States. // Just display the message. state() DisplayMessage { } // Damage the instigator who caused this event. state() DamageInstigator { function Trigger( actor Other, pawn EventInstigator ) { Global.Trigger( Self, EventInstigator ); if ( Other.IsA('PlayerPawn') ) Level.Game.SpecialDamageString = DamageString; Other.TakeDamage( Damage, EventInstigator, EventInstigator.Location, Vect(0,0,0), DamageType); } } // Kill the instigator who caused this event. state() KillInstigator { function Trigger( actor Other, pawn EventInstigator ) { Global.Trigger( Self, EventInstigator ); if ( Other.IsA('PlayerPawn') ) Level.Game.SpecialDamageString = DamageString; if( EventInstigator != None ) EventInstigator.Died( None, DamageType, EventInstigator.Location ); } } // Play a sound. state() PlaySoundEffect { function Trigger( actor Other, pawn EventInstigator ) { Global.Trigger( Self, EventInstigator ); PlaySound( Sound ); } } // Play a sound. state() PlayersPlaySoundEffect { function Trigger( actor Other, pawn EventInstigator ) { local pawn P; Global.Trigger( Self, EventInstigator ); for ( P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.bIsPlayer && P.IsA('PlayerPawn') ) PlayerPawn(P).ClientPlaySound(Sound); } } // Place Ambient sound effect on player state() PlayAmbientSoundEffect { function Trigger( actor Other, pawn EventInstigator ) { Global.Trigger( Self, EventInstigator ); EventInstigator.AmbientSound = AmbientSound; } } // Send the player on a spline path through the level. state() PlayerPath { function Trigger( actor Other, pawn EventInstigator ) { local InterpolationPoint i; Global.Trigger( Self, EventInstigator ); if( EventInstigator!=None && EventInstigator.bIsPlayer && (Level.NetMode == NM_Standalone) ) { foreach AllActors( class 'InterpolationPoint', i, Event ) { if( i.Position == 0 ) { EventInstigator.GotoState(''); EventInstigator.SetCollision(True,false,false); EventInstigator.bCollideWorld = False; EventInstigator.Target = i; EventInstigator.SetPhysics(PHYS_Interpolating); EventInstigator.PhysRate = 1.0; EventInstigator.PhysAlpha = 0.0; EventInstigator.bInterpolating = true; EventInstigator.AmbientSound = AmbientSound; } } } } } L[LzBr@2 \L'LLPTP}TTTTTTTTTTPTTT+TԝXP TTԝXP ԝXTT ZBw4w4l//============================================================================= // SpawnNotify - Actor spawn notification. // NB - This happens on the client AND server for replicated actors. //============================================================================= class SpawnNotify expands Actor native; var class ActorClass; var SpawnNotify Next; replication { reliable if( Role == ROLE_Authority ) ActorClass; } simulated function PostBeginPlay() { local SpawnNotify N; for(N = Level.SpawnNotify; N != None; N = N.Next) if(N == Self) return; Next = Level.SpawnNotify; Level.SpawnNotify = Self; } simulated event Destroyed() { local SpawnNotify N; if(Level.SpawnNotify == Self) { Level.SpawnNotify = Next; Next = None; } else { for(N = Level.SpawnNotify; N != None && N.Next != None; N = N.Next) { if(N.Next == Self) { N.Next = Next; Next = None; return; } } } } simulated event Actor SpawnNotification(Actor A) { return A; } w4d//============================================================================= // SkyZoneInfo. //============================================================================= class SkyZoneInfo extends ZoneInfo native; w4Y//============================================================================= // ScriptedTexture: A scriptable Unreal texture // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class ScriptedTexture extends Texture safereplace native noexport; // A SciptedTexture calls its Script's Render() method to draw to the texture at // runtime var Actor NotifyActor; var() Texture SourceTexture; var transient const int Junk1; // C++ stuff var transient const int Junk2; // C++ stuff var transient const int Junk3; // C++ stuff var transient const float LocalTime; // C++ stuff native(473) final function DrawTile( float X, float Y, float XL, float YL, float U, float V, float UL, float VL, Texture Tex, bool bMasked ); native(472) final function DrawText( float X, float Y, string Text, Font Font ); native(474) final function DrawColoredText( float X, float Y, string Text, Font Font, color FontColor ); native(475) final function ReplaceTexture( Texture Tex ); native(476) final function TextSize( string Text, out float XL, out float YL, Font Font ); w4@//============================================================================= // Scout used for path generation. //============================================================================= class Scout extends Pawn native; function PreBeginPlay() { Destroy(); //scouts shouldn't exist during play } w4q//============================================================================= // ScoreBoard //============================================================================= class ScoreBoard extends Info; var font RegFont; var HUD OwnerHUD; function ShowScores( canvas Canvas ); function ShowMiniScores( Canvas Canvas ); function PreBeginPlay() { } w4_//============================================================================= // ScaledSprite. //============================================================================= class ScaledSprite extends Decoration; <bLxBcLu<G |(w4w4K//============================================================================= // 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; // Distance moved. var bool bRun; var bool bDuck; var bool bPressedJump; var bool bFire; var bool bAltFire; var bool bForceFire; var bool bForceAltFire; var EDodgeDir DodgeMove; // Dodge info. final function Clear() { TimeStamp = 0; Delta = 0; DodgeMove = DODGE_None; Acceleration = vect(0,0,0); bFire = false; bRun = false; bDuck = false; bAltFire = false; bPressedJump = false; bForceFire = false; bForceAltFire = false; } w4Y //============================================================================= // RoundRobin: Each time it's triggered, it advances through a list of // outgoing events. //============================================================================= class RoundRobin extends Triggers; var() name OutEvents[16]; // Events to generate. var() bool bLoop; // Whether to loop when get to end. var int i; // Internal counter. // // When RoundRobin is triggered... // function Trigger( actor Other, pawn EventInstigator ) { local actor A; if( OutEvents[i] != '' ) { foreach AllActors( class 'Actor', A, OutEvents[i] ) { A.Trigger( Self, EventInstigator ); } if( ++i>=ArrayCount(OutEvents) || OutEvents[i]=='' ) { if( bLoop ) i=0; else SetCollision(false,false,false); } } } w4hLP#ח @ql#@L>mL>du>Su>&@@mqqP@::$LP&$"(P&$" w4NPbKg w4eiLf#K-kF#f# w4A 8ږm w4{7@w4w4nLv!aZ> w4]@w4LeLTBs@mLLPԝXw4w4RMME?66'[-O ::$q!?8v! w4@w4w4bZ \ <eha#?ezwauK!Z ծg?,9eZ *iZ uhgigZ կi?,h w4D8rLE^: .w_*_, T w4w4w4RzLvZ6UUdd-m-m-l-lw*@rUd-m-l-} w*-}'D-}( w4s//============================================================================= // ReplicationInfo. //============================================================================= class ReplicationInfo extends Info abstract native; w4w0//============================================================================= // Projectile. // // A delayed-hit projectile moves around for some time after it is created. // An instant-hit projectile acts immediately. //============================================================================= class Projectile extends Actor abstract native; #exec Texture Import File=Textures\S_Camera.pcx Name=S_Camera Mips=Off Flags=2 //----------------------------------------------------------------------------- // Projectile variables. // Motion information. var() float Speed; // Initial speed of projectile. var() float MaxSpeed; // Limit on speed of projectile (0 means no limit) // Damage attributes. var() float Damage; var() int MomentumTransfer; // Momentum imparted by impacting projectile. var() name MyDamageType; // Projectile sound effects var() sound SpawnSound; // Sound made when projectile is spawned. var() sound ImpactSound; // Sound made when projectile hits something. var() sound MiscSound; // Miscellaneous Sound. var() float ExploWallOut; // distance to move explosions out from wall // explosion decal var() class ExplosionDecal; //============== // 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 actor HitActor; local vector HitLocation, HitNormal, TestLocation; if ( Other.IsA('BlockAll') ) { HitWall( Normal(Location - Other.Location), Other); return; } if ( Other.bProjTarget || (Other.bBlockActors && Other.bBlockPlayers) ) { //get exact hitlocation HitActor = Trace(HitLocation, HitNormal, Location, OldLocation, true); if (HitActor == Other) { if ( Other.bIsPawn && !Pawn(Other).AdjustHitLocation(HitLocation, Velocity) ) return; ProcessTouch(Other, HitLocation); } else ProcessTouch(Other, Other.Location + Other.CollisionRadius * Normal(Location - Other.Location)); } } simulated function ProcessTouch(Actor Other, Vector HitLocation) { //should be implemented in subclass } simulated function HitWall (vector HitNormal, actor Wall) { if ( Role == ROLE_Authority ) { if ( (Mover(Wall) != None) && Mover(Wall).bDamageTriggered ) Wall.TakeDamage( Damage, instigator, Location, MomentumTransfer * Normal(Velocity), ''); MakeNoise(1.0); } Explode(Location + ExploWallOut * HitNormal, HitNormal); if ( (ExplosionDecal != None) && (Level.NetMode != NM_DedicatedServer) ) Spawn(ExplosionDecal,self,,Location, rotator(HitNormal)); } 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; } w4jo%5)o%w4I8r^t 8ra/! r  #(Ml% wM*saMrrNr  r  ra/! w.ro*.ro~.sxw.s*.so.ros@a s  կs)r)#?.ro*sa/! .s-Q'.sfws*s*r*sNrN'( w4w4w4vLn%y )n%w4\{LIrIp5UIdN-m-v-l-u`w*rUd-m-l-} w*-}'D-}( w4QM{aD4{ a@ tw4m%T9Say -Y 'q!p w4|LKF!9TeamSay -Y 'q!p w4}LJ  &%, w4~LL-  &%, w4L\*H\*y w4@w4w4@w4w4@Mg%GVg%yf% w4wLQ#C$ wl*l CQ#( w4GMNF, %FayV V NGF?%F=ǎT FNF?%FL>a@?&T 66-g6D?, C=N-g6?6??Cd6?6ff??C6Dff??C-g(?,N-g-gv6D?, C=N-g6'?6???CV6#?6?ff??C6D?ff??C-g'vv?,N-g-g_a6666%6%D?6?6, =N_6D?6, =N_66% w4CMe%Ie%i w4S8U!s B'-hl c #\ =U!|?n s66'a t(}k v6'a j(n n ?,\ k k ?,\ 6k|6kl ?, \ g}gc ?, \ l c #[6k"{?6k?k6k#???6g㥛<6g6g㥛<6g6g㥛<6g w4w4w4FM[#Y[#iZ# w4sw4w4U8`!c Pge-Ta%t!eH-`!Ea%t!|Z=eea%t!|_= w4IM\#^Q\#d w4PMq#dll^#@L>m=du>Su>R=d@lmlR#?9-]R6 6 6 6 YlO?R@$6YO?RA$p qq@::$Lqd$a=p (qd$a=p -e( w4w4w4LMd%Ed%dY# w4ec9X#KX%-kF#X# w4~NAMO=.4)w * /p|m  w4OMR#F R#K w4w4w4w4w4RMS#DXS#K?W# w4DMM9V-@ TM[M-@  wl*-@ l9M[-@  w4X8B353 w4UMNK gN%ZN,@NyNi!w4Nd*NKN~ w4Q//============================================================================= // Player start location. //============================================================================= class PlayerStart extends NavigationPoint native; #exec Texture Import File=Textures\S_Player.pcx Name=S_Player Mips=Off Flags=2 // 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; var() bool bSinglePlayerStart; var() bool bCoopStart; var() bool bEnabled; function Trigger( actor Other, pawn EventInstigator ) { bEnabled = !bEnabled; } function PlayTeleportEffect(actor Incoming, bool bOut) { if ( Level.Game.bDeathMatch && Incoming.IsA('PlayerPawn') ) PlayerPawn(Incoming).SetFOVAngle(135); Level.Game.PlayTeleportEffect(Incoming, bOut, Level.Game.bDeathMatch ); } w4XMb%^!{aTD?T&?,@a a &,@&Ti`%~@u TyaTdb%TKI ~ w4@ w4w4l"//============================================================================= // PlayerReplicationInfo. //============================================================================= class PlayerReplicationInfo expands ReplicationInfo native nativereplication; var string PlayerName; // Player name, or blank if none. var string OldName; // Temporary value. var int PlayerID; // Unique id number. var string TeamName; // Team name, or blank if none. var byte Team; // Player Team, 255 = None for player. var int TeamID; // Player position in team. var float Score; // Player's current score. var float Deaths; // Number of player's deaths. var class VoiceType; var Decoration HasFlag; var int Ping; var byte PacketLoss; var bool bIsFemale; var bool bIsABot; var bool bFeigningDeath; var bool bIsSpectator; var bool bWaitingPlayer; var bool bAdmin; var Texture TalkTexture; var ZoneInfo PlayerZone; var LocationID PlayerLocation; // Time elapsed. var int StartTime; var int TimeAcc; replication { // Things the server should send to the client. reliable if ( Role == ROLE_Authority ) PlayerName, OldName, PlayerID, TeamName, Team, TeamID, Score, Deaths, VoiceType, HasFlag, Ping, PacketLoss, bIsFemale, bIsABot, bFeigningDeath, bIsSpectator, bWaitingPlayer, bAdmin, TalkTexture, PlayerZone, PlayerLocation, StartTime; } function PostBeginPlay() { StartTime = Level.TimeSeconds; Timer(); SetTimer(2.0, true); bIsFemale = Pawn(Owner).bIsFemale; } function Timer() { local float MinDist, Dist; local LocationID L; MinDist = 1000000; PlayerLocation = None; if ( PlayerZone != None ) for ( L=PlayerZone.LocationID; L!=None; L=L.NextLocation ) { Dist = VSize(Owner.Location - L.Location); if ( (Dist < L.Radius) && (Dist < MinDist) ) { PlayerLocation = L; MinDist = Dist; } } if ( FRand() < 0.65 ) return; if (PlayerPawn(Owner) != None) Ping = int(PlayerPawn(Owner).ConsoleCommand("GETPING")); if (PlayerPawn(Owner) != None) PacketLoss = int(PlayerPawn(Owner).ConsoleCommand("GETLOSS")); } w4dMw4w4ZMaz V"{aTD?T&?,@a a &,@&Ti!,~@u TyaTd*TKI ~ w4C//============================================================================= // PlayerPawn. // player controlled pawns // Note that Pawns which implement functions for the PlayerTick messages // must handle player control in these functions //============================================================================= class PlayerPawn expands Pawn config(user) native nativereplication; // Player info. var const player Player; var globalconfig string Password; // for restarting coop savegames var travel float DodgeClickTimer; // max double click interval for dodge move var(Movement) globalconfig float DodgeClickTime; var(Movement) globalconfig float Bob; var float LandBob, AppliedBob; var float bobtime; // Camera info. var int ShowFlags; var int RendMap; var int Misc1; var int Misc2; var actor ViewTarget; var vector FlashScale, FlashFog; var HUD myHUD; var ScoreBoard Scoring; var class HUDType; var class ScoringType; var float DesiredFlashScale, ConstantGlowScale, InstantFlash; var vector DesiredFlashFog, ConstantGlowFog, InstantFog; var globalconfig float DesiredFOV; var globalconfig float DefaultFOV; // Music info. var music Song; var byte SongSection; var byte CdTrack; var EMusicTransition Transition; var float shaketimer; // player uses this for shaking view var int shakemag; // max magnitude in degrees of shaking var float shakevert; // max vertical shake magnitude var float maxshake; var float verttimer; var(Pawn) class CarcassType; var travel globalconfig float MyAutoAim; var travel globalconfig float Handedness; var(Sounds) sound JumpSound; // Player control flags var bool bAdmin; 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 bWasForward; // used for dodge move var bool bWasBack; var bool bWasLeft; var bool bWasRight; var bool bEdgeForward; var bool bEdgeBack; var bool bEdgeLeft; var bool bEdgeRight; var bool bIsCrouching; var bool bShakeDir; var bool bAnimTransition; var bool bIsTurning; var bool bFrozen; var bool bBadConnectionAlert; var globalconfig bool bInvertMouse; var bool bShowScores; var bool bShowMenu; var bool bSpecialMenu; var bool bWokeUp; var bool bPressedJump; var bool bUpdatePosition; var bool bDelayedCommand; var bool bRising; var bool bReducedVis; var bool bCenterView; var() globalconfig bool bMaxMouseSmoothing; var bool bMouseZeroed; var bool bReadyToPlay; var globalconfig bool bNoFlash; var globalconfig bool bNoVoices; var globalconfig bool bMessageBeep; var bool bZooming; var() bool bSinglePlayer; // this class allowed in single player var bool bJustFired; var bool bJustAltFired; var bool bIsTyping; var bool bFixedCamera; var globalconfig bool bNeverAutoSwitch; // if true, don't automatically switch to picked up weapon var bool bJumpStatus; // used in net games var bool bUpdating; var bool bCheatsEnabled; var float ZoomLevel; var class SpecialMenu; var string DelayedCommand; var globalconfig float MouseSensitivity; var globalconfig name WeaponPriority[50]; //weapon class priorities (9 is highest) var float SmoothMouseX, SmoothMouseY, BorrowedMouseX, BorrowedMouseY; var() globalconfig float MouseSmoothThreshold; var float MouseZeroTime; // Input axes. var input float aBaseX, aBaseY, aBaseZ, aMouseX, aMouseY, aForward, aTurn, aStrafe, aUp, aLookUp, aExtra4, aExtra3, aExtra2, aExtra1, aExtra0; // Move Buffering. var SavedMove SavedMoves; var SavedMove FreeMoves; var SavedMove PendingMove; var float CurrentTimeStamp,LastUpdateTime,ServerTimeStamp,TimeMargin, ClientUpdateTime; var globalconfig float MaxTimeMargin; // Progess Indicator. var string ProgressMessage[8]; var color ProgressColor[8]; var float ProgressTimeOut; // Localized strings var localized string QuickSaveString; var localized string NoPauseMessage; var localized string ViewingFrom; var localized string OwnCamera; var localized string FailedView; // ReplicationInfo var GameReplicationInfo GameReplicationInfo; // ngWorldStats Logging var() globalconfig private string ngWorldSecret; var() globalconfig bool ngSecretSet; var bool ReceivedSecretChecksum; // Remote Pawn ViewTargets var rotator TargetViewRotation; var float TargetEyeHeight; var vector TargetWeaponViewOffset; // Demo recording view rotation var int DemoViewPitch; var int DemoViewYaw; var float LastPlaySound; // text message sending var float LastMessageWindow; // UTPG -- var int LoginAttempts; // How many login attempts we've made var bool bLoginDisabled; // no longer able to login even if correct password var float NextLoginTime; // Time at which game will accept another attempt to login // All received from GameInfo var float ViewDelay; // Seconds between each viewplayer()/viewplayernum() var float TauntDelay; // Seconds between taunts var float SpeechDelay; // Seconds between chat messages var float LastView; // Used to track last view var float LastTaunt; // Used to track last taunt var float LastSpeech; // Used to track last chat message var bool bCyclingView; // Used to allow ViewClass to disregard LastView var float MinFOV; // Enforced MinFOV for this server var float MaxFOV; // Enforced MaxFOV for this server var int MaxNameChanges; // Max number of time a player can change their name in the game var int NameChanges; // Used to track name changes replication { // Things the server should send to the client. reliable if( bNetOwner && Role==ROLE_Authority ) ViewTarget, ScoringType, HUDType, GameReplicationInfo, bFixedCamera, bCheatsEnabled; unreliable if ( bNetOwner && Role==ROLE_Authority ) TargetViewRotation, TargetEyeHeight, TargetWeaponViewOffset; reliable if( bDemoRecording && Role==ROLE_Authority ) DemoViewPitch, DemoViewYaw; // Things the client should send to the server reliable if ( Role 0.01 ) { AppliedBob += FMin(1, 16 * deltatime) * LandBob; LandBob *= (1 - 8*Deltatime); } if ( Speed2D < 10 ) WalkBob.Z = AppliedBob + Bob * 30 * sin(12 * BobTime); else WalkBob.Z = AppliedBob + Bob * Speed2D * sin(12 * BobTime); } exec function ViewPlayerNum(optional int num) { local Pawn P; if ( !PlayerReplicationInfo.bIsSpectator && !Level.Game.bTeamGame ) return; if ( num >= 0 ) { P = Pawn(ViewTarget); if ( (P != None) && P.bIsPlayer && (P.PlayerReplicationInfo.TeamID == num) ) { ViewTarget = None; bBehindView = false; return; } for ( P=Level.PawnList; P!=None; P=P.NextPawn ) if ( (P.PlayerReplicationInfo != None) && (P.PlayerReplicationInfo.Team == PlayerReplicationInfo.Team) && !P.PlayerReplicationInfo.bIsSpectator && (P.PlayerReplicationInfo.TeamID == num) ) { if ( P != self ) { ViewTarget = P; bBehindView = true; } return; } return; } if ( Role == ROLE_Authority ) { if (ViewDelay > 0.0) if (bCyclingView || ((Level.TimeSeconds - LastView) < ViewDelay)) return; ViewClass(class'Pawn', true); bCyclingView = True; While ( (ViewTarget != None) && (!Pawn(ViewTarget).bIsPlayer || Pawn(ViewTarget).PlayerReplicationInfo.bIsSpectator) ) ViewClass(class'Pawn', true); bCyclingView = False; if ( ViewTarget != None ) ClientMessage(ViewingFrom@Pawn(ViewTarget).PlayerReplicationInfo.PlayerName, 'Event', true); else ClientMessage(ViewingFrom@OwnCamera, 'Event', true); LastView = Level.TimeSeconds; } } exec function Profile() { //TEMP for performance measurement log("Average AI Time"@Level.AvgAITime); log(" < 5% "$Level.AIProfile[0]); log(" < 10% "$Level.AIProfile[1]); log(" < 15% "$Level.AIProfile[2]); log(" < 20% "$Level.AIProfile[3]); log(" < 25% "$Level.AIProfile[4]); log(" < 30% "$Level.AIProfile[5]); log(" < 35% "$Level.AIProfile[6]); log(" > 35% "$Level.AIProfile[7]); } // Execute an administrative console command on the server. exec function Admin( string CommandLine ) { local string Result; if( bAdmin ) Result = ConsoleCommand( CommandLine ); if( Result!="" ) ClientMessage( Result ); } // Login as the administrator. exec function AdminLogin( string Password ) { if ( (Level.TimeSeconds < NextLoginTime) || bLoginDisabled ) return; Level.Game.AdminLogin( Self, Password ); if (bAdmin) { LoginAttempts = 0; return; } LoginAttempts++; NextLoginTime = Level.TimeSeconds + Level.Game.LoginDelaySeconds; if (LoginAttempts >= Level.Game.MaxLoginAttempts) { switch (Level.Game.ActionToTake) { case DO_KickBanPlayer: KickBanMe("Too many login attempts."); break; case DO_KickPlayer: KickMe("Too many login attempts."); break; case DO_DisableLogin: bLoginDisabled = True; break; case DO_Log: log(LoginAttempts@"incorrect admin login attempts from"@PlayerReplicationInfo.PlayerName@GetPlayerNetworkAddress()); } } } // Logout as the administrator. exec function AdminLogout() { Level.Game.AdminLogout( Self ); } exec function SShot() { local float b; b = float(ConsoleCommand("get ini:Engine.Engine.ViewportManager Brightness")); ConsoleCommand("set ini:Engine.Engine.ViewportManager Brightness 1"); ConsoleCommand("flush"); ConsoleCommand("shot"); ConsoleCommand("set ini:Engine.Engine.ViewportManager Brightness "$string(B)); ConsoleCommand("flush"); } exec function PlayerList() { local PlayerReplicationInfo PRI; log("Player List:"); ForEach AllActors(class'PlayerReplicationInfo', PRI) log(PRI.PlayerName@"( ping"@PRI.Ping$")"); } // // Native ClientSide Functions // event ReceiveLocalizedMessage( class Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ) { Message.Static.ClientReceive( Self, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject ); } event ClientMessage( coerce string S, optional Name Type, optional bool bBeep ) { if (Player == None) return; if (Type == '') Type = 'Event'; if (Player.Console != None) Player.Console.Message( PlayerReplicationInfo, S, Type ); if (bBeep && bMessageBeep) PlayBeepSound(); if ( myHUD != None ) myHUD.Message( PlayerReplicationInfo, S, Type ); } event TeamMessage( PlayerReplicationInfo PRI, coerce string S, name Type, optional bool bBeep ) { if (Player.Console != None) Player.Console.Message ( PRI, S, Type ); if (bBeep && bMessageBeep) PlayBeepSound(); if ( myHUD != None ) myHUD.Message( PRI, S, Type ); } 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); } simulated function PlayBeepSound(); // // Send movement to the server. // Passes acceleration in components so it doesn't get rounded. // function ServerMove ( float TimeStamp, vector InAccel, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, bool bFired, bool bAltFired, bool bForceFire, bool bForceAltFire, eDodgeDir DodgeMove, byte ClientRoll, int View, optional byte OldTimeDelta, optional int OldAccel ) { local float DeltaTime, clientErr, OldTimeStamp; local rotator DeltaRot, Rot; local vector Accel, LocDiff; local int maxPitch, ViewPitch, ViewYaw; local actor OldBase; local bool NewbPressedJump, OldbRun, OldbDuck; local eDodgeDir OldDodgeMove; // If this move is outdated, discard it. if ( CurrentTimeStamp >= TimeStamp ) return; // 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 ); OldbDuck = ( (OldAccel & 32) != 0 ); NewbPressedJump = ( (OldAccel & 16) != 0 ); if ( NewbPressedJump ) bJumpStatus = NewbJumpStatus; switch (OldAccel & 7) { case 0: OldDodgeMove = DODGE_None; break; case 1: OldDodgeMove = DODGE_Left; break; case 2: OldDodgeMove = DODGE_Right; break; case 3: OldDodgeMove = DODGE_Forward; break; case 4: OldDodgeMove = DODGE_Back; break; } //log("Recovered move from "$OldTimeStamp$" acceleration "$Accel$" from "$OldAccel); MoveAutonomous(OldTimeStamp - CurrentTimeStamp, OldbRun, OldbDuck, NewbPressedJump, OldDodgeMove, Accel, rot(0,0,0)); CurrentTimeStamp = OldTimeStamp; } } // View components ViewPitch = View/32768; ViewYaw = 2 * (View - 32768 * ViewPitch); ViewPitch *= 2; // Make acceleration. Accel = InAccel/10; NewbPressedJump = (bJumpStatus != NewbJumpStatus); bJumpStatus = NewbJumpStatus; // handle firing and alt-firing if ( bFired ) { if ( bForceFire && (Weapon != None) ) Weapon.ForceFire(); else if ( bFire == 0 ) Fire(0); bFire = 1; } else bFire = 0; if ( bAltFired ) { if ( bForceAltFire && (Weapon != None) ) Weapon.ForceAltFire(); else if ( bAltFire == 0 ) AltFire(0); bAltFire = 1; } else bAltFire = 0; // Save move parameters. DeltaTime = TimeStamp - CurrentTimeStamp; if ( ServerTimeStamp > 0 ) { // allow 1% error TimeMargin += DeltaTime - 1.01 * (Level.TimeSeconds - ServerTimeStamp); if ( TimeMargin > MaxTimeMargin ) { // player is too far ahead TimeMargin -= DeltaTime; if ( TimeMargin < 0.5 ) MaxTimeMargin = Default.MaxTimeMargin; else MaxTimeMargin = 0.5; DeltaTime = 0; } } CurrentTimeStamp = TimeStamp; ServerTimeStamp = Level.TimeSeconds; Rot.Roll = 256 * ClientRoll; Rot.Yaw = ViewYaw; if ( (Physics == PHYS_Swimming) || (Physics == PHYS_Flying) ) maxPitch = 2; else maxPitch = 1; 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); ViewRotation.Pitch = ViewPitch; ViewRotation.Yaw = ViewYaw; ViewRotation.Roll = 0; SetRotation(Rot); OldBase = Base; // Perform actual movement. if ( (Level.Pauser == "") && (DeltaTime > 0) ) MoveAutonomous(DeltaTime, NewbRun, NewbDuck, NewbPressedJump, DodgeMove, Accel, DeltaRot); // Accumulate movement error. if ( Level.TimeSeconds - LastUpdateTime > 500.0/Player.CurrentNetSpeed ) ClientErr = 10000; else if ( Level.TimeSeconds - LastUpdateTime > 180.0/Player.CurrentNetSpeed ) { LocDiff = Location - ClientLoc; ClientErr = LocDiff Dot LocDiff; } // If client has accumulated a noticeable positional error, correct him. if ( ClientErr > 3 ) { if ( Mover(Base) != None ) ClientLoc = Location - Base.Location; else ClientLoc = Location; //log("Client Error at "$TimeStamp$" is "$ClientErr$" with acceleration "$Accel$" LocDiff "$LocDiff$" Physics "$Physics); LastUpdateTime = Level.TimeSeconds; ClientAdjustPosition ( TimeStamp, GetStateName(), Physics, ClientLoc.X, ClientLoc.Y, ClientLoc.Z, Velocity.X, Velocity.Y, Velocity.Z, Base ); } //log("Server "$Role$" moved "$self$" stamp "$TimeStamp$" location "$Location$" Acceleration "$Acceleration$" Velocity "$Velocity); } function ProcessMove ( float DeltaTime, vector newAccel, eDodgeDir DodgeMove, rotator DeltaRot) { Acceleration = newAccel; } final function MoveAutonomous ( float DeltaTime, bool NewbRun, bool NewbDuck, bool NewbPressedJump, eDodgeDir DodgeMove, vector newAccel, rotator DeltaRot ) { if ( NewbRun ) bRun = 1; else bRun = 0; if ( NewbDuck ) bDuck = 1; else bDuck = 0; bPressedJump = NewbPressedJump; HandleWalking(); ProcessMove(DeltaTime, newAccel, DodgeMove, DeltaRot); AutonomousPhysics(DeltaTime); //log("Role "$Role$" moveauto time "$100 * DeltaTime$" ("$Level.TimeDilation$")"); } // 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 Decoration Carried; local vector OldLoc, NewLocation; if ( CurrentTimeStamp > TimeStamp ) return; CurrentTimeStamp = TimeStamp; NewLocation.X = NewLocX; NewLocation.Y = NewLocY; NewLocation.Z = NewLocZ; Velocity.X = NewVelX; Velocity.Y = NewVelY; Velocity.Z = NewVelZ; SetBase(NewBase); if ( Mover(NewBase) != None ) NewLocation += NewBase.Location; //log("Client "$Role$" adjust "$self$" stamp "$TimeStamp$" location "$Location); Carried = CarriedDecoration; OldLoc = Location; bCanTeleport = false; SetLocation(NewLocation); bCanTeleport = true; if ( Carried != None ) { CarriedDecoration = Carried; CarriedDecoration.SetLocation(NewLocation + CarriedDecoration.Location - OldLoc); CarriedDecoration.SetPhysics(PHYS_None); CarriedDecoration.SetBase(self); } SetPhysics(newPhysics); if ( !IsInState(newState) ) GotoState(newState); bUpdatePosition = true; } function ClientUpdatePosition() { local SavedMove CurrentMove; local int realbRun, realbDuck; local bool bRealJump; local float TotalTime, AdjPCol; local pawn P; local vector Dir; bUpdatePosition = false; realbRun= bRun; realbDuck = bDuck; bRealJump = bPressedJump; CurrentMove = SavedMoves; bUpdating = true; while ( CurrentMove != None ) { if ( CurrentMove.TimeStamp <= CurrentTimeStamp ) { SavedMoves = CurrentMove.NextMove; CurrentMove.NextMove = FreeMoves; FreeMoves = CurrentMove; FreeMoves.Clear(); CurrentMove = SavedMoves; } else { // adjust radius of nearby players with uncertain location if ( TotalTime > 0 ) ForEach AllActors(class'Pawn', P) if ( (P != self) && (P.Velocity != vect(0,0,0)) && P.bBlockPlayers ) { Dir = Normal(P.Location - Location); if ( (Velocity Dot Dir > 0) && (P.Velocity Dot Dir > 0) ) { // if other pawn moving away from player, push it away if its close // since the client-side position is behind the server side position if ( VSize(P.Location - Location) < P.CollisionRadius + CollisionRadius + CurrentMove.Delta * GroundSpeed ) P.MoveSmooth(P.Velocity * 0.5 * PlayerReplicationInfo.Ping); } } TotalTime += CurrentMove.Delta; MoveAutonomous(CurrentMove.Delta, CurrentMove.bRun, CurrentMove.bDuck, CurrentMove.bPressedJump, CurrentMove.DodgeMove, CurrentMove.Acceleration, rot(0,0,0)); CurrentMove = CurrentMove.NextMove; } } bUpdating = false; bDuck = realbDuck; bRun = realbRun; bPressedJump = bRealJump; //log("Client adjusted "$self$" stamp "$CurrentTimeStamp$" location "$Location$" dodge "$DodgeDir); } final function SavedMove GetFreeMove() { local SavedMove s; if ( FreeMoves == None ) 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; } // // Replicate this client's desired movement to the server. // function ReplicateMove ( float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot ) { local SavedMove NewMove, OldMove, LastMove; local byte ClientRoll; local int i; local float OldTimeDelta, TotalTime, NetMoveDelta; local int OldAccel; local vector BuildAccel, AccelNorm; local float AdjPCol; local pawn P; local vector Dir; // Get a SavedMove actor to store the movement in. if ( PendingMove != None ) { //add this move to the pending move PendingMove.TimeStamp = Level.TimeSeconds; if ( VSize(NewAccel) > 3072 ) NewAccel = 3072 * Normal(NewAccel); TotalTime = PendingMove.Delta + DeltaTime; PendingMove.Acceleration = (DeltaTime * NewAccel + PendingMove.Delta * PendingMove.Acceleration)/TotalTime; // Set this move's data. if ( PendingMove.DodgeMove == DODGE_None ) PendingMove.DodgeMove = DodgeMove; PendingMove.bRun = (bRun > 0); PendingMove.bDuck = (bDuck > 0); PendingMove.bPressedJump = bPressedJump || PendingMove.bPressedJump; PendingMove.bFire = PendingMove.bFire || bJustFired || (bFire != 0); PendingMove.bForceFire = PendingMove.bForceFire || bJustFired; PendingMove.bAltFire = PendingMove.bAltFire || bJustAltFired || (bAltFire != 0); PendingMove.bForceAltFire = PendingMove.bForceAltFire || bJustFired; PendingMove.Delta = TotalTime; } if ( SavedMoves != None ) { NewMove = SavedMoves; AccelNorm = Normal(NewAccel); while ( NewMove.NextMove != None ) { // find most recent interesting move to send redundantly if ( NewMove.bPressedJump || ((NewMove.DodgeMove != Dodge_NONE) && (NewMove.DodgeMove < 5)) || ((NewMove.Acceleration != NewAccel) && ((normal(NewMove.Acceleration) Dot AccelNorm) < 0.95)) ) OldMove = NewMove; NewMove = NewMove.NextMove; } if ( NewMove.bPressedJump || ((NewMove.DodgeMove != Dodge_NONE) && (NewMove.DodgeMove < 5)) || ((NewMove.Acceleration != NewAccel) && ((normal(NewMove.Acceleration) Dot AccelNorm) < 0.95)) ) OldMove = NewMove; } LastMove = NewMove; NewMove = GetFreeMove(); NewMove.Delta = DeltaTime; if ( VSize(NewAccel) > 3072 ) NewAccel = 3072 * Normal(NewAccel); NewMove.Acceleration = NewAccel; // Set this move's data. NewMove.DodgeMove = DodgeMove; NewMove.TimeStamp = Level.TimeSeconds; NewMove.bRun = (bRun > 0); NewMove.bDuck = (bDuck > 0); NewMove.bPressedJump = bPressedJump; NewMove.bFire = (bJustFired || (bFire != 0)); NewMove.bForceFire = bJustFired; NewMove.bAltFire = (bJustAltFired || (bAltFire != 0)); NewMove.bForceAltFire = bJustAltFired; if ( Weapon != None ) // approximate pointing so don't have to replicate Weapon.bPointing = ((bFire != 0) || (bAltFire != 0)); bJustFired = false; bJustAltFired = false; // adjust radius of nearby players with uncertain location ForEach AllActors(class'Pawn', P) if ( (P != self) && (P.Velocity != vect(0,0,0)) && P.bBlockPlayers ) { Dir = Normal(P.Location - Location); if ( (Velocity Dot Dir > 0) && (P.Velocity Dot Dir > 0) ) { // if other pawn moving away from player, push it away if its close // since the client-side position is behind the server side position if ( VSize(P.Location - Location) < P.CollisionRadius + CollisionRadius + NewMove.Delta * GroundSpeed ) P.MoveSmooth(P.Velocity * 0.5 * PlayerReplicationInfo.Ping); } } // Simulate the movement locally. ProcessMove(NewMove.Delta, NewMove.Acceleration, NewMove.DodgeMove, DeltaRot); AutonomousPhysics(NewMove.Delta); //log("Role "$Role$" repmove at "$Level.TimeSeconds$" Move time "$100 * DeltaTime$" ("$Level.TimeDilation$")"); // Decide whether to hold off on move // send if dodge, jump, or fire unless really too soon, or if newmove.delta big enough // on client side, save extra buffered time in LastUpdateTime if ( PendingMove == None ) PendingMove = NewMove; else { NewMove.NextMove = FreeMoves; FreeMoves = NewMove; FreeMoves.Clear(); NewMove = PendingMove; } NetMoveDelta = FMax(64.0/Player.CurrentNetSpeed, 0.011); if ( !PendingMove.bForceFire && !PendingMove.bForceAltFire && !PendingMove.bPressedJump && (PendingMove.Delta < NetMoveDelta - ClientUpdateTime) ) { // save as pending move return; } else if ( (ClientUpdateTime < 0) && (PendingMove.Delta < NetMoveDelta - ClientUpdateTime) ) return; else { ClientUpdateTime = PendingMove.Delta - NetMoveDelta; if ( SavedMoves == None ) SavedMoves = PendingMove; else LastMove.NextMove = PendingMove; PendingMove = None; } // check if need to redundantly send previous move if ( OldMove != None ) { // log("Redundant send timestamp "$OldMove.TimeStamp$" accel "$OldMove.Acceleration$" at "$Level.Timeseconds$" New accel "$NewAccel); // 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.bDuck ) OldAccel += 32; if ( OldMove.bPressedJump ) OldAccel += 16; OldAccel += OldMove.DodgeMove; } //else // log("No redundant timestamp at "$Level.TimeSeconds$" with accel "$NewAccel); // Send to the server ClientRoll = (Rotation.Roll >> 8) & 255; if ( NewMove.bPressedJump ) bJumpStatus = !bJumpStatus; ServerMove ( NewMove.TimeStamp, NewMove.Acceleration * 10, Location, NewMove.bRun, NewMove.bDuck, bJumpStatus, NewMove.bFire, NewMove.bAltFire, NewMove.bForceFire, NewMove.bForceAltFire, NewMove.DodgeMove, ClientRoll, (32767 & (ViewRotation.Pitch/2)) * 32768 + (32767 & (ViewRotation.Yaw/2)), OldTimeDelta, OldAccel ); //log("Replicated "$self$" stamp "$NewMove.TimeStamp$" location "$Location$" dodge "$NewMove.DodgeMove$" to "$DodgeDir); } function HandleWalking() { local rotator carried; bIsWalking = ((bRun != 0) || (bDuck != 0)) && !Region.Zone.IsA('WarpZoneInfo'); if ( CarriedDecoration != None ) { if ( (Role == ROLE_Authority) && (standingcount == 0) ) CarriedDecoration = None; if ( CarriedDecoration != None ) //verify its still in front { bIsWalking = true; if ( Role == ROLE_Authority ) { carried = Rotator(CarriedDecoration.Location - Location); carried.Yaw = ((carried.Yaw & 65535) - (Rotation.Yaw & 65535)) & 65535; if ( (carried.Yaw > 3072) && (carried.Yaw < 62463) ) DropDecoration(); } } } } //---------------------------------------------- simulated event Destroyed() { Super.Destroyed(); if ( myHud != None ) myHud.Destroy(); if ( Scoring != None ) Scoring.Destroy(); While ( FreeMoves != None ) { FreeMoves.Destroy(); FreeMoves = FreeMoves.NextMove; } While ( SavedMoves != None ) { SavedMoves.Destroy(); SavedMoves = SavedMoves.NextMove; } } function ServerReStartGame() { } function PlayHit(float Damage, vector HitLocation, name damageType, vector Momentum) { Level.Game.SpecialDamageString = ""; } function SetFOVAngle(float newFOV) { FOVAngle = newFOV; } function ClientFlash( float scale, vector fog ) { DesiredFlashScale = scale; DesiredFlashFog = 0.001 * fog; } function ClientInstantFlash( float scale, vector fog ) { InstantFlash = scale; InstantFog = 0.001 * fog; } //Play a sound client side (so only client will hear it simulated function ClientPlaySound(sound ASound, optional bool bInterrupt, optional bool bVolumeControl ) { local actor SoundPlayer; LastPlaySound = Level.TimeSeconds; // so voice messages won't overlap if ( ViewTarget != None ) SoundPlayer = ViewTarget; else SoundPlayer = self; SoundPlayer.PlaySound(ASound, SLOT_None, 16.0, bInterrupt); SoundPlayer.PlaySound(ASound, SLOT_Interface, 16.0, bInterrupt); SoundPlayer.PlaySound(ASound, SLOT_Misc, 16.0, bInterrupt); SoundPlayer.PlaySound(ASound, SLOT_Talk, 16.0, bInterrupt); } simulated function ClientReliablePlaySound(sound ASound, optional bool bInterrupt, optional bool bVolumeControl ) { ClientPlaySound(ASound, bInterrupt, bVolumeControl); } function ClientAdjustGlow( float scale, vector fog ) { ConstantGlowScale += scale; ConstantGlowFog += 0.001 * fog; } function ClientShake(vector shake) { if ( (shakemag < shake.X) || (shaketimer <= 0.01 * shake.Y) ) { shakemag = shake.X; shaketimer = 0.01 * shake.Y; maxshake = 0.01 * shake.Z; verttimer = 0; ShakeVert = -1.1 * maxshake; } } function ShakeView( float shaketime, float RollMag, float vertmag) { local vector shake; shake.X = RollMag; shake.Y = 100 * shaketime; shake.Z = 100 * vertmag; ClientShake(shake); } function ClientSetMusic( music NewSong, byte NewSection, byte NewCdTrack, EMusicTransition NewTransition ) { Song = NewSong; SongSection = NewSection; CdTrack = NewCdTrack; Transition = NewTransition; } function ServerFeignDeath() { } function ServerSetHandedness( float hand) { Handedness = hand; if ( Weapon != None ) Weapon.SetHand(Handedness); } function ServerReStartPlayer() { } function ServerChangeSkin( coerce string SkinName, coerce string FaceName, byte TeamNum ) { local string MeshName; MeshName = GetItemName(string(Mesh)); if ( Level.Game.bCanChangeSkin ) { Self.static.SetMultiSkin(Self, SkinName, FaceName, TeamNum ); } } //************************************************************************************* // Normal gameplay execs // Type the name of the exec function at the console to execute it exec function ShowSpecialMenu( string ClassName ) { local class aMenuClass; aMenuClass = class( DynamicLoadObject( ClassName, class'Class' ) ); if( aMenuClass!=None ) { bSpecialMenu = true; SpecialMenu = aMenuClass; ShowMenu(); } } exec function Jump( optional float F ) { if ( !bShowMenu && (Level.Pauser == PlayerReplicationInfo.PlayerName) ) SetPause(False); else bPressedJump = true; } exec function CauseEvent( name N ) { local actor A; if( !bCheatsEnabled ) return; if( (bAdmin || (Level.Netmode == NM_Standalone)) && (N != '') ) foreach AllActors( class 'Actor', A, N ) A.Trigger( Self, Self ); } exec function Taunt( name Sequence ) { if ( GetAnimGroup(Sequence) == 'Gesture') { // if (IsAnimating()) // FinishAnim(); ServerTaunt(Sequence); PlayAnim(Sequence, 0.7, 0.2); } } singular function ServerTaunt(name Sequence ) { if (Level.TimeSeconds - LastTaunt > TauntDelay && GetAnimGroup(Sequence) == 'Gesture') { // if (IsAnimating()) // FinishAnim(); PlayAnim(Sequence, 0.7, 0.2); LastTaunt = Level.TimeSeconds; } } exec function FeignDeath() { } exec function CallForHelp() { local Pawn P; if ( !Level.Game.bTeamGame || (Enemy == None) || (Enemy.Health <= 0) ) return; for ( P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.bIsPlayer && (P.PlayerReplicationInfo.Team == PlayerReplicationInfo.Team) ) P.HandleHelpMessageFrom(self); } function damageAttitudeTo(pawn Other) { if ( Other != Self ) Enemy = Other; } exec function Grab() { if (CarriedDecoration == None) GrabDecoration(); else DropDecoration(); } // Send a voice message of a certain type to a certain player. exec function Speech( int Type, int Index, int Callsign ) { local VoicePack V; if (Level.TimeSeconds - OldMessageTime > SpeechDelay) { V = Spawn(PlayerReplicationInfo.VoiceType, Self); if (V != None) V.PlayerSpeech( Type, Index, Callsign ); } } function PlayChatting(); function Typing( bool bTyping ) { bIsTyping = bTyping; if (bTyping) { if (Level.Game.WorldLog != None) Level.Game.WorldLog.LogTypingEvent(True, Self); if (Level.Game.LocalLog != None) Level.Game.LocalLog.LogTypingEvent(True, Self); PlayChatting(); } else { if (Level.Game.WorldLog != None) Level.Game.WorldLog.LogTypingEvent(False, Self); if (Level.Game.LocalLog != None) Level.Game.LocalLog.LogTypingEvent(False, Self); } } // Send a message to all players. exec function Say( string Msg ) { local Pawn P; if ( bAdmin && (left(Msg,1) == "#") ) { Msg = right(Msg,len(Msg)-1); for( P=Level.PawnList; P!=None; P=P.nextPawn ) if( P.IsA('PlayerPawn') ) { PlayerPawn(P).ClearProgressMessages(); PlayerPawn(P).SetProgressTime(6); PlayerPawn(P).SetProgressMessage(Msg,0); } return; } // if (Level.TimeSeconds - LastSpeech < SpeechDelay) // return; LastSpeech = Level.TimeSeconds; if ( Level.Game.AllowsBroadcast(self, Len(Msg)) ) for( P=Level.PawnList; P!=None; P=P.nextPawn ) if( P.bIsPlayer || P.IsA('MessagingSpectator') ) { if ( (Level.Game != None) && (Level.Game.MessageMutator != None) ) { if ( Level.Game.MessageMutator.MutatorTeamMessage(Self, P, PlayerReplicationInfo, Msg, 'Say', true) ) P.TeamMessage( PlayerReplicationInfo, Msg, 'Say', true ); } else P.TeamMessage( PlayerReplicationInfo, Msg, 'Say', true ); } return; } exec function TeamSay( string Msg ) { local Pawn P; if ( !Level.Game.bTeamGame ) { Say(Msg); return; } if ( Msg ~= "Help" ) { CallForHelp(); return; } // if (Level.TimeSeconds - LastSpeech < SpeechDelay) // return; // LastSpeech = Level.TimeSeconds; if ( Level.Game.AllowsBroadcast(self, Len(Msg)) ) for( P=Level.PawnList; P!=None; P=P.nextPawn ) if( P.bIsPlayer && (P.PlayerReplicationInfo.Team == PlayerReplicationInfo.Team) ) { if ( P.IsA('PlayerPawn') ) { if ( (Level.Game != None) && (Level.Game.MessageMutator != None) ) { if ( Level.Game.MessageMutator.MutatorTeamMessage(Self, P, PlayerReplicationInfo, Msg, 'TeamSay', true) ) P.TeamMessage( PlayerReplicationInfo, Msg, 'TeamSay', true ); } else P.TeamMessage( PlayerReplicationInfo, Msg, 'TeamSay', true ); } } } exec function RestartLevel() { if( bAdmin || Level.Netmode==NM_Standalone ) ClientTravel( "?restart", TRAVEL_Relative, false ); } exec function LocalTravel( string URL ) { if( bAdmin || Level.Netmode==NM_Standalone ) ClientTravel( URL, TRAVEL_Relative, true ); } exec function ThrowWeapon() { if( Level.NetMode == NM_Client ) return; if( Weapon==None || (Weapon.Class==Level.Game.BaseMutator.MutatedDefaultWeapon()) || !Weapon.bCanThrow ) return; Weapon.Velocity = Vector(ViewRotation) * 500 + vect(0,0,220); Weapon.bTossedOut = true; TossWeapon(); if ( Weapon == None ) SwitchToBestWeapon(); } function ToggleZoom() { if ( DefaultFOV != DesiredFOV ) EndZoom(); else StartZoom(); } function StartZoom() { ZoomLevel = 0.0; bZooming = true; } function StopZoom() { bZooming = false; } function EndZoom() { bZooming = false; DesiredFOV = DefaultFOV; } exec function FOV(float F) { SetDesiredFOV(F); } exec function SetDesiredFOV(float F) { if( (F >= 80.0) || Level.bAllowFOV || bAdmin || (Level.Netmode==NM_Standalone) ) { DefaultFOV = FClamp(F, MinFOV, MaxFOV); DesiredFOV = DefaultFOV; SaveConfig(); } } /* PrevWeapon() - switch to previous inventory group weapon */ exec function PrevWeapon() { local int prevGroup; local Inventory inv; local Weapon realWeapon, w, Prev; local bool bFoundWeapon; if( bShowMenu || Level.Pauser!="" ) return; if ( Weapon == None ) { SwitchToBestWeapon(); return; } prevGroup = 0; realWeapon = Weapon; if ( PendingWeapon != None ) Weapon = PendingWeapon; PendingWeapon = None; for (inv=Inventory; inv!=None; inv=inv.Inventory) { w = Weapon(inv); if ( w != None ) { if ( w.InventoryGroup == Weapon.InventoryGroup ) { if ( w == Weapon ) { bFoundWeapon = true; if ( Prev != None ) { PendingWeapon = Prev; break; } } else if ( !bFoundWeapon && ((w.AmmoType == None) || (w.AmmoType.AmmoAmount>0)) ) Prev = W; } else if ( (w.InventoryGroup < Weapon.InventoryGroup) && ((w.AmmoType == None) || (w.AmmoType.AmmoAmount>0)) && (w.InventoryGroup >= prevGroup) ) { prevGroup = w.InventoryGroup; PendingWeapon = w; } } } bFoundWeapon = false; prevGroup = Weapon.InventoryGroup; if ( PendingWeapon == None ) for (inv=Inventory; inv!=None; inv=inv.Inventory) { w = Weapon(inv); if ( w != None ) { if ( w.InventoryGroup == Weapon.InventoryGroup ) { if ( w == Weapon ) bFoundWeapon = true; else if ( bFoundWeapon && (PendingWeapon == None) && ((w.AmmoType == None) || (w.AmmoType.AmmoAmount>0)) ) PendingWeapon = W; } else if ( (w.InventoryGroup > PrevGroup) && ((w.AmmoType == None) || (w.AmmoType.AmmoAmount>0)) ) { prevGroup = w.InventoryGroup; PendingWeapon = w; } } } Weapon = realWeapon; if ( PendingWeapon == None ) return; Weapon.PutDown(); } /* NextWeapon() - switch to next inventory group weapon */ exec function NextWeapon() { local int nextGroup; local Inventory inv; local Weapon realWeapon, w, Prev; local bool bFoundWeapon; if( bShowMenu || Level.Pauser!="" ) return; if ( Weapon == None ) { SwitchToBestWeapon(); return; } nextGroup = 100; realWeapon = Weapon; if ( PendingWeapon != None ) Weapon = PendingWeapon; PendingWeapon = None; for (inv=Inventory; inv!=None; inv=inv.Inventory) { w = Weapon(inv); if ( w != None ) { if ( w.InventoryGroup == Weapon.InventoryGroup ) { if ( w == Weapon ) bFoundWeapon = true; else if ( bFoundWeapon && ((w.AmmoType == None) || (w.AmmoType.AmmoAmount>0)) ) { PendingWeapon = W; break; } } else if ( (w.InventoryGroup > Weapon.InventoryGroup) && ((w.AmmoType == None) || (w.AmmoType.AmmoAmount>0)) && (w.InventoryGroup < nextGroup) ) { nextGroup = w.InventoryGroup; PendingWeapon = w; } } } bFoundWeapon = false; nextGroup = Weapon.InventoryGroup; if ( PendingWeapon == None ) for (inv=Inventory; inv!=None; inv=inv.Inventory) { w = Weapon(Inv); if ( w != None ) { if ( w.InventoryGroup == Weapon.InventoryGroup ) { if ( w == Weapon ) { bFoundWeapon = true; if ( Prev != None ) PendingWeapon = Prev; } else if ( !bFoundWeapon && (PendingWeapon == None) && ((w.AmmoType == None) || (w.AmmoType.AmmoAmount>0)) ) Prev = W; } else if ( (w.InventoryGroup < nextGroup) && ((w.AmmoType == None) || (w.AmmoType.AmmoAmount>0)) ) { nextGroup = w.InventoryGroup; PendingWeapon = w; } } } Weapon = realWeapon; if ( PendingWeapon == None ) return; Weapon.PutDown(); } exec function Mutate(string MutateString) { if( Level.NetMode == NM_Client ) return; Level.Game.BaseMutator.Mutate(MutateString, Self); } exec function QuickSave() { if ( (Health > 0) && (Level.NetMode == NM_Standalone) && !Level.Game.bDeathMatch ) { ClientMessage(QuickSaveString); ConsoleCommand("SaveGame 9"); } } exec function QuickLoad() { if ( (Level.NetMode == NM_Standalone) && !Level.Game.bDeathMatch ) ClientTravel( "?load=9", TRAVEL_Absolute, false); } final function KickMe(optional string Reason) { if (Level.Game.bLogAdminActions) log(PlayerReplicationInfo.PlayerName@"("$GetPlayerNetworkAddress()$") was kicked from the server:"@Reason,'AdminAction'); Destroy(); } final function KickBanMe(optional string Reason) { local string IP; local int j; IP = GetPlayerNetworkAddress(); if(Level.Game.CheckIPPolicy(IP)) { IP = Left(IP, InStr(IP, ":")); if (Level.Game.bLogAdminActions) log(PlayerReplicationInfo.PlayerName@"("$GetPlayerNetworkAddress()$") was banned from the server:"@Reason,'AdminAction'); Log("Adding IP Ban for: "$IP); for(j=0;j NewWeaponClass ) { local Inventory Inv; if ( (Inventory == None) || (NewWeaponClass == None) || ((Weapon != None) && (Weapon.Class == NewWeaponClass)) ) return; for ( Inv=Inventory; Inv!=None; Inv=Inv.Inventory ) if ( Inv.Class == NewWeaponClass ) { PendingWeapon = Weapon(Inv); if ( (PendingWeapon.AmmoType != None) && (PendingWeapon.AmmoType.AmmoAmount <= 0) ) { Pawn(Owner).ClientMessage( PendingWeapon.ItemName$PendingWeapon.MessageNoAmmo ); PendingWeapon = None; return; } Weapon.PutDown(); return; } } // The player wants to select previous item exec function PrevItem() { local Inventory Inv, LastItem; if ( bShowMenu || Level.Pauser!="" ) return; if (SelectedItem==None) { SelectedItem = Inventory.SelectNext(); Return; } if (SelectedItem.Inventory!=None) for( Inv=SelectedItem.Inventory; Inv!=None; Inv=Inv.Inventory ) { if (Inv==None) Break; if (Inv.bActivatable) LastItem=Inv; } for( Inv=Inventory; Inv!=SelectedItem; Inv=Inv.Inventory ) { if (Inv==None) Break; if (Inv.bActivatable) LastItem=Inv; } if (LastItem!=None) { SelectedItem = LastItem; ClientMessage(SelectedItem.ItemName$SelectedItem.M_Selected); } } // The player wants to active selected item exec function ActivateItem() { if( bShowMenu || Level.Pauser!="" ) return; if (SelectedItem!=None) SelectedItem.Activate(); } // The player wants to fire. exec function Fire( optional float F ) { bJustFired = true; if( bShowMenu || (Level.Pauser!="") || (Role < ROLE_Authority) ) { if( (Role < ROLE_Authority) && (Weapon!=None) ) bJustFired = Weapon.ClientFire(F); if ( !bShowMenu && (Level.Pauser == PlayerReplicationInfo.PlayerName) ) SetPause(False); return; } if( Weapon!=None ) { Weapon.bPointing = true; PlayFiring(); Weapon.Fire(F); } } // The player wants to alternate-fire. exec function AltFire( optional float F ) { bJustAltFired = true; if( bShowMenu || (Level.Pauser!="") || (Role < ROLE_Authority) ) { if( (Role < ROLE_Authority) && (Weapon!=None) ) bJustAltFired = Weapon.ClientAltFire(F); if ( !bShowMenu && (Level.Pauser == PlayerReplicationInfo.PlayerName) ) SetPause(False); return; } if( Weapon!=None ) { Weapon.bPointing = true; PlayFiring(); Weapon.AltFire(F); } } //Player Jumped function DoJump( optional float F ) { if ( CarriedDecoration != None ) return; if ( !bIsCrouching && (Physics == PHYS_Walking) ) { if ( !bUpdating ) PlayOwnedSound(JumpSound, SLOT_Talk, 1.5, true, 1200, 1.0 ); if ( (Level.Game != None) && (Level.Game.Difficulty > 0) ) MakeNoise(0.1 * Level.Game.Difficulty); PlayInAir(); if ( bCountJumps && (Role == ROLE_Authority) && (Inventory != None) ) Inventory.OwnerJumped(); Velocity.Z = JumpZ; if ( (Base != Level) && (Base != None) ) Velocity.Z += Base.Velocity.Z; SetPhysics(PHYS_Falling); } } exec function Suicide() { KilledBy( None ); } exec function AlwaysMouseLook( Bool B ) { ChangeAlwaysMouseLook(B); SaveConfig(); } function ChangeAlwaysMouseLook(Bool B) { bAlwaysMouseLook = B; if ( bAlwaysMouseLook ) bLookUpStairs = false; } exec function SnapView( bool B ) { ChangeSnapView(B); SaveConfig(); } function ChangeSnapView( bool B ) { bSnapToLevel = B; } exec function StairLook( bool B ) { ChangeStairLook(B); SaveConfig(); } function ChangeStairLook( bool B ) { bLookUpStairs = B; if ( bLookUpStairs ) bAlwaysMouseLook = false; } exec function SetDodgeClickTime( float F ) { ChangeDodgeClickTime(F); SaveConfig(); } function ChangeDodgeClickTime( float F ) { DodgeClickTime = FMin(0.3, F); } final function ReplaceText(out string Text, string Replace, string With) { local int i; local string Input; Input = Text; Text = ""; i = InStr(Input, Replace); while(i != -1) { Text = Text $ Left(Input, i) $ With; Input = Mid(Input, i + Len(Replace)); i = InStr(Input, Replace); } Text = Text $ Input; } exec function SetName( coerce string S ) { if ( Len(S) > 28 ) S = left(S,28); ReplaceText(S, " ", "_"); ChangeName(S); UpdateURL("Name", S, true); SaveConfig(); } exec function Name( coerce string S ) { SetName(S); } function ChangeName( coerce string S ) { if (MaxNameChanges > 0 && NameChanges < MaxNameChanges) { NameChanges++; Level.Game.ChangeName( self, S, false ); } } function ChangeTeam( int N ) { local int OldTeam; OldTeam = PlayerReplicationInfo.Team; Level.Game.ChangeTeam(self, N); if ( Level.Game.bTeamGame && (PlayerReplicationInfo.Team != OldTeam) ) Died( None, '', Location ); } function ClientChangeTeam( int N ) { local Pawn P; if ( PlayerReplicationInfo != None ) PlayerReplicationInfo.Team = N; // if listen server, this may be called for non-local players that are logging in // if so, don't update URL if ( (Level.NetMode == NM_ListenServer) && (Player == None) ) { // check if any other players exist for ( P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.IsA('PlayerPawn') && (ViewPort(PlayerPawn(P).Player) != None) ) return; } UpdateURL("Team",string(N), true); } exec function SetAutoAim( float F ) { ChangeAutoAim(F); SaveConfig(); } function ChangeAutoAim( float F ) { MyAutoAim = FMax(Level.Game.AutoAim, F); } exec function PlayersOnly() { if ( Level.Netmode != NM_Standalone ) return; Level.bPlayersOnly = !Level.bPlayersOnly; } exec function SetHand( string S ) { ChangeSetHand(S); SaveConfig(); } function ChangeSetHand( 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; ServerSetHandedness(Handedness); } exec function ViewPlayer( string S ) { local pawn P; for ( P=Level.pawnList; P!=None; P= P.NextPawn ) if ( P.bIsPlayer && (P.PlayerReplicationInfo.PlayerName ~= S) ) break; if ( (P != None) && Level.Game.CanSpectate(self, P) ) { ClientMessage(ViewingFrom@P.PlayerReplicationInfo.PlayerName, 'Event', true); if ( P == self) ViewTarget = None; else ViewTarget = P; } else ClientMessage(FailedView); bBehindView = ( ViewTarget != None ); if ( bBehindView ) ViewTarget.BecomeViewTarget(); } exec function CheatView( class aClass ) { local actor other, first; local bool bFound; if( !bCheatsEnabled ) return; if( !bAdmin && Level.NetMode!=NM_Standalone ) return; first = None; ForEach AllActors( aClass, other ) { if ( (first == None) && (other != self) ) { first = other; bFound = true; } if ( other == ViewTarget ) first = None; } if ( first != None ) { if ( first.IsA('Pawn') && Pawn(first).bIsPlayer && (Pawn(first).PlayerReplicationInfo.PlayerName != "") ) ClientMessage(ViewingFrom@Pawn(first).PlayerReplicationInfo.PlayerName, 'Event', true); else ClientMessage(ViewingFrom@first, 'Event', true); ViewTarget = first; } else { if ( bFound ) ClientMessage(ViewingFrom@OwnCamera, 'Event', true); else ClientMessage(FailedView, 'Event', true); ViewTarget = None; } bBehindView = ( ViewTarget != None ); if ( bBehindView ) ViewTarget.BecomeViewTarget(); } exec function ViewSelf() { bBehindView = false; Viewtarget = None; ClientMessage(ViewingFrom@OwnCamera, 'Event', true); } exec function ViewClass( class aClass, optional bool bQuiet ) { local actor other, first; local bool bFound; if ( (Level.Game != None) && !Level.Game.bCanViewOthers ) return; if (ViewDelay > 0.0) if (((Level.TimeSeconds - LastView) < ViewDelay) && !bCyclingView) return; if (!bCyclingView) LastView = Level.TimeSeconds; first = None; ForEach AllActors( aClass, other ) { if ( (first == None) && (other != self) && ( (bAdmin && Level.Game==None) || Level.Game.CanSpectate(self, other) ) ) { first = other; bFound = true; } if ( other == ViewTarget ) first = None; } if ( first != None ) { if ( !bQuiet ) { if ( first.IsA('Pawn') && Pawn(first).bIsPlayer && (Pawn(first).PlayerReplicationInfo.PlayerName != "") ) ClientMessage(ViewingFrom@Pawn(first).PlayerReplicationInfo.PlayerName, 'Event', true); else ClientMessage(ViewingFrom@first, 'Event', true); } ViewTarget = first; } else { if ( !bQuiet ) { if ( bFound ) ClientMessage(ViewingFrom@OwnCamera, 'Event', true); else ClientMessage(FailedView, 'Event', true); } ViewTarget = None; } bBehindView = ( ViewTarget != None ); if ( bBehindView ) ViewTarget.BecomeViewTarget(); } exec function NeverSwitchOnPickup( bool B ) { bNeverAutoSwitch = B; bNeverSwitchOnPickup = B; ServerNeverSwitchOnPickup(B); if (Level.NetMode < NM_DedicatedServer) SaveConfig(); } function ServerNeverSwitchOnPickup(bool B) { bNeverSwitchOnPickup = B; } exec function InvertMouse( bool B ) { bInvertMouse = B; SaveConfig(); } exec function SwitchLevel( string URL ) { if( bAdmin || Player.IsA('ViewPort') ) Level.ServerTravel( URL, false ); } exec function SwitchCoopLevel( string URL ) { if( bAdmin || Player.IsA('ViewPort') ) Level.ServerTravel( URL, true ); } exec function ShowScores() { bShowScores = !bShowScores; } exec function ShowMenu() { WalkBob = vect(0,0,0); bShowMenu = true; // menu is responsible for turning this off Player.Console.GotoState('Menuing'); if( Level.Netmode == NM_Standalone ) SetPause(true); } exec function ShowLoadMenu() { ShowMenu(); } exec function AddBots(int N) { ServerAddBots(N); } function ServerAddBots(int N) { local int i; if ( !bAdmin && (Level.Netmode != NM_Standalone) ) return; if ( !Level.Game.bDeathMatch ) return; for ( i=0; i aClass) { local Actor A; if ( !bCheatsEnabled ) return; if( !bAdmin && (Level.Netmode != NM_Standalone) ) return; ForEach AllActors(class 'Actor', A) if ( ClassIsChildOf(A.class, aClass) ) A.Destroy(); } exec function KillPawns() { local Pawn P; if( !bCheatsEnabled || (Level.Netmode != NM_Standalone) ) return; ForEach AllActors(class 'Pawn', P) if (PlayerPawn(P) == None) P.Destroy(); } exec function Summon( string ClassName ) { local class NewClass; if( !bCheatsEnabled ) return; if( !bAdmin && (Level.Netmode != NM_Standalone) ) return; log( "Fabricate " $ ClassName ); NewClass = class( DynamicLoadObject( ClassName, class'Class' ) ); if( NewClass!=None ) Spawn( NewClass,,,Location + 72 * Vector(Rotation) + vect(0,0,1) * 15 ); } //============== // Navigation Aids exec function ShowPath() { //find next path to remembered spot local Actor node; if (!bAdmin && Level.NetMode == NM_DedicatedServer) return; node = FindPathTo(Destination); if (node != None) { log("found path"); Spawn(class 'WayBeacon', self, '', node.location); } else log("didn't find path"); } exec function RememberSpot() { //remember spot Destination = Location; } //============================================================================= // Input related functions. // Postprocess the player's input. event PlayerInput( float DeltaTime ) { local float SmoothTime, FOVScale, MouseScale, AbsSmoothX, AbsSmoothY, MouseTime; if ( bShowMenu && (myHud != None) ) { if ( myHud.MainMenu != None ) myHud.MainMenu.MenuTick( DeltaTime ); // clear inputs bEdgeForward = false; bEdgeBack = false; bEdgeLeft = false; bEdgeRight = false; bWasForward = false; bWasBack = false; bWasLeft = false; bWasRight = false; aStrafe = 0; aTurn = 0; aForward = 0; aLookUp = 0; return; } else if ( bDelayedCommand ) { bDelayedCommand = false; ConsoleCommand(DelayedCommand); } // Check for Dodge 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 SmoothTime = FMin(0.2, 3 * DeltaTime * Level.TimeDilation); FOVScale = DesiredFOV * 0.01111; MouseScale = MouseSensitivity * FOVScale; aMouseX *= MouseScale; aMouseY *= MouseScale; //************************************************************************ //log("X "$aMouseX$" Smooth "$SmoothMouseX$" Borrowed "$BorrowedMouseX$" zero time "$(Level.TimeSeconds - MouseZeroTime)$" vs "$MouseSmoothThreshold); AbsSmoothX = SmoothMouseX; AbsSmoothY = SmoothMouseY; MouseTime = (Level.TimeSeconds - MouseZeroTime)/Level.TimeDilation; if ( bMaxMouseSmoothing && (aMouseX == 0) && (MouseTime < MouseSmoothThreshold) ) { SmoothMouseX = 0.5 * (MouseSmoothThreshold - MouseTime) * AbsSmoothX/MouseSmoothThreshold; BorrowedMouseX += SmoothMouseX; } else { if ( (SmoothMouseX == 0) || (aMouseX == 0) || ((SmoothMouseX > 0) != (aMouseX > 0)) ) { SmoothMouseX = aMouseX; BorrowedMouseX = 0; } else { SmoothMouseX = 0.5 * (SmoothMouseX + aMouseX - BorrowedMouseX); if ( (SmoothMouseX > 0) != (aMouseX > 0) ) { if ( AMouseX > 0 ) SmoothMouseX = 1; else SmoothMouseX = -1; } BorrowedMouseX = SmoothMouseX - aMouseX; } AbsSmoothX = SmoothMouseX; } if ( bMaxMouseSmoothing && (aMouseY == 0) && (MouseTime < MouseSmoothThreshold) ) { SmoothMouseY = 0.5 * (MouseSmoothThreshold - MouseTime) * AbsSmoothY/MouseSmoothThreshold; BorrowedMouseY += SmoothMouseY; } else { if ( (SmoothMouseY == 0) || (aMouseY == 0) || ((SmoothMouseY > 0) != (aMouseY > 0)) ) { SmoothMouseY = aMouseY; BorrowedMouseY = 0; } else { SmoothMouseY = 0.5 * (SmoothMouseY + aMouseY - BorrowedMouseY); if ( (SmoothMouseY > 0) != (aMouseY > 0) ) { if ( AMouseY > 0 ) SmoothMouseY = 1; else SmoothMouseY = -1; } BorrowedMouseY = SmoothMouseY - aMouseY; } AbsSmoothY = SmoothMouseY; } if ( (aMouseX != 0) || (aMouseY != 0) ) MouseZeroTime = Level.TimeSeconds; // adjust keyboard and joystick movements aLookUp *= FOVScale; aTurn *= FOVScale; // Remap raw x-axis movement. if( bStrafe!=0 ) { // Strafe. aStrafe += aBaseX + SmoothMouseX; aBaseX = 0; } else { // Forward. aTurn += aBaseX * FOVScale + SmoothMouseX; aBaseX = 0; } // Remap mouse y-axis movement. if( (bStrafe == 0) && (bAlwaysMouseLook || (bLook!=0)) ) { // Look up/down. if ( bInvertMouse ) aLookUp -= SmoothMouseY; else aLookUp += SmoothMouseY; } else { // Move forward/backward. aForward += SmoothMouseY; } SmoothMouseX = AbsSmoothX; SmoothMouseY = AbsSmoothY; 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(); } //============================================================================= // functions. event UpdateEyeHeight(float DeltaTime) { local float smooth, bound; // smooth up/down stairs If( (Physics==PHYS_Walking) && !bJustLanded ) { smooth = FMin(1.0, 10.0 * DeltaTime/Level.TimeDilation); EyeHeight = (EyeHeight - Location.Z + OldLocation.Z) * (1 - smooth) + ( ShakeVert + BaseEyeHeight) * smooth; bound = -0.5 * CollisionHeight; if (EyeHeight < bound) EyeHeight = bound; else { bound = CollisionHeight + FClamp((OldLocation.Z - Location.Z), 0.0, MaxStepHeight); if ( EyeHeight > bound ) EyeHeight = bound; } } else { smooth = FClamp(10.0 * DeltaTime/Level.TimeDilation, 0.35,1.0); bJustLanded = false; EyeHeight = EyeHeight * ( 1 - smooth) + (BaseEyeHeight + ShakeVert) * smooth; } // 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 += DeltaTime * 1.0; if (ZoomLevel > 0.9) ZoomLevel = 0.9; DesiredFOV = FClamp(90.0 - (ZoomLevel * 88.0), 1, 170); } } event PlayerTimeOut() { if (Health > 0) Died(None, 'Suicided', Location); } // Just changed to pendingWeapon function ChangedWeapon() { Super.ChangedWeapon(); if ( PendingWeapon != None ) PendingWeapon.SetHand(Handedness); } function JumpOffPawn() { Velocity += 60 * VRand(); Velocity.Z = 120; SetPhysics(PHYS_Falling); } event TravelPostAccept() { if ( Health <= 0 ) Health = Default.Health; } // This pawn was possessed by a player. event Possess() { if ( Level.Netmode == NM_Client ) { // replicate client weapon preferences to server NeverSwitchOnPickup(bNeverAutoSwitch); ServerSetHandedness(Handedness); UpdateWeaponPriorities(); } ServerUpdateWeapons(); bIsPlayer = true; DodgeClickTime = FMin(0.3, DodgeClickTime); EyeHeight = BaseEyeHeight; NetPriority = 3; StartWalk(); } function UpdateWeaponPriorities() { local byte i; // send new priorities to server if ( Level.Netmode == NM_Client ) for ( i=0; i maxZ ) { if ( TraceDir.Z >= 0 ) return false; adjZ = (maxZ - HitLocation.Z)/TraceDir.Z; HitLocation.Z = maxZ; HitLocation.X = HitLocation.X + TraceDir.X * adjZ; HitLocation.Y = HitLocation.Y + TraceDir.Y * adjZ; if ( VSize(HitLocation - Location) > CollisionRadius ) return false; } return true; } /* AdjustAim() Calls this version for player aiming help. Aimerror not used in this version. Only adjusts aiming at pawns */ function rotator AdjustAim(float projSpeed, vector projStart, int aimerror, bool bLeadTarget, bool bWarnTarget) { local vector FireDir, AimSpot, HitNormal, HitLocation; local actor BestTarget; local float bestAim, bestDist; local actor HitActor; FireDir = vector(ViewRotation); HitActor = Trace(HitLocation, HitNormal, projStart + 4000 * FireDir, projStart, true); if ( (HitActor != None) && HitActor.bProjTarget ) { if ( bWarnTarget && HitActor.IsA('Pawn') ) Pawn(HitActor).WarnTarget(self, projSpeed, FireDir); return ViewRotation; } bestAim = FMin(0.93, MyAutoAim); BestTarget = PickTarget(bestAim, bestDist, FireDir, projStart); if ( bWarnTarget && (Pawn(BestTarget) != None) ) Pawn(BestTarget).WarnTarget(self, projSpeed, FireDir); if ( (Level.NetMode != NM_Standalone) || (Level.Game.Difficulty > 2) || bAlwaysMouseLook || ((BestTarget != None) && (bestAim < MyAutoAim)) || (MyAutoAim >= 1) ) return ViewRotation; if ( BestTarget == None ) { bestAim = MyAutoAim; BestTarget = PickAnyTarget(bestAim, bestDist, FireDir, projStart); if ( BestTarget == None ) return ViewRotation; } AimSpot = projStart + FireDir * bestDist; AimSpot.Z = BestTarget.Location.Z + 0.3 * BestTarget.CollisionHeight; return rotator(AimSpot - projStart); } function Falling() { //SetPhysics(PHYS_Falling); //Note - physics changes type to PHYS_Falling by default //log(class$" Falling"); PlayInAir(); } function Landed(vector HitNormal) { //Note - physics changes type to PHYS_Walking by default for landed pawns if ( bUpdating ) return; PlayLanded(Velocity.Z); LandBob = FMin(50, 0.055 * Velocity.Z); TakeFallingDamage(); bJustLanded = true; } function Died(pawn Killer, name damageType, vector HitLocation) { StopZoom(); Super.Died(Killer, damageType, HitLocation); } function eAttitude AttitudeTo(Pawn Other) { if (Other.bIsPlayer) return AttitudeToPlayer; else return Other.AttitudeToPlayer; } function string KillMessage( name damageType, pawn Other ) { return ( Level.Game.PlayerKillMessage(damageType, Other.PlayerReplicationInfo)$PlayerReplicationInfo.PlayerName ); } //============================================================================= // Player Control function KilledBy( pawn EventInstigator ) { Health = 0; Died( EventInstigator, 'Suicided', Location ); } // Player view. // Compute the rendering viewpoint for the player. // function CalcBehindView(out vector CameraLocation, out rotator CameraRotation, float Dist) { local vector View,HitLocation,HitNormal; local float ViewDist; CameraRotation = ViewRotation; View = vect(1,0,0) >> CameraRotation; if( Trace( HitLocation, HitNormal, CameraLocation - (Dist + 30) * vector(CameraRotation), CameraLocation ) != None ) ViewDist = FMin( (CameraLocation - HitLocation) Dot View, Dist ); else ViewDist = Dist; CameraLocation -= (ViewDist - 30) * View; } event PlayerCalcView(out actor ViewActor, out vector CameraLocation, out rotator CameraRotation ) { local Pawn PTarget; if ( ViewTarget != None ) { ViewActor = ViewTarget; CameraLocation = ViewTarget.Location; CameraRotation = ViewTarget.Rotation; PTarget = Pawn(ViewTarget); if ( PTarget != None ) { if ( Level.NetMode == NM_Client ) { if ( PTarget.bIsPlayer ) PTarget.ViewRotation = TargetViewRotation; PTarget.EyeHeight = TargetEyeHeight; if ( PTarget.Weapon != None ) PTarget.Weapon.PlayerViewOffset = TargetWeaponViewOffset; } if ( PTarget.bIsPlayer ) CameraRotation = PTarget.ViewRotation; if ( !bBehindView ) CameraLocation.Z += PTarget.EyeHeight; } if ( bBehindView ) CalcBehindView(CameraLocation, CameraRotation, 180); return; } ViewActor = Self; CameraLocation = Location; if( bBehindView ) //up and behind CalcBehindView(CameraLocation, CameraRotation, 150); else { // First-person view. CameraRotation = ViewRotation; CameraLocation.Z += EyeHeight; CameraLocation += WalkBob; } } exec function SetViewFlash(bool B) { bNoFlash = !B; } function ViewFlash(float DeltaTime) { local vector goalFog; local float goalscale, delta; if ( bNoFlash ) { InstantFlash = 0; InstantFog = vect(0,0,0); } delta = FMin(0.1, DeltaTime); goalScale = 1 + DesiredFlashScale + ConstantGlowScale + HeadRegion.Zone.ViewFlash.X; goalFog = DesiredFlashFog + ConstantGlowFog + HeadRegion.Zone.ViewFog; DesiredFlashScale -= DesiredFlashScale * 2 * delta; DesiredFlashFog -= DesiredFlashFog * 2 * delta; FlashScale.X += (goalScale - FlashScale.X + InstantFlash) * 10 * delta; FlashFog += (goalFog - FlashFog + InstantFog) * 10 * delta; InstantFlash = 0; InstantFog = vect(0,0,0); if ( FlashScale.X > 0.981 ) FlashScale.X = 1; FlashScale = FlashScale.X * vect(1,1,1); if ( FlashFog.X < 0.019 ) FlashFog.X = 0; if ( FlashFog.Y < 0.019 ) FlashFog.Y = 0; if ( FlashFog.Z < 0.019 ) FlashFog.Z = 0; } function ViewShake(float DeltaTime) { if (shaketimer > 0.0) //shake view { shaketimer -= DeltaTime; if ( verttimer == 0 ) { verttimer = 0.1; ShakeVert = -1.1 * maxshake; } else { verttimer -= DeltaTime; if ( verttimer < 0 ) { verttimer = 0.2 * FRand(); shakeVert = (2 * FRand() - 1) * maxshake; } } ViewRotation.Roll = ViewRotation.Roll & 65535; if (bShakeDir) { ViewRotation.Roll += Int( 10 * shakemag * FMin(0.1, DeltaTime)); bShakeDir = (ViewRotation.Roll > 32768) || (ViewRotation.Roll < (0.5 + FRand()) * shakemag); if ( (ViewRotation.Roll < 32768) && (ViewRotation.Roll > 1.3 * shakemag) ) { ViewRotation.Roll = 1.3 * shakemag; bShakeDir = false; } else if (FRand() < 3 * DeltaTime) bShakeDir = !bShakeDir; } else { ViewRotation.Roll -= Int( 10 * shakemag * FMin(0.1, DeltaTime)); bShakeDir = (ViewRotation.Roll > 32768) && (ViewRotation.Roll < 65535 - (0.5 + FRand()) * shakemag); if ( (ViewRotation.Roll > 32768) && (ViewRotation.Roll < 65535 - 1.3 * shakemag) ) { ViewRotation.Roll = 65535 - 1.3 * shakemag; bShakeDir = true; } else if (FRand() < 3 * DeltaTime) bShakeDir = !bShakeDir; } } else { ShakeVert = 0; ViewRotation.Roll = ViewRotation.Roll & 65535; if (ViewRotation.Roll < 32768) { if ( ViewRotation.Roll > 0 ) ViewRotation.Roll = Max(0, ViewRotation.Roll - (Max(ViewRotation.Roll,500) * 10 * FMin(0.1,DeltaTime))); } else { ViewRotation.Roll += ((65536 - Max(500,ViewRotation.Roll)) * 10 * FMin(0.1,DeltaTime)); if ( ViewRotation.Roll > 65534 ) ViewRotation.Roll = 0; } } } function UpdateRotation(float DeltaTime, float maxPitch) { local rotator newRotation; DesiredRotation = ViewRotation; //save old rotation ViewRotation.Pitch += 32.0 * DeltaTime * aLookUp; ViewRotation.Pitch = ViewRotation.Pitch & 65535; If ((ViewRotation.Pitch > 18000) && (ViewRotation.Pitch < 49152)) { If (aLookUp > 0) ViewRotation.Pitch = 18000; else ViewRotation.Pitch = 49152; } ViewRotation.Yaw += 32.0 * DeltaTime * aTurn; ViewShake(deltaTime); ViewFlash(deltaTime); newRotation = Rotation; newRotation.Yaw = ViewRotation.Yaw; newRotation.Pitch = ViewRotation.Pitch; If ( (newRotation.Pitch > maxPitch * RotationRate.Pitch) && (newRotation.Pitch < 65536 - maxPitch * RotationRate.Pitch) ) { If (ViewRotation.Pitch < 32768) newRotation.Pitch = maxPitch * RotationRate.Pitch; else newRotation.Pitch = 65536 - maxPitch * RotationRate.Pitch; } setRotation(newRotation); } function SwimAnimUpdate(bool bNotForward) { if ( !bAnimTransition && (GetAnimGroup(AnimSequence) != 'Gesture') ) { if ( bNotForward ) { if ( GetAnimGroup(AnimSequence) != 'Waiting' ) TweenToWaiting(0.1); } else if ( GetAnimGroup(AnimSequence) == 'Waiting' ) TweenToSwimming(0.1); } } auto state InvalidState { event PlayerTick( float DeltaTime ) { log(self$" invalid state"); if ( bUpdatePosition ) ClientUpdatePosition(); PlayerMove(DeltaTime); } function PlayerMove( float DeltaTime ) { if ( Role < ROLE_Authority ) // then save this move and replicate it ReplicateMove(DeltaTime, vect(0,0,0), Dodge_None, rot(0,0,0)); } } // Player movement. // Player Standing, walking, running, falling. state PlayerWalking { ignores SeePlayer, HearNoise, Bump; exec function FeignDeath() { if ( Physics == PHYS_Walking ) { ServerFeignDeath(); Acceleration = vect(0,0,0); GotoState('FeigningDeath'); } } function ServerFeignDeath() { local Weapon W; W = Weapon; PendingWeapon = None; if ( Weapon != None ) Weapon.PutDown(); PendingWeapon = W; GotoState('FeigningDeath'); } function ZoneChange( ZoneInfo NewZone ) { if (NewZone.bWaterZone) { setPhysics(PHYS_Swimming); GotoState('PlayerSwimming'); } } function AnimEnd() { local name MyAnimGroup; bAnimTransition = false; if (Physics == PHYS_Walking) { if (bIsCrouching) { if ( !bIsTurning && ((Velocity.X * Velocity.X + Velocity.Y * Velocity.Y) < 1000) ) PlayDuck(); else PlayCrawling(); } else { MyAnimGroup = GetAnimGroup(AnimSequence); if ((Velocity.X * Velocity.X + Velocity.Y * Velocity.Y) < 1000) { if ( MyAnimGroup == 'Waiting' ) PlayWaiting(); else { bAnimTransition = true; TweenToWaiting(0.2); } } else if (bIsWalking) { if ( (MyAnimGroup == 'Waiting') || (MyAnimGroup == 'Landing') || (MyAnimGroup == 'Gesture') || (MyAnimGroup == 'TakeHit') ) { TweenToWalking(0.1); bAnimTransition = true; } else PlayWalking(); } else { if ( (MyAnimGroup == 'Waiting') || (MyAnimGroup == 'Landing') || (MyAnimGroup == 'Gesture') || (MyAnimGroup == 'TakeHit') ) { bAnimTransition = true; TweenToRunning(0.1); } else PlayRunning(); } } } else PlayInAir(); } function Landed(vector HitNormal) { Global.Landed(HitNormal); if (DodgeDir == DODGE_Active) { DodgeDir = DODGE_Done; DodgeClickTimer = 0.0; Velocity *= 0.1; } else DodgeDir = DODGE_None; } function Dodge(eDodgeDir DodgeMove) { local vector X,Y,Z; if ( bIsCrouching || (Physics != PHYS_Walking) ) return; GetAxes(Rotation,X,Y,Z); if (DodgeMove == DODGE_Forward) Velocity = 1.5*GroundSpeed*X + (Velocity Dot Y)*Y; else if (DodgeMove == DODGE_Back) Velocity = -1.5*GroundSpeed*X + (Velocity Dot Y)*Y; else if (DodgeMove == DODGE_Left) Velocity = 1.5*GroundSpeed*Y + (Velocity Dot X)*X; else if (DodgeMove == DODGE_Right) Velocity = -1.5*GroundSpeed*Y + (Velocity Dot X)*X; Velocity.Z = 160; PlayOwnedSound(JumpSound, SLOT_Talk, 1.0, true, 800, 1.0 ); PlayDodge(DodgeMove); DodgeDir = DODGE_Active; SetPhysics(PHYS_Falling); } function ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot) { local vector OldAccel; OldAccel = Acceleration; Acceleration = NewAccel; bIsTurning = ( Abs(DeltaRot.Yaw/DeltaTime) > 5000 ); if ( (DodgeMove == DODGE_Active) && (Physics == PHYS_Falling) ) DodgeDir = DODGE_Active; else if ( (DodgeMove != DODGE_None) && (DodgeMove < DODGE_Active) ) Dodge(DodgeMove); if ( bPressedJump ) DoJump(); if ( (Physics == PHYS_Walking) && (GetAnimGroup(AnimSequence) != 'Dodge') ) { if (!bIsCrouching) { if (bDuck != 0) { bIsCrouching = true; PlayDuck(); } } else if (bDuck == 0) { OldAccel = vect(0,0,0); bIsCrouching = false; TweenToRunning(0.1); } if ( !bIsCrouching ) { if ( (!bAnimTransition || (AnimFrame > 0)) && (GetAnimGroup(AnimSequence) != 'Landing') ) { if ( Acceleration != vect(0,0,0) ) { if ( (GetAnimGroup(AnimSequence) == 'Waiting') || (GetAnimGroup(AnimSequence) == 'Gesture') || (GetAnimGroup(AnimSequence) == 'TakeHit') ) { bAnimTransition = true; TweenToRunning(0.1); } } else if ( (Velocity.X * Velocity.X + Velocity.Y * Velocity.Y < 1000) && (GetAnimGroup(AnimSequence) != 'Gesture') ) { if ( GetAnimGroup(AnimSequence) == 'Waiting' ) { if ( bIsTurning && (AnimFrame >= 0) ) { bAnimTransition = true; PlayTurning(); } } else if ( !bIsTurning ) { bAnimTransition = true; TweenToWaiting(0.2); } } } } else { if ( (OldAccel == vect(0,0,0)) && (Acceleration != vect(0,0,0)) ) PlayCrawling(); else if ( !bIsTurning && (Acceleration == vect(0,0,0)) && (AnimFrame > 0.1) ) PlayDuck(); } } } event PlayerTick( float DeltaTime ) { if ( bUpdatePosition ) ClientUpdatePosition(); PlayerMove(DeltaTime); } function PlayerMove( float DeltaTime ) { local vector X,Y,Z, NewAccel; local EDodgeDir OldDodge; local eDodgeDir DodgeMove; local rotator OldRotation; local float Speed2D; local bool bSaveJump; local name AnimGroupName; GetAxes(Rotation,X,Y,Z); aForward *= 0.4; aStrafe *= 0.4; aLookup *= 0.24; aTurn *= 0.24; // Update acceleration. NewAccel = aForward*X + aStrafe*Y; NewAccel.Z = 0; // Check for Dodge move if ( DodgeDir == DODGE_Active ) DodgeMove = DODGE_Active; else DodgeMove = DODGE_None; if (DodgeClickTime > 0.0) { if ( DodgeDir < DODGE_Active ) { OldDodge = DodgeDir; DodgeDir = DODGE_None; if (bEdgeForward && bWasForward) DodgeDir = DODGE_Forward; if (bEdgeBack && bWasBack) DodgeDir = DODGE_Back; if (bEdgeLeft && bWasLeft) DodgeDir = DODGE_Left; if (bEdgeRight && bWasRight) DodgeDir = DODGE_Right; if ( DodgeDir == DODGE_None) DodgeDir = OldDodge; else if ( DodgeDir != OldDodge ) DodgeClickTimer = DodgeClickTime + 0.5 * DeltaTime; else DodgeMove = DodgeDir; } if (DodgeDir == DODGE_Done) { DodgeClickTimer -= DeltaTime; if (DodgeClickTimer < -0.35) { DodgeDir = DODGE_None; DodgeClickTimer = DodgeClickTime; } } else if ((DodgeDir != DODGE_None) && (DodgeDir != DODGE_Active)) { DodgeClickTimer -= DeltaTime; if (DodgeClickTimer < 0) { DodgeDir = DODGE_None; DodgeClickTimer = DodgeClickTime; } } } AnimGroupName = GetAnimGroup(AnimSequence); if ( (Physics == PHYS_Walking) && (AnimGroupName != 'Dodge') ) { //if walking, look up/down stairs - unless player is rotating view if ( !bKeyboardLook && (bLook == 0) ) { if ( bLookUpStairs ) ViewRotation.Pitch = FindStairRotation(deltaTime); 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) < 1000 ) ViewRotation.Pitch = 0; } } Speed2D = Sqrt(Velocity.X * Velocity.X + Velocity.Y * Velocity.Y); //add bobbing when walking if ( !bShowMenu ) CheckBob(DeltaTime, Speed2D, Y); } else if ( !bShowMenu ) { BobTime = 0; WalkBob = WalkBob * (1 - FMin(1, 8 * deltatime)); } // Update rotation. OldRotation = Rotation; UpdateRotation(DeltaTime, 1); if ( bPressedJump && (AnimGroupName == 'Dodge') ) { bSaveJump = true; bPressedJump = false; } else bSaveJump = false; if ( Role < ROLE_Authority ) // then save this move and replicate it ReplicateMove(DeltaTime, NewAccel, DodgeMove, OldRotation - Rotation); else ProcessMove(DeltaTime, NewAccel, DodgeMove, OldRotation - Rotation); bPressedJump = bSaveJump; } function BeginState() { if ( Mesh == None ) SetMesh(); WalkBob = vect(0,0,0); DodgeDir = DODGE_None; bIsCrouching = false; bIsTurning = false; bPressedJump = false; if (Physics != PHYS_Falling) SetPhysics(PHYS_Walking); if ( !IsAnimating() ) PlayWaiting(); } function EndState() { WalkBob = vect(0,0,0); bIsCrouching = false; } } state FeigningDeath { ignores SeePlayer, HearNoise, Bump; function ZoneChange( ZoneInfo NewZone ) { if (NewZone.bWaterZone) { setPhysics(PHYS_Swimming); GotoState('PlayerSwimming'); } } exec function Fire( optional float F ) { bJustFired = true; } exec function AltFire( optional float F ) { bJustFired = true; } function PlayChatting() { } exec function Taunt( name Sequence ) { } function AnimEnd() { if ( Role < ROLE_Authority ) return; if ( Health <= 0 ) { GotoState('Dying'); return; } GotoState('PlayerWalking'); PendingWeapon.SetDefaultDisplayProperties(); ChangedWeapon(); } function Landed(vector HitNormal) { if ( Role == ROLE_Authority ) PlaySound(Land, SLOT_Interact, 0.3, false, 800, 1.0); if ( bUpdating ) return; TakeFallingDamage(); bJustLanded = true; } function Rise() { if ( (Role == ROLE_Authority) && (Health <= 0) ) { GotoState('Dying'); return; } if ( !bRising ) { Enable('AnimEnd'); BaseEyeHeight = Default.BaseEyeHeight; bRising = true; PlayRising(); } } function ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot) { if ( bJustFired || bPressedJump || (NewAccel.Z > 0) ) Rise(); Acceleration = vect(0,0,0); } event PlayerTick( float DeltaTime ) { Weapon = None; // in case client confused because of weapon switch just before feign death if ( bUpdatePosition ) ClientUpdatePosition(); PlayerMove(DeltaTime); } function ServerMove ( float TimeStamp, vector Accel, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, bool bFired, bool bAltFired, bool bForceFire, bool bForceAltFire, eDodgeDir DodgeMove, byte ClientRoll, int View, optional byte OldTimeDelta, optional int OldAccel ) { Global.ServerMove(TimeStamp, Accel, ClientLoc, NewbRun, NewbDuck, NewbJumpStatus, bFired, bAltFired, bForceFire, bForceAltFire, DodgeMove, ClientRoll, (32767 & (Rotation.Pitch/2)) * 32768 + (32767 & (Rotation.Yaw/2))); } function PlayerMove( float DeltaTime) { local rotator currentRot; local vector NewAccel; aLookup *= 0.24; aTurn *= 0.24; // Update acceleration. if ( !IsAnimating() && (aForward != 0) || (aStrafe != 0) ) NewAccel = vect(0,0,1); else NewAccel = vect(0,0,0); // Update view rotation. currentRot = Rotation; UpdateRotation(DeltaTime, 1); SetRotation(currentRot); if ( Role < ROLE_Authority ) // then save this move and replicate it ReplicateMove(DeltaTime, NewAccel, DODGE_None, Rot(0,0,0)); else ProcessMove(DeltaTime, NewAccel, DODGE_None, Rot(0,0,0)); bPressedJump = false; } function PlayTakeHit(float tweentime, vector HitLoc, int Damage) { if ( IsAnimating() ) { Enable('AnimEnd'); Global.PlayTakeHit(tweentime, HitLoc, Damage); } } function PlayDying(name DamageType, vector HitLocation) { BaseEyeHeight = Default.BaseEyeHeight; if ( bRising || IsAnimating() ) Global.PlayDying(DamageType, HitLocation); } function ChangedWeapon() { Weapon = None; Inventory.ChangedWeapon(); } function EndState() { bJustFired = false; PlayerReplicationInfo.bFeigningDeath = false; } function BeginState() { local rotator NewRot; if ( carriedDecoration != None ) DropDecoration(); NewRot = Rotation; NewRot.Pitch = 0; SetRotation(NewRot); BaseEyeHeight = -0.5 * CollisionHeight; bIsCrouching = false; bPressedJump = false; bJustFired = false; bRising = false; Disable('AnimEnd'); PlayFeignDeath(); PlayerReplicationInfo.bFeigningDeath = true; } } // Player movement. // Player Swimming state PlayerSwimming { ignores SeePlayer, HearNoise, Bump; event UpdateEyeHeight(float DeltaTime) { local float smooth, bound; // smooth up/down stairs if( !bJustLanded ) { smooth = FMin(1.0, 10.0 * DeltaTime/Level.TimeDilation); EyeHeight = (EyeHeight - Location.Z + OldLocation.Z) * (1 - smooth) + ( ShakeVert + BaseEyeHeight) * smooth; bound = -0.5 * CollisionHeight; if (EyeHeight < bound) EyeHeight = bound; else { bound = CollisionHeight + FClamp((OldLocation.Z - Location.Z), 0.0, MaxStepHeight); if ( EyeHeight > bound ) EyeHeight = bound; } } else { smooth = FClamp(10.0 * DeltaTime/Level.TimeDilation, 0.35, 1.0); bJustLanded = false; EyeHeight = EyeHeight * ( 1 - smooth) + (BaseEyeHeight + ShakeVert) * smooth; } // 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 += DeltaTime * 1.0; if (ZoomLevel > 0.9) ZoomLevel = 0.9; DesiredFOV = FClamp(90.0 - (ZoomLevel * 88.0), 1, 170); } } function Landed(vector HitNormal) { if ( !bUpdating ) { //log(class$" Landed while swimming"); PlayLanded(Velocity.Z); TakeFallingDamage(); bJustLanded = true; } if ( Region.Zone.bWaterZone ) SetPhysics(PHYS_Swimming); else { GotoState('PlayerWalking'); AnimEnd(); } } function AnimEnd() { local vector X,Y,Z; GetAxes(Rotation, X,Y,Z); if ( (Acceleration Dot X) <= 0 ) { if ( GetAnimGroup(AnimSequence) == 'TakeHit' ) { bAnimTransition = true; TweenToWaiting(0.2); } else PlayWaiting(); } else { if ( GetAnimGroup(AnimSequence) == 'TakeHit' ) { bAnimTransition = true; TweenToSwimming(0.2); } else PlaySwimming(); } } function ZoneChange( ZoneInfo NewZone ) { local actor HitActor; local vector HitLocation, HitNormal, checkpoint; if (!NewZone.bWaterZone) { SetPhysics(PHYS_Falling); if (bUpAndOut && CheckWaterJump(HitNormal)) //check for waterjump { velocity.Z = 330 + 2 * CollisionRadius; //set here so physics uses this for remainder of tick PlayDuck(); GotoState('PlayerWalking'); } else if (!FootRegion.Zone.bWaterZone || (Velocity.Z > 160) ) { GotoState('PlayerWalking'); AnimEnd(); } else //check if in deep water { checkpoint = Location; checkpoint.Z -= (CollisionHeight + 6.0); HitActor = Trace(HitLocation, HitNormal, checkpoint, Location, false); if (HitActor != None) { GotoState('PlayerWalking'); AnimEnd(); } else { Enable('Timer'); SetTimer(0.7,false); } } //log("Out of water"); } else { Disable('Timer'); SetPhysics(PHYS_Swimming); } } function ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot) { local vector X,Y,Z, Temp; GetAxes(ViewRotation,X,Y,Z); Acceleration = NewAccel; SwimAnimUpdate( (X Dot Acceleration) <= 0 ); bUpAndOut = ((X Dot Acceleration) > 0) && ((Acceleration.Z > 0) || (ViewRotation.Pitch > 2048)); if ( bUpAndOut && !Region.Zone.bWaterZone && CheckWaterJump(Temp) ) //check for waterjump { velocity.Z = 330 + 2 * CollisionRadius; //set here so physics uses this for remainder of tick PlayDuck(); GotoState('PlayerWalking'); } } event PlayerTick( float DeltaTime ) { if ( bUpdatePosition ) ClientUpdatePosition(); PlayerMove(DeltaTime); } function PlayerMove(float DeltaTime) { local rotator oldRotation; local vector X,Y,Z, NewAccel; local float Speed2D; GetAxes(ViewRotation,X,Y,Z); aForward *= 0.2; aStrafe *= 0.1; aLookup *= 0.24; aTurn *= 0.24; aUp *= 0.1; NewAccel = aForward*X + aStrafe*Y + aUp*vect(0,0,1); //add bobbing when swimming if ( !bShowMenu ) { Speed2D = Sqrt(Velocity.X * Velocity.X + Velocity.Y * Velocity.Y); WalkBob = Y * Bob * 0.5 * Speed2D * sin(4.0 * Level.TimeSeconds); WalkBob.Z = Bob * 1.5 * Speed2D * sin(8.0 * Level.TimeSeconds); } // Update rotation. oldRotation = Rotation; UpdateRotation(DeltaTime, 2); if ( Role < ROLE_Authority ) // then save this move and replicate it ReplicateMove(DeltaTime, NewAccel, DODGE_None, OldRotation - Rotation); else ProcessMove(DeltaTime, NewAccel, DODGE_None, OldRotation - Rotation); bPressedJump = false; } function Timer() { if ( !Region.Zone.bWaterZone && (Role == ROLE_Authority) ) { //log("timer out of water"); GotoState('PlayerWalking'); AnimEnd(); } Disable('Timer'); } function BeginState() { Disable('Timer'); if ( !IsAnimating() ) TweenToWaiting(0.3); //log("player swimming"); } } state PlayerFlying { ignores SeePlayer, HearNoise, Bump; function AnimEnd() { PlaySwimming(); } event PlayerTick( float DeltaTime ) { if ( bUpdatePosition ) ClientUpdatePosition(); PlayerMove(DeltaTime); } function PlayerMove(float DeltaTime) { local rotator newRotation; local vector X,Y,Z; GetAxes(Rotation,X,Y,Z); aForward *= 0.2; aStrafe *= 0.2; aLookup *= 0.24; aTurn *= 0.24; Acceleration = aForward*X + aStrafe*Y; // Update rotation. UpdateRotation(DeltaTime, 2); if ( Role < ROLE_Authority ) // then save this move and replicate it ReplicateMove(DeltaTime, Acceleration, DODGE_None, rot(0,0,0)); else ProcessMove(DeltaTime, Acceleration, DODGE_None, rot(0,0,0)); } function BeginState() { SetPhysics(PHYS_Flying); if ( !IsAnimating() ) PlayWalking(); //log("player flying"); } } state CheatFlying { ignores SeePlayer, HearNoise, Bump, TakeDamage; function AnimEnd() { PlaySwimming(); } function ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot) { Acceleration = Normal(NewAccel); Velocity = Normal(NewAccel) * 300; AutonomousPhysics(DeltaTime); } event PlayerTick( float DeltaTime ) { if ( bUpdatePosition ) ClientUpdatePosition(); PlayerMove(DeltaTime); } function PlayerMove(float DeltaTime) { local rotator newRotation; local vector X,Y,Z; GetAxes(ViewRotation,X,Y,Z); aForward *= 0.1; aStrafe *= 0.1; aLookup *= 0.24; aTurn *= 0.24; aUp *= 0.1; Acceleration = 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, DODGE_None, rot(0,0,0)); else ProcessMove(DeltaTime, Acceleration, DODGE_None, rot(0,0,0)); } function BeginState() { EyeHeight = BaseEyeHeight; SetPhysics(PHYS_Flying); if ( !IsAnimating() ) PlaySwimming(); // log("cheat flying"); } } state PlayerWaiting { ignores SeePlayer, HearNoise, Bump, TakeDamage, Died, ZoneChange, FootZoneChange; exec function Jump( optional float F ) { } exec function Suicide() { } function ChangeTeam( int N ) { Level.Game.ChangeTeam(self, N); } exec function Fire(optional float F) { bReadyToPlay = true; } exec function AltFire(optional float F) { bReadyToPlay = true; } function ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot) { Acceleration = NewAccel; MoveSmooth(Acceleration * DeltaTime); } function PlayWaiting() {} event PlayerTick( float DeltaTime ) { if ( bUpdatePosition ) ClientUpdatePosition(); PlayerMove(DeltaTime); } function PlayerMove(float DeltaTime) { local rotator newRotation; local vector X,Y,Z; GetAxes(ViewRotation,X,Y,Z); aForward *= 0.1; aStrafe *= 0.1; aLookup *= 0.24; aTurn *= 0.24; aUp *= 0.1; Acceleration = 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, DODGE_None, rot(0,0,0)); else ProcessMove(DeltaTime, Acceleration, DODGE_None, rot(0,0,0)); } function EndState() { SetMesh(); PlayerReplicationInfo.bIsSpectator = false; PlayerReplicationInfo.bWaitingPlayer = false; SetCollision(true,true,true); } function BeginState() { Mesh = None; if ( PlayerReplicationInfo != None ) { PlayerReplicationInfo.bIsSpectator = true; PlayerReplicationInfo.bWaitingPlayer = true; } SetCollision(false,false,false); EyeHeight = BaseEyeHeight; SetPhysics(PHYS_None); } } state PlayerSpectating { ignores SeePlayer, HearNoise, Bump, TakeDamage, Died, ZoneChange, FootZoneChange; exec function Suicide() { } function SendVoiceMessage(PlayerReplicationInfo Sender, PlayerReplicationInfo Recipient, name messagetype, byte messageID, name broadcasttype) { } exec function AltFire( optional float F ) { bBehindView = false; Viewtarget = None; ClientMessage(ViewingFrom@OwnCamera, 'Event', true); } function ChangeTeam( int N ) { Level.Game.ChangeTeam(self, N); } exec function Fire( optional float F ) { if ( Role == ROLE_Authority ) { ViewPlayerNum(-1); bBehindView = true; } } function ProcessMove(float DeltaTime, vector NewAccel, eDodgeDir DodgeMove, rotator DeltaRot) { Acceleration = NewAccel; MoveSmooth(Acceleration * DeltaTime); } event PlayerTick( float DeltaTime ) { if ( bUpdatePosition ) ClientUpdatePosition(); PlayerMove(DeltaTime); } function PlayerMove(float DeltaTime) { local rotator newRotation; local vector X,Y,Z; GetAxes(ViewRotation,X,Y,Z); aForward *= 0.1; aStrafe *= 0.1; aLookup *= 0.24; aTurn *= 0.24; aUp *= 0.1; Acceleration = 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, DODGE_None, rot(0,0,0)); else ProcessMove(DeltaTime, Acceleration, DODGE_None, rot(0,0,0)); } function EndState() { PlayerReplicationInfo.bIsSpectator = false; PlayerReplicationInfo.bWaitingPlayer = false; SetMesh(); SetCollision(true,true,true); } function BeginState() { PlayerReplicationInfo.bIsSpectator = true; PlayerReplicationInfo.bWaitingPlayer = true; bShowScores = true; Mesh = None; SetCollision(false,false,false); EyeHeight = Default.BaseEyeHeight; SetPhysics(PHYS_None); } } //=============================================================================== state PlayerWaking { ignores SeePlayer, HearNoise, KilledBy, Bump, HitWall, HeadZoneChange, FootZoneChange, ZoneChange, SwitchWeapon, Falling; function Timer() { BaseEyeHeight = Default.BaseEyeHeight; } event PlayerTick( float DeltaTime ) { if ( bUpdatePosition ) ClientUpdatePosition(); PlayerMove(DeltaTime); } function PlayerMove(Float DeltaTime) { ViewFlash(deltaTime * 0.5); if ( TimerRate == 0 ) { ViewRotation.Pitch -= DeltaTime * 12000; if ( ViewRotation.Pitch < 0 ) { ViewRotation.Pitch = 0; GotoState('PlayerWalking'); } } if ( Role < ROLE_Authority ) // then save this move and replicate it ReplicateMove(DeltaTime, vect(0,0,0), DODGE_None, rot(0,0,0)); else ProcessMove(DeltaTime, vect(0,0,0), DODGE_None, rot(0,0,0)); } function BeginState() { if ( bWokeUp ) { ViewRotation.Pitch = 0; SetTimer(0, false); return; } BaseEyeHeight = 0; EyeHeight = 0; SetTimer(3.0, false); bWokeUp = true; } } state Dying { ignores SeePlayer, HearNoise, KilledBy, Bump, HitWall, HeadZoneChange, FootZoneChange, ZoneChange, SwitchWeapon, Falling, PainTimer; exec function Suicide() { } function ServerReStartPlayer() { //log("calling restartplayer in dying with netmode "$Level.NetMode); if ( (bFrozen && (TimerRate>0.0)) || (Level.NetMode == NM_Client) ) return; if( Level.Game.RestartPlayer(self) ) { ServerTimeStamp = 0; TimeMargin = 0; Enemy = None; Level.Game.StartPlayer(self); if ( Mesh != None ) PlayWaiting(); ClientReStart(); } else log("Restartplayer failed"); } exec function Fire( optional float F ) { if ( (Level.NetMode == NM_Standalone) && !Level.Game.bDeathMatch ) { if ( bFrozen ) return; ShowLoadMenu(); } else if ( !bFrozen || (TimerRate <= 0.0) ) ServerReStartPlayer(); } exec function AltFire( optional float F ) { Fire(F); } function PlayChatting() { } exec function Taunt( name Sequence ) { } function ServerMove ( float TimeStamp, vector Accel, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, bool bFired, bool bAltFired, bool bForceFire, bool bForceAltFire, eDodgeDir DodgeMove, byte ClientRoll, int View, optional byte OldTimeDelta, optional int OldAccel ) { Global.ServerMove( TimeStamp, Accel, ClientLoc, false, false, false, false, false, false, false, DodgeMove, ClientRoll, View); } function PlayerCalcView(out actor ViewActor, out vector CameraLocation, out rotator CameraRotation ) { local vector View,HitLocation,HitNormal, FirstHit, spot; local float DesiredDist, ViewDist, WallOutDist; local actor HitActor; local Pawn PTarget; if ( ViewTarget != None ) { ViewActor = ViewTarget; CameraLocation = ViewTarget.Location; CameraRotation = ViewTarget.Rotation; PTarget = Pawn(ViewTarget); if ( PTarget != None ) { if ( Level.NetMode == NM_Client ) { if ( PTarget.bIsPlayer ) PTarget.ViewRotation = TargetViewRotation; PTarget.EyeHeight = TargetEyeHeight; if ( PTarget.Weapon != None ) PTarget.Weapon.PlayerViewOffset = TargetWeaponViewOffset; } if ( PTarget.bIsPlayer ) CameraRotation = PTarget.ViewRotation; CameraLocation.Z += PTarget.EyeHeight; } if ( Carcass(ViewTarget) != None ) { if ( bBehindView || (ViewTarget.Physics == PHYS_None) ) CameraRotation = ViewRotation; else ViewRotation = CameraRotation; if ( bBehindView ) CalcBehindView(CameraLocation, CameraRotation, 190); } else if ( bBehindView ) CalcBehindView(CameraLocation, CameraRotation, 180); return; } // View rotation. CameraRotation = ViewRotation; DesiredFOV = DefaultFOV; ViewActor = self; if( bBehindView ) //up and behind (for death scene) CalcBehindView(CameraLocation, CameraRotation, 180); else { // First-person view. CameraLocation = Location; CameraLocation.Z += Default.BaseEyeHeight; } } event PlayerTick( float DeltaTime ) { if ( bUpdatePosition ) ClientUpdatePosition(); PlayerMove(DeltaTime); } function PlayerMove(float DeltaTime) { local vector X,Y,Z; if ( !bFrozen ) { if ( bPressedJump ) { Fire(0); bPressedJump = false; } GetAxes(ViewRotation,X,Y,Z); // Update view rotation. aLookup *= 0.24; aTurn *= 0.24; ViewRotation.Yaw += 32.0 * DeltaTime * aTurn; ViewRotation.Pitch += 32.0 * DeltaTime * aLookUp; ViewRotation.Pitch = ViewRotation.Pitch & 65535; If ((ViewRotation.Pitch > 18000) && (ViewRotation.Pitch < 49152)) { If (aLookUp > 0) ViewRotation.Pitch = 18000; else ViewRotation.Pitch = 49152; } if ( Role < ROLE_Authority ) // then save this move and replicate it ReplicateMove(DeltaTime, vect(0,0,0), DODGE_None, rot(0,0,0)); } ViewShake(DeltaTime); ViewFlash(DeltaTime); } function FindGoodView() { local vector cameraLoc; local rotator cameraRot; local int tries, besttry; local float bestdist, newdist; local int startYaw; local actor ViewActor; //fixme - try to pick view with killer visible //fixme - also try varying starting pitch ////log("Find good death scene view"); ViewRotation.Pitch = 56000; tries = 0; besttry = 0; bestdist = 0.0; startYaw = ViewRotation.Yaw; for (tries=0; tries<16; tries++) { cameraLoc = Location; PlayerCalcView(ViewActor, cameraLoc, cameraRot); newdist = VSize(cameraLoc - Location); if (newdist > bestdist) { bestdist = newdist; besttry = tries; } ViewRotation.Yaw += 4096; } ViewRotation.Yaw = startYaw + besttry * 4096; } function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType) { if ( !bHidden ) Super.TakeDamage(Damage, instigatedBy, hitlocation, momentum, damageType); } function Timer() { bFrozen = false; bShowScores = true; bPressedJump = false; } function BeginState() { BaseEyeheight = Default.BaseEyeHeight; EyeHeight = BaseEyeHeight; if ( Carcass(ViewTarget) == None ) bBehindView = true; bFrozen = true; bPressedJump = false; bJustFired = false; bJustAltFired = false; FindGoodView(); if ( (Role == ROLE_Authority) && !bHidden ) Super.Timer(); SetTimer(1.0, false); // clean out saved moves while ( SavedMoves != None ) { SavedMoves.Destroy(); SavedMoves = SavedMoves.NextMove; } if ( PendingMove != None ) { PendingMove.Destroy(); PendingMove = None; } } function EndState() { // clean out saved moves while ( SavedMoves != None ) { SavedMoves.Destroy(); SavedMoves = SavedMoves.NextMove; } if ( PendingMove != None ) { PendingMove.Destroy(); PendingMove = None; } Velocity = vect(0,0,0); Acceleration = vect(0,0,0); bBehindView = false; bShowScores = false; bJustFired = false; bJustAltFired = false; bPressedJump = false; if ( Carcass(ViewTarget) != None ) ViewTarget = None; //Log(self$" exiting dying with remote role "$RemoteRole$" and role "$Role); } } state GameEnded { ignores SeePlayer, HearNoise, KilledBy, Bump, HitWall, HeadZoneChange, FootZoneChange, ZoneChange, Falling, TakeDamage, PainTimer, Died, Suicide; exec function ThrowWeapon() { } exec function Taunt( name Sequence ) { if ( Health > 0 ) Global.Taunt(Sequence); } exec function ViewClass( class aClass, optional bool bQuiet ) { } exec function ViewPlayer( string S ) { } function ServerReStartGame() { 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); } event PlayerTick( float DeltaTime ) { if ( bUpdatePosition ) ClientUpdatePosition(); PlayerMove(DeltaTime); } function PlayerMove(float DeltaTime) { local vector X,Y,Z; GetAxes(ViewRotation,X,Y,Z); // Update view rotation. if ( !bFixedCamera ) { aLookup *= 0.24; aTurn *= 0.24; ViewRotation.Yaw += 32.0 * DeltaTime * aTurn; ViewRotation.Pitch += 32.0 * DeltaTime * aLookUp; ViewRotation.Pitch = ViewRotation.Pitch & 65535; If ((ViewRotation.Pitch > 18000) && (ViewRotation.Pitch < 49152)) { If (aLookUp > 0) ViewRotation.Pitch = 18000; else ViewRotation.Pitch = 49152; } } else if ( ViewTarget != None ) ViewRotation = ViewTarget.Rotation; ViewShake(DeltaTime); ViewFlash(DeltaTime); if ( Role < ROLE_Authority ) // then save this move and replicate it ReplicateMove(DeltaTime, vect(0,0,0), DODGE_None, rot(0,0,0)); else ProcessMove(DeltaTime, vect(0,0,0), DODGE_None, rot(0,0,0)); bPressedJump = false; } function ServerMove ( float TimeStamp, vector InAccel, vector ClientLoc, bool NewbRun, bool NewbDuck, bool NewbJumpStatus, bool bFired, bool bAltFired, bool bForceFire, bool bForceAltFire, eDodgeDir DodgeMove, byte ClientRoll, int View, optional byte OldTimeDelta, optional int OldAccel ) { Global.ServerMove(TimeStamp, InAccel, ClientLoc, NewbRun, NewbDuck, NewbJumpStatus, bFired, bAltFired, bForceFire, bForceAltFire, DodgeMove, ClientRoll, (32767 & (ViewRotation.Pitch/2)) * 32768 + (32767 & (ViewRotation.Yaw/2)) ); } function FindGoodView() { local vector cameraLoc; local rotator cameraRot; local int tries, besttry; local float bestdist, newdist; local int startYaw; local actor ViewActor; ViewRotation.Pitch = 56000; tries = 0; besttry = 0; bestdist = 0.0; startYaw = ViewRotation.Yaw; for (tries=0; tries<16; tries++) { if ( ViewTarget != None ) cameraLoc = ViewTarget.Location; else cameraLoc = Location; PlayerCalcView(ViewActor, cameraLoc, cameraRot); newdist = VSize(cameraLoc - Location); if (newdist > bestdist) { bestdist = newdist; besttry = tries; } ViewRotation.Yaw += 4096; } ViewRotation.Yaw = startYaw + besttry * 4096; } function Timer() { bFrozen = false; } function BeginState() { local Pawn P; EndZoom(); AnimRate = 0.0; SimAnim.Y = 0; bFire = 0; bAltFire = 0; SetCollision(false,false,false); bShowScores = true; bFrozen = true; if ( !bFixedCamera ) { FindGoodView(); bBehindView = true; } SetTimer(1.5, false); SetPhysics(PHYS_None); ForEach AllActors(class'Pawn', P) { P.Velocity = vect(0,0,0); P.SetPhysics(PHYS_None); } } } // ngStats Accessors function string GetNGSecret() { return ngWorldSecret; } function SetNGSecret(string newSecret) { ngWorldSecret = newSecret; } w4}//============================================================================= // 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 native noexport; //----------------------------------------------------------------------------- // Player properties. // Internal. var native const int vfOut; var native const int vfExec; // The actor this player controls. var transient const playerpawn Actor; var transient const console Console; // Window input variables var transient const bool bWindowsMouseAvailable; var bool bShowWindowsMouse; var bool bSuspendPrecaching; var transient const float WindowsMouseX; var transient const float WindowsMouseY; var int CurrentNetSpeed; var globalconfig int ConfiguredInternetSpeed, ConfiguredLanSpeed; var byte SelectedCursor; 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; w4bMw4jw4w4w4\D//============================================================================= // Pickup items. //============================================================================= class Pickup extends Inventory abstract native nativereplication; var inventory Inv; var travel int NumCopies; var() bool bCanHaveMultipleCopies; // if player can possess more than one of this var() bool bCanActivate; // Item can be selected and activated var() localized String ExpireMessage; // Messages shown when pickup charge runs out var() bool bAutoActivate; replication { // Things the server should send to the client. reliable if( bNetOwner && (Role==ROLE_Authority) ) NumCopies; } function TravelPostAccept() { Super.TravelPostAccept(); PickupFunction(Pawn(Owner)); } // // 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( inventory Item ) { if (item.class == class) { if (bCanHaveMultipleCopies) { // for items like Artifact NumCopies++; if (Level.Game.LocalLog != None) Level.Game.LocalLog.LogPickup(Item, Pawn(Owner)); if (Level.Game.WorldLog != None) Level.Game.WorldLog.LogPickup(Item, Pawn(Owner)); if ( Item.PickupMessageClass == None ) Pawn(Owner).ClientMessage(item.PickupMessage, 'Pickup'); else Pawn(Owner).ReceiveLocalizedMessage( item.PickupMessageClass, 0, None, None, item.Class ); Item.PlaySound (Item.PickupSound,,2.0); Item.SetRespawn(); } else if ( bDisplayableInv ) { if ( Charge0) ) return; Super.Activate(); } } w4\8w4w4w8w4w4gMw4w4w4w4s U 'B&I U 7tNttU N__tNttU N~U  u %u  w4l//============================================================================= // Pawn, the base class of all actors that can be controlled by players or AI. // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class Pawn extends Actor abstract native nativereplication; #exec Texture Import File=Textures\Pawn.pcx Name=S_Pawn Mips=Off Flags=2 //----------------------------------------------------------------------------- // Pawn variables. // General flags. var bool bBehindView; // Outside-the-player view. var bool bIsPlayer; // Pawn is a player or a player-bot. var bool bJustLanded; // used by eyeheight adjustment var bool bUpAndOut; // used by swimming var bool bIsWalking; var const bool bHitSlopedWall; // used by Physics var globalconfig bool bNeverSwitchOnPickup; // if true, don't automatically switch to picked up weapon var bool bWarping; // Set when travelling through warpzone (so shouldn't telefrag) var bool bUpdatingDisplay; // to avoid infinite recursion through inventory setdisplay //AI flags var(Combat) bool bCanStrafe; var(Orders) bool bFixedStart; var const bool bReducedSpeed; //used by movement natives var bool bCanJump; var bool bCanWalk; var bool bCanSwim; var bool bCanFly; var bool bCanOpenDoors; var bool bCanDoSpecial; var bool bDrowning; var const bool bLOSflag; // used for alternating LineOfSight traces var bool bFromWall; 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 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 bJumpOffPawn; var bool bShootSpecial; var bool bAutoActivate; var bool bIsHuman; // for games which care about whether a pawn is a human var bool bIsFemale; var bool bIsMultiSkinned; var bool bCountJumps; var bool bAdvancedTactics; // used during movement between pathnodes var bool bViewTarget; // Ticked pawn timers var float SightCounter; //Used to keep track of when to check player visibility var float PainTime; //used for getting PainTimer() messages (for Lava, no air, etc.) var float SpeechTime; // Physics updating time monitoring (for AI monitoring reaching destinations) var const float AvgPhysicsTime; // Additional pawn region information. var PointRegion FootRegion; var PointRegion HeadRegion; // Navigation AI var float MoveTimer; var Actor MoveTarget; // set by movement natives var Actor FaceTarget; // set by strafefacing native var vector Destination; // set by Movement natives var vector Focus; // set by Movement natives var float DesiredSpeed; var float MaxDesiredSpeed; var(Combat) float MeleeRange; // Max range for melee attack (not including collision radii) // Player and enemy movement. var(Movement) float GroundSpeed; // The maximum ground speed. var(Movement) float WaterSpeed; // The maximum swimming speed. var(Movement) float AirSpeed; // The maximum flying speed. var(Movement) float AccelRate; // max acceleration rate var(Movement) float JumpZ; // vertical acceleration w/ jump var(Movement) float MaxStepHeight; // Maximum size of upward/downward step. var(Movement) float AirControl; // amount of AirControl available to the pawn // AI basics. var float MinHitWall; // Minimum HitNormal dot Velocity.Normal to get a HitWall from the // physics var() byte Visibility; //How visible is the pawn? 0 = invisible. // 128 = normal. 255 = highly visible. var float Alertness; // -1 to 1 ->Used within specific states for varying reaction to stimuli var float Stimulus; // Strength of stimulus - Set when stimulus happens, used in Acquisition state var(AI) float SightRadius; //Maximum seeing distance. var(AI) float PeripheralVision;//Cosine of limits of peripheral vision. var(AI) float HearingThreshold; //Minimum noise loudness for hearing 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 Pawn Enemy; // Player info. var travel Weapon Weapon; // The pawn's current weapon. var Weapon PendingWeapon; // Will become weapon once current weapon is put down var travel Inventory SelectedItem; // currently selected inventory item // Movement. var rotator ViewRotation; // View rotation. var vector WalkBob; var() float BaseEyeHeight; // Base eye height above collision center. var float EyeHeight; // Current eye height, adjusted for bobbing and stairs. var const vector Floor; // Normal of floor pawn is standing on (only used // by PHYS_Spider) var float SplashTime; // time of last splash // View var float OrthoZoom; // Orthogonal/map view zoom factor. var() float FovAngle; // X field of view angle in degrees, usually 90. // Player game statistics. var int DieCount, ItemCount, KillCount, SecretCount, Spree; //Health var() travel int Health; // Health: 100 = normal maximum // Selection Mesh var() string SelectionMesh; var() string SpecialMesh; // Inherent Armor (for creatures). var() name ReducedDamageType; //Either a damagetype name or 'All', 'AllEnvironment' (Burned, Corroded, Frozen) var() float ReducedDamagePct; // Inventory to drop when killed (for creatures) var() class DropWhenKilled; // Zone pain var(Movement) float UnderWaterTime; //how much time pawn can go without air (in seconds) var(AI) enum EAttitude //important - order in decreasing importance { ATTITUDE_Fear, //will try to run away ATTITUDE_Hate, // will attack enemy ATTITUDE_Frenzy, //will attack anything, indiscriminately ATTITUDE_Threaten, // animations, but no attack ATTITUDE_Ignore, ATTITUDE_Friendly, ATTITUDE_Follow //accepts player as leader } AttitudeToPlayer; //determines how creature will react on seeing player (if in human form) var(AI) enum EIntelligence //important - order in increasing intelligence { BRAINS_NONE, //only reacts to immediate stimulus BRAINS_REPTILE, //follows to last seen position BRAINS_MAMMAL, //simple navigation (limited path length) BRAINS_HUMAN //complex navigation, team coordination, use environment stuff (triggers, etc.) } Intelligence; var(AI) float Skill; // skill, scaled by game difficulty (add difficulty to this value) var actor SpecialGoal; // used by navigation AI var float SpecialPause; // Sound and noise management 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; // chained pawn list var const pawn nextPawn; // Common sounds var(Sounds) sound HitSound1; var(Sounds) sound HitSound2; var(Sounds) sound Land; var(Sounds) sound Die; var(Sounds) sound WaterStep; // Input buttons. var input byte bZoom, bRun, bLook, bDuck, bSnapLevel, bStrafe, bFire, bAltFire, bFreeLook, bExtra0, bExtra1, bExtra2, bExtra3; var(Combat) float CombatStyle; // -1 to 1 = low means tends to stay off and snipe, high means tends to charge and melee var NavigationPoint home; //set when begin play, used for retreating and attitude checks var name NextState; //for queueing states var name NextLabel; //for queueing states var float SoundDampening; var float DamageScaling; var(Orders) name AlarmTag; // tag of object to go to when see player var(Orders) name SharedAlarmTag; var Decoration carriedDecoration; var Name PlayerReStartState; var() localized string MenuName; //Name used for this pawn type in menus (e.g. player selection) var() localized string NameArticle; //article used in conjunction with this class (e.g. "a", "an") var() byte VoicePitch; //for speech var() string VoiceType; //for speech var float OldMessageTime; //to limit frequency of voice messages // Route Cache for Navigation var NavigationPoint RouteCache[16]; // Replication Info var() class PlayerReplicationInfoClass; var PlayerReplicationInfo PlayerReplicationInfo; // shadow decal var Decal Shadow; replication { // Variables the server should send to the client. reliable if( Role==ROLE_Authority ) Weapon, PlayerReplicationInfo, Health, bCanFly; reliable if( bNetOwner && Role==ROLE_Authority ) bIsPlayer, CarriedDecoration, SelectedItem, GroundSpeed, WaterSpeed, AirSpeed, AccelRate, JumpZ, AirControl, bBehindView, PlayerRestartState; unreliable if( (bNetOwner && bIsPlayer && bNetInitial && Role==ROLE_Authority) || bDemoRecording ) ViewRotation; unreliable if( bNetOwner && Role==ROLE_Authority ) MoveTarget; reliable if( bDemoRecording ) EyeHeight; // Functions the server calls on the client side. reliable if( RemoteRole==ROLE_AutonomousProxy ) ClientDying, ClientReStart, ClientGameEnded, ClientSetRotation, ClientSetLocation, ClientPutDown; unreliable if( (!bDemoRecording || bClientDemoRecording && bClientDemoNetFunc) && Role==ROLE_Authority ) ClientHearSound; reliable if ( (!bDemoRecording || (bClientDemoRecording && bClientDemoNetFunc)) && Role == ROLE_Authority ) ClientVoiceMessage; reliable if ( (!bDemoRecording || (bClientDemoRecording && bClientDemoNetFunc) || (Level.NetMode==NM_Standalone && IsA('PlayerPawn'))) && Role == ROLE_Authority ) ClientMessage, TeamMessage, ReceiveLocalizedMessage; // Functions the client calls on the server. unreliable if( Role Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ); function BecomeViewTarget() { bViewTarget = true; } event FellOutOfWorld() { if ( Role < ROLE_Authority ) return; Health = -1; SetPhysics(PHYS_None); Weapon = None; Died(None, 'Fell', Location); } function PlayRecoil(float Rate); function SpecialFire(); function bool CheckFutureSight(float DeltaTime) { return true; } function RestartPlayer(); // // Broadcast a message to all players, or all on the same team. // function TeamBroadcast( coerce string Msg) { local Pawn P; local bool bGlobal; if ( Left(Msg, 1) ~= "@" ) { Msg = Right(Msg, Len(Msg)-1); bGlobal = true; } if ( Left(Msg, 1) ~= "." ) Msg = "."$VoicePitch$Msg; if ( bGlobal || !Level.Game.bTeamGame ) { if ( Level.Game.AllowsBroadcast(self, Len(Msg)) ) for( P=Level.PawnList; P!=None; P=P.nextPawn ) if( P.bIsPlayer || P.IsA('MessagingSpectator') ) P.TeamMessage( PlayerReplicationInfo, Msg, 'Say' ); return; } if ( Level.Game.AllowsBroadcast(self, Len(Msg)) ) for( P=Level.PawnList; P!=None; P=P.nextPawn ) if( P.bIsPlayer && (P.PlayerReplicationInfo.Team == PlayerReplicationInfo.Team) ) { if ( P.IsA('PlayerPawn') ) P.TeamMessage( PlayerReplicationInfo, Msg, 'TeamSay' ); } } //------------------------------------------------------------------------------ // Speech related function SendGlobalMessage(PlayerReplicationInfo Recipient, name MessageType, byte MessageID, float Wait) { SendVoiceMessage(PlayerReplicationInfo, Recipient, MessageType, MessageID, 'GLOBAL'); } function SendTeamMessage(PlayerReplicationInfo Recipient, name MessageType, byte MessageID, float Wait) { SendVoiceMessage(PlayerReplicationInfo, Recipient, MessageType, MessageID, 'TEAM'); } function SendVoiceMessage(PlayerReplicationInfo Sender, PlayerReplicationInfo Recipient, name messagetype, byte messageID, name broadcasttype) { local Pawn P; local bool bNoSpeak; if ( Level.TimeSeconds - OldMessageTime < 2.5 ) bNoSpeak = true; else OldMessageTime = Level.TimeSeconds; for ( P=Level.PawnList; P!=None; P=P.NextPawn ) { if ( P.IsA('PlayerPawn') ) { if ( !bNoSpeak ) { if ( (broadcasttype == 'GLOBAL') || !Level.Game.bTeamGame ) P.ClientVoiceMessage(Sender, Recipient, messagetype, messageID); else if ( Sender.Team == P.PlayerReplicationInfo.Team ) P.ClientVoiceMessage(Sender, Recipient, messagetype, messageID); } } else if ( (P.PlayerReplicationInfo == Recipient) || ((messagetype == 'ORDER') && (Recipient == None)) ) P.BotVoiceMessage(messagetype, messageID, self); } } function ClientVoiceMessage(PlayerReplicationInfo Sender, PlayerReplicationInfo Recipient, name messagetype, byte messageID); function BotVoiceMessage(name messagetype, byte MessageID, Pawn Sender); //*************************************************************** function HandleHelpMessageFrom(Pawn Other); function FearThisSpot(Actor ASpot); function float GetRating() { return 1000; } function AddVelocity( vector NewVelocity) { if (Physics == PHYS_Walking) SetPhysics(PHYS_Falling); if ( (Velocity.Z > 380) && (NewVelocity.Z > 0) ) NewVelocity.Z *= 0.5; Velocity += NewVelocity; } function ClientSetLocation( vector NewLocation, rotator NewRotation ) { local Pawn P; ViewRotation = NewRotation; If ( (ViewRotation.Pitch > RotationRate.Pitch) && (ViewRotation.Pitch < 65536 - RotationRate.Pitch) ) { If (ViewRotation.Pitch < 32768) NewRotation.Pitch = RotationRate.Pitch; else NewRotation.Pitch = 65536 - RotationRate.Pitch; } NewRotation.Roll = 0; SetRotation( NewRotation ); SetLocation( NewLocation ); } function ClientSetRotation( rotator NewRotation ) { local Pawn P; ViewRotation = NewRotation; NewRotation.Pitch = 0; NewRotation.Roll = 0; SetRotation( NewRotation ); } function ClientDying(name DamageType, vector HitLocation) { PlayDying(DamageType, HitLocation); GotoState('Dying'); } function ClientReStart() { //log("client restart"); Velocity = vect(0,0,0); Acceleration = vect(0,0,0); BaseEyeHeight = Default.BaseEyeHeight; EyeHeight = BaseEyeHeight; PlayWaiting(); if ( Region.Zone.bWaterZone && (PlayerRestartState == 'PlayerWalking') ) { if (HeadRegion.Zone.bWaterZone) PainTime = UnderWaterTime; setPhysics(PHYS_Swimming); GotoState('PlayerSwimming'); } else GotoState(PlayerReStartState); } function ClientGameEnded() { GotoState('GameEnded'); } //============================================================================= // Inventory related functions. function float AdjustDesireFor(Inventory Inv) { return 0; } // toss out the weapon currently held function TossWeapon() { local vector X,Y,Z; if ( Weapon == None ) return; GetAxes(Rotation,X,Y,Z); Weapon.DropFrom(Location + 0.8 * CollisionRadius * X + - 0.5 * CollisionRadius * Y); } // The player/bot wants to select next item exec function NextItem() { local Inventory Inv; 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; for( Inv=Inventory; Inv!=None; Inv=Inv.Inventory ) if ( Inv.class == DesiredClass ) return Inv; 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; // The item should not have been destroyed if we get here. if (NewItem ==None ) log("tried to add none inventory to "$self); for( Inv=Inventory; Inv!=None; Inv=Inv.Inventory ) if( Inv == NewItem ) return false; // Add to front of inventory chain. NewItem.SetOwner(Self); NewItem.Inventory = Inventory; Inventory = NewItem; return true; } // Remove Item from this pawn's inventory, if it exists. // Returns true if it existed and was deleted, false if it did not exist. function bool DeleteInventory( inventory Item ) { // If this item is in our inventory chain, unlink it. local actor Link; 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; break; } } Item.SetOwner(None); } // Just changed to pendingWeapon function ChangedWeapon() { local Weapon OldWeapon; OldWeapon = Weapon; if (Weapon == PendingWeapon) { if ( Weapon == None ) SwitchToBestWeapon(); else if ( Weapon.IsInState('DownWeapon') ) Weapon.BringUp(); if ( Weapon != None ) Weapon.SetDefaultDisplayProperties(); Inventory.ChangedWeapon(); // tell inventory that weapon changed (in case any effect was being applied) PendingWeapon = None; return; } if ( PendingWeapon == None ) PendingWeapon = Weapon; PlayWeaponSwitch(PendingWeapon); if ( (PendingWeapon != None) && (PendingWeapon.Mass > 20) && (carriedDecoration != None) ) DropDecoration(); if ( Weapon != None ) Weapon.SetDefaultDisplayProperties(); Weapon = PendingWeapon; Inventory.ChangedWeapon(); // tell inventory that weapon changed (in case any effect was being applied) if ( Weapon != None ) { Weapon.RaiseUp(OldWeapon); if ( (Level.Game != None) && (Level.Game.Difficulty > 1) ) MakeNoise(0.1 * Level.Game.Difficulty); } PendingWeapon = None; } //============== // Encroachment event bool EncroachingOn( actor Other ) { if ( (Other.Brush != None) || (Brush(Other) != None) ) return true; if ( (!bIsPlayer || bWarping) && (Pawn(Other) != None)) return true; return false; } event EncroachedBy( actor Other ) { if ( Pawn(Other) != None ) gibbedBy(Other); } function gibbedBy(actor Other) { local pawn instigatedBy; if ( Role < ROLE_Authority ) return; instigatedBy = pawn(Other); if (instigatedBy == None) instigatedBy = Other.instigator; health = -1000; //make sure gibs Died(instigatedBy, 'Gibbed', Location); } event PlayerTimeOut() { if (Health > 0) Died(None, 'Suicided', 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 += 60 * VRand(); Velocity.Z = 180; SetPhysics(PHYS_Falling); } function UnderLift(Mover M); singular event BaseChange() { local float decorMass; if ( (base == None) && (Physics == PHYS_None) ) SetPhysics(PHYS_Falling); else if (Pawn(Base) != None) { Base.TakeDamage( (1-Velocity.Z/400)* Mass/Base.Mass, Self,Location,0.5 * Velocity , 'stomped'); 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, 'stomped'); } } event LongFall(); //============================================================================= // Network related functions. simulated event Destroyed() { local Inventory Inv; local Pawn OtherPawn; if ( Shadow != None ) Shadow.Destroy(); if ( Role < ROLE_Authority ) return; RemovePawn(); for( Inv=Inventory; Inv!=None; Inv=Inv.Inventory ) Inv.Destroy(); Weapon = None; Inventory = None; if ( bIsPlayer && (Level.Game != None) ) Level.Game.logout(self); if ( PlayerReplicationInfo != None ) PlayerReplicationInfo.Destroy(); for ( OtherPawn=Level.PawnList; OtherPawn!=None; OtherPawn=OtherPawn.nextPawn ) OtherPawn.Killed(None, self, ''); Super.Destroyed(); } //============================================================================= // functions. // // native client-side functions. // native simulated event ClientHearSound ( actor Actor, int Id, sound S, vector SoundLocation, vector Parameters ); // // Called immediately before gameplay begins. // event PreBeginPlay() { AddPawn(); Super.PreBeginPlay(); if ( bDeleteMe ) return; // Set instigator to self. Instigator = Self; DesiredRotation = Rotation; SightCounter = 0.2 * FRand(); //offset randomly if ( Level.Game != None ) Skill += Level.Game.Difficulty; Skill = FClamp(Skill, 0, 3); PreSetMovement(); if ( DrawScale != Default.Drawscale ) { SetCollisionSize(CollisionRadius*DrawScale/Default.DrawScale, CollisionHeight*DrawScale/Default.DrawScale); Health = Health * DrawScale/Default.DrawScale; } if (bIsPlayer) { if (PlayerReplicationInfoClass != None) PlayerReplicationInfo = Spawn(PlayerReplicationInfoClass, Self,,vect(0,0,0),rot(0,0,0)); else PlayerReplicationInfo = Spawn(class'PlayerReplicationInfo', Self,,vect(0,0,0),rot(0,0,0)); InitPlayerReplicationInfo(); } if (!bIsPlayer) { if ( BaseEyeHeight == 0 ) BaseEyeHeight = 0.8 * CollisionHeight; EyeHeight = BaseEyeHeight; if (Fatness == 0) //vary monster fatness slightly if at default Fatness = 120 + Rand(8) + Rand(8); } if ( menuname == "" ) menuname = GetItemName(string(class)); if (SelectionMesh == "") SelectionMesh = string(Mesh); } event PostBeginPlay() { Super.PostBeginPlay(); SplashTime = 0; } // called after PostBeginPlay on net client simulated event PostNetBeginPlay() { if ( Role != ROLE_SimulatedProxy ) return; if ( bIsMultiSkinned ) { if ( MultiSkins[1] == None ) { if ( bIsPlayer ) SetMultiSkin(self, "","", PlayerReplicationInfo.team); else SetMultiSkin(self, "","", 0); } } else if ( Skin == None ) Skin = Default.Skin; if ( (PlayerReplicationInfo != None) && (PlayerReplicationInfo.Owner == None) ) PlayerReplicationInfo.SetOwner(self); } /* PreSetMovement() default for walking creature. Re-implement in subclass for swimming/flying capability */ function PreSetMovement() { if (JumpZ > 0) bCanJump = true; bCanWalk = true; bCanSwim = false; bCanFly = false; MinHitWall = -0.6; if (Intelligence > BRAINS_Reptile) bCanOpenDoors = true; if (Intelligence == BRAINS_Human) bCanDoSpecial = true; } simulated function SetMesh() { mesh = default.mesh; } //============================================================================= // Multiskin support static function SetMultiSkin( actor SkinActor, string SkinName, string FaceName, byte TeamNum ) { local Texture NewSkin; if(SkinName != "") { NewSkin = texture(DynamicLoadObject(SkinName, class'Texture')); if ( NewSkin != None ) SkinActor.Skin = NewSkin; } } static function GetMultiSkin( Actor SkinActor, out string SkinName, out string FaceName ) { SkinName = String(SkinActor.Skin); FaceName = ""; } static function bool SetSkinElement(Actor SkinActor, int SkinNo, string SkinName, string DefaultSkinName) { local Texture NewSkin; local bool bProscribed; local string pkg, SkinItem, MeshName; local int i; if ( (SkinActor.Level.NetMode != NM_Standalone) && (SkinActor.Level.NetMode != NM_Client) && (DefaultSkinName != "") ) { // make sure that an illegal skin package is not used // ignore if already have skins set if ( SkinActor.Mesh != None ) MeshName = SkinActor.GetItemName(string(SkinActor.Mesh)); else MeshName = SkinActor.GetItemName(string(SkinActor.Default.Mesh)); SkinItem = SkinActor.GetItemName(SkinName); pkg = Left(SkinName, Len(SkinName) - Len(SkinItem) - 1); bProscribed = !CheckValidSkinPackage(pkg, MeshName); if ( bProscribed ) log("Attempted to use illegal skin from package "$pkg$" for "$Meshname); } NewSkin = Texture(DynamicLoadObject(SkinName, class'Texture')); if ( !bProscribed && (NewSkin != None) ) { SkinActor.Multiskins[SkinNo] = NewSkin; return True; } else { log("Failed to load "$SkinName$" so load "$DefaultSkinName); if(DefaultSkinName != "") { NewSkin = Texture(DynamicLoadObject(DefaultSkinName, class'Texture')); SkinActor.Multiskins[SkinNo] = NewSkin; } return False; } } //============================================================================= // Replication function InitPlayerReplicationInfo() { if (PlayerReplicationInfo.PlayerName == "") PlayerReplicationInfo.PlayerName = class'GameInfo'.Default.DefaultPlayerName; } //============================================================================= // Animation playing - should be implemented in subclass, // // PlayWaiting, PlayRunning, and PlayGutHit, PlayMovingAttack (if used) // and PlayDying are required to be implemented in the subclass function PlayRunning() { ////log("Error - PlayRunning should be implemented in subclass of"@class); } function PlayWalking() { PlayRunning(); } function PlayWaiting() { ////log("Error - PlayWaiting should be implemented in subclass"); } function PlayMovingAttack() { ////log("Error - PlayMovingAttack should be implemented in subclass"); //Note - must restart attack timer when done with moving attack PlayRunning(); } function PlayWaitingAmbush() { PlayWaiting(); } function TweenToFighter(float tweentime) { } function TweenToRunning(float tweentime) { TweenToFighter(0.1); } function TweenToWalking(float tweentime) { TweenToRunning(tweentime); } function TweenToPatrolStop(float tweentime) { TweenToFighter(tweentime); } function TweenToWaiting(float tweentime) { TweenToFighter(tweentime); } function PlayThreatening() { TweenToFighter(0.1); } function PlayPatrolStop() { PlayWaiting(); } function PlayTurning() { TweenToFighter(0.1); } function PlayBigDeath(name DamageType); function PlayHeadDeath(name DamageType); function PlayLeftDeath(name DamageType); function PlayRightDeath(name DamageType); function PlayGutDeath(name DamageType); function PlayDying(name DamageType, vector HitLoc) { local vector X,Y,Z, HitVec, HitVec2D; local float dotp; if ( Velocity.Z > 250 ) { PlayBigDeath(DamageType); return; } if ( DamageType == 'Decapitated' ) { PlayHeadDeath(DamageType); return; } GetAxes(Rotation,X,Y,Z); X.Z = 0; HitVec = Normal(HitLoc - Location); HitVec2D= HitVec; HitVec2D.Z = 0; dotp = HitVec2D dot X; //first check for head hit if ( HitLoc.Z - Location.Z > 0.5 * CollisionHeight ) { if (dotp > 0) PlayHeadDeath(DamageType); else PlayGutDeath(DamageType); return; } if (dotp > 0.71) //then hit in front PlayGutDeath(DamageType); else { dotp = HitVec dot Y; if (dotp > 0.0) PlayLeftDeath(DamageType); else PlayRightDeath(DamageType); } } function PlayGutHit(float tweentime) { log("Error - play gut hit must be implemented in subclass of"@class); } function PlayHeadHit(float tweentime) { PlayGutHit(tweentime); } function PlayLeftHit(float tweentime) { PlayGutHit(tweentime); } function PlayRightHit(float tweentime) { PlayGutHit(tweentime); } function FireWeapon(); /* TraceShot - used by instant hit weapons, and monsters */ function actor TraceShot(out vector HitLocation, out vector HitNormal, vector EndTrace, vector StartTrace) { local vector realHit; local actor Other; Other = Trace(HitLocation,HitNormal,EndTrace,StartTrace,True); if ( Pawn(Other) != None ) { realHit = HitLocation; if ( !Pawn(Other).AdjustHitLocation(HitLocation, EndTrace - StartTrace) ) Other = Pawn(Other).TraceShot(HitLocation,HitNormal,EndTrace,realHit); } return Other; } /* Adjust hit location - adjusts the hit location in for pawns, and returns true if it was really a hit, and false if not (for ducking, etc.) */ simulated function bool AdjustHitLocation(out vector HitLocation, vector TraceDir) { local float adjZ, maxZ; TraceDir = Normal(TraceDir); HitLocation = HitLocation + 0.4 * CollisionRadius * TraceDir; if ( (GetAnimGroup(AnimSequence) == 'Ducking') && (AnimFrame > -0.03) ) { maxZ = Location.Z + 0.25 * CollisionHeight; if ( HitLocation.Z > maxZ ) { if ( TraceDir.Z >= 0 ) return false; adjZ = (maxZ - HitLocation.Z)/TraceDir.Z; HitLocation.Z = maxZ; HitLocation.X = HitLocation.X + TraceDir.X * adjZ; HitLocation.Y = HitLocation.Y + TraceDir.Y * adjZ; if ( VSize(HitLocation - Location) > CollisionRadius ) return false; } } return true; } function PlayTakeHit(float tweentime, vector HitLoc, int damage) { local vector X,Y,Z, HitVec, HitVec2D; local float dotp; GetAxes(Rotation,X,Y,Z); X.Z = 0; HitVec = Normal(HitLoc - Location); HitVec2D= HitVec; HitVec2D.Z = 0; dotp = HitVec2D dot X; //first check for head hit if ( HitLoc.Z - Location.Z > 0.5 * CollisionHeight ) { if (dotp > 0) PlayHeadHit(tweentime); else PlayGutHit(tweentime); return; } if (dotp > 0.71) //then hit in front PlayGutHit( tweentime); else if (dotp < -0.71) // then hit in back PlayHeadHit(tweentime); else { dotp = HitVec dot Y; if (dotp > 0.0) PlayLeftHit(tweentime); else PlayRightHit(tweentime); } } function PlayVictoryDance() { TweenToFighter(0.1); } function PlayOutOfWater() { TweenToFalling(); } function PlayDive(); function TweenToFalling(); function PlayInAir(); function PlayDuck(); function PlayCrawling(); function PlayLanded(float impactVel) { local float landVol; //default - do nothing (keep playing existing animation) landVol = impactVel/JumpZ; landVol = 0.005 * Mass * landVol * landVol; PlaySound(Land, SLOT_Interact, FMin(20, landVol)); } function PlayFiring(); function PlayWeaponSwitch(Weapon NewWeapon); function TweenToSwimming(float tweentime); //----------------------------------------------------------------------------- // Sound functions function PlayTakeHitSound(int Damage, name damageType, int Mult) { if ( Level.TimeSeconds - LastPainSound < 0.25 ) return; if (HitSound1 == None)return; LastPainSound = Level.TimeSeconds; if (FRand() < 0.5) PlaySound(HitSound1, SLOT_Pain, FMax(Mult * TransientSoundVolume, Mult * 2.0)); else PlaySound(HitSound2, SLOT_Pain, FMax(Mult * TransientSoundVolume, Mult * 2.0)); } function Gasp(); function DropDecoration() { if (CarriedDecoration != None) { CarriedDecoration.bWasCarried = true; CarriedDecoration.SetBase(None); CarriedDecoration.SetPhysics(PHYS_Falling); CarriedDecoration.Velocity = Velocity + 10 * VRand(); CarriedDecoration.Instigator = self; CarriedDecoration = None; } } function GrabDecoration() { local vector lookDir, HitLocation, HitNormal, T1, T2, extent; local actor HitActor; if ( carriedDecoration == None ) { //first trace to find it lookDir = vector(Rotation); lookDir.Z = 0; T1 = Location + BaseEyeHeight * vect(0,0,1) + lookDir * 0.8 * CollisionRadius; T2 = T1 + lookDir * 1.2 * CollisionRadius; HitActor = Trace(HitLocation, HitNormal, T2, T1, true); if ( HitActor == None ) { T1 = T2 - (BaseEyeHeight + CollisionHeight - 2) * vect(0,0,1); HitActor = Trace(HitLocation, HitNormal, T1, T2, true); } else if ( HitActor == Level ) { T2 = HitLocation - lookDir; T1 = T2 - (BaseEyeHeight + CollisionHeight - 2) * vect(0,0,1); HitActor = Trace(HitLocation, HitNormal, T1, T2, true); } if ( (HitActor == None) || (HitActor == Level) ) { extent.X = CollisionRadius; extent.Y = CollisionRadius; extent.Z = CollisionHeight; HitActor = Trace(HitLocation, HitNormal, Location + lookDir * 1.2 * CollisionRadius, Location, true, extent); } if ( Mover(HitActor) != None ) { if ( Mover(HitActor).bUseTriggered ) HitActor.Trigger( self, self ); } else if ( (Decoration(HitActor) != None) && ((weapon == None) || (weapon.Mass < 20)) ) { CarriedDecoration = Decoration(HitActor); if ( !CarriedDecoration.bPushable || (CarriedDecoration.Mass > 40) || (CarriedDecoration.StandingCount > 0) ) { CarriedDecoration = None; return; } lookDir.Z = 0; if ( CarriedDecoration.SetLocation(Location + (0.5 * CollisionRadius + CarriedDecoration.CollisionRadius) * lookDir) ) { CarriedDecoration.SetPhysics(PHYS_None); CarriedDecoration.SetBase(self); } else CarriedDecoration = None; } } } function StopFiring(); function ShakeView( float shaketime, float RollMag, float vertmag); function TakeFallingDamage() { if (Velocity.Z < -1.4 * JumpZ) { MakeNoise(-0.5 * Velocity.Z/(FMax(JumpZ, 150.0))); if (Velocity.Z <= -750 - JumpZ) { if ( (Velocity.Z < -1650 - JumpZ) && (ReducedDamageType != 'All') ) TakeDamage(1000, None, Location, vect(0,0,0), 'Fell'); else if ( Role == ROLE_Authority ) TakeDamage(-0.15 * (Velocity.Z + 700 + JumpZ), None, Location, vect(0,0,0), 'Fell'); ShakeView(0.175 - 0.00007 * Velocity.Z, -0.85 * Velocity.Z, -0.002 * Velocity.Z); } } else if ( Velocity.Z > 0.5 * Default.JumpZ ) MakeNoise(0.35); } /* AdjustAim() ScriptedPawn version does adjustment for non-controlled pawns. PlayerPawn 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(float projSpeed, vector projStart, int aimerror, bool bLeadTarget, bool bWarnTarget) { return ViewRotation; } function rotator AdjustToss(float projSpeed, vector projStart, int aimerror, bool bLeadTarget, bool bWarnTarget) { return ViewRotation; } function WarnTarget(Pawn shooter, float projSpeed, vector FireDir) { // AI controlled creatures may duck // if not falling, and projectile time is long enough // often pick opposite to current direction (relative to shooter axis) } function SetMovementPhysics() { //implemented in sub-class } function PlayHit(float Damage, vector HitLocation, name damageType, vector Momentum) { } function PlayDeathHit(float Damage, vector HitLocation, name damageType, vector Momentum) { } function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType) { local int actualDamage; local bool bAlreadyDead; if ( Role < ROLE_Authority ) { log(self$" client damage type "$damageType$" by "$instigatedBy); return; } //log(self@"take damage in state"@GetStateName()); bAlreadyDead = (Health <= 0); if (Physics == PHYS_None) SetMovementPhysics(); if (Physics == PHYS_Walking) momentum.Z = FMax(momentum.Z, 0.4 * VSize(momentum)); if ( instigatedBy == self ) momentum *= 0.6; momentum = momentum/Mass; actualDamage = Level.Game.ReduceDamage(Damage, DamageType, self, instigatedBy); if ( bIsPlayer ) { if (ReducedDamageType == 'All') //God mode actualDamage = 0; else if (Inventory != None) //then check if carrying armor actualDamage = Inventory.ReduceDamage(actualDamage, DamageType, HitLocation); else actualDamage = Damage; } else if ( (InstigatedBy != None) && (InstigatedBy.IsA(Class.Name) || self.IsA(InstigatedBy.Class.Name)) ) ActualDamage = ActualDamage * FMin(1 - ReducedDamagePct, 0.35); else if ( (ReducedDamageType == 'All') || ((ReducedDamageType != '') && (ReducedDamageType == damageType)) ) actualDamage = float(actualDamage) * (1 - ReducedDamagePct); if ( Level.Game.DamageMutator != None ) Level.Game.DamageMutator.MutatorTakeDamage( ActualDamage, Self, InstigatedBy, HitLocation, Momentum, DamageType ); AddVelocity( momentum ); Health -= actualDamage; if (CarriedDecoration != None) DropDecoration(); if ( HitLocation == vect(0,0,0) ) HitLocation = Location; if (Health > 0) { if ( (instigatedBy != None) && (instigatedBy != Self) ) damageAttitudeTo(instigatedBy); PlayHit(actualDamage, hitLocation, damageType, Momentum); } else if ( !bAlreadyDead ) { //log(self$" died"); NextState = ''; PlayDeathHit(actualDamage, hitLocation, damageType, Momentum); if ( actualDamage > mass ) Health = -1 * actualDamage; if ( (instigatedBy != None) && (instigatedBy != Self) ) damageAttitudeTo(instigatedBy); Died(instigatedBy, damageType, HitLocation); } else { //Warn(self$" took regular damage "$damagetype$" from "$instigator$" while already dead"); // SpawnGibbedCarcass(); if ( bIsPlayer ) { HidePlayer(); GotoState('Dying'); } else Destroy(); } MakeNoise(1.0); } function Died(pawn Killer, name damageType, vector HitLocation) { local pawn OtherPawn; local actor A; // mutator hook to prevent deaths // WARNING - don't prevent bot suicides - they suicide when really needed if ( Level.Game.BaseMutator.PreventDeath(self, Killer, damageType, HitLocation) ) { Health = max(Health, 1); //mutator should set this higher return; } if ( bDeleteMe ) return; //already destroyed Health = Min(0, Health); for ( OtherPawn=Level.PawnList; OtherPawn!=None; OtherPawn=OtherPawn.nextPawn ) OtherPawn.Killed(Killer, self, damageType); if ( CarriedDecoration != None ) DropDecoration(); level.game.Killed(Killer, self, damageType); //log(class$" dying"); if( Event != '' ) foreach AllActors( class 'Actor', A, Event ) A.Trigger( Self, Killer ); Level.Game.DiscardInventory(self); Velocity.Z *= 1.3; if ( Gibbed(damageType) ) { SpawnGibbedCarcass(); if ( bIsPlayer ) HidePlayer(); else Destroy(); } PlayDying(DamageType, HitLocation); if ( Level.Game.bGameEnded ) return; if ( RemoteRole == ROLE_AutonomousProxy ) ClientDying(DamageType, HitLocation); GotoState('Dying'); } function bool Gibbed(name damageType) { return false; } function Carcass SpawnCarcass() { log(self$" should never call base spawncarcass"); return None; } function SpawnGibbedCarcass() { } function HidePlayer() { SetCollision(false, false, false); TweenToFighter(0.01); bHidden = true; } event HearNoise( float Loudness, Actor NoiseMaker); event SeePlayer( actor Seen ); event UpdateEyeHeight( float DeltaTime ); event UpdateTactics(float DeltaTime); // for advanced tactics event EnemyNotVisible(); function Killed(pawn Killer, pawn Other, name damageType) { if ( Enemy == Other ) Enemy = None; } //Typically implemented in subclass function string KillMessage( name damageType, pawn Other ) { local string message; message = Level.Game.CreatureKillMessage(damageType, Other); return (Other.PlayerReplicationInfo.PlayerName$message$namearticle$menuname); } function damageAttitudeTo(pawn Other); function Falling() { //SetPhysics(PHYS_Falling); //Note - physics changes type to PHYS_Falling by default //log(class$" Falling"); PlayInAir(); } // Pawn interface called while PHYS_Walking and PHYS_Swimming to update the pawn with // the latest information about the walk surface -- added by Legend on 1/31/1999 event WalkTexture( texture Texture, vector StepLocation, vector StepNormal ); event Landed(vector HitNormal) { SetMovementPhysics(); if ( !IsAnimating() ) PlayLanded(Velocity.Z); if (Velocity.Z < -1.4 * JumpZ) MakeNoise(-0.5 * Velocity.Z/(FMax(JumpZ, 150.0))); bJustLanded = true; } event FootZoneChange(ZoneInfo newFootZone) { local actor HitActor; local vector HitNormal, HitLocation; local float splashSize; local actor splash; if ( Level.NetMode == NM_Client ) return; if ( Level.TimeSeconds - SplashTime > 0.25 ) { SplashTime = Level.TimeSeconds; if (Physics == PHYS_Falling) MakeNoise(1.0); else MakeNoise(0.3); if ( FootRegion.Zone.bWaterZone ) { if ( !newFootZone.bWaterZone && (Role==ROLE_Authority) ) { if ( FootRegion.Zone.ExitSound != None ) PlaySound(FootRegion.Zone.ExitSound, SLOT_Interact, 1); if ( FootRegion.Zone.ExitActor != None ) Spawn(FootRegion.Zone.ExitActor,,,Location - CollisionHeight * vect(0,0,1)); } } else if ( newFootZone.bWaterZone && (Role==ROLE_Authority) ) { splashSize = FClamp(0.000025 * Mass * (300 - 0.5 * FMax(-500, Velocity.Z)), 1.0, 4.0 ); if ( newFootZone.EntrySound != None ) { HitActor = Trace(HitLocation, HitNormal, Location - (CollisionHeight + 40) * vect(0,0,0.8), Location - CollisionHeight * vect(0,0,0.8), false); if ( HitActor == None ) PlaySound(newFootZone.EntrySound, SLOT_Misc, 2 * splashSize); else PlaySound(WaterStep, SLOT_Misc, 1.5 + 0.5 * splashSize); } if( newFootZone.EntryActor != None ) { splash = Spawn(newFootZone.EntryActor,,,Location - CollisionHeight * vect(0,0,1)); if ( splash != None ) splash.DrawScale = splashSize; } //log("Feet entering water"); } } if (FootRegion.Zone.bPainZone) { if ( !newFootZone.bPainZone && !HeadRegion.Zone.bWaterZone ) PainTime = -1.0; } else if (newFootZone.bPainZone) PainTime = 0.01; } event HeadZoneChange(ZoneInfo newHeadZone) { if ( Level.NetMode == NM_Client ) return; if (HeadRegion.Zone.bWaterZone) { if (!newHeadZone.bWaterZone) { if ( bIsPlayer && (PainTime > 0) && (PainTime < 8) ) Gasp(); if ( Inventory != None ) Inventory.ReduceDamage(0, 'Breathe', Location); //inform inventory of zone change bDrowning = false; if ( !FootRegion.Zone.bPainZone ) PainTime = -1.0; } } else { if (newHeadZone.bWaterZone) { if ( !FootRegion.Zone.bPainZone ) PainTime = UnderWaterTime; if ( Inventory != None ) Inventory.ReduceDamage(0, 'Drowned', Location); //inform inventory of zone change //log("Can't breathe"); } } } event SpeechTimer(); //Pain timer just expired. //Check what zone I'm in (and which parts are) //based on that cause damage, and reset PainTime event PainTimer() { local float depth; //log("Pain Timer"); if ( (Health < 0) || (Level.NetMode == NM_Client) ) return; if ( FootRegion.Zone.bPainZone ) { depth = 0.4; if (Region.Zone.bPainZone) depth += 0.4; if (HeadRegion.Zone.bPainZone) depth += 0.2; if (FootRegion.Zone.DamagePerSec > 0) { if ( IsA('PlayerPawn') ) Level.Game.SpecialDamageString = FootRegion.Zone.DamageString; TakeDamage(int(float(FootRegion.Zone.DamagePerSec) * depth), None, Location, vect(0,0,0), FootRegion.Zone.DamageType); } else if ( Health < Default.Health ) Health = Min(Default.Health, Health - depth * FootRegion.Zone.DamagePerSec); if (Health > 0) PainTime = 1.0; } else if ( HeadRegion.Zone.bWaterZone ) { TakeDamage(5, None, Location + CollisionHeight * vect(0,0,0.5), vect(0,0,0), 'Drowned'); if ( Health > 0 ) PainTime = 2.0; } } function bool CheckWaterJump(out vector WallNormal) { local actor HitActor; local vector HitLocation, HitNormal, checkpoint, start, checkNorm, Extent; if (CarriedDecoration != None) return false; checkpoint = vector(Rotation); checkpoint.Z = 0.0; checkNorm = Normal(checkpoint); checkPoint = Location + CollisionRadius * checkNorm; Extent = CollisionRadius * vect(1,1,0); Extent.Z = CollisionHeight; HitActor = Trace(HitLocation, HitNormal, checkpoint, Location, true, Extent); 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) return true; } return false; } exec function bool SwitchToBestWeapon() { local float rating; local int usealt; if ( Inventory == None ) return false; PendingWeapon = Inventory.RecommendWeapon(rating, usealt); if ( PendingWeapon == Weapon ) PendingWeapon = None; if ( PendingWeapon == None ) return false; if ( Weapon == None ) ChangedWeapon(); if ( Weapon != PendingWeapon ) Weapon.PutDown(); return (usealt > 0); } State Dying { ignores SeePlayer, EnemyNotVisible, HearNoise, KilledBy, Trigger, Bump, HitWall, HeadZoneChange, FootZoneChange, ZoneChange, Falling, WarnTarget, Died, LongFall, PainTimer; function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType) { if ( bDeleteMe ) return; Health = Health - Damage; Momentum = Momentum/Mass; AddVelocity( momentum ); if ( !bHidden && Gibbed(damageType) ) { bHidden = true; SpawnGibbedCarcass(); if ( bIsPlayer ) HidePlayer(); else Destroy(); } } function Timer() { if ( !bHidden ) { bHidden = true; SpawnCarcass(); if ( bIsPlayer ) HidePlayer(); else Destroy(); } } event Landed(vector HitNormal) { SetPhysics(PHYS_None); } function BeginState() { SetTimer(0.3, false); } } state GameEnded { ignores SeePlayer, HearNoise, KilledBy, Bump, HitWall, HeadZoneChange, FootZoneChange, ZoneChange, Falling, TakeDamage, WarnTarget, Died; function BeginState() { SetPhysics(PHYS_None); HidePlayer(); } } w4w4w4hMlMJPa( w4w4w4kMnS( w4mMoW(-M'K  w4nMpMm[K) w4qM@w4w4@w4w4oMV| a){46z':46G:$VyVS ^c#JV^ :46G:$46-]^ :46G:$^q%M:46G:$^e#:46G:$^g#:46G:$^b#{^VJ $VyVM%JV^ w4U //============================================================================= // PatrolPoint. //============================================================================= class PatrolPoint extends NavigationPoint; #exec Texture Import File=Textures\Pathnode.pcx Name=S_Patrol Mips=Off Flags=2 var() name Nextpatrol; //next point to go to var() float pausetime; //how long to pause here var vector lookdir; //direction to look while stopped var() name PatrolAnim; var() sound PatrolSound; var() byte numAnims; var int AnimCount; var PatrolPoint NextPatrolPoint; function PreBeginPlay() { if (pausetime > 0.0) lookdir = 200 * vector(Rotation); //find the patrol point with the tag specified by Nextpatrol foreach AllActors(class 'PatrolPoint', NextPatrolPoint, Nextpatrol) break; Super.PreBeginPlay(); } w4e//============================================================================= // PathNode. //============================================================================= class PathNode extends NavigationPoint native; w4rMLJ[-{L-{(LaJAIL2Lo?,A?,n?,I?,L aJ( w4l//============================================================================= // 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; w4V'//============================================================================= // NavigationPoint. //============================================================================= class NavigationPoint extends Actor native; #exec Texture Import File=Textures\S_Pickup.pcx Name=S_Pickup Mips=Off Flags=2 //------------------------------------------------------------------------------ // NavigationPoint variables var() name ownerTeam; //creature clan owning this area (area visible from this point) var bool taken; //set when a creature is occupying this spot var int upstreamPaths[16]; var int Paths[16]; //index of reachspecs (used by C++ Navigation code) var int PrunedPaths[16]; var NavigationPoint VisNoReachPaths[16]; //paths that are visible but not directly reachable var int visitedWeight; var actor routeCache; var const int bestPathWeight; var const NavigationPoint nextNavigationPoint; var const NavigationPoint nextOrdered; var const NavigationPoint prevOrdered; var const NavigationPoint startPath; var const NavigationPoint previousPath; var int cost; //added cost to visit this pathnode var() int ExtraCost; var() bool bPlayerOnly; //only players should use this path var bool bEndPoint; //used by C++ navigation code var bool bEndPointOnly; //only used as an endpoint in routing network var bool bSpecialCost; //if true, navigation code will call SpecialCost function for this navigation point 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 bAutoBuilt; // placed during execution of "PATHS BUILD" var bool bTwoWay; // hacked here to fix CTF problems post release (used by Botpack.AlternatePath) native(519) final function describeSpec(int iSpec, out Actor Start, out Actor End, out int ReachFlags, out int Distance); event int SpecialCost(Pawn Seeker); // Accept an actor that has teleported in. // used for random spawning and initial placement of creatures event bool Accept( actor Incoming, actor Source ) { // Move the actor here. taken = Incoming.SetLocation( Location + vect (0,0,20)); if (taken) { Incoming.Velocity = vect(0,0,0); Incoming.SetRotation(Rotation); } // Play teleport-in effect. PlayTeleportEffect(Incoming, true); return taken; } function PlayTeleportEffect(actor Incoming, bool bOut) { Level.Game.PlayTeleportEffect(Incoming, bOut, false); } w4m`//============================================================================= // Mutator. // called by the IsRelevant() function of DeathMatchPlus // by adding new mutators, you can change actors in the level without requiring // a new game class. Multiple mutators can be linked together. //============================================================================= class Mutator expands Info native; var Mutator NextMutator; var Mutator NextDamageMutator; var Mutator NextMessageMutator; var Mutator NextHUDMutator; var bool bHUDMutator; var class DefaultWeapon; event PreBeginPlay() { //Don't call Actor PreBeginPlay() } simulated event PostRender( canvas Canvas ); function ModifyPlayer(Pawn Other) { // called by GameInfo.RestartPlayer() if ( NextMutator != None ) NextMutator.ModifyPlayer(Other); } function bool HandleRestartGame() { if ( NextMutator != None ) return NextMutator.HandleRestartGame(); return false; } function bool HandleEndGame() { // called by GameInfo.RestartPlayer() if ( NextMutator != None ) return NextMutator.HandleEndGame(); return false; } function bool HandlePickupQuery(Pawn Other, Inventory item, out byte bAllowPickup) { if ( NextMutator != None ) return NextMutator.HandlePickupQuery(Other, item, bAllowPickup); return false; } function bool PreventDeath(Pawn Killed, Pawn Killer, name damageType, vector HitLocation) { if ( NextMutator != None ) return NextMutator.PreventDeath(Killed,Killer, damageType,HitLocation); return false; } function ModifyLogin(out class SpawnClass, out string Portal, out string Options) { if ( NextMutator != None ) NextMutator.ModifyLogin(SpawnClass, Portal, Options); } function ScoreKill(Pawn Killer, Pawn Other) { // called by GameInfo.ScoreKill() if ( NextMutator != None ) NextMutator.ScoreKill(Killer, Other); } // return what should replace the default weapon // mutators further down the list override earlier mutators function Class MutatedDefaultWeapon() { local Class W; if ( NextMutator != None ) { W = NextMutator.MutatedDefaultWeapon(); if ( W == Level.Game.DefaultWeapon ) W = MyDefaultWeapon(); } else W = MyDefaultWeapon(); return W; } function Class MyDefaultWeapon() { if ( DefaultWeapon != None ) return DefaultWeapon; else return Level.Game.DefaultWeapon; } function AddMutator(Mutator M) { if ( NextMutator == None ) NextMutator = M; else NextMutator.AddMutator(M); } /* 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 ( Other.IsA('Inventory') && (Other.Location == vect(0,0,0)) ) return false; aClass = class(DynamicLoadObject(aClassName, class'Class')); if ( aClass != None ) A = Spawn(aClass,Other.Owner,Other.tag,Other.Location, Other.Rotation); if ( Other.IsA('Inventory') ) { if ( Inventory(Other).MyMarker != None ) { Inventory(Other).MyMarker.markedItem = Inventory(A); if ( Inventory(A) != None ) { Inventory(A).MyMarker = Inventory(Other).MyMarker; A.SetLocation(A.Location + (A.CollisionHeight - Other.CollisionHeight) * vect(0,0,1)); } Inventory(Other).MyMarker = None; } else if ( A.IsA('Inventory') ) { Inventory(A).bHeldItem = true; Inventory(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; // allow mutators to remove actors bResult = CheckReplacement(Other, bSuperRelevant); if ( bResult && (NextMutator != None) ) bResult = NextMutator.IsRelevant(Other, bSuperRelevant); return bResult; } function bool CheckReplacement(Actor Other, out byte bSuperRelevant) { return true; } function Mutate(string MutateString, PlayerPawn Sender) { if ( NextMutator != None ) NextMutator.Mutate(MutateString, Sender); } function MutatorTakeDamage( out int ActualDamage, Pawn Victim, Pawn InstigatedBy, out Vector HitLocation, out Vector Momentum, name DamageType) { if ( NextDamageMutator != None ) NextDamageMutator.MutatorTakeDamage( ActualDamage, Victim, InstigatedBy, HitLocation, Momentum, DamageType ); } function bool MutatorTeamMessage( Actor Sender, Pawn Receiver, PlayerReplicationInfo PRI, coerce string S, name Type, optional bool bBeep ) { if ( NextMessageMutator != None ) return NextMessageMutator.MutatorTeamMessage( Sender, Receiver, PRI, S, Type, bBeep ); else return true; } function bool MutatorBroadcastMessage( Actor Sender, Pawn Receiver, out coerce string Msg, optional bool bBeep, out optional name Type ) { if ( NextMessageMutator != None ) return NextMessageMutator.MutatorBroadcastMessage( Sender, Receiver, Msg, bBeep, Type ); else return true; } function bool MutatorBroadcastLocalizedMessage( Actor Sender, Pawn Receiver, out class Message, out optional int Switch, out optional PlayerReplicationInfo RelatedPRI_1, out optional PlayerReplicationInfo RelatedPRI_2, out optional Object OptionalObject ) { if ( NextMessageMutator != None ) return NextMessageMutator.MutatorBroadcastLocalizedMessage( Sender, Receiver, Message, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject ); else return true; } // Registers the current mutator on the client to receive PostRender calls. simulated function RegisterHUDMutator() { local Pawn P; ForEach AllActors(class'Pawn', P) if ( P.IsA('PlayerPawn') && (PlayerPawn(P).myHUD != None) ) { NextHUDMutator = PlayerPawn(P).myHud.HUDMutator; PlayerPawn(P).myHUD.HUDMutator = Self; bHUDMutator = True; } } w4d//============================================================================= // MusicEvent. //============================================================================= class MusicEvent extends Triggers; // Variables. var() music Song; var() byte SongSection; var() byte CdTrack; var() EMusicTransition Transition; var() bool bSilence; var() bool bOnceOnly; var() bool bAffectAllPlayers; // When gameplay starts. function BeginPlay() { if( Song==None ) { Song = Level.Song; } if( bSilence ) { SongSection = 255; CdTrack = 255; } } // When triggered. function Trigger( actor Other, pawn EventInstigator ) { local PlayerPawn P; local Pawn A; if( bAffectAllPlayers ) { A = Level.PawnList; While ( A != None ) { if ( A.IsA('PlayerPawn') ) PlayerPawn(A).ClientSetMusic( Song, SongSection, CdTrack, Transition ); A = A.nextPawn; } } else { // Only affect the one player. P = PlayerPawn(EventInstigator); if( P==None ) return; // Go to music. P.ClientSetMusic( Song, SongSection, CdTrack, Transition ); } // Turn off if once-only. if( bOnceOnly ) { SetCollision(false,false,false); disable( 'Trigger' ); } } w4uMWb.W-i#WLW,i ^*WwWf?q-x YUW| WA%Wh ?An?WLW?aP)on?Wl WD on|% H %u |A\ Dn?||%Wh WLWi y o?|?WL?\ Wi y o?|?H %Wh WL?u W#i y ?H ?\ u ?WLo?H ?u W#i y ?H ?\ u ?Wh A%xWwW LyMLBx@{M#LPPT+T+PbUZw4w4]//============================================================================= // The moving brush class. // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class Mover extends Brush 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, // Cany 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. //----------------------------------------------------------------------------- // 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 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() 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() 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. //----------------------------------------------------------------------------- // Internal. var vector KeyPos[8]; var rotator KeyRot[8]; var vector BasePos, OldPos, OldPrePivot, SavedPos; var rotator BaseRot, OldRot, SavedRot; // AI related var NavigationPoint myMarker; var Actor TriggerActor; var Actor TriggerActor2; var Pawn WaitingPawn; var bool bOpening, bDelaying, bClientPause; var bool bPlayerOnly; var Trigger RecommendedTrigger; // for client side replication var vector SimOldPos; var int SimOldRotPitch, SimOldRotYaw, SimOldRotRoll; var vector SimInterpolate; var vector RealPosition; var rotator RealRotation; var int ClientUpdate; replication { // Things the server should send to the client. reliable if( Role==ROLE_Authority ) SimOldPos, SimOldRotPitch, SimOldRotYaw, SimOldRotRoll, SimInterpolate, RealPosition, RealRotation; } simulated function Timer() { if ( Velocity != vect(0,0,0) ) { bClientPause = false; return; } if ( Level.NetMode == NM_Client ) { 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 { RealPosition = Location; RealRotation = Rotation; } } function FindTriggerActor() { local Actor A; TriggerActor = None; TriggerActor2 = None; ForEach AllActors(class 'Actor', A) if ( (A.Event == Tag) && (A.IsA('Trigger') || A.IsA('Mover')) ) { if ( A.IsA('Counter') || A.IsA('Pawn') ) { bPlayerOnly = true; return; //FIXME - handle counters } if (TriggerActor == None) TriggerActor = A; else if ( TriggerActor2 == None ) TriggerActor2 = A; } if ( TriggerActor == None ) { bPlayerOnly = (BumpType == BT_PlayerBump); return; } bPlayerOnly = ( TriggerActor.IsA('Trigger') && (Trigger(TriggerActor).TriggerType == TT_PlayerProximity) ); if ( bPlayerOnly && ( TriggerActor2 != None) ) { bPlayerOnly = ( TriggerActor2.IsA('Trigger') && (Trigger(TriggerActor).TriggerType == TT_PlayerProximity) ); if ( !bPlayerOnly ) { A = TriggerActor; TriggerActor = TriggerActor2; TriggerActor2 = A; } } } /* set specialgoal/movetarget or special pause if necessary if mover can't be affected by this pawn, return false Each mover state should implement the appropriate version */ function bool HandleDoor(pawn Other) { return false; } function bool HandleTriggerDoor(pawn Other) { local bool bOne, bTwo; local float DP1, DP2, Dist1, Dist2; if ( bOpening || bDelaying ) { WaitingPawn = Other; Other.SpecialPause = 2.5; return true; } if ( bPlayerOnly && !Other.bIsPlayer ) return false; if ( bUseTriggered ) { WaitingPawn = Other; Other.SpecialPause = 2.5; Trigger(Other, Other); return true; } if ( (BumpEvent == tag) || (Other.bIsPlayer && (PlayerBumpEvent == tag)) ) { WaitingPawn = Other; Other.SpecialPause = 2.5; if ( Other.Base == Self ) Trigger(Other, Other); return true; } if ( bDamageTriggered ) { WaitingPawn = Other; Other.SpecialGoal = self; if ( !Other.bCanDoSpecial || (Other.Weapon == None) ) return false; Other.Target = self; Other.bShootSpecial = true; Other.FireWeapon(); Trigger(Self, Other); Other.bFire = 0; Other.bAltFire = 0; return true; } if ( RecommendedTrigger != None ) { Other.SpecialGoal = RecommendedTrigger; Other.MoveTarget = RecommendedTrigger; return True; } bOne = ( (TriggerActor != None) && (!TriggerActor.IsA('Trigger') || Trigger(TriggerActor).IsRelevant(Other)) ); bTwo = ( (TriggerActor2 != None) && (!TriggerActor2.IsA('Trigger') || Trigger(TriggerActor2).IsRelevant(Other)) ); if ( bOne && bTwo ) { // Dotp, dist Dist1 = VSize(TriggerActor.Location - Other.Location); Dist2 = VSize(TriggerActor2.Location - Other.Location); if ( Dist1 < Dist2 ) { if ( (Dist1 < 500) && Other.ActorReachable(TriggerActor) ) bTwo = false; } else if ( (Dist2 < 500) && Other.ActorReachable(TriggerActor2) ) bOne = false; if ( bOne && bTwo ) { DP1 = Normal(Location - Other.Location) Dot (TriggerActor.Location - Other.Location)/Dist1; DP2 = Normal(Location - Other.Location) Dot (TriggerActor2.Location - Other.Location)/Dist2; if ( (DP1 > 0) && (DP2 < 0) ) bOne = false; else if ( (DP1 < 0) && (DP2 > 0) ) bTwo = false; else if ( Dist1 < Dist2 ) bTwo = false; else bOne = false; } } if ( bOne ) { Other.SpecialGoal = TriggerActor; Other.MoveTarget = TriggerActor; return True; } else if ( bTwo ) { Other.SpecialGoal = TriggerActor2; Other.MoveTarget = TriggerActor2; return True; } return false; } function Actor SpecialHandling(Pawn Other) { if ( bDamageTriggered ) { if ( !Other.bCanDoSpecial || (Other.Weapon == None) ) return None; Other.Target = self; Other.bShootSpecial = true; Other.FireWeapon(); Other.bFire = 0; Other.bAltFire = 0; return self; } if ( BumpType == BT_PlayerBump && !Other.bIsPlayer ) return None; return self; } //----------------------------------------------------------------------------- // Movement functions. // Interpolate to keyframe KeyNum in Seconds time. final function InterpolateTo( byte NewKeyNum, float Seconds ) { 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; } // 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; } // 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. function InterpolateEnd( actor Other ) { local byte OldKeyNum; 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; if ( (ClientUpdate == 0) && (Level.NetMode != NM_Client) ) { RealPosition = Location; RealRotation = Rotation; } } } //----------------------------------------------------------------------------- // Mover functions. // Notify AI that mover finished movement function FinishNotify() { local Pawn P; if ( StandingCount > 0 ) for ( P=Level.PawnList; P!=None; P=P.nextPawn ) if ( P.Base == self ) { P.StopWaiting(); if ( (P.SpecialGoal == self) || (P.SpecialGoal == myMarker) ) P.SpecialGoal = None; if ( P == WaitingPawn ) WaitingPawn = None; } if ( WaitingPawn != None ) { WaitingPawn.StopWaiting(); if ( (WaitingPawn.SpecialGoal == self) || (WaitingPawn.SpecialGoal == myMarker) ) WaitingPawn.SpecialGoal = None; WaitingPawn = None; } } // Handle when the mover finishes closing. function FinishedClosing() { // Update sound effects. PlaySound( ClosedSound, SLOT_None ); // Notify our triggering actor that we have completed. if( SavedTrigger != None ) SavedTrigger.EndEvent(); SavedTrigger = None; Instigator = None; FinishNotify(); } // Handle when the mover finishes opening. function FinishedOpening() { local actor A; // Update sound effects. PlaySound( OpenedSound, SLOT_None ); // Trigger any chained movers. if( Event != '' ) foreach AllActors( class 'Actor', A, Event ) A.Trigger( Self, Instigator ); FinishNotify(); } // Open the mover. function DoOpen() { bOpening = true; bDelaying = false; InterpolateTo( 1, MoveTime ); PlaySound( OpeningSound, SLOT_None ); AmbientSound = MoveAmbientSound; } // Close the mover. function DoClose() { local actor A; bOpening = false; bDelaying = false; InterpolateTo( Max(0,KeyNum-1), MoveTime ); PlaySound( ClosingSound, SLOT_None ); if( Event != '' ) foreach AllActors( class 'Actor', A, Event ) A.UnTrigger( Self, Instigator ); AmbientSound = MoveAmbientSound; } //----------------------------------------------------------------------------- // Engine notifications. // When mover enters gameplay. simulated function BeginPlay() { local rotator R; // timer updates real position every second in network play if ( Level.NetMode != NM_Standalone ) { if ( Level.NetMode == NM_Client ) settimer(4.0, true); else settimer(1.0, true); if ( Role < ROLE_Authority ) return; } if ( Level.NetMode != NM_Client ) { RealPosition = Location; RealRotation = Rotation; } // Init key info. Super.BeginPlay(); KeyNum = Clamp( KeyNum, 0, ArrayCount(KeyPos)-1 ); PhysAlpha = 0.0; // Set initial location. Move( BasePos + KeyPos[KeyNum] - Location ); // Initial rotation. SetRotation( BaseRot + KeyRot[KeyNum] ); // find movers in same group if ( ReturnGroup == '' ) ReturnGroup = tag; } // Immediately after mover enters gameplay. function PostBeginPlay() { local mover M; //brushes can't be deleted, so if not relevant, make it invisible and non-colliding if ( !Level.Game.IsRelevant(self) ) { SetCollision(false, false, false); SetLocation(Location + vect(0,0,20000)); // temp since still in bsp bHidden = true; } else { FindTriggerActor(); // Initialize all slaves. if( !bSlave ) { foreach AllActors( class 'Mover', M, Tag ) { if( M.bSlave ) { M.GotoState(''); M.SetBase( Self ); } } } if ( Leader == None ) { Leader = self; ForEach AllActors( class'Mover', M ) if ( (M != self) && (M.ReturnGroup == ReturnGroup) ) { M.Leader = self; M.Follower = Follower; Follower = M; } } } } function MakeGroupStop() { // Stop moving immediately. bInterpolating = false; AmbientSound = None; GotoState( , '' ); if ( Follower != None ) Follower.MakeGroupStop(); } function MakeGroupReturn() { // Abort move and reverse course. bInterpolating = false; AmbientSound = None; if( KeyNum= DamageThreshold) ) self.Trigger(self, instigatedBy); } //----------------------------------------------------------------------------- // Trigger states. // When triggered, open, wait, then close. state() TriggerOpenTimed { function bool HandleDoor(pawn Other) { return HandleTriggerDoor(Other); } function Trigger( actor Other, pawn EventInstigator ) { SavedTrigger = Other; Instigator = EventInstigator; if ( SavedTrigger != None ) SavedTrigger.BeginEvent(); GotoState( 'TriggerOpenTimed', 'Open' ); } function BeginState() { bOpening = false; } Open: Disable( 'Trigger' ); if ( DelayTime > 0 ) { bDelaying = true; Sleep(DelayTime); } DoOpen(); FinishInterpolation(); FinishedOpening(); Sleep( StayOpenTime ); if( bTriggerOnceOnly ) GotoState(''); Close: DoClose(); FinishInterpolation(); FinishedClosing(); Enable( 'Trigger' ); } // Toggle when triggered. state() TriggerToggle { function bool HandleDoor(pawn Other) { return HandleTriggerDoor(Other); } 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(); } // Open when triggered, close when get untriggered. state() TriggerControl { function bool HandleDoor(pawn Other) { return HandleTriggerDoor(Other); } function Trigger( actor Other, pawn EventInstigator ) { numTriggerEvents++; SavedTrigger = Other; Instigator = EventInstigator; if ( SavedTrigger != None ) SavedTrigger.BeginEvent(); GotoState( 'TriggerControl', 'Open' ); } function UnTrigger( actor Other, pawn EventInstigator ) { numTriggerEvents--; if ( numTriggerEvents <=0 ) { numTriggerEvents = 0; SavedTrigger = Other; Instigator = EventInstigator; SavedTrigger.BeginEvent(); GotoState( 'TriggerControl', 'Close' ); } } function BeginState() { numTriggerEvents = 0; } Open: if ( DelayTime > 0 ) { bDelaying = true; Sleep(DelayTime); } DoOpen(); FinishInterpolation(); FinishedOpening(); SavedTrigger.EndEvent(); if( bTriggerOnceOnly ) GotoState(''); Stop; Close: DoClose(); FinishInterpolation(); FinishedClosing(); } // Start pounding when triggered. state() TriggerPound { function bool HandleDoor(pawn Other) { return HandleTriggerDoor(Other); } 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 ( DelayTime > 0 ) { bDelaying = true; Sleep(DelayTime); } DoOpen(); FinishInterpolation(); Sleep(OtherTime); Close: DoClose(); FinishInterpolation(); Sleep(StayOpenTime); if( bTriggerOnceOnly ) GotoState(''); if( SavedTrigger != None ) goto 'Open'; } //----------------------------------------------------------------------------- // Bump states. // Open when bumped, wait, then close. state() BumpOpenTimed { function bool HandleDoor(pawn Other) { if ( (BumpType == BT_PlayerBump) && !Other.bIsPlayer ) return false; Bump(Other); WaitingPawn = Other; Other.SpecialPause = 2.5; return true; } function Bump( actor Other ) { if ( (BumpType != BT_AnyBump) && (Pawn(Other) == None) ) return; if ( (BumpType == BT_PlayerBump) && !Pawn(Other).bIsPlayer ) return; if ( (BumpType == BT_PawnBump) && (Other.Mass < 10) ) return; Global.Bump( Other ); SavedTrigger = None; Instigator = Pawn(Other); GotoState( 'BumpOpenTimed', 'Open' ); } Open: Disable( 'Bump' ); if ( DelayTime > 0 ) { bDelaying = true; Sleep(DelayTime); } DoOpen(); FinishInterpolation(); FinishedOpening(); Sleep( StayOpenTime ); if( bTriggerOnceOnly ) GotoState(''); Close: DoClose(); FinishInterpolation(); FinishedClosing(); Enable( 'Bump' ); } // Open when bumped, close when reset. state() BumpButton { function bool HandleDoor(pawn Other) { if ( (BumpType == BT_PlayerBump) && !Other.bIsPlayer ) return false; Bump(Other); return false; //let pawn try to move around this button } function Bump( actor Other ) { if ( (BumpType != BT_AnyBump) && (Pawn(Other) == None) ) return; if ( (BumpType == BT_PlayerBump) && !Pawn(Other).bIsPlayer ) return; if ( (BumpType == BT_PawnBump) && (Other.Mass < 10) ) return; Global.Bump( Other ); SavedTrigger = Other; Instigator = Pawn( Other ); GotoState( 'BumpButton', 'Open' ); } function BeginEvent() { bSlave=true; } function EndEvent() { bSlave = false; Instigator = None; GotoState( 'BumpButton', 'Close' ); } Open: Disable( 'Bump' ); if ( DelayTime > 0 ) { bDelaying = true; Sleep(DelayTime); } DoOpen(); FinishInterpolation(); FinishedOpening(); if( bTriggerOnceOnly ) GotoState(''); if( bSlave ) Stop; Close: DoClose(); FinishInterpolation(); FinishedClosing(); Enable( 'Bump' ); } //----------------------------------------------------------------------------- // Stand states. // Open when stood on, wait, then close. state() StandOpenTimed { function bool HandleDoor(pawn Other) { if ( bPlayerOnly && !Other.bIsPlayer ) return false; Other.SpecialPause = 2.5; WaitingPawn = Other; if ( Other.Base == self ) Attach(Other); return true; } function Attach( actor Other ) { local pawn P; P = Pawn(Other); if ( (BumpType != BT_AnyBump) && (P == None) ) return; if ( (BumpType == BT_PlayerBump) && !P.bIsPlayer ) return; if ( (BumpType == BT_PawnBump) && (Other.Mass < 10) ) return; SavedTrigger = None; GotoState( 'StandOpenTimed', 'Open' ); } Open: Disable( 'Attach' ); if ( DelayTime > 0 ) { bDelaying = true; Sleep(DelayTime); } DoOpen(); FinishInterpolation(); FinishedOpening(); Sleep( StayOpenTime ); if( bTriggerOnceOnly ) GotoState(''); Close: DoClose(); FinishInterpolation(); FinishedClosing(); Enable( 'Attach' ); } w4M//============================================================================= // MessagingSpectator - spectator base class for game helper spectators which receive messages //============================================================================= class MessagingSpectator expands Spectator abstract; function PostBeginPlay() { Super.PostBeginPlay(); bIsPlayer = False; } w4Mw4w4@Nw4w4ANw4w4BNw4w4w4w4zMVxA4s A&D?T&,@?,@y(>9_ H_ a &cD?T,@,_ &?,@VyVS ci!oci!pV3aШpcd/:cydeVacyde4e?%e@s DeX?s e?%VL@?s VyVS ci!oci!pV*aѨpcd/:cy( Vacy(_ > w4H4//============================================================================= // Menu: An in-game menu. // This is a built-in Unreal class and it shouldn't be modified. // // Serves as a generic menu master class. Can be used with any style // of menu implementation. Offers menu services such as reading input. // Not dependent on any visual style. //============================================================================= class Menu extends Actor native; var Menu ParentMenu; var int Selection; var() int MenuLength; var bool bConfigChanged; var bool bExitAllMenus; var PlayerPawn PlayerOwner; var() localized string HelpMessage[24]; var() localized string MenuList[24]; var() localized string LeftString; var() localized string RightString; var() localized string CenterString; var() localized string EnabledString; var() localized string DisabledString; var() localized string MenuTitle; var() localized string YesString; var() localized string NoString; function bool ProcessSelection(); function bool ProcessLeft(); function bool ProcessRight(); function bool ProcessYes(); function bool ProcessNo(); function SaveConfigs(); function PlaySelectSound(); function PlayModifySound(); function PlayEnterSound(); function ProcessMenuInput( coerce string InputString ); function ProcessMenuUpdate( coerce string InputString ); function ProcessMenuEscape(); function ProcessMenuKey( int KeyNo, string KeyName ); function MenuTick( float DeltaTime ); function MenuInit(); function DrawMenu(canvas Canvas); function ExitAllMenus() { while ( Hud(Owner).MainMenu != None ) Hud(Owner).MainMenu.ExitMenu(); } function Menu ExitMenu() { Hud(Owner).MainMenu = ParentMenu; if ( bConfigChanged ) SaveConfigs(); if ( ParentMenu == None ) { PlayerOwner.bShowMenu = false; PlayerOwner.Player.Console.GotoState(''); if( Level.Netmode == NM_Standalone ) PlayerOwner.SetPause(False); } Destroy(); } function SetFontBrightness(canvas Canvas, bool bBright) { if ( bBright ) { Canvas.DrawColor.R = 255; Canvas.DrawColor.G = 255; Canvas.DrawColor.B = 255; } else Canvas.DrawColor = Canvas.Default.DrawColor; } function MenuProcessInput( byte KeyNum, byte ActionNum ) { if ( KeyNum == EInputKey.IK_Escape ) { PlayEnterSound(); ExitMenu(); return; } else if ( KeyNum == EInputKey.IK_Up ) { PlaySelectSound(); Selection--; if ( Selection < 1 ) Selection = MenuLength; } else if ( KeyNum == EInputKey.IK_Down ) { PlaySelectSound(); Selection++; if ( Selection > MenuLength ) Selection = 1; } else if ( KeyNum == EInputKey.IK_Enter ) { bConfigChanged=true; if ( ProcessSelection() ) PlayEnterSound(); } else if ( KeyNum == EInputKey.IK_Left ) { bConfigChanged=true; if ( ProcessLeft() ) PlayModifySound(); } else if ( KeyNum == EInputKey.IK_Right ) { bConfigChanged=true; if ( ProcessRight() ) PlayModifySound(); } else if ( Chr(KeyNum) ~= left(YesString, 1) ) { bConfigChanged=true; if ( ProcessYes() ) PlayModifySound(); } else if ( Chr(KeyNum) ~= left(NoString, 1) ) { bConfigChanged=true; if ( ProcessNo() ) PlayModifySound(); } if ( bExitAllMenus ) ExitAllMenus(); } w4C//============================================================================= // MapList. // // contains a list of maps to cycle through // //============================================================================= class MapList extends Info; var(Maps) config string Maps[32]; var config int MapNum; function string GetNextMap() { local string CurrentMap; local int i; CurrentMap = GetURLMap(); if ( CurrentMap != "" ) { if ( Right(CurrentMap,4) ~= ".unr" ) CurrentMap = CurrentMap; else CurrentMap = CurrentMap$".unr"; for ( i=0; i ArrayCount(Maps) - 1 ) MapNum = 0; if ( Maps[MapNum] == "" ) MapNum = 0; SaveConfig(); return Maps[MapNum]; } w4 //============================================================================= // LocationID - marks and names an area in a zone //============================================================================= class LocationID extends KeyPoint native; var() localized string LocationName; var() float Radius; var LocationID NextLocation; function PostBeginPlay() { local LocationID L; Super.PostBeginPlay(); // add self to zone list if ( Region.Zone.LocationID == None ) { Region.Zone.LocationID = self; return; } for ( L=Region.Zone.LocationID; L!=None; L=L.NextLocation ) if ( L.NextLocation == None ) { L.NextLocation = self; return; } } w4[*// // Represents a schematic for a client localized message. // class LocalMessage expands Info; var bool bComplexString; // Indicates a multicolor string message class. var bool bIsSpecial; // If true, don't add to normal queue. var bool bIsUnique; // If true and special, only one can be in the HUD queue at a time. var bool bIsConsoleMessage; // If true, put a GetString on the console. var bool bFadeMessage; // If true, use fade out effect on message. var bool bBeep; // If true, beep! var bool bOffsetYPos; // If the YPos indicated isn't where the message appears. var int Lifetime; // # of seconds to stay in HUD message queue. var class ChildMessage; // In some cases, we need to refer to a child message. // Canvas Variables var bool bFromBottom; // Subtract YPos. var color DrawColor; // Color to display message with. var float XPos, YPos; // Coordinates to print message at. var bool bCenter; // Whether or not to center the message. 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 GetString( optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ) { return ""; } static function string AssembleString( HUD myHUD, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional String MessageString ) { return ""; } static function ClientReceive( PlayerPawn 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 ( Default.bBeep && P.bMessageBeep ) P.PlayBeepSound(); if ( Default.bIsConsoleMessage ) { if ((P.Player != None) && (P.Player.Console != None)) P.Player.Console.AddString(Static.GetString( Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject )); } } static function color GetColor( optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2 ) { return Default.DrawColor; } static function float GetOffset(int Switch, float YL, float ClipY ) { return Default.YPos; } static function int GetFontSize( int Switch ); w4p//============================================================================= // The light class. //============================================================================= class Light extends Actor native; #exec Texture Import File=Textures\S_Light.pcx Name=S_Light Mips=Off Flags=2 w4I//============================================================================= // LiftExit. //============================================================================= class LiftExit extends NavigationPoint native; var() name LiftTag; var Mover MyLift; var() name LiftTrigger; var trigger RecommendedTrigger; var float LastTriggerTime; function PostBeginPlay() { if ( LiftTag != '' ) ForEach AllActors(class'Mover', MyLift, LiftTag ) break; //log(self$" attached to "$MyLift); if ( LiftTrigger != '' ) ForEach AllActors(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 */ function Actor SpecialHandling(Pawn Other) { if ( (Other.Base == MyLift) && (MyLift != None) ) { if ( (self.Location.Z < Other.Location.Z + Other.CollisionHeight) && Other.LineOfSightTo(self) ) return self; Other.SpecialGoal = None; Other.DesiredRotation = rotator(Location - Other.Location); MyLift.HandleDoor(Other); if ( (Other.SpecialGoal == MyLift) || (Other.SpecialGoal == None) ) Other.SpecialGoal = MyLift.myMarker; return Other.SpecialGoal; } return self; } w4CNJwD8*Jh cw46"*'46" QJ 46-]-X hp(>9_JyJS Jahr~ J#L@n?A~ ?&J ah((u %846-]46-LqT_%B_, q%*{qyqKqKI  qi!o_G pVqd:qy _G qy_8_G qnq%JyJS _%(_,{,_G J(L@@?, q?, GJa,_G r~ Ja,_G (~ AGq_m w4_://============================================================================= // LiftCenter. //============================================================================= class LiftCenter extends NavigationPoint native; var() name LiftTag; var mover MyLift; var() name LiftTrigger; var trigger RecommendedTrigger; var float LastTriggerTime; var() float MaxZDiffAdd; //added threshold for Z difference between pawn and lift (for lifts which are at the end of a ramp or stairs) var() float MaxDist2D; var vector LiftOffset; function PostBeginPlay() { if ( LiftTag != '' ) ForEach AllActors(class'Mover', MyLift, LiftTag ) { MyLift.myMarker = self; SetBase(MyLift); LiftOffset = Location - MyLift.Location; if ( MyLift.InitialState == 'BumpOpenTimed' ) log("Warning: "$MyLift$" is BumpOpenTimed. Bots don't understand this well - use StandOpenTimed instead!"); break; } // log(self$" attached to "$MyLift); if ( LiftTrigger != '' ) ForEach AllActors(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 */ function Actor SpecialHandling(Pawn Other) { local float dist2d; local NavigationPoint N, Exit; if ( MyLift == None ) return self; if ( Other.base == MyLift ) { if ( (RecommendedTrigger != None) && (myLift.SavedTrigger == None) && (Level.TimeSeconds - LastTriggerTime > 5) ) { Other.SpecialGoal = RecommendedTrigger; LastTriggerTime = Level.TimeSeconds; return RecommendedTrigger; } return self; } if ( (LiftExit(Other.MoveTarget) != None) && (LiftExit(Other.MoveTarget).RecommendedTrigger != None) && (LiftExit(Other.MoveTarget).LiftTag == LiftTag) && (Level.TimeSeconds - LiftExit(Other.MoveTarget).LastTriggerTime > 5) && (MyLift.SavedTrigger == None) && (Abs(Other.Location.X - Other.MoveTarget.Location.X) < Other.CollisionRadius) && (Abs(Other.Location.Y - Other.MoveTarget.Location.Y) < Other.CollisionRadius) && (Abs(Other.Location.Z - Other.MoveTarget.Location.Z) < Other.CollisionHeight) ) { LiftExit(Other.MoveTarget).LastTriggerTime = Level.TimeSeconds; Other.SpecialGoal = LiftExit(Other.MoveTarget).RecommendedTrigger; return LiftExit(Other.MoveTarget).RecommendedTrigger; } SetLocation(MyLift.Location + LiftOffset); SetBase(MyLift); dist2d = square(Location.X - Other.Location.X) + square(Location.Y - Other.Location.Y); if ( (Location.Z - CollisionHeight - MaxZDiffAdd < Other.Location.Z - Other.CollisionHeight + Other.MaxStepHeight) && (Location.Z - CollisionHeight > Other.Location.Z - Other.CollisionHeight - 1200) && ( dist2D < MaxDist2D * MaxDist2D) ) { return self; } if ( MyLift.BumpType == BT_PlayerBump && !Other.bIsPlayer ) return None; Other.SpecialGoal = None; // make sure Other is at valid lift exit if ( LiftExit(Other.MoveTarget) == None ) { for ( N=Level.NavigationPointList; N!=None; N=N.NextNavigationPoint ) if ( N.IsA('LiftExit') && (LiftExit(N).LiftTag == LiftTag) && (Abs(Other.Location.X - N.Location.X) < Other.CollisionRadius) && (Abs(Other.Location.Y - N.Location.Y) < Other.CollisionRadius) && (Abs(Other.Location.Z - N.Location.Z) < Other.CollisionHeight) ) { Exit = N; break; } if ( Exit == None ) return self; } MyLift.HandleDoor(Other); MyLift.RecommendedTrigger = None; if ( (Other.SpecialGoal == MyLift) || (Other.SpecialGoal == None) ) Other.SpecialGoal = self; return Other.SpecialGoal; } w4F //============================================================================= // LevelSummary contains the summary properties from the LevelInfo actor. // Designed for fast loading. //============================================================================= class LevelSummary extends Object native; //----------------------------------------------------------------------------- // Properties. // From LevelInfo. var() localized string Title; var() string Author; var() localized string IdealPlayerCount; var() int RecommendedEnemies; var() int RecommendedTeammates; var() localized string LevelEnterText; w4_i//============================================================================= // 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; // Textures. #exec Texture Import File=Textures\DefaultTexture.pcx //----------------------------------------------------------------------------- // 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. //----------------------------------------------------------------------------- // Text info about level. var() localized string Title; var() string Author; // Who built it. var() localized string IdealPlayerCount;// Ideal number of players for this level. I.E.: 6-8 var() int RecommendedEnemies; // number of enemy bots recommended (used by rated games) var() int RecommendedTeammates; // number of friendly bots recommended (used by rated games) var() localized string LevelEnterText; // Message to tell players when they enter. var() string LocalizedPkg; // Package to look in for localizations. var string 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() bool bLonePlayer; // No multiplayer coordination, i.e. for entranceways. var bool bBegunPlay; // Whether gameplay has begun. var bool bPlayersOnly; // Only update players. var bool bHighDetailMode; // Client high-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() bool bHumansOnly; // Only allow "human" player pawns in this level var bool bNoCheating; var bool bAllowFOV; var config bool bLowRes; // optimize for low resolution (e.g. TV) //----------------------------------------------------------------------------- // Audio properties. var(Audio) const music Song; // Default song for level. var(Audio) const byte SongSection; // Default song order for level. var(Audio) const byte CdTrack; // Default CD track for level. var(Audio) float PlayerDoppler; // Player doppler shift, 0=none, 1=full. //----------------------------------------------------------------------------- // Miscellaneous information. var() float Brightness; var() texture Screenshot; var texture DefaultTexture; var int HubStackLevel; var transient enum ELevelAction { LEVACT_None, LEVACT_Loading, LEVACT_Saving, LEVACT_Connecting, LEVACT_Precaching } LevelAction; //----------------------------------------------------------------------------- // Renderer Management. var() bool bNeverPrecache; //----------------------------------------------------------------------------- // 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() class DefaultGameType; var GameInfo Game; //----------------------------------------------------------------------------- // Navigation point and Pawn lists (chained using nextNavigationPoint and nextPawn). var const NavigationPoint NavigationPointList; var const Pawn PawnList; //----------------------------------------------------------------------------- // Server related. var string NextURL; var bool bNextItems; var float NextSwitchCountdown; //----------------------------------------------------------------------------- // Actor Performance Management var int AIProfile[8]; // TEMP statistics var float AvgAITime; //moving average of Actor time //----------------------------------------------------------------------------- // Physics control var() bool bCheckWalkSurfaces; // enable texture-specific physics code for Pawns. //----------------------------------------------------------------------------- // Spawn notification list var SpawnNotify SpawnNotify; //----------------------------------------------------------------------------- // Functions. // // Return the URL of this level on the local machine. // native simulated function string GetLocalURL(); // // Return the URL of this level, which may possibly // exist on a remote machine. // native simulated function string GetAddressURL(); // // Jump the server to a new level. // event ServerTravel( string URL, bool bItems ) { if( NextURL=="" ) { SetTimer(0.0,False); bNextItems = bItems; NextURL = URL; if( Game!=None ) Game.ProcessServerTravel( URL, bItems ); else NextSwitchCountdown = 0; } } event BeginPlay() { if (NetMode == NM_DedicatedServer || NetMode == NM_ListenServer) SetTimer(TimeDilation,True); } event Timer() { if (Pauser != "" && Game != None) Game.SentText = 0; } //----------------------------------------------------------------------------- // Network replication. replication { reliable if( Role==ROLE_Authority ) Pauser, TimeDilation, bNoCheating, bAllowFOV; } w4|//============================================================================= // Keypoint, the base class of invisible actors which mark things. //============================================================================= class Keypoint extends Actor abstract native; // Sprite. #exec Texture Import File=Textures\Keypoint.pcx Name=S_Keypoint Mips=Off Flags=2 w4L//============================================================================= // InventorySpot. //============================================================================= class InventorySpot extends NavigationPoint native; var Inventory markedItem; w4c//============================================================================= // The inventory class, the parent class of all objects which can be // picked up and carried by actors. //============================================================================= class Inventory extends Actor abstract native nativereplication; #exec Texture Import File=Textures\Inventry.pcx Name=S_Inventory Mips=Off Flags=2 //----------------------------------------------------------------------------- // Information relevant to Active/Inactive state. var() travel byte AutoSwitchPriority; // Autoswitch value, 0=never autoswitch. var() byte InventoryGroup; // The weapon/inventory set, 1-9 (0=none). var() bool bActivatable; // Whether item can be activated. var() bool bDisplayableInv; // Item displayed in HUD. var travel bool bActive; // Whether item is currently activated. var bool bSleepTouch; // Set when item is touched when leaving sleep state. var bool bHeldItem; // Set once an item has left pickup state. var bool bTossedOut; // true if weapon was tossed out (so players can't cheat w/ weaponstay) //----------------------------------------------------------------------------- // Ambient glow related info. var(Display) bool bAmbientGlow; // Whether to glow or not. //----------------------------------------------------------------------------- // Information relevant to Pickup state. var() bool bInstantRespawn; // Can be tagged so this item respawns instantly. var() bool bRotatingPickup; // Rotates when in pickup state. var() localized string PickupMessage; // Human readable description when picked up. var() localized string ItemName; // Human readable name of item var() localized string ItemArticle; // Human readable article (e.g. "a", "an") var() float RespawnTime; // Respawn after this time, 0 for instant. var name PlayerLastTouched; // Player who last touched this item. //----------------------------------------------------------------------------- // Rendering information. // Player view rendering info. var() vector PlayerViewOffset; // Offset from view center. var() mesh PlayerViewMesh; // Mesh to render. var() float PlayerViewScale; // Mesh scale. var() float BobDamping; // how much to damp view bob // Pickup view rendering info. var() mesh PickupViewMesh; // Mesh to render. var() float PickupViewScale; // Mesh scale. // 3rd person mesh. var() mesh ThirdPersonMesh; // Mesh to render. var() float ThirdPersonScale; // Mesh scale. //----------------------------------------------------------------------------- // Status bar info. var() texture StatusIcon; // Icon used with ammo/charge/power count. //----------------------------------------------------------------------------- // Armor related info. var() name ProtectionType1; // Protects against DamageType (None if non-armor). var() name ProtectionType2; // Secondary protection type (None if non-armor). var() travel int Charge; // Amount of armor or charge if not an armor (charge in time*10). var() int ArmorAbsorption; // Percent of damage item absorbs 0-100. var() bool bIsAnArmor; // Item will protect player. var() int AbsorptionPriority; // Which items absorb damage first (higher=first). var() inventory NextArmor; // Temporary list created by Armors to prioritize damage absorption. //----------------------------------------------------------------------------- // AI related info. var() float MaxDesireability; // Maximum desireability this item will ever have. var InventorySpot MyMarker; //----------------------------------------------------------------------------- // 3rd person muzzleflash var bool bSteadyFlash3rd; var bool bFirstFrame; var(MuzzleFlash) bool bMuzzleFlashParticles; var(MuzzleFlash) bool bToggleSteadyFlash; var bool bSteadyToggle; var byte FlashCount, OldFlashCount; var(MuzzleFlash) ERenderStyle MuzzleFlashStyle; var(MuzzleFlash) mesh MuzzleFlashMesh; var(MuzzleFlash) float MuzzleFlashScale; var(MuzzleFlash) texture MuzzleFlashTexture; //----------------------------------------------------------------------------- // Sound assignments. var() sound PickupSound, ActivateSound, DeActivateSound, RespawnSound; //----------------------------------------------------------------------------- // HUD graphics. var() texture Icon; var() localized String M_Activated; var() localized String M_Selected; var() localized String M_Deactivated; //----------------------------------------------------------------------------- // Messaging var() class PickupMessageClass; var() class ItemMessageClass; // Network replication. replication { // Things the server should send to the client. reliable if( Role==ROLE_Authority && bNetOwner ) bIsAnArmor, Charge, bActivatable, bActive, PlayerViewOffset, PlayerViewMesh, PlayerViewScale; unreliable if( Role==ROLE_Authority ) FlashCount, bSteadyFlash3rd, ThirdPersonMesh, ThirdPersonScale; } function PostBeginPlay() { if ( ItemName == "" ) ItemName = GetItemName(string(Class)); Super.PostBeginPlay(); } // Draw first person view of inventory simulated event RenderOverlays( canvas Canvas ) { if ( Owner == None ) return; if ( (Level.NetMode == NM_Client) && (!Owner.IsA('PlayerPawn') || (PlayerPawn(Owner).Player == None)) ) return; SetLocation( Owner.Location + CalcDrawOffset() ); SetRotation( Pawn(Owner).ViewRotation ); Canvas.DrawActor(self, false); } function String GetHumanName() { return ItemArticle@ItemName; } // overridable function to ask the inventory object to draw its StatusIcon simulated function DrawStatusIconAt( canvas Canvas, int X, int Y, optional float Scale ) { if( Scale == 0.0 ) Scale = 1.0; Canvas.SetPos( X, Y ); Canvas.DrawIcon( StatusIcon, Scale ); } //============================================================================= // AI inventory functions. event float BotDesireability( pawn Bot ) { local Inventory AlreadyHas; local float desire; local bool bChecked; desire = MaxDesireability; if ( RespawnTime < 10 ) { bChecked = true; AlreadyHas = Bot.FindInventoryType(class); if ( (AlreadyHas != None) && (AlreadyHas.Charge >= Charge) ) return -1; } if( bIsAnArmor ) { if ( !bChecked ) AlreadyHas = Bot.FindInventoryType(class); if ( AlreadyHas != None ) desire *= (1 - AlreadyHas.Charge * AlreadyHas.ArmorAbsorption * 0.00003); desire *= (Charge * 0.005); desire *= (ArmorAbsorption * 0.01); return desire; } else return desire; } function Weapon RecommendWeapon( out float rating, out int bUseAltMode ) { if ( inventory != None ) return inventory.RecommendWeapon(rating, bUseAltMode); 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) ); if( bActive ) Activate(); } //============================================================================= // General inventory functions. // // Called by engine when destroyed. // function Destroyed() { if (MyMarker != None ) MyMarker.markedItem = None; // Remove from owner's inventory. if( Pawn(Owner)!=None ) Pawn(Owner).DeleteInventory( Self ); } // // Compute offset for drawing. // simulated final function vector CalcDrawOffset() { local vector DrawOffset, WeaponBob; local Pawn PawnOwner; PawnOwner = Pawn(Owner); DrawOffset = ((0.9/PawnOwner.FOVAngle * PlayerViewOffset) >> PawnOwner.ViewRotation); if ( (Level.NetMode == NM_DedicatedServer) || ((Level.NetMode == NM_ListenServer) && (Owner.RemoteRole == ROLE_AutonomousProxy)) ) DrawOffset += (PawnOwner.BaseEyeHeight * vect(0,0,1)); else { DrawOffset += (PawnOwner.EyeHeight * vect(0,0,1)); WeaponBob = BobDamping * PawnOwner.WalkBob; WeaponBob.Z = (0.45 + 0.55 * BobDamping) * PawnOwner.WalkBob.Z; DrawOffset += WeaponBob; } return DrawOffset; } // // Become a pickup. // function BecomePickup() { if ( Physics != PHYS_Falling ) RemoteRole = ROLE_SimulatedProxy; Mesh = PickupViewMesh; DrawScale = PickupViewScale; bOnlyOwnerSee = false; bHidden = false; bCarriedItem = false; NetPriority = 1.4; SetCollision( true, false, false ); } // // Become an inventory item. // function BecomeItem() { RemoteRole = ROLE_SimulatedProxy; Mesh = PlayerViewMesh; DrawScale = PlayerViewScale; bOnlyOwnerSee = true; bHidden = true; bCarriedItem = true; NetPriority = 1.4; SetCollision( false, false, false ); SetPhysics(PHYS_None); SetTimer(0.0,False); AmbientGlow = 0; } // // Give this inventory item to a pawn. // function GiveTo( pawn Other ) { Instigator = Other; BecomeItem(); Other.AddInventory( Self ); GotoState('Idle2'); } // 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( Level.Game.ShouldRespawn(self) ) { Copy = spawn(Class,Other,,,rot(0,0,0)); Copy.Tag = Tag; Copy.Event = Event; GotoState('Sleeping'); } else Copy = self; Copy.RespawnTime = 0.0; Copy.bHeldItem = true; Copy.GiveTo( Other ); return Copy; } // // Set up respawn waiting if desired. // function SetRespawn() { if( Level.Game.ShouldRespawn(self) ) GotoState('Sleeping'); else Destroy(); } // // Toggle Activation of selected Item. // function Activate() { if( bActivatable ) { if (Level.Game.LocalLog != None) Level.Game.LocalLog.LogItemActivate(Self, Pawn(Owner)); if (Level.Game.WorldLog != None) Level.Game.WorldLog.LogItemActivate(Self, Pawn(Owner)); if ( M_Activated != "" ) Pawn(Owner).ClientMessage(ItemName$M_Activated); GoToState('Activated'); } } // // 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( inventory Item ) { if ( Item.Class == Class ) return true; if ( Inventory == None ) return false; return Inventory.HandlePickupQuery(Item); } // // Select first activatable item. // function Inventory SelectNext() { if ( bActivatable ) { if ( M_Selected != "" ) Pawn(Owner).ClientMessage(ItemName$M_Selected); return self; } if ( Inventory != None ) return Inventory.SelectNext(); else return None; } // // Toss this item out. // function DropFrom(vector StartLocation) { if ( !SetLocation(StartLocation) ) return; RespawnTime = 0.0; //don't respawn SetPhysics(PHYS_Falling); RemoteRole = ROLE_DumbProxy; BecomePickup(); NetPriority = 2.5; NetUpdateFrequency = 20; bCollideWorld = true; if ( Pawn(Owner) != None ) Pawn(Owner).DeleteInventory(self); Inventory = None; GotoState('PickUp', 'Dropped'); } function DropInventory() { } //============================================================================= // Capabilities: For feeding general info to bots. // For future use. function float InventoryCapsFloat( name Property, pawn Other, actor Test ); function string InventoryCapsString( name Property, pawn Other, actor Test ); //============================================================================= // Firing/using. // Fire functions which must be implemented in child classes. function Fire( float Value ); function AltFire( float Value ); function Use( pawn User ); //============================================================================= // Weapon functions. // // Find a weapon in inventory that has an Inventory Group matching F. // function Weapon WeaponChange( byte F ) { if( Inventory == None) return None; else return Inventory.WeaponChange( F ); } //============================================================================= // Armor functions. // // Scan the player's inventory looking for items that reduce damage // to the player. If Armor's protection type matches DamageType, then no damage is taken. // Returns the reduced damage. // function int ReduceDamage( int Damage, name DamageType, vector HitLocation ) { local Inventory FirstArmor; local int ReducedAmount,ArmorDamage; if( Damage<0 ) return 0; ReducedAmount = Damage; FirstArmor = PrioritizeArmor(Damage, DamageType, HitLocation); while( (FirstArmor != None) && (ReducedAmount > 0) ) { ReducedAmount = FirstArmor.ArmorAbsorbDamage(ReducedAmount, DamageType, HitLocation); FirstArmor = FirstArmor.nextArmor; } return ReducedAmount; } // // Return the best armor to use. // function inventory PrioritizeArmor( int Damage, name DamageType, vector HitLocation ) { local Inventory FirstArmor, InsertAfter; if ( Inventory != None ) FirstArmor = Inventory.PrioritizeArmor(Damage, DamageType, HitLocation); else FirstArmor = None; if ( bIsAnArmor) { 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; } // // Absorb damage. // function int ArmorAbsorbDamage(int Damage, name DamageType, vector HitLocation) { local int ArmorDamage; if ( DamageType != 'Drowned' ) ArmorImpactEffect(HitLocation); if( (DamageType!='None') && ((ProtectionType1==DamageType) || (ProtectionType2==DamageType)) ) return 0; if (DamageType=='Drowned') Return Damage; ArmorDamage = (Damage * ArmorAbsorption) / 100; if( ArmorDamage >= Charge ) { ArmorDamage = Charge; Destroy(); } else Charge -= ArmorDamage; return (Damage - ArmorDamage); } // // Return armor value. // function int ArmorPriority(name DamageType) { if ( DamageType == 'Drowned' ) return 0; if( (DamageType!='None') && ((ProtectionType1==DamageType) || (ProtectionType2==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){ } // // Used to inform inventory when owner jumps. // function OwnerJumped() { if( Inventory != None ) Inventory.OwnerJumped(); } // // Used to inform inventory when owner weapon changes. // function ChangedWeapon() { if( Inventory != None ) Inventory.ChangedWeapon(); } // used to ask inventory if it needs to affect its owners display properties function SetOwnerDisplay() { if( Inventory != None ) Inventory.SetOwnerDisplay(); } //============================================================================= // Pickup state: this inventory item is sitting on the ground. auto state Pickup { singular function ZoneChange( ZoneInfo NewZone ) { local float splashsize; local actor splash; if( NewZone.bWaterZone && !Region.Zone.bWaterZone ) { splashSize = 0.000025 * Mass * (250 - 0.5 * Velocity.Z); if ( NewZone.EntrySound != None ) PlaySound(NewZone.EntrySound, SLOT_Interact, splashSize); if ( NewZone.EntryActor != None ) { splash = Spawn(NewZone.EntryActor); if ( splash != None ) splash.DrawScale = 2 * splashSize; } } } // Validate touch, and if valid trigger event. function bool ValidTouch( actor Other ) { local Actor A; if( Other.bIsPawn && Pawn(Other).bIsPlayer && (Pawn(Other).Health > 0) && Level.Game.PickupQuery(Pawn(Other), self) ) { if( Event != '' ) foreach AllActors( class 'Actor', A, Event ) A.Trigger( Other, Other.Instigator ); return true; } return false; } // When touched by an actor. function Touch( actor Other ) { // If touched by a player pawn, let him pick this up. if( ValidTouch(Other) ) { if (Level.Game.LocalLog != None) Level.Game.LocalLog.LogPickup(Self, Pawn(Other)); if (Level.Game.WorldLog != None) Level.Game.WorldLog.LogPickup(Self, Pawn(Other)); SpawnCopy(Pawn(Other)); if ( PickupMessageClass == None ) Pawn(Other).ClientMessage(PickupMessage, 'Pickup'); else Pawn(Other).ReceiveLocalizedMessage( PickupMessageClass, 0, None, None, Self.Class ); PlaySound (PickupSound); if ( Level.Game.Difficulty > 1 ) Other.MakeNoise(0.1 * Level.Game.Difficulty); if ( Pawn(Other).MoveTarget == self ) Pawn(Other).MoveTimer = -1.0; } else if ( bTossedOut && (Other.Class == Class) && Inventory(Other).bTossedOut ) Destroy(); } // Landed on ground. function Landed(Vector HitNormal) { local rotator newRot; newRot = Rotation; newRot.pitch = 0; netUpdateFrequency = Default.NetUpdateFrequency; SetRotation(newRot); SetTimer(2.0, false); } // Make sure no pawn already touching (while touch was disabled in sleep). function CheckTouching() { local int i; bSleepTouch = false; for ( i=0; i<4; i++ ) if ( (Touching[i] != None) && Touching[i].IsA('Pawn') ) Touch(Touching[i]); } function Timer() { if ( RemoteRole != ROLE_SimulatedProxy ) { NetPriority = 1.4; RemoteRole = ROLE_SimulatedProxy; if ( bHeldItem ) { if ( bTossedOut ) SetTimer(15.0, false); else SetTimer(40.0, false); } return; } if ( bHeldItem ) { if ( (FRand() < 0.1) || !PlayerCanSeeMe() ) Destroy(); else SetTimer(3.0, true); } } function BeginState() { BecomePickup(); bCollideWorld = true; if ( bHeldItem ) SetTimer(30, false); else if ( Level.bStartup ) { bAlwaysRelevant = true; NetUpdateFrequency = 8; } } function EndState() { bCollideWorld = false; bSleepTouch = false; } Begin: BecomePickup(); if ( bRotatingPickup && (Physics != PHYS_Falling) ) SetPhysics(PHYS_Rotating); Dropped: if( bAmbientGlow ) AmbientGlow=255; if( bSleepTouch ) CheckTouching(); } //============================================================================= // Active state: this inventory item is armed and ready to rock! state Activated { function BeginState() { bActive = true; if ( Pawn(Owner).bIsPlayer && (ProtectionType1 != '') ) Pawn(Owner).ReducedDamageType = ProtectionType1; } function EndState() { bActive = false; if ( (Pawn(Owner) != None) && Pawn(Owner).bIsPlayer && (ProtectionType1 != '') ) Pawn(Owner).ReducedDamageType = ''; } function Activate() { if ( (Pawn(Owner) != None) && (M_Deactivated != "") ) Pawn(Owner).ClientMessage(ItemName$M_Deactivated); GoToState('DeActivated'); } } //============================================================================= // Sleeping state: Sitting hidden waiting to respawn. State Sleeping { ignores Touch; function BeginState() { BecomePickup(); bHidden = true; } function EndState() { local int i; bSleepTouch = false; for ( i=0; i<4; i++ ) if ( (Touching[i] != None) && Touching[i].IsA('Pawn') ) bSleepTouch = true; } Begin: Sleep( ReSpawnTime ); PlaySound( RespawnSound ); Sleep( Level.Game.PlaySpawnEffect(self) ); GoToState( 'Pickup' ); } function ActivateTranslator(bool bHint) { if( Inventory!=None ) Inventory.ActivateTranslator( bHint ); } // // Null state. // State Idle2 { } w4[ //============================================================================= // InterpolationPoint. //============================================================================= class InterpolationPoint extends Keypoint native; // Sprite. #exec Texture Import File=Textures\IntrpPnt.pcx Name=S_Interp Mips=Off Flags=2 // Number in sequence sharing this tag. var() int Position; var() float RateModifier; var() float GameSpeedModifier; var() float FovModifier; var() bool bEndOfPath; var() bool bSkipNextPath; var() float ScreenFlashScale; var() vector ScreenFlashFog; // Other points in this interpolation path. var InterpolationPoint Prev, Next; // // At start of gameplay, link all matching interpolation points together. // function BeginPlay() { Super.BeginPlay(); // Try to find previous. foreach AllActors( class 'InterpolationPoint', Prev, Tag ) if( Prev.Position == Position-1 ) break; if( Prev != None ) Prev.Next = Self; // Try to find next. foreach AllActors( class 'InterpolationPoint', Next, Tag ) if( Next.Position == Position+1 ) break; if( Next == None ) foreach AllActors( class 'InterpolationPoint', Next, Tag ) if( Next.Position == 0 ) break; if( Next != None ) Next.Prev = Self; } // // Verify that we're linked up. // function PostBeginPlay() { Super.PostBeginPlay(); //log( "Interpolation point" @ Tag @ Position $ ":" ); //if( Prev != None ) // log( " Prev # " $ Prev.Position ); //if( Next != None ) // log( " Next # " $ Next.Position ); } // // When reach an interpolation point. // function InterpolateEnd( actor Other ) { if( bEndOfPath ) { if( Pawn(Other)!=None && Pawn(Other).bIsPlayer ) { Other.bCollideWorld = True; Other.bInterpolating = false; if ( Pawn(Other).Health > 0 ) { Other.SetCollision(true,true,true); Other.SetPhysics(PHYS_Falling); Other.AmbientSound = None; if ( Other.IsA('PlayerPawn') ) Other.GotoState('PlayerWalking'); } } } } w4r//============================================================================= // InternetInfo: Parent class for Internet connection classes //============================================================================= class InternetInfo extends Info native transient; function string GetBeaconAddress( int i ); function string GetBeaconText( int i ); w4JN_NpHw4m%F 2=9q!w4 w4pTNC n76>v-Y -Y ('t:C , :C :C ~:C `9p9:C H%' w4K//============================================================================= // Info, the root of all information holding classes. //============================================================================= class Info extends Actor abstract native; w4w4w4s UNnGGy?-Y (^:n:$+H%H%TB{99TNq!w4H%{8GnAS%':A:$(:n:$ H%H%{9A%^*(>9!HD?g?,V 9gjj4gR,Rg,&K99}5K^*mErrorsExecCore!H^*!HNq!w4H%:n:$&gRD?g?,V 99D?g?,V H%h:n:$(D?g?,V 9Vgj9D?g?,V ^9H%:n:$!H,@H,@&:n:$"H%H%:n:$ :n:$%}9%99}9&H%' w4z///============================================================================= // HUD: Superclass of the heads-up display. //============================================================================= class HUD extends Actor abstract native config(user); //============================================================================= // Variables. var globalconfig int HudMode; var globalconfig int Crosshair; var() class MainMenuType; var() string HUDConfigWindowType; var color WhiteColor; var Menu MainMenu; var Mutator HUDMutator; var PlayerPawn PlayerOwner; // always the actual owner struct HUDLocalizedMessage { var Class Message; var int Switch; var PlayerReplicationInfo RelatedPRI; var Object OptionalObject; var float EndOfLife; var float LifeTime; var bool bDrawing; var int numLines; var string StringMessage; var color DrawColor; var font StringFont; var float XL, YL; var float YPos; }; function ClearMessage(out HUDLocalizedMessage M) { M.Message = None; M.Switch = 0; M.RelatedPRI = None; M.OptionalObject = None; M.EndOfLife = 0; M.StringMessage = ""; M.DrawColor = WhiteColor; M.XL = 0; M.bDrawing = false; } function CopyMessage(out HUDLocalizedMessage M1, HUDLocalizedMessage M2) { M1.Message = M2.Message; M1.Switch = M2.Switch; M1.RelatedPRI = M2.RelatedPRI; M1.OptionalObject = M2.OptionalObject; M1.EndOfLife = M2.EndOfLife; M1.StringMessage = M2.StringMessage; M1.DrawColor = M2.DrawColor; M1.XL = M2.XL; M1.YL = M2.YL; M1.YPos = M2.YPos; M1.bDrawing = M2.bDrawing; M1.LifeTime = M2.LifeTime; M1.numLines = M2.numLines; } //============================================================================= // Status drawing. simulated event PreRender( canvas Canvas ); simulated event PostRender( canvas Canvas ); simulated function InputNumber(byte F); simulated function ChangeHud(int d); simulated function ChangeCrosshair(int d); simulated function DrawCrossHair( canvas Canvas, int StartX, int StartY); //============================================================================= // Messaging. simulated function Message( PlayerReplicationInfo PRI, coerce string Msg, name N ); simulated function LocalizedMessage( class Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject, optional string CriticalString ); simulated function PlayReceivedMessage( string S, string PName, ZoneInfo PZone ) { PlayerPawn(Owner).ClientMessage(S); if (PlayerPawn(Owner).bMessageBeep) PlayerPawn(Owner).PlayBeepSound(); } // DisplayMessages is called by the Console in PostRender. // It offers the HUD a chance to deal with messages instead of the // Console. Returns true if messages were dealt with. simulated function bool DisplayMessages(canvas Canvas) { return false; } function bool ProcessKeyEvent( int Key, int Action, FLOAT Delta ) { return false; } w4T//============================================================================= // HomeBase. //============================================================================= class HomeBase extends NavigationPoint; #exec Texture Import File=Textures\Flag1.pcx Name=S_Flag Mips=Off Flags=2 var() float extent; //how far the base extends from central point (in line of sight) var vector lookdir; //direction to look while stopped function PreBeginPlay() { lookdir = 200 * vector(Rotation); Super.PreBeginPlay(); } w4z8@w4w4Kw4ZNR=x]NM**w4v$/D Q=@w4w4XNIG(-X '46 p-X  w4^NMG3-X (46 p-X N w4SNgNWjJw4s R%GH:N:$(Wr46"*$r46"u*(46"uCR%NH%' w4w4w4Y- //============================================================================= // GameReplicationInfo. //============================================================================= class GameReplicationInfo extends ReplicationInfo native nativereplication; var string GameName; // Assigned by GameInfo. var string GameClass; // Assigned by GameInfo. var bool bTeamGame; // Assigned by GameInfo. var bool bClassicDeathMessages; var bool bStopCountDown; var int RemainingTime, ElapsedTime, RemainingMinute; var float SecondCount; var int NumPlayers; var int SumFrags; var float UpdateTimer; 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 Region; // Region of the game server. var() globalconfig string MOTDLine1; // Message var() globalconfig string MOTDLine2; // Of var() globalconfig string MOTDLine3; // The var() globalconfig string MOTDLine4; // Day var string GameEndedComments; // set by gameinfo when game ends var PlayerReplicationInfo PRIArray[32]; replication { reliable if ( Role == ROLE_Authority ) RemainingMinute, bStopCountDown, GameEndedComments, NumPlayers; reliable if ( bNetInitial && (Role==ROLE_Authority) ) GameName, GameClass, bTeamGame, ServerName, ShortName, AdminName, AdminEmail, Region, MOTDLine1, MOTDLine2, MOTDLine3, MOTDLine4,RemainingTime, ElapsedTime; } simulated function PostBeginPlay() { 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 = ""; MOTDLine1 = ""; MOTDLine2 = ""; MOTDLine3 = ""; MOTDLine4 = ""; } SecondCount = Level.TimeSeconds; SetTimer(0.2, true); } simulated function Timer() { local PlayerReplicationInfo PRI; local int i, FragAcc; if ( Level.NetMode == NM_Client ) { if (Level.TimeSeconds - SecondCount >= Level.TimeDilation) { ElapsedTime++; if ( RemainingMinute != 0 ) { RemainingTime = RemainingMinute; RemainingMinute = 0; } if ( (RemainingTime > 0) && !bStopCountDown ) RemainingTime--; SecondCount += Level.TimeDilation; } } for (i=0; i<32; i++) PRIArray[i] = None; i=0; foreach AllActors(class'PlayerReplicationInfo', PRI) { if ( i < 32 ) PRIArray[i++] = PRI; } // Update various information. UpdateTimer = 0; for (i=0; i<32; i++) if (PRIArray[i] != None) FragAcc += PRIArray[i].Score; SumFrags = FragAcc; if ( Level.Game != None ) NumPlayers = Level.Game.NumPlayers; } w4eNw4w4w4w4aN$J w4fNMgJ w4`NiN@Kw4s X*GKGr46"*$r46"u*(46"uCX*O%H%' w4u88V)"  w4C9w4w4mNw4w4w4w4hNyN!&Rw4p`nL:`, :`:`~:``:` 9p9:`H%w46"*$w46"u*46"u I9' w4k//============================================================================= // GameInfo. // // default game info is normal single player // //============================================================================= class GameInfo extends Info native; //----------------------------------------------------------------------------- // Variables. var int ItemGoals, KillGoals, SecretGoals; // Special game goals. var byte Difficulty; // 0=easy, 1=medium, 2=hard, 3=very hard. var() config bool bNoMonsters; // Whether monsters are allowed in this play mode. var() globalconfig bool bMuteSpectators; // Whether spectators are allowed to speak. var() config bool bHumansOnly; // Whether non human player models are allowed. var() bool bRestartLevel; var() bool bPauseable; // Whether the level is pauseable. var() config bool bCoopWeaponMode; // Whether or not weapons stay when picked up. var() config bool bClassicDeathmessages; // Weapon deathmessages if false. var globalconfig bool bLowGore; // Whether or not to reduce gore. var bool bCanChangeSkin; // Allow player to change skins in game. var() bool bTeamGame; // This is a teamgame. var globalconfig bool bVeryLowGore; // Greatly reduces gore. var() globalconfig bool bNoCheating; // Disallows cheating. Hehe. var() globalconfig bool bAllowFOV; // Allows FOV changes in net games var() bool bDeathMatch; // This game is some type of deathmatch (where players can respawn during gameplay) var bool bGameEnded; // set when game ends var bool bOverTime; var localized bool bAlternateMode; var bool bCanViewOthers; var globalconfig bool bExternalBatcher; var() globalconfig float AutoAim; // 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() class DefaultPlayerClass; var() class DefaultWeapon; // Default weapon given to player at start. var() globalconfig int MaxSpectators; // Maximum number of spectators. var int NumSpectators; // Current number of spectators. var() private globalconfig string AdminPassword; // Password to receive bAdmin privileges. var() private globalconfig string GamePassword; // Password to enter game. var() class ScoreBoardType; // Type of scoreboard this game uses. var() class GameMenuType; // Type of oldstyle game options menu to display. var() string BotMenuType; // Type of bot menu to display. var() string RulesMenuType; // Type of rules menu to display. var() string SettingsMenuType; // Type of settings menu to display. var() string GameUMenuType; // Type of Game dropdown to display. var() string MultiplayerUMenuType; // Type of Multiplayer dropdown to display. var() string GameOptionsMenuType; // Type of options dropdown to display. var() class HUDType; // HUD class this game uses. var() class MapListType; // Maplist this game uses. var() string MapPrefix; // Prefix characters for names of maps for this game type. var() string BeaconName; // Identifying string used for finding LAN servers. var() string SpecialDamageString; var localized string SwitchLevelMessage; var int SentText; var localized string DefaultPlayerName; var localized string LeftMessage; var localized string FailedSpawnMessage; var localized string FailedPlaceMessage; var localized string FailedTeamMessage; var localized string NameChangedMessage; var localized string EnteredMessage; var localized string GameName; var localized string MaxedOutMessage; var localized string WrongPassword; var localized string NeedPassword; var localized string IPBanned; var() globalconfig int MaxPlayers; var int NumPlayers; var int CurrentID; // Message classes. var class DeathMessageClass; var class DMMessageClass; // Mutator (for modifying actors as they enter the game) var class MutatorClass; var Mutator BaseMutator; var Mutator DamageMutator; // linked list of mutators which affect damage var Mutator MessageMutator; // linked list of mutators which get localized message queries // Default waterzone entry and exit effects var class WaterZoneType; // What state a player should start in for this game type var name DefaultPlayerState; // ReplicationInfo var() class GameReplicationInfoClass; var GameReplicationInfo GameReplicationInfo; // Server Log var globalconfig string ServerLogName; // Statistics Logging var StatLog LocalLog; var StatLog WorldLog; var globalconfig bool bLocalLog; var globalconfig bool bWorldLog; var globalconfig bool bBatchLocal; var bool bLoggingGame; // Does this gametype log? var string LocalLogFileName; var string WorldLogFileName; var class StatLogClass; // Demo Information var globalconfig int DemoBuild; var globalconfig int DemoHasTuts; // Server query info var string EnabledMutators; // UTPG var globalconfig float PlayerViewDelay; var globalconfig float PlayerSpeechDelay; var globalconfig float PlayerTauntDelay; var config float MinFOV; var config float MaxFOV; var config int MaxNameChanges; //------------------------------------------------------------------------------ // Admin // Admin account protection // var globalconfig bool bLogAdminActions; var globalconfig float LoginDelaySeconds; // Seconds after unsuccessful login before allowing another attempt var globalconfig int MaxLoginAttempts; // Maximum number of unsuccessful logins from a player before taking action var globalconfig enum ELoginAction { DO_Nothing, // Do nothing (standard) DO_Log, // Write alert to server log DO_DisableLogin, // Disable this player's ability to login as admin for the remainder of the current game DO_KickPlayer, // Kick this player DO_KickBanPlayer // Ban this player by IP address } ActionToTake; // Action to take when MaxAllowedLoginAttempts has been reached var() globalconfig string IPPolicies[256]; function AdminLogin( PlayerPawn P, string Password ) { if (AdminPassword == "") return; if (Password == AdminPassword) { P.bAdmin = True; P.PlayerReplicationInfo.bAdmin = P.bAdmin; if (bLogAdminActions) log(P.PlayerReplicationInfo.PlayerName@"logged in as administrator from"@P.GetPlayerNetworkAddress(),'Admin'); else Log("Administrator logged in."); BroadcastMessage( P.PlayerReplicationInfo.PlayerName@"became a server administrator." ); } } function AdminLogout( PlayerPawn P ) { local float OldScore; if (P.bAdmin) { P.bAdmin = False; P.PlayerReplicationInfo.bAdmin = P.bAdmin; if ( P.ReducedDamageType == 'All' ) P.ReducedDamageType = ''; P.StartWalk(); OldScore = P.PlayerReplicationInfo.Score; P.Suicide(); P.PlayerReplicationInfo.Score = OldScore; if (bLogAdminActions) log(P.PlayerReplicationInfo.PlayerName@"logged out as administrator."); else Log("Administrator logged out."); BroadcastMessage( P.PlayerReplicationInfo.PlayerName@"gave up administrator abilities." ); } } //------------------------------------------------------------------------------ // Engine notifications. function PreBeginPlay() { StartTime = 0; SetGameSpeed(GameSpeed); Level.bNoCheating = bNoCheating; Level.bAllowFOV = bAllowFOV; // Make sure MaxFOV cannot be set below MinFOV, // Also make sure we have valid values MinFOV = FClamp(MinFOV, 1.0, 130.0); MaxFOV = FClamp(MaxFOV, MinFOV, 170.0); if (GameReplicationInfoClass != None) GameReplicationInfo = Spawn(GameReplicationInfoClass); else GameReplicationInfo = Spawn(class'GameReplicationInfo'); InitGameReplicationInfo(); } function PostBeginPlay() { local ZoneInfo W; if ( bAlternateMode ) { bLowGore = true; bVeryLowGore = true; } if ( bVeryLowGore ) bLowGore = true; if ( WaterZoneType != None ) { ForEach AllActors(class'ZoneInfo', W ) if ( W.bWaterZone ) { if( W.EntryActor == None ) W.EntryActor = WaterZoneType.Default.EntryActor; if( W.ExitActor == None ) W.ExitActor = WaterZoneType.Default.ExitActor; if( W.EntrySound == None ) W.EntrySound = WaterZoneType.Default.EntrySound; if( W.ExitSound == None ) W.ExitSound = WaterZoneType.Default.ExitSound; } } // Setup local statistics logging. InitLogging(); Super.PostBeginPlay(); } function InitLogging() { local Mutator M; if (bLocalLog && bLoggingGame) { Log("Initiating local logging..."); LocalLog = spawn(StatLogClass); LocalLog.bWorld = False; LocalLog.StartLog(); LocalLog.LogStandardInfo(); LocalLog.LogServerInfo(); LocalLog.LogMapParameters(); for (M = BaseMutator; M != None; M = M.NextMutator) LocalLog.LogMutator(M); LogGameParameters(LocalLog); LocalLogFileName = LocalLog.GetLogFileName(); } // Setup world statistics logging. if ((Level.NetMode != NM_DedicatedServer) && (Level.NetMode != NM_ListenServer)) return; if (bWorldLog && bLoggingGame) { Log("Initiating world logging..."); WorldLog = spawn(StatLogClass); WorldLog.bWorld = True; WorldLog.StartLog(); WorldLog.LogStandardInfo(); WorldLog.LogServerInfo(); WorldLog.LogMapParameters(); WorldLog.InitialCheck(Self); for (M = BaseMutator; M != None; M = M.NextMutator) WorldLog.LogMutator(M); LogGameParameters(WorldLog); WorldLogFileName = WorldLog.GetLogFileName(); } } function Timer() { SentText = 0; } // Called when game shutsdown. event GameEnding() { if (LocalLog != None) { LocalLog.LogGameEnd("serverquit"); LocalLog.StopLog(); LocalLog.Destroy(); LocalLog = None; } if (WorldLog != None) { WorldLog.LogGameEnd("serverquit"); WorldLog.StopLog(); WorldLog.Destroy(); WorldLog = None; } } //------------------------------------------------------------------------------ // Replication function InitGameReplicationInfo() { GameReplicationInfo.bTeamGame = bTeamGame; GameReplicationInfo.GameName = GameName; GameReplicationInfo.GameClass = string(Class); GameReplicationInfo.bClassicDeathmessages = bClassicDeathmessages; } native function string GetNetworkNumber(); //------------------------------------------------------------------------------ // Game Querying. function string GetInfo() { local string ResultSet; // World logging enabled and working if ( WorldLog != None && !WorldLog.bWorldBatcherError ) ResultSet = "\\worldlog\\true"; else ResultSet = "\\worldlog\\false"; // World logging activated if ( WorldLog != None ) ResultSet = ResultSet$"\\wantworldlog\\true"; else ResultSet = ResultSet$"\\wantworldlog\\false"; return ResultSet; } function string GetRules() { local string ResultSet; local Mutator M; local string NextMutator, NextDesc; local int Num, i; ResultSet = ""; if( EnabledMutators == "" ) { for (M = BaseMutator.NextMutator; M != None; M = M.NextMutator) { Num = 0; NextMutator = ""; GetNextIntDesc("Engine.Mutator", 0, NextMutator, NextDesc); while( (NextMutator != "") && (Num < 50) ) { if(NextMutator ~= string(M.Class)) { i = InStr(NextDesc, ","); if(i != -1) NextDesc = Left(NextDesc, i); if(EnabledMutators != "") EnabledMutators = EnabledMutators $ ", "; EnabledMutators = EnabledMutators $ NextDesc; break; } Num++; GetNextIntDesc("Engine.Mutator", Num, NextMutator, NextDesc); } } // utpg: mutator/browser fix begin } if(EnabledMutators != "") ResultSet = ResultSet $ "\\mutators\\"$EnabledMutators; // utpg: mutator/browser fix end ResultSet = ResultSet $ "\\listenserver\\"$string(Level.NetMode==NM_ListenServer) $ "\\password\\"$string(GamePassword!=""); return ResultSet; } // Return the server's port number. function int GetServerPort() { local string S; local int i; // Figure out the server's port. S = Level.GetAddressURL(); i = InStr( S, ":" ); assert(i>=0); return int(Mid(S,i+1)); } function bool SetPause( BOOL bPause, PlayerPawn P ) { if( bPauseable || P.bAdmin || Level.Netmode==NM_Standalone ) { if( bPause ) Level.Pauser=P.PlayerReplicationInfo.PlayerName; else Level.Pauser=""; return True; } else return False; } //------------------------------------------------------------------------------ // Stat Logging. function LogGameParameters(StatLog StatLog) { if (StatLog == None) return; StatLog.LogEventString(StatLog.GetTimeStamp()$Chr(9)$"game"$Chr(9)$"GameName"$Chr(9)$GameName); StatLog.LogEventString(StatLog.GetTimeStamp()$Chr(9)$"game"$Chr(9)$"GameClass"$Chr(9)$Class);// <-- Move to c++ StatLog.LogEventString(StatLog.GetTimeStamp()$Chr(9)$"game"$Chr(9)$"GameVersion"$Chr(9)$Level.EngineVersion); StatLog.LogEventString(StatLog.GetTimeStamp()$Chr(9)$"game"$Chr(9)$"MinNetVersion"$Chr(9)$Level.MinNetVersion); StatLog.LogEventString(StatLog.GetTimeStamp()$Chr(9)$"game"$Chr(9)$"NoMonsters"$Chr(9)$bNoMonsters); StatLog.LogEventString(StatLog.GetTimeStamp()$Chr(9)$"game"$Chr(9)$"MuteSpectators"$Chr(9)$bMuteSpectators); StatLog.LogEventString(StatLog.GetTimeStamp()$Chr(9)$"game"$Chr(9)$"HumansOnly"$Chr(9)$bHumansOnly); StatLog.LogEventString(StatLog.GetTimeStamp()$Chr(9)$"game"$Chr(9)$"WeaponsStay"$Chr(9)$bCoopWeaponMode); StatLog.LogEventString(StatLog.GetTimeStamp()$Chr(9)$"game"$Chr(9)$"ClassicDeathmessages"$Chr(9)$bClassicDeathmessages); StatLog.LogEventString(StatLog.GetTimeStamp()$Chr(9)$"game"$Chr(9)$"LowGore"$Chr(9)$bLowGore); StatLog.LogEventString(StatLog.GetTimeStamp()$Chr(9)$"game"$Chr(9)$"VeryLowGore"$Chr(9)$bVeryLowGore); StatLog.LogEventString(StatLog.GetTimeStamp()$Chr(9)$"game"$Chr(9)$"TeamGame"$Chr(9)$bTeamGame); StatLog.LogEventString(StatLog.GetTimeStamp()$Chr(9)$"game"$Chr(9)$"GameSpeed"$Chr(9)$int(GameSpeed*100)); StatLog.LogEventString(StatLog.GetTimeStamp()$Chr(9)$"game"$Chr(9)$"MaxSpectators"$Chr(9)$MaxSpectators); StatLog.LogEventString(StatLog.GetTimeStamp()$Chr(9)$"game"$Chr(9)$"MaxPlayers"$Chr(9)$MaxPlayers); } //------------------------------------------------------------------------------ // Game parameters. // // Set gameplay speed. // function SetGameSpeed( Float T ) { GameSpeed = FMax(T, 0.1); Level.TimeDilation = GameSpeed; SetTimer(Level.TimeDilation, true); } static function ResetGame(); // // Called after setting low or high detail mode. // event DetailChange() { local actor A; local zoneinfo Z; local skyzoneinfo S; if( !Level.bHighDetailMode ) { foreach AllActors(class'Actor', A) { if( A.bHighDetail && !A.bGameRelevant ) A.Destroy(); } } foreach AllActors(class'ZoneInfo', Z) Z.LinkToSkybox(); } // // Return whether an actor should be destroyed in // this type of game. // function bool IsRelevant( actor Other ) { local byte bSuperRelevant; // let the mutators mutate the actor or choose to remove it if ( BaseMutator.AlwaysKeep(Other) ) return true; if ( BaseMutator.IsRelevant(Other, bSuperRelevant) ) { if ( bSuperRelevant == 1 ) // mutator wants to override any logic in here return true; } else return false; if ( (Difficulty==0 && !Other.bDifficulty0 ) || (Difficulty==1 && !Other.bDifficulty1 ) || (Difficulty==2 && !Other.bDifficulty2 ) || (Difficulty==3 && !Other.bDifficulty3 ) || (!Other.bSinglePlayer && (Level.NetMode==NM_Standalone) ) || (!Other.bNet && ((Level.NetMode == NM_DedicatedServer) || (Level.NetMode == NM_ListenServer)) ) || (!Other.bNetSpecial && (Level.NetMode==NM_Client)) ) return False; if( bNoMonsters && (Pawn(Other) != None) && !Pawn(Other).bIsPlayer ) return False; if( FRand() > Other.OddsOfAppearing ) return False; // Update the level info goal counts. if( Other.bIsSecretGoal ) SecretGoals++; if( Other.bIsItemGoal ) ItemGoals++; if( Other.bIsKillGoal ) KillGoals++; return True; } //------------------------------------------------------------------------------ // Player start functions // // Grab the next option from a string. // 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. // 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 = ""; } } // // See if an option was specified in the options string. // 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; } // // Find an option in the options string and return it. // 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 ""; } // // Initialize the game. //warning: this is called before actors' PreBeginPlay. // event InitGame( string Options, out string Error ) { local string InOpt, LeftOpt, NextMutator, NextDesc; local int pos, i; local class MClass; log( "InitGame:" @ Options ); MaxPlayers = Min( 32,GetIntOption( Options, "MaxPlayers", MaxPlayers )); InOpt = ParseOption( Options, "Difficulty" ); if( InOpt != "" ) Difficulty = int(InOpt); InOpt = ParseOption( Options, "AdminPassword"); if( InOpt!="" ) AdminPassword = InOpt; InOpt = ParseOption( Options, "GameSpeed"); if( InOpt != "" ) { log("GameSpeed"@InOpt); SetGameSpeed(float(InOpt)); } BaseMutator = spawn(MutatorClass); log("Base Mutator is "$BaseMutator); 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 = ""; } log("Add mutator "$LeftOpt); MClass = class(DynamicLoadObject(LeftOpt, class'Class')); BaseMutator.AddMutator(Spawn(MClass)); } } InOpt = ParseOption( Options, "GamePassword"); if( InOpt != "" ) { GamePassWord = InOpt; log( "GamePassword" @ InOpt ); } InOpt = ParseOption( Options, "LocalLog"); if( InOpt ~= "true" ) bLocalLog = True; InOpt = ParseOption( Options, "WorldLog"); if( InOpt ~= "true" ) bWorldLog = True; } // // Return beacon text for serverbeacon. // event string GetBeaconText() { return Level.ComputerName $ " " $ Left(Level.Title,24) $ " " $ BeaconName $ " " $ NumPlayers $ "/" $ MaxPlayers; } // // Optional handling of ServerTravel for network games. // function ProcessServerTravel( string URL, bool bItems ) { local playerpawn P, LocalPlayer; if (LocalLog != None) { LocalLog.LogGameEnd("mapchange"); LocalLog.StopLog(); LocalLog.Destroy(); LocalLog = None; } if (WorldLog != None) { WorldLog.LogGameEnd("mapchange"); WorldLog.StopLog(); WorldLog.Destroy(); WorldLog = None; } // 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 AllActors( class'PlayerPawn', P ) if( NetConnection(P.Player)!=None ) P.ClientTravel( URL, TRAVEL_Relative, bItems ); else { LocalPlayer = P; P.PreClientTravel(); } if ( (Level.NetMode == NM_ListenServer) && (LocalPlayer != None) ) Level.NextURL = Level.NextURL$"?Skin="$LocalPlayer.GetDefaultURL("Skin") $"?Face="$LocalPlayer.GetDefaultURL("Face") $"?Team="$LocalPlayer.GetDefaultURL("Team") $"?Name="$LocalPlayer.GetDefaultURL("Name") $"?Class="$LocalPlayer.GetDefaultURL("Class"); // Switch immediately if not networking. if( Level.NetMode!=NM_DedicatedServer && Level.NetMode!=NM_ListenServer ) Level.NextSwitchCountdown = 0.0; } function bool AtCapacity(string Options) { return ( (MaxPlayers>0) && (NumPlayers>=MaxPlayers) ); } // // 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, out string Error, out string FailCode ) { // Do any name or password or name validation here. local string InPassword; Error=""; InPassword = ParseOption( Options, "Password" ); if( (Level.NetMode != NM_Standalone) && AtCapacity(Options) ) { Error=MaxedOutMessage; } else if ( GamePassword!="" && caps(InPassword)!=caps(GamePassword) && (AdminPassword=="" || caps(InPassword)!=caps(AdminPassword)) ) { if( InPassword == "" ) { Error = NeedPassword; FailCode = "NEEDPW"; } else { Error = WrongPassword; FailCode = "WRONGPW"; } } if(!CheckIPPolicy(Address)) Error = IPBanned; } function bool CheckIPPolicy(string Address) { 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; i SpawnClass ) { local NavigationPoint StartSpot; local PlayerPawn NewPlayer, TestPlayer; local Pawn PawnLink; local string InName, InPassword, InSkin, InFace, InChecksum; local byte InTeam; // Make sure there is capacity. (This might have changed since the PreLogin call). if ( Level.NetMode != NM_Standalone ) { if ( ClassIsChildOf(SpawnClass, class'Spectator') ) { if ( (NumSpectators >= MaxSpectators) && ((Level.NetMode != NM_ListenServer) || (NumPlayers > 0)) ) { Error=MaxedOutMessage; return None; } } else if ( (MaxPlayers>0) && (NumPlayers>=MaxPlayers) ) { Error=MaxedOutMessage; return None; } } BaseMutator.ModifyLogin(SpawnClass, Portal, Options); // Get URL options. InName = Left(ParseOption ( Options, "Name"), 20); InTeam = GetIntOption( Options, "Team", 255 ); // default to "no team" InPassword = ParseOption ( Options, "Password" ); InSkin = ParseOption ( Options, "Skin" ); InFace = ParseOption ( Options, "Face" ); InChecksum = ParseOption ( Options, "Checksum" ); log( "Login:" @ InName ); if( InPassword != "" ) log( "Password"@InPassword ); // Find a start spot. StartSpot = FindPlayerStart( None, InTeam, Portal ); if( StartSpot == None ) { Error = FailedPlaceMessage; return None; } // Try to match up to existing unoccupied player in level, // for savegames and coop level switching. for( PawnLink=Level.PawnList; PawnLink!=None; PawnLink=PawnLink.NextPawn ) { TestPlayer = PlayerPawn(PawnLink); if ( TestPlayer!=None && TestPlayer.Player==None && TestPlayer.PlayerReplicationInfo != None && TestPlayer.bIsPlayer && TestPlayer.PlayerReplicationInfo.PlayerName != class'PlayerReplicationInfo'.default.PlayerName ) { if ( (Level.NetMode==NM_Standalone) || (TestPlayer.PlayerReplicationInfo.PlayerName~=InName && TestPlayer.Password~=InPassword) ) { // Found matching unoccupied player, so use this one. NewPlayer = TestPlayer; break; } } } // In not found, spawn a new player. if( NewPlayer==None ) { // Make sure this kind of player is allowed. if ( (bHumansOnly || Level.bHumansOnly) && !SpawnClass.Default.bIsHuman && !ClassIsChildOf(SpawnClass, class'Spectator') ) SpawnClass = DefaultPlayerClass; NewPlayer = Spawn(SpawnClass,,,StartSpot.Location,StartSpot.Rotation); if( NewPlayer!=None ) NewPlayer.ViewRotation = StartSpot.Rotation; } // Handle spawn failure. if( NewPlayer == None ) { log("Couldn't spawn player at "$StartSpot); Error = FailedSpawnMessage; return None; } NewPlayer.static.SetMultiSkin(NewPlayer, InSkin, InFace, InTeam); // Set the player's ID. NewPlayer.PlayerReplicationInfo.PlayerID = CurrentID++; // Init player's information. NewPlayer.ClientSetRotation(NewPlayer.Rotation); if( InName=="" ) InName=DefaultPlayerName; if( Level.NetMode!=NM_Standalone || NewPlayer.PlayerReplicationInfo.PlayerName==DefaultPlayerName ) ChangeName( NewPlayer, InName, false ); // Change player's team. if ( !ChangeTeam(newPlayer, InTeam) ) { Error = FailedTeamMessage; return None; } if( NewPlayer.IsA('Spectator') && (Level.NetMode == NM_DedicatedServer) ) NumSpectators++; // Init player's administrative privileges NewPlayer.Password = InPassword; NewPlayer.bAdmin = AdminPassword!="" && caps(InPassword)==caps(AdminPassword); NewPlayer.PlayerReplicationInfo.bAdmin = NewPlayer.bAdmin; if( NewPlayer.bAdmin ) log( "Administrator logged in!" ); // Init player's replication info NewPlayer.GameReplicationInfo = GameReplicationInfo; // If we are a server, broadcast a welcome message. if( Level.NetMode==NM_DedicatedServer || Level.NetMode==NM_ListenServer ) BroadcastMessage( NewPlayer.PlayerReplicationInfo.PlayerName$EnteredMessage, false ); // Teleport-in effect. StartSpot.PlayTeleportEffect( NewPlayer, true ); // Log it. if ( LocalLog != None ) LocalLog.LogPlayerConnect(NewPlayer); if ( WorldLog != None ) WorldLog.LogPlayerConnect(NewPlayer, InChecksum); NewPlayer.ReceivedSecretChecksum = !(InChecksum ~= "NoChecksum"); if ( !NewPlayer.IsA('Spectator') ) NumPlayers++; return newPlayer; } // // Called after a successful login. This is the first place // it is safe to call replicated functions on the PlayerPawn. // event PostLogin( playerpawn NewPlayer ) { local Pawn P; // Start player's music. NewPlayer.ClientSetMusic( Level.Song, Level.SongSection, Level.CdTrack, MTRAN_Fade ); if ( Level.NetMode != NM_Standalone ) { // replicate skins for ( P=Level.PawnList; P!=None; P=P.NextPawn ) if ( P.bIsPlayer && (P != NewPlayer) ) { if ( P.bIsMultiSkinned ) NewPlayer.ClientReplicateSkins(P.MultiSkins[0], P.MultiSkins[1], P.MultiSkins[2], P.MultiSkins[3]); else NewPlayer.ClientReplicateSkins(P.Skin); if ( (P.PlayerReplicationInfo != None) && P.PlayerReplicationInfo.bWaitingPlayer && P.IsA('PlayerPawn') ) { if ( NewPlayer.bIsMultiSkinned ) PlayerPawn(P).ClientReplicateSkins(NewPlayer.MultiSkins[0], NewPlayer.MultiSkins[1], NewPlayer.MultiSkins[2], NewPlayer.MultiSkins[3]); else PlayerPawn(P).ClientReplicateSkins(NewPlayer.Skin); } } } // Set all expoit limits NewPlayer.ViewDelay = PlayerViewDelay; NewPlayer.SpeechDelay = PlayerSpeechDelay; NewPlayer.TauntDelay = PlayerTauntDelay; NewPlayer.MinFOV = Max( MinFOV, 1 ); NewPlayer.MaxFOV = Min( MaxFOV, 170 ); NewPlayer.MaxNameChanges = MaxNameChanges; } // // Add bot to game. // function bool AddBot(); function bool ForceAddBot(); // // Pawn exits. // function Logout( pawn Exiting ) { local bool bMessage; bMessage = true; if ( Exiting.IsA('PlayerPawn') ) { if ( Exiting.IsA('Spectator') ) { bMessage = false; if ( Level.NetMode == NM_DedicatedServer ) NumSpectators--; } else NumPlayers--; } if( bMessage && (Level.NetMode==NM_DedicatedServer || Level.NetMode==NM_ListenServer) ) BroadcastMessage( Exiting.PlayerReplicationInfo.PlayerName$LeftMessage, false ); if ( LocalLog != None ) LocalLog.LogPlayerDisconnect(Exiting); if ( WorldLog != None ) WorldLog.LogPlayerDisconnect(Exiting); } // // 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) local inventory inv; // Initialize the inventory. AddDefaultInventory( PlayerPawn ); log( "All inventory from" @ PlayerPawn.PlayerReplicationInfo.PlayerName @ "is accepted" ); } // // Spawn any default inventory for the player. // function AddDefaultInventory( pawn PlayerPawn ) { local Weapon newWeapon; local class WeapClass; PlayerPawn.JumpZ = PlayerPawn.Default.JumpZ * PlayerJumpZScaling(); if( PlayerPawn.IsA('Spectator') ) return; // Spawn default weapon. WeapClass = BaseMutator.MutatedDefaultWeapon(); if( (WeapClass!=None) && (PlayerPawn.FindInventoryType(WeapClass)==None) ) { newWeapon = Spawn(WeapClass,,,PlayerPawn.Location); if( newWeapon != None ) { newWeapon.Instigator = PlayerPawn; newWeapon.BecomeItem(); PlayerPawn.AddInventory(newWeapon); newWeapon.BringUp(); newWeapon.GiveAmmo(PlayerPawn); newWeapon.SetSwitchPriority(PlayerPawn); newWeapon.WeaponSet(PlayerPawn); } } BaseMutator.ModifyPlayer(PlayerPawn); } // // Return the 'best' player start for this player to start from. // Re-implement for each game type. // function NavigationPoint FindPlayerStart( Pawn Player, optional byte InTeam, optional string incomingName ) { local PlayerStart Dest; local Teleporter Tel; if( incomingName!="" ) foreach AllActors( class 'Teleporter', Tel ) if( string(Tel.Tag)~=incomingName ) return Tel; foreach AllActors( class 'PlayerStart', Dest ) if( Dest.bSinglePlayerStart && Dest.bEnabled ) return Dest; // if none, check for any that aren't enabled log("WARNING: All single player starts were disabled - picking one anyway!"); foreach AllActors( class 'PlayerStart', Dest ) if( Dest.bSinglePlayerStart ) return Dest; log( "No single player start found" ); return None; } // // Restart a player. // function bool RestartPlayer( pawn aPlayer ) { local NavigationPoint startSpot; local bool foundStart; if( bRestartLevel && Level.NetMode!=NM_DedicatedServer && Level.NetMode!=NM_ListenServer ) return true; startSpot = FindPlayerStart(aPlayer, 255); if( startSpot == None ) { log(" Player start not found!!!"); return false; } foundStart = aPlayer.SetLocation(startSpot.Location); if( foundStart ) { startSpot.PlayTeleportEffect(aPlayer, true); aPlayer.SetRotation(startSpot.Rotation); aPlayer.ViewRotation = aPlayer.Rotation; aPlayer.Acceleration = vect(0,0,0); aPlayer.Velocity = vect(0,0,0); aPlayer.Health = aPlayer.Default.Health; aPlayer.SetCollision( true, true, true ); aPlayer.ClientSetLocation( startSpot.Location, startSpot.Rotation ); aPlayer.bHidden = false; aPlayer.DamageScaling = aPlayer.Default.DamageScaling; aPlayer.SoundDampening = aPlayer.Default.SoundDampening; AddDefaultInventory(aPlayer); } else log(startspot$" Player start not useable!!!"); return foundStart; } // // Start a player. // function StartPlayer(PlayerPawn Other) { if( Level.NetMode==NM_DedicatedServer || Level.NetMode==NM_ListenServer || !bRestartLevel ) Other.GotoState(Other.PlayerRestartState); else Other.ClientTravel( "?restart", TRAVEL_Relative, false ); } //------------------------------------------------------------------------------ // Level death message functions. function Killed( pawn Killer, pawn Other, name damageType ) { local String Message, KillerWeapon, OtherWeapon; local bool bSpecialDamage; if (Other.bIsPlayer) { if ( (Killer != None) && (!Killer.bIsPlayer) ) { Message = Killer.KillMessage(damageType, Other); BroadcastMessage( Message, false, 'DeathMessage'); if ( LocalLog != None ) LocalLog.LogSuicide(Other, DamageType, None); if ( WorldLog != None ) WorldLog.LogSuicide(Other, DamageType, None); return; } if ( (DamageType == 'SpecialDamage') && (SpecialDamageString != "") ) { BroadcastMessage( ParseKillMessage( Killer.PlayerReplicationInfo.PlayerName, Other.PlayerReplicationInfo.PlayerName, Killer.Weapon.ItemName, SpecialDamageString ), false, 'DeathMessage'); bSpecialDamage = True; } Other.PlayerReplicationInfo.Deaths += 1; if ( (Killer == Other) || (Killer == None) ) { // Suicide if (damageType == '') { if ( LocalLog != None ) LocalLog.LogSuicide(Other, 'Unknown', Killer); if ( WorldLog != None ) WorldLog.LogSuicide(Other, 'Unknown', Killer); } else { if ( LocalLog != None ) LocalLog.LogSuicide(Other, damageType, Killer); if ( WorldLog != None ) WorldLog.LogSuicide(Other, damageType, Killer); } if (!bSpecialDamage) { if ( damageType == 'Fell' ) BroadcastLocalizedMessage(DeathMessageClass, 2, Other.PlayerReplicationInfo, None); else if ( damageType == 'Eradicated' ) BroadcastLocalizedMessage(DeathMessageClass, 3, Other.PlayerReplicationInfo, None); else if ( damageType == 'Drowned' ) BroadcastLocalizedMessage(DeathMessageClass, 4, Other.PlayerReplicationInfo, None); else if ( damageType == 'Burned' ) BroadcastLocalizedMessage(DeathMessageClass, 5, Other.PlayerReplicationInfo, None); else if ( damageType == 'Corroded' ) BroadcastLocalizedMessage(DeathMessageClass, 6, Other.PlayerReplicationInfo, None); else if ( damageType == 'Mortared' ) BroadcastLocalizedMessage(DeathMessageClass, 7, Other.PlayerReplicationInfo, None); else BroadcastLocalizedMessage(DeathMessageClass, 1, Other.PlayerReplicationInfo, None); } } else { if ( Killer.bIsPlayer ) { KillerWeapon = "None"; if (Killer.Weapon != None) KillerWeapon = Killer.Weapon.ItemName; OtherWeapon = "None"; if (Other.Weapon != None) OtherWeapon = Other.Weapon.ItemName; if ( Killer.PlayerReplicationInfo.Team == Other.PlayerReplicationInfo.Team ) { if ( LocalLog != None ) LocalLog.LogTeamKill( Killer.PlayerReplicationInfo.PlayerID, Other.PlayerReplicationInfo.PlayerID, KillerWeapon, OtherWeapon, damageType ); if ( WorldLog != None ) WorldLog.LogTeamKill( Killer.PlayerReplicationInfo.PlayerID, Other.PlayerReplicationInfo.PlayerID, KillerWeapon, OtherWeapon, damageType ); } else { if ( LocalLog != None ) LocalLog.LogKill( Killer.PlayerReplicationInfo.PlayerID, Other.PlayerReplicationInfo.PlayerID, KillerWeapon, OtherWeapon, damageType ); if ( WorldLog != None ) WorldLog.LogKill( Killer.PlayerReplicationInfo.PlayerID, Other.PlayerReplicationInfo.PlayerID, KillerWeapon, OtherWeapon, damageType ); } if (!bSpecialDamage && (Other != None)) { BroadcastRegularDeathMessage(Killer, Other, damageType); } } } } ScoreKill(Killer, Other); } function BroadcastRegularDeathMessage(pawn Killer, pawn Other, name damageType) { BroadcastLocalizedMessage(DeathMessageClass, 0, Killer.PlayerReplicationInfo, Other.PlayerReplicationInfo, Killer.Weapon.Class); } // %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 WeaponName, string DeathMessage ); function ScoreKill(pawn Killer, pawn Other) { Other.DieCount++; if( (killer == Other) || (killer == None) ) Other.PlayerReplicationInfo.Score -= 1; else if ( killer != None ) { killer.killCount++; if ( killer.PlayerReplicationInfo != None ) killer.PlayerReplicationInfo.Score += 1; } BaseMutator.ScoreKill(Killer, Other); } // // Default death message. // static function string KillMessage( name damageType, pawn Other ) { return " died."; } //------------------------------------------------------------------------------------- // Level gameplay modification. // // Return whether Viewer is allowed to spectate from the // point of view of ViewTarget. // function bool CanSpectate( pawn Viewer, actor ViewTarget ) { return true; } function RegisterDamageMutator(Mutator M) { M.NextDamageMutator = DamageMutator; DamageMutator = M; } function RegisterMessageMutator(Mutator M) { M.NextMessageMutator = MessageMutator; MessageMutator = M; } // // Use reduce damage for teamplay modifications, etc. // function int ReduceDamage( int Damage, name DamageType, pawn injured, pawn instigatedBy ) { if( injured.Region.Zone.bNeutralZone ) return 0; return Damage; } // // Award a score to an actor. // function ScoreEvent( name EventName, actor EventActor, pawn InstigatedBy ) { } // // Return whether an item should respawn. // function bool ShouldRespawn( actor Other ) { if( Level.NetMode == NM_StandAlone ) return false; return Inventory(Other)!=None && Inventory(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, Inventory item ) { local Mutator M; local byte bAllowPickup; if ( BaseMutator.HandlePickupQuery(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 ) { local actor dropped; local inventory Inv; local weapon weap; local float speed; if( Other.DropWhenKilled != None ) { dropped = Spawn(Other.DropWhenKilled,,,Other.Location); Inv = Inventory(dropped); if ( Inv != None ) { Inv.RespawnTime = 0.0; //don't respawn Inv.BecomePickup(); } if ( dropped != None ) { dropped.RemoteRole = ROLE_DumbProxy; dropped.SetPhysics(PHYS_Falling); dropped.bCollideWorld = true; dropped.Velocity = Other.Velocity + VRand() * 280; } if ( Inv != None ) Inv.GotoState('PickUp', 'Dropped'); } if( (Other.Weapon!=None) && (Other.Weapon.Class!=Level.Game.BaseMutator.MutatedDefaultWeapon()) && Other.Weapon.bCanThrow ) { speed = VSize(Other.Velocity); weap = Other.Weapon; if (speed != 0) weap.Velocity = Normal(Other.Velocity/speed + 0.5 * VRand()) * (speed + 280); else { weap.Velocity.X = 0; weap.Velocity.Y = 0; weap.Velocity.Z = 0; } Other.TossWeapon(); if ( weap.PickupAmmoCount == 0 ) weap.PickupAmmoCount = 1; } Other.Weapon = None; Other.SelectedItem = None; for( Inv=Other.Inventory; Inv!=None; Inv=Inv.Inventory ) Inv.Destroy(); } // Return the player jumpZ scaling for this gametype function float PlayerJumpZScaling() { return 1.0; } // // Try to change a player's name. // function ChangeName( Pawn Other, coerce string S, bool bNameChange ) { if( S == "" ) return; if (LocalLog != None) LocalLog.LogNameChange(Other); if (WorldLog != None) WorldLog.LogNameChange(Other); Other.PlayerReplicationInfo.PlayerName = S; if( bNameChange ) Other.ClientMessage( NameChangedMessage $ Other.PlayerReplicationInfo.PlayerName ); } // // Return whether a team change is allowed. // function bool ChangeTeam(Pawn Other, int N) { Other.PlayerReplicationInfo.Team = N; if (LocalLog != None) LocalLog.LogTeamChange(Other); if (WorldLog != None) WorldLog.LogTeamChange(Other); return true; } // // Play an inventory respawn effect. // function float PlaySpawnEffect( inventory Inv ) { return 0.3; } // // Generate a player killled message. // static function string PlayerKillMessage( name damageType, PlayerReplicationInfo Other ) { local string message; message = " was killed by "; return message; } // // Generate a killed by creature message. // static function string CreatureKillMessage( name damageType, pawn Other ) { return " was killed by a "; } // // Send a player to a URL. // function SendPlayer( PlayerPawn aPlayer, string URL ) { aPlayer.ClientTravel( URL, TRAVEL_Relative, true ); } // // Play a teleporting special effect. // function PlayTeleportEffect( actor Incoming, bool bOut, bool bSound); // // Restart the game. // function RestartGame() { Level.ServerTravel( "?Restart", false ); } // // Whether players are allowed to broadcast messages now. // function bool AllowsBroadcast( actor broadcaster, int Len ) { local PlayerPawn P; P = PlayerPawn(BroadCaster); if ( P != None ) { // prevent message spamming if ( (Level.TimeSeconds - P.LastMessageWindow < 20) && (Level.TimeSeconds > 20) ) return false; P.LastMessageWindow = 0.75 * P.LastMessageWindow + 0.25 * Level.TimeSeconds; } SentText += Len; return (SentText < 260); } // // End of game. // function EndGame( string Reason ) { local actor A; local Mutator M; // don't end game if not really ready // mutator can set bOverTime if doesn't want game to end if ( !BaseMutator.HandleEndGame() && !SetEndCams(Reason) ) { bOverTime = true; return; } bGameEnded = true; foreach AllActors(class'Actor', A, 'EndGame') A.trigger(self, none); if (LocalLog != None) { LocalLog.LogGameEnd(Reason); LocalLog.StopLog(); if (bBatchLocal) LocalLog.ExecuteSilentLogBatcher(); LocalLog.Destroy(); LocalLog = None; } if (WorldLog != None) { WorldLog.LogGameEnd(Reason); WorldLog.StopLog(); WorldLog.ExecuteWorldLogBatcher(); WorldLog.Destroy(); WorldLog = None; } } function bool SetEndCams(string Reason) { local pawn aPawn; for ( aPawn=Level.PawnList; aPawn!=None; aPawn=aPawn.NextPawn ) if ( aPawn.bIsPlayer ) { aPawn.GotoState('GameEnded'); aPawn.ClientGameEnded(); } return true; } w4w4w4s oNB G6N:Z*:$(Wr46"*$r46"u*(U 46"u:B :$H%H%{99q!WU RH%3:B :$ H%H%0{9U t 99q!WH%:B :$ :B :$%u}9%99}9&H%U I9' w4HB//============================================================================= // Fragment. //============================================================================= class Fragment extends Projectile; var() MESH Fragments[11]; var int numFragmentTypes; var bool bFirstHit; function PostBeginPlay() { if ( Region.Zone.bDestructive ) Destroy(); else Super.PostBeginPlay(); } simulated function CalcVelocity(vector Momentum, float ExplosionSize) { Velocity = VRand()*(ExplosionSize+FRand()*150.0+100.0 + VSize(Momentum)/80); } simulated function HitWall (vector HitNormal, actor HitWall) { 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 > 50) { if (FRand()<0.5) PlaySound(ImpactSound, SLOT_None, 0.5+FRand()*0.5,, 300, 0.85+FRand()*0.3); else PlaySound(MiscSound, SLOT_None, 0.5+FRand()*0.5,, 300, 0.85+FRand()*0.3); } } auto state Flying { simulated function timer() { GoToState('Dying'); } simulated function Touch(actor Other) { if (Pawn(Other)==None) Return; if (!Pawn(Other).bIsPlayer) Destroy(); } simulated singular function ZoneChange( ZoneInfo NewZone ) { local float splashsize; local actor splash; if ( NewZone.bWaterZone ) { Velocity = 0.2 * Velocity; splashSize = 0.0005 * (250 - 0.5 * Velocity.Z); if ( Level.NetMode != NM_DedicatedServer ) { if ( NewZone.EntrySound != None ) PlaySound(NewZone.EntrySound, SLOT_Interact, splashSize); if ( NewZone.EntryActor != None ) { splash = Spawn(NewZone.EntryActor); if ( splash != None ) splash.DrawScale = 4 * splashSize; } } if (bFirstHit) { bFirstHit=False; bRotatetoDesired=True; bFixedRotationDir=False; DesiredRotation.Pitch=0; DesiredRotation.Yaw=FRand()*65536; DesiredRotation.roll=0; } RotationRate = 0.2 * RotationRate; GotoState('Dying'); } if ( NewZone.bPainZone && (NewZone.DamagePerSec > 0) ) Destroy(); } simulated function BeginState() { RandSpin(125000); if (RotationRate.Pitch>-10000&&RotationRate.Pitch<10000) RotationRate.Pitch=10000; if (RotationRate.Roll>-10000&&RotationRate.Roll<10000) RotationRate.Roll=10000; Mesh = Fragments[int(FRand()*numFragmentTypes)]; if ( Level.NetMode == NM_Standalone ) LifeSpan = 20 + 40 * FRand(); SetTimer(5.0,True); } } state Dying { simulated function HitWall (vector HitNormal, actor HitWall) { 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 ( (Velocity.Z < 50) && (HitNormal.Z > 0.7) ) { SetPhysics(PHYS_none); bBounce = false; } else If (speed > 80) { if (FRand()<0.5) PlaySound(ImpactSound, SLOT_None, 0.5+FRand()*0.5,, 300, 0.85+FRand()*0.3); else PlaySound(MiscSound, SLOT_None, 0.5+FRand()*0.5,, 300, 0.85+FRand()*0.3); } } function TakeDamage( int Dam, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType) { Destroy(); } simulated function timer() { if (!PlayerCanSeeMe()) Destroy(); } simulated function BeginState() { SetTimer(1.5,True); SetCollision(true, false, false); } } w4I9@w4w4vNw4w4U w4w4q//============================================================================= // 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; // Drivers. var config class GameRenderDevice; var(Drivers) config class AudioDevice; var(Drivers) config class Console; var(Drivers) config class NetworkDevice; var(Drivers) config class Language; // Variables. var primitive Cylinder; var const client Client; var const renderbase Render; var const audiosubsystem Audio; var int TickCycles, GameCycles, ClientCycles; var(Settings) config int CacheSizeMegs; var(Settings) config bool UseSound; var(Settings) float CurrentTickRate; w4rNQ!Console entering MenuTyping w4xNMQ Console leaving MenuTyping w4nNDOADUw4pbn*RNw46"*$w46"u*46"uG:b:bH%q!W w4Z//============================================================================= // Effects, the base class of all gratuitous special effects. //============================================================================= class Effects extends Actor; var() sound EffectSound1; var() sound EffectSound2; var() bool bOnlyTriggerable; w4w4w4s {NnG2T:B+:$Nw46"*$w46"u*46"u"G:nW M:n,H%q!W' w4T//============================================================================= // Dispatcher: receives one trigger (corresponding to its name) as input, // then triggers a set of specifid events with optional delays. //============================================================================= class Dispatcher extends Triggers; #exec Texture Import File=Textures\Dispatch.pcx Name=S_Dispatcher Mips=Off Flags=2 //----------------------------------------------------------------------------- // Dispatcher variables. var() name OutEvents[8]; // Events to generate. var() float OutDelays[8]; // Relative delays before generating events. var int i; // Internal counter. //============================================================================= // Dispatcher logic. // // When dispatcher is triggered... // function Trigger( actor Other, pawn EventInstigator ) { Instigator = EventInstigator; gotostate('Dispatch'); } // // Dispatch events. // state Dispatch { Begin: disable('Trigger'); for( i=0; iEw|"*|"YZROEq-M)|-u |@-N)w|L*w|Lb*|Lb z VZROE  w4w4w4EOqUW -x  -x '-Y' w4HOj]W -x  -x (F  w4IOxF khXx46A^ x$R M Z^ ?%j mj ?~ ^ ipS~ _#q^ ]#d#qea#qd ]qj `#.46  ii-G_ppppppppppppqj  Unreal 46c, , qe Min, , qd  Max, , y _ LNCBm@KO\sLPԝX ~Aw4w4O4//============================================================================= // DemoRecSpectator - spectator for demo recordings to replicate ClientMessages //============================================================================= class DemoRecSpectator extends MessagingSpectator; var PlayerPawn PlaybackActor; var GameReplicationInfo PlaybackGRI; function ClientMessage( coerce string S, optional name Type, optional bool bBeep ) { RepClientMessage( S, Type, bBeep ); } function TeamMessage( PlayerReplicationInfo PRI, coerce string S, name Type, optional bool bBeep ) { RepTeamMessage( PRI, S, Type ); } function ClientVoiceMessage(PlayerReplicationInfo Sender, PlayerReplicationInfo Recipient, name messagetype, byte messageID) { RepClientVoiceMessage(Sender, Recipient, messagetype, messageID); } function ReceiveLocalizedMessage( class Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ) { RepReceiveLocalizedMessage( Message, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject ); } //==== Called during demo playback ============================================ simulated function Tick(float Delta) { local PlayerPawn p; local GameReplicationInfo g; // find local playerpawn and attach. if(Level.NetMode == NM_Client) { if(PlaybackActor == None) { foreach AllActors(class'PlayerPawn', p) { if( p.Player.IsA('Viewport') ) { PlaybackActor = p; if(PlaybackGRI != None) PlaybackActor.GameReplicationInfo = PlaybackGRI; Log("Attached to player "$p); break; } } } if(PlaybackGRI == None) { foreach AllActors(class'GameReplicationInfo', g) { PlaybackGRI = g; if(PlaybackActor != None) PlaybackActor.GameReplicationInfo = PlaybackGRI; break; } } if(PlaybackActor != None && PlaybackGRI != None) Disable('Tick'); } else { Disable('Tick'); } } simulated function RepClientMessage( coerce string S, optional name Type, optional bool bBeep ) { if(PlaybackActor != None && PlaybackActor.Role == ROLE_Authority) PlaybackActor.ClientMessage( S, Type, bBeep ); } simulated function RepTeamMessage( PlayerReplicationInfo PRI, coerce string S, name Type ) { if(PlaybackActor != None && PlaybackActor.Role == ROLE_Authority) PlaybackActor.TeamMessage( PRI, S, Type ); } simulated function RepClientVoiceMessage(PlayerReplicationInfo Sender, PlayerReplicationInfo Recipient, name messagetype, byte messageID) { if(PlaybackActor != None && PlaybackActor.Role == ROLE_Authority) PlaybackActor.ClientVoiceMessage(Sender, Recipient, messagetype, messageID); } simulated function RepReceiveLocalizedMessage( class Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ) { if(PlaybackActor != None && PlaybackActor.Role == ROLE_Authority) PlaybackActor.ReceiveLocalizedMessage( Message, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject ); } replication { reliable if ( bDemoRecording ) RepClientMessage, RepTeamMessage, RepClientVoiceMessage, RepReceiveLocalizedMessage; } GLO\0Ug -^ 6MOT%G o++++++++P+\R@G++Vw4w4c_//============================================================================= // Decoration. //============================================================================= class Decoration extends Actor abstract native; // If set, the pyrotechnic or explosion when item is damaged. var() class EffectWhenDestroyed; var() bool bPushable; var() bool bOnlyTriggerable; var bool bSplash; var bool bBobbing; var bool bWasCarried; var() sound PushSound; var const int numLandings; // Used by engine physics. var() class contents; var() class content2; var() class content3; var() sound EndPushSound; var bool bPushSoundPlaying; simulated function FollowHolder(Actor Other); function Drop(vector newVel); function Landed(vector HitNormall) { if( bWasCarried && !SetLocation(Location) ) { if( Instigator!=None && (VSize(Instigator.Location - Location) < CollisionRadius + Instigator.CollisionRadius) ) SetLocation(Instigator.Location); TakeDamage( 1000, Instigator, Location, Vect(0,0,1)*900,'exploded' ); } bWasCarried = false; bBobbing = false; } singular function ZoneChange( ZoneInfo NewZone ) { local float splashsize; local actor splash; if( NewZone.bWaterZone ) { if( bSplash && !Region.Zone.bWaterZone && Mass<=Buoyancy && ((Abs(Velocity.Z) < 100) || (Mass == 0)) && (FRand() < 0.05) && !PlayerCanSeeMe() ) { bSplash = false; SetPhysics(PHYS_None); } else if( !Region.Zone.bWaterZone && (Velocity.Z < -200) ) { // Else play a splash. splashSize = FClamp(0.0001 * Mass * (250 - 0.5 * FMax(-600,Velocity.Z)), 1.0, 3.0 ); if( NewZone.EntrySound != None ) PlaySound(NewZone.EntrySound, SLOT_Interact, splashSize); if( NewZone.EntryActor != None ) { splash = Spawn(NewZone.EntryActor); if ( splash != None ) splash.DrawScale = splashSize; } } bSplash = true; } else if( Region.Zone.bWaterZone && (Buoyancy > Mass) ) { bBobbing = true; if( Buoyancy > 1.1 * Mass ) Buoyancy = 0.95 * Buoyancy; // waterlog else if( Buoyancy > 1.03 * Mass ) Buoyancy = 0.99 * Buoyancy; } if( NewZone.bPainZone && (NewZone.DamagePerSec > 0) ) TakeDamage(100, None, location, vect(0,0,0), NewZone.DamageType); } function Trigger( actor Other, pawn EventInstigator ) { Instigator = EventInstigator; TakeDamage( 1000, Instigator, Location, Vect(0,0,1)*900,'exploded' ); } singular function BaseChange() { local float decorMass, decorMass2; decormass= FMax(1, Mass); bBobbing = false; if( Velocity.Z < -500 ) TakeDamage( (1-Velocity.Z/30),Instigator,Location,vect(0,0,0) , 'crushed'); if( (base == None) && (bPushable || IsA('Carcass')) && (Physics == PHYS_None) ) SetPhysics(PHYS_Falling); else if( (Pawn(base) != None) && (Pawn(Base).CarriedDecoration != self) ) { Base.TakeDamage( (1-Velocity.Z/400)* decormass/Base.Mass,Instigator,Location,0.5 * Velocity , '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 ) { decorMass2 = FMax(Decoration(Base).Mass, 1); Base.TakeDamage((1 - decorMass/decorMass2 * Velocity.Z/30), Instigator, Location, 0.2 * Velocity, 'stomped'); Velocity.Z = 100; if (FRand() < 0.5) Velocity.X += 70; else Velocity.Y += 70; SetPhysics(PHYS_Falling); } else instigator = None; } function Destroyed() { local actor dropped, A; local class tempClass; if( (Pawn(Base) != None) && (Pawn(Base).CarriedDecoration == self) ) Pawn(Base).DropDecoration(); if( (Contents!=None) && !Level.bStartup ) { tempClass = Contents; if (Content2!=None && FRand()<0.3) tempClass = Content2; if (Content3!=None && FRand()<0.3) tempClass = Content3; dropped = Spawn(tempClass); dropped.RemoteRole = ROLE_DumbProxy; dropped.SetPhysics(PHYS_Falling); dropped.bCollideWorld = true; if ( inventory(dropped) != None ) inventory(dropped).GotoState('Pickup', 'Dropped'); } if( Event != '' ) foreach AllActors( class 'Actor', A, Event ) A.Trigger( Self, None ); if ( bPushSoundPlaying ) PlaySound(EndPushSound, SLOT_Misc,0.0); Super.Destroyed(); } simulated function skinnedFrag(class FragType, texture FragSkin, vector Momentum, float DSize, int NumFrags) { local int i; local actor A, Toucher; local Fragment s; if ( bOnlyTriggerable ) return; if (Event!='') foreach AllActors( class 'Actor', A, Event ) A.Trigger( Toucher, pawn(Toucher) ); if ( Region.Zone.bDestructive ) { Destroy(); return; } for (i=0 ; i FragType, vector Momentum, float DSize, int NumFrags) { local int i; local actor A, Toucher; local Fragment s; if ( bOnlyTriggerable ) return; if (Event!='') foreach AllActors( class 'Actor', A, Event ) A.Trigger( Toucher, pawn(Toucher) ); if ( Region.Zone.bDestructive ) { Destroy(); return; } for (i=0 ; i 40) ) { bBobbing = false; 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,0.25); bPushSoundPlaying = True; } else Velocity.Z = oldZ; SetPhysics(PHYS_Falling); SetTimer(0.3,False); Instigator = Pawn(Other); } } w4E class Decal expands Actor native; // properties var int MultiDecalLevel; var float LastRenderedTime; // native stuff. var const array SurfList; simulated native function Texture AttachDecal( float TraceDistance, optional vector DecalDir ); // trace forward and attach this decal to surfaces. simulated native function DetachDecal(); // detach this decal from all surfaces. simulated event PostBeginPlay() { AttachToSurface(); } simulated function AttachToSurface() { if(AttachDecal(100) == None) // trace 100 units ahead in direction of current rotation Destroy(); } simulated event Destroyed() { DetachDecal(); Super.Destroyed(); } event Update(Actor L); w4JOuYM[u46A;-Mjq-M(-Y-Y(R u$M K R o R ~ %o %ed J du$K d?M do u$o %K u$ ~ o u$o ?&J?o u$o e?% JeeJJd d Jo %o u$K u$ w4B //============================================================================= // DamageType, the base class of all damagetypes. // this and its subclasses are never spawned, just used as information holders //============================================================================= class DamageType extends Actor abstract; // Description of a type of damage. var() localized string Name; // Description of damage. var() localized string AltName; // Alternative description. var() float ViewFlash; // View flash to play. var() vector ViewFog; // View fog to play. var() class DamageEffect; // Special effect. static function string DeathMessage() { if( FRand() < 0.5 ) return Default.Name; else return Default.AltName; } QOnKi3RO^ԝXs]killedw4w4PO^UE`^yp%6^k=,6^k=,6^k=,W]q?~ 46A$R M Eu%qJ^aWv F^0L^wv >^f^aW^aEv F^7L^wv >^fF^aE w4l"//============================================================================= // Counter: waits until it has been triggered 'NumToCount' times, and then // it sends Trigger/UnTrigger events to actors whose names match 'EventName'. //============================================================================= class Counter extends Triggers; #exec Texture Import File=Textures\Counter.pcx Name=S_Counter Mips=Off Flags=2 //----------------------------------------------------------------------------- // Counter variables. var() byte NumToCount; // Number to count down from. var() bool bShowMessage; // Display count message? var() localized string CountMessage; // Human readable count message. var() localized string CompleteMessage; // Completion message. var byte OriginalNum; // Number to count at startup time. //----------------------------------------------------------------------------- // Counter functions. // // Init for play. // function BeginPlay() { OriginalNum = NumToCount; } // // Reset the counter. // function Reset() { NumToCount = OriginalNum; } // // Counter was triggered. // function Trigger( actor Other, pawn EventInstigator ) { local string S; local string Num; local int i; local actor A; if( NumToCount > 0 ) { if( --NumToCount == 0 ) { // Trigger all matching actors. if( bShowMessage && CompleteMessage != "" ) EventInstigator.ClientMessage( CompleteMessage ); if( Event != '' ) foreach AllActors( class 'Actor', A, Event ) A.Trigger( Other, EventInstigator ); } else if( bShowMessage && CountMessage != "" ) { // Still counting down. switch( NumToCount ) { case 1: Num="one"; break; case 2: Num="two"; break; case 3: Num="three"; break; case 4: Num="four"; break; case 5: Num="five"; break; case 6: Num="six"; break; default: Num=string(NumToCount); break; } S = CountMessage; while( InStr(S, "%i") >= 0 ) { i = InStr(S, "%i"); S = Left(S,i) $ Num $ Mid(S,i+2); } EventInstigator.ClientMessage( S ); } } } w4j//============================================================================= // Console: A player console, associated with a viewport. // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class Console extends Object native noexport transient; // Imports. #exec Texture Import NAME=ConsoleBack File=Textures\Console.pcx #exec Texture Import File=Textures\Border.pcx // Internal. var private const int vtblOut; // Constants. const MaxBorder=6; const MaxLines=64; const MaxHistory=16; const TextMsgSize=128; // Variables. var viewport Viewport; var int HistoryTop, HistoryBot, HistoryCur; var string TypedStr, History[16]; var int Scrollback, NumLines, TopLine, TextLines; var float MsgTime, MsgTickTime; var string MsgText[64]; var name MsgType[64]; var PlayerReplicationInfo MsgPlayer[64]; var float MsgTick[64]; var int BorderSize; var int ConsoleLines, BorderLines, BorderPixels; var float ConsolePos, ConsoleDest; var float FrameX, FrameY; var texture ConBackground, Border; var bool bNoStuff, bTyping; var bool bNoDrawWorld; // Timedemo var bool bTimeDemo; var bool bStartTimeDemo; var bool bRestartTimeDemo; var bool bSaveTimeDemoToFile; var float StartTime; var float ExtraTime; var float LastFrameTime; var float LastSecondStartTime; var int FrameCount; var int LastSecondFrameCount; var float MinFPS; var float MaxFPS; var float LastSecFPS; var Font TimeDemoFont; var localized string LoadingMessage; var localized string SavingMessage; var localized string ConnectingMessage; var localized string PausedMessage; var localized string PrecachingMessage; var localized string FrameRateText; var localized string AvgText; var localized string LastSecText; var localized string MinText; var localized string MaxText; var localized string fpsText; var localized string SecondsText; var localized string FramesText; //----------------------------------------------------------------------------- // 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_UnknownB9 ,IK_Semicolon ,IK_Equals , /*BC*/ IK_Comma ,IK_Minus ,IK_Period ,IK_Slash , /*C0*/ IK_Tilde ,IK_UnknownC1 ,IK_UnknownC2 ,IK_UnknownC3 , /*C4*/ IK_UnknownC4 ,IK_UnknownC5 ,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_JoyX ,IK_JoyY ,IK_JoyZ ,IK_JoyR , /*E4*/ IK_MouseX ,IK_MouseY ,IK_MouseZ ,IK_MouseW , /*E8*/ IK_JoyU ,IK_JoyV ,IK_UnknownEA ,IK_UnknownEB , /*EC*/ IK_MouseWheelUp ,IK_MouseWheelDown,IK_Unknown10E,UK_Unknown10F , /*F0*/ IK_UnknownF0 ,IK_UnknownF1 ,IK_UnknownF2 ,IK_UnknownF3 , /*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 }; //----------------------------------------------------------------------------- // natives. // Execute a command on this console. native function bool ConsoleCommand( coerce string S ); native function SaveTimeDemo( string S ); //----------------------------------------------------------------------------- // Exec functions accessible from the console and key bindings. // Begin typing a command on the console. exec function Type() { TypedStr=""; GotoState( 'Typing' ); } exec function Talk() { TypedStr="Say "; bNoStuff = true; GotoState( 'Typing' ); } exec function TeamTalk() { TypedStr="TeamSay "; bNoStuff = true; GotoState( 'Typing' ); } // Size the view up. exec function ViewUp() { BorderSize = Clamp( BorderSize-1, 0, MaxBorder ); } // Size the view down. exec function ViewDown() { BorderSize = Clamp( BorderSize+1, 0, MaxBorder ); } //----------------------------------------------------------------------------- // Member Access Functions. function string GetMsgText( int Index ) { return MsgText[Index]; } function SetMsgText( int Index, string NewMsgText ) { MsgText[Index] = NewMsgText; } function name GetMsgType(int Index) { return MsgType[Index]; } function SetMsgType(int Index, name NewMsgType) { MsgType[Index] = NewMsgType; } function PlayerReplicationInfo GetMsgPlayer(int Index) { return MsgPlayer[Index]; } function SetMsgPlayer(int Index, PlayerReplicationInfo NewMsgPlayer) { MsgPlayer[Index] = NewMsgPlayer; } function float GetMsgTick(int Index) { return MsgTick[Index]; } function SetMsgTick(int Index, int NewMsgTick) { MsgTick[Index] = NewMsgTick; } //----------------------------------------------------------------------------- // Functions. // Clear messages. function ClearMessages() { local int i; for (i=0; i ConsoleDest ) ConsolePos = FMax(ConsolePos-Delta,ConsoleDest); // Update status message. if( ((MsgTime-=Delta) <= 0.0) && (TextLines > 0) ) TextLines--; } // Called before rendering the world view. event PreRender( canvas C ); // Called when video settings change (resolution, driver, color depth). event VideoChange(); event NotifyLevelChange() { bRestartTimeDemo = True; ClearMessages(); } event ConnectFailure( string FailCode, string URL ); function DrawLevelAction( canvas C ) { local string BigMessage; if ( (Viewport.Actor.Level.Pauser != "") && (Viewport.Actor.Level.LevelAction == LEVACT_None) ) { C.Font = C.MedFont; BigMessage = PausedMessage; // Add pauser name? PrintActionMessage(C, BigMessage); return; } if ( (Viewport.Actor.Level.LevelAction == LEVACT_None) || Viewport.Actor.bShowMenu ) { BigMessage = ""; return; } else if ( Viewport.Actor.Level.LevelAction == LEVACT_Loading ) BigMessage = LoadingMessage; else if ( Viewport.Actor.Level.LevelAction == LEVACT_Saving ) BigMessage = SavingMessage; else if ( Viewport.Actor.Level.LevelAction == LEVACT_Connecting ) BigMessage = ConnectingMessage; else if ( Viewport.Actor.Level.LevelAction == LEVACT_Precaching ) BigMessage = PrecachingMessage; if ( BigMessage != "" ) { C.Style = 1; C.Font = C.LargeFont; PrintActionMessage(C, BigMessage); } } function PrintActionMessage( Canvas C, string BigMessage ) { local float XL, YL; C.bCenter = false; C.StrLen( BigMessage, XL, YL ); C.SetPos(FrameX/2 - XL/2, FrameY/2 - YL/2); C.DrawText( BigMessage, false ); } // Add localization to hardcoded strings!! // Called after rendering the world view. event PostRender( canvas C ) { local int YStart, YEnd, Y, I, J, Line, iLine; if(bNoDrawWorld) { C.SetPos(0,0); C.DrawPattern( Texture'Border', C.ClipX, C.ClipY, 1.0 ); } if( bTimeDemo ) { TimeDemoCalc(); TimeDemoRender( C ); } // call overridable "level action" rendering code to draw the "big message" DrawLevelAction( C ); // If the console has changed since the previous frame, draw it. if ( ConsoleLines > 0 ) { C.SetOrigin(0.0, ConsoleLines - FrameY*0.6); C.SetPos(0.0, 0.0); C.DrawTile( ConBackground, FrameX, FrameY*0.6, C.CurX, C.CurY, FrameX, FrameY ); } // Draw border. if ( BorderLines > 0 || BorderPixels > 0 ) { YStart = BorderLines + ConsoleLines; YEnd = FrameY - BorderLines; if ( BorderLines > 0 ) { C.SetOrigin(0.0, 0.0); C.SetPos(0.0, 0.0); C.DrawPattern( Border, FrameX, BorderLines, 1.0 ); C.SetPos(0.0, YEnd); C.DrawPattern( Border, FrameX, BorderLines, 1.0 ); } if ( BorderPixels > 0 ) { C.SetOrigin(0.0, 0.0); C.SetPos(0.0, YStart); C.DrawPattern( Border, BorderPixels, YEnd - YStart, 1.0 ); C.SetPos( FrameX - BorderPixels, YStart ); C.DrawPattern( Border, BorderPixels, YEnd - YStart, 1.0 ); } } // Draw console text. C.SetOrigin(0.0, 0.0); if ( ConsoleLines > 0 ) DrawConsoleView( C ); else DrawSingleView( C ); } simulated function DrawConsoleView( Canvas C ) { local int Y, I, Line; local float XL, YL; // Console is visible; display console view. Y = ConsoleLines - 1; MsgText[(TopLine + 1 + MaxLines) % MaxLines] = "(>"@TypedStr; for ( I = Scrollback; I < (NumLines + 1); I++ ) { // Display all text in the buffer. Line = (TopLine + MaxLines*2 - (I-1)) % MaxLines; C.Font = C.MedFont; if (( MsgType[Line] == 'Say' ) || ( MsgType[Line] == 'TeamSay' )) C.StrLen( MsgPlayer[Line].PlayerName$":"@MsgText[Line], XL, YL ); else C.StrLen( MsgText[Line], XL, YL ); // Half-space blank lines. if ( YL == 0 ) YL = 5; Y -= YL; if ( (Y + YL) < 0 ) break; C.SetPos(4, Y); C.Font = C.MedFont; if (( MsgType[Line] == 'Say' ) || ( MsgType[Line] == 'TeamSay' )) C.DrawText( MsgPlayer[Line].PlayerName$":"@MsgText[Line], false ); else C.DrawText( MsgText[Line], false ); } } simulated function DrawSingleView( Canvas C ) { local string TypingPrompt; local int I, J; local float XL, YL; local string ShortMessages[4]; local int ExtraSpace; // Console is hidden; display single-line view. C.SetOrigin(0.0, 0.0); // Ask the HUD to deal with messages. if ( Viewport.Actor.myHUD != None && Viewport.Actor.myHUD.DisplayMessages(C) ) return; // If the HUD doesn't deal with messages, use the default behavior if (!Viewport.Actor.bShowMenu) { if ( bTyping ) { TypingPrompt = "(>"@TypedStr$"_"; C.Font = C.MedFont; C.StrLen( TypingPrompt, XL, YL ); C.SetPos( 2, FrameY - ConsoleLines - YL - 1 ); C.DrawText( TypingPrompt, false ); } } if ( TextLines > 0 && (!Viewport.Actor.bShowMenu || Viewport.Actor.bShowScores) ) { J = TopLine; I = 0; while ((I < 4) && (J >= 0)) { if ((MsgText[J] != "") && (MsgTick[J] > 0.0) && (MsgTick[J] > MsgTickTime) ) { if (MsgType[J] == 'Say') ShortMessages[I] = MsgPlayer[J]$":"@MsgText[J]; else ShortMessages[I] = MsgText[J]; I++; } else ShortMessages[I] = ""; J--; } J = 0; C.Font = C.MedFont; for ( I = 0; I < 4; I++ ) { if (ShortMessages[3 - I] != "") { C.SetPos(4, 2 + (10 * J) + (10 * ExtraSpace)); C.StrLen( ShortMessages[3 - I], XL, YL ); C.DrawText( ShortMessages[3 - I], false ); if ( YL == 18.0 ) ExtraSpace++; J++; } } } } //----------------------------------------------------------------------------- // State used while typing a command on the console. state Typing { exec function Type() { TypedStr=""; gotoState( '' ); } function bool KeyType( EInputKey Key ) { if ( bNoStuff ) { bNoStuff = false; return true; } if( Key>=0x20 && Key<0x100 && Key!=Asc("~") && Key!=Asc("`") ) { TypedStr = TypedStr $ Chr(Key); Scrollback=0; return true; } } function bool KeyEvent( EInputKey Key, EInputAction Action, FLOAT Delta ) { local string Temp; bNoStuff = false; if( Key==IK_Escape ) { if( Scrollback!=0 ) { Scrollback=0; } else if( TypedStr!="" ) { TypedStr=""; } else { ConsoleDest=0.0; GotoState( '' ); } Scrollback=0; } else if( global.KeyEvent( Key, Action, Delta ) ) { return true; } else if( Action != IST_Press ) { return false; } else if( Key==IK_Enter ) { if( Scrollback!=0 ) { Scrollback=0; } else { if( TypedStr!="" ) { // Print to console. if( ConsoleLines!=0 ) Message( None, "(>" @ TypedStr, 'Console' ); // Update history buffer. History[HistoryCur++ % MaxHistory] = TypedStr; if( HistoryCur > HistoryBot ) HistoryBot++; if( HistoryCur - HistoryTop >= MaxHistory ) HistoryTop = HistoryCur - MaxHistory + 1; // Make a local copy of the string. Temp=TypedStr; TypedStr=""; if( !ConsoleCommand( Temp ) ) Message( None, Localize("Errors","Exec","Core"), 'Console' ); Message( None, "", 'Console' ); } if( ConsoleDest==0.0 ) GotoState(''); Scrollback=0; } } else if( Key==IK_Up ) { if( HistoryCur > HistoryTop ) { History[HistoryCur % MaxHistory] = TypedStr; TypedStr = History[--HistoryCur % MaxHistory]; } Scrollback=0; } else if( Key==IK_Down ) { History[HistoryCur % MaxHistory] = TypedStr; if( HistoryCur < HistoryBot ) TypedStr = History[++HistoryCur % MaxHistory]; else TypedStr=""; Scrollback=0; } else if( Key==IK_PageUp ) { if( ++Scrollback >= MaxLines ) Scrollback = MaxLines-1; } else if( Key==IK_PageDown ) { if( --Scrollback < 0 ) Scrollback = 0; } else if( Key==IK_Backspace || Key==IK_Left ) { if( Len(TypedStr)>0 ) TypedStr = Left(TypedStr,Len(TypedStr)-1); Scrollback = 0; } return true; } function BeginState() { bTyping = true; Viewport.Actor.Typing(bTyping); } function EndState() { bTyping = false; Viewport.Actor.Typing(bTyping); //log("Console leaving Typing"); ConsoleDest=0.0; } } //----------------------------------------------------------------------------- // State used while in a menu. state Menuing { function bool KeyEvent( EInputKey Key, EInputAction Action, FLOAT Delta ) { if ( Action != IST_Press ) return false; if ( Viewport.Actor.myHUD == None || Viewport.Actor.myHUD.MainMenu == None ) return false; Viewport.Actor.myHUD.MainMenu.MenuProcessInput(Key, Action); Scrollback=0; return true; } function BeginState() { //log("Console entering Menuing"); } function EndState() { //log("Console leaving Menuing"); } } state EndMenuing { // pass all key events, not just presses function bool KeyEvent( EInputKey Key, EInputAction Action, FLOAT Delta ) { if ( Viewport.Actor.myHUD == None || Viewport.Actor.myHUD.MainMenu == None ) return false; Viewport.Actor.myHUD.MainMenu.MenuProcessInput(Key, Action); Scrollback=0; return true; } } //----------------------------------------------------------------------------- // State used while typing in a menu. state MenuTyping { function bool KeyType( EInputKey Key ) { if( Key>=0x20 && Key<0x100 && Key!=Asc("~") && Key!=Asc("`") && Key!=Asc(" ") ) { TypedStr = TypedStr $ Chr(Key); Scrollback=0; if ( (Viewport.Actor.myHUD != None) && (Viewport.Actor.myHUD.MainMenu != None) ) Viewport.Actor.myHUD.MainMenu.ProcessMenuUpdate( TypedStr ); return true; } } function bool KeyEvent( EInputKey Key, EInputAction Action, FLOAT Delta ) { local Menu PlayerMenu; if( Action != IST_Press ) return false; if( Viewport.Actor.myHUD==None || Viewport.Actor.myHUD.MainMenu==None ) return false; PlayerMenu = Viewport.Actor.myHUD.MainMenu; if( Key==IK_Escape ) { if( Scrollback!=0 ) Scrollback = 0; else if( TypedStr!="" ) TypedStr=""; else GotoState( 'Menuing' ); PlayerMenu.ProcessMenuEscape(); Scrollback=0; } else if( Key==IK_Enter ) { if( Scrollback!=0 ) Scrollback = 0; else { if( TypedStr!="" ) PlayerMenu.ProcessMenuInput( TypedStr ); TypedStr=""; GotoState( 'Menuing' ); Scrollback = 0; } } else if( Key==IK_Backspace || Key==IK_Left ) { if( Len(TypedStr)>0 ) TypedStr = Left(TypedStr,Len(TypedStr)-1); Scrollback = 0; PlayerMenu.ProcessMenuUpdate( TypedStr ); } return true; } function BeginState() { log("Console entering MenuTyping"); } function EndState() { log("Console leaving MenuTyping"); } } //----------------------------------------------------------------------------- // State used while expecting single key input in a menu. state KeyMenuing { function bool KeyType( EInputKey Key ) { ConsoleDest=0.0; if( Viewport.Actor.myHUD!=None && Viewport.Actor.myHUD.MainMenu!=None ) Viewport.Actor.myHUD.MainMenu.ProcessMenuKey( Key, Chr(Key) ); Scrollback=0; GotoState( 'Menuing' ); } function bool KeyEvent( EInputKey Key, EInputAction Action, FLOAT Delta ) { if( Action==IST_Press ) { ConsoleDest=0.0; if( Viewport.Actor.myHUD!=None && Viewport.Actor.myHUD.MainMenu!=None ) Viewport.Actor.myHUD.MainMenu.ProcessMenuKey( Key, mid(string(GetEnum(enum'EInputKey',Key)),3) ); Scrollback=0; GotoState( 'Menuing' ); return true; } } function BeginState() { //log( "Console entering KeyMenuing" ); } function EndState() { //log( "Console leaving KeyMenuing" ); } } //----------------------------------------------------------------------------- // Timedemo functions exec function TimeDemo(bool bEnabled, optional bool bSaveToFile) { bSaveTimeDemoToFile = bSaveToFile; if(bEnabled) StartTimeDemo(); else StopTimeDemo(); } function StartTimeDemo() { if(bTimeDemo) return; bTimeDemo = True; bStartTimeDemo = True; } function StopTimeDemo() { if(!bTimeDemo) return; bTimeDemo = False; PrintTimeDemoResult(); } function PrintTimeDemoResult() { local LevelInfo Entry; local float Avg; local float Delta; local string AvgString; local string Temp; Entry = Viewport.Actor.GetEntryLevel(); Delta = Entry.TimeSeconds - StartTime - ExtraTime; if(Delta <= 0) Avg = 0; else Avg = FrameCount / Delta; AvgString = string(FrameCount)@FramesText@FormatFloat(delta)@SecondsText@MinText@FormatFloat(MinFPS)@MaxText@FormatFloat(MaxFPS)@AvgText@FormatFloat(Avg)@fpsText$"."; Viewport.Actor.ClientMessage(AvgString); Log(AvgString); if(bSaveTimeDemoToFile) { Temp = FormatFloat(Avg) $ " Unreal "$ Viewport.Actor.Level.EngineVersion $ Chr(13) $ Chr(10) $ FormatFloat(MinFPS) $ " Min"$ Chr(13) $ Chr(10) $ FormatFloat(MaxFPS) $ " Max"$ Chr(13) $ Chr(10); SaveTimeDemo(Temp); } } function TimeDemoCalc() { local LevelInfo Entry; local float Delta; Entry = Viewport.Actor.GetEntryLevel(); if( bRestartTimeDemo ) { StopTimeDemo(); StartTimeDemo(); bRestartTimeDemo = False; } if( bStartTimeDemo ) { bStartTimeDemo = False; StartTime = Entry.TimeSeconds; ExtraTime = 0; LastFrameTime = StartTime; LastSecondStartTime = StartTime; FrameCount = 0; LastSecondFrameCount = 0; MinFPS = 0; MaxFPS = 0; LastSecFPS = 0; return; } Delta = Entry.TimeSeconds - LastFrameTime; // If delta time is more than a half of a second, ignore frame entirely (precaching, loading etc) if( Delta > 0.5 ) { ExtraTime += Delta; LastSecondStartTime = Entry.TimeSeconds; LastSecondFrameCount = 0; LastFrameTime = Entry.TimeSeconds; return; } FrameCount++; LastSecondFrameCount++; if( Entry.TimeSeconds - LastSecondStartTime > 1) { LastSecFPS = LastSecondFrameCount / (Entry.TimeSeconds - LastSecondStartTime); if( MinFPS == 0 || LastSecFPS < MinFPS ) MinFPS = LastSecFPS; if( LastSecFPS > MaxFPS ) MaxFPS = LastSecFPS; LastSecondFrameCount = 0; LastSecondStartTime = Entry.TimeSeconds; } LastFrameTime = Entry.TimeSeconds; } function TimeDemoRender( Canvas C ) { local string AText, LText; local float W, H; C.Font = TimeDemoFont; C.DrawColor.R = 255; C.DrawColor.G = 255; C.DrawColor.B = 255; AText = AvgText @ FormatFloat(FrameCount / (Viewport.Actor.GetEntryLevel().TimeSeconds - StartTime - ExtraTime)); LText = LastSecText @ FormatFloat(LastSecFPS); C.TextSize(AText, W, H); C.SetPos(C.ClipX - W, 0.3*C.ClipY); C.DrawText(AText); C.TextSize(LText, W, H); C.SetPos(C.ClipX - W, 0.3*C.ClipY+H); C.DrawText(LText); } final function string FormatFloat( float f) { local string s; local int i; s = string(f); i = InStr(s, "."); if(i != -1) s = Left(s, i+3); return s; } w4N%//============================================================================= // Carcass. //============================================================================= class Carcass extends Decoration native; // Sprite. #exec Texture Import File=Textures\Corpse.pcx Name=S_Corpse Mips=Off Flags=2 // Variables. var bool bPlayerCarcass; var() byte flies; var() byte rats; var() bool bReducedHeight; var bool bDecorative; var bool bSlidingCarcass; var int CumulativeDamage; var PlayerReplicationInfo PlayerOwner; var Pawn Bugs; function CreateReplacement() { if (Bugs != None) Bugs.Destroy(); } function Destroyed() { local Actor A; if (Bugs != None) Bugs.Destroy(); Super.Destroyed(); } function Initfor(actor Other) { //implemented in subclasses } function ChunkUp(int Damage) { destroy(); } static simulated function bool AllowChunk(int N, name A) { return true; } function TakeDamage( int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, name damageType) { if ( !bDecorative ) { bBobbing = false; SetPhysics(PHYS_Falling); } if ( (Physics == PHYS_None) && (Momentum.Z < 0) ) Momentum.Z *= -1; Velocity += 3 * momentum/(Mass + 200); if ( DamageType == 'shot' ) Damage *= 0.4; CumulativeDamage += Damage; if ( (((Damage > 30) || !IsAnimating()) && (CumulativeDamage > 0.8 * Mass)) || (Damage > 0.4 * Mass) || ((Velocity.Z > 150) && !IsAnimating()) ) ChunkUp(Damage); if ( bDecorative ) Velocity = vect(0,0,0); } auto state Dying { ignores TakeDamage; Begin: Sleep(0.2); GotoState('Dead'); } state Dead { function Timer() { local bool bSeen; local Pawn aPawn; local float dist; if ( Region.Zone.NumCarcasses <= Region.Zone.MaxCarcasses ) { if ( !PlayerCanSeeMe() ) Destroy(); else SetTimer(2.0, false); } else Destroy(); } function AddFliesAndRats() { } function CheckZoneCarcasses() { } function BeginState() { if ( bDecorative ) lifespan = 0.0; else SetTimer(18.0, false); } Begin: FinishAnim(); Sleep(5.0); CheckZoneCarcasses(); Sleep(7.0); if ( !bDecorative && !bHidden && !Region.Zone.bWaterZone && !Region.Zone.bPainZone ) AddFliesAndRats(); } w4P?//============================================================================= // 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; // Objects. #exec Font Import File=Textures\SmallFont.bmp Name=SmallFont #exec Font Import File=Textures\MedFont.pcx Name=MedFont #exec Font Import File=Textures\LargeFont.pcx Name=LargeFont #exec Font Import File=Textures\BigFont.pcx Name=BigFont // Modifiable properties. var font Font; // Font for DrawText. 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. // Stock fonts. var font SmallFont; // Small system font. var font MedFont; // Medium system font. var font BigFont; // Big system font. var font LargeFont; // Large system font. // Internal. var const viewport Viewport; // Viewport that owns the canvas. var const int FramePtr; // Scene frame pointer. var const int RenderPtr; // Render device pointer, only valid during UGameEngine::Draw // native functions. native(464) final function StrLen( coerce string String, out float XL, out float YL ); native(465) final function DrawText( coerce string Text, optional bool CR ); native(466) final function DrawTile( texture Tex, float XL, float YL, float U, float V, float UL, float VL ); native(467) final function DrawActor( Actor A, bool WireFrame, optional bool ClearZ ); native(468) final function DrawTileClipped( texture Tex, 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 ); native(471) final function DrawClippedActor( Actor A, bool WireFrame, int X, int Y, int XB, int YB, optional bool ClearZ ); 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 ); // UnrealScript functions. event Reset() { Font = Default.Font; 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; } 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( texture 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 ); } w4W9w4w4x @w4w4N//============================================================================= // A camera, used in UnrealEd. //============================================================================= class Camera extends PlayerPawn native; // Sprite. #exec Texture Import File=Textures\S_Camera.pcx Name=S_Camera Mips=Off Flags=2 w4L//============================================================================= // ButtonMarker. //============================================================================= class ButtonMarker extends NavigationPoint native; // OBSOLETE - TO BE REMOVED w4C@w4tS"""""̔pw4a @w4bO@     ) 2 ; C K T ] f n w                      %  .  7  @  I  R  [  d  m  s  |                   % . 7 @ H Q Z c l u ~                  & / 8 A J S \ ) 3 m) f3 /3 A ]= 3 ) ) ) B3 ) >= q= N= G= 3 [= {= h= q= ) ) ) Y= ) 3 3 3 O3   ) e 3  3 3 3 3 3 3 x3 ) 3 3 3 3 R) ) v) #= = = [) 5= = 3  )  B3   )   w    )   o3 ) .) ) ) 3 %) f= d) @) ) 7) n ,= = I) rS"""""pw4> @Y~X^wwhnmmwmwYQPXIo&QQE ))AT4444B4BT4044V,?HZt3@H@KINN3IH\scUI`UCU[J[IIIIIIIIJC[UkvՄWMWvvvu}uvv}{k]XPX~ݒۓۓY%%~~܉܈~w~X%YQQ^QX'&&&P'''_I(IIEE* *B?IA̵̳͵͵ͳ?4IA0-VT--4,44aIINZHIK@db\F3FHI@a@3sIcpC[[[GGI`cIpfJ`JCO}ùďùďu]x{}}keeOMO%YI~~Y&X2R__R 2_SSRR)jS*)SijjiSjR4I?4ABT-BTI4AL?I0FNd@KdHbqHdIKZaHIJsrIUpIps[UI[Dxuuexտx{uWv}uknwۓ%nPEE_S_S_S_SRR_S_S40A04IB/A-\@IIII3\IIHZc`cp`IUII`r}uѼekekeϼxeuď}uu~ܒ~~~%&&'_ijijiji)E_SijSE_SijI̳͵I0I0I0II}[44A04UI0L?A0I0?I\H@I3UdIK@[U[U[U[[I`[U[J`IUU[Us[[U}}}}}ϼxx{}WvkeU}}v]}PXYij_S_S_SRRYRY_S_SI0ijijSijijijI0-4I?I0I0I0I0I0[UHr[U[U[U[U[U[Uuu}ù}x}}}}}UUSYUUS2RUI4I?UUS\FNUSUU}}}ϼxUUw4eO@   + C U m          " " #" 4" E" V" g" x" " " " " " " " C C .C CC VC hC zC C C C C C C C d d +d =d Od bd td d d d d d   ! , 9 E W qS"""""pw4@(    7(    rwkrk-rwkkk- (?H(  rrkkk- >>>?zzr6zzr6 )7HT?7)// a) zzr6 7 ( UUUH̯G̯G ./HHUU?.7H77/)ͯG)7/..>7)H/.))  ?./WWWJЯЯ8J>WVJl>WWJIlWV0 VJ 8ЯHUUU>?UU? UUV/. .H/>^^^J"鯩|鯩| @K! lJ^JJ8 ^^^J^X0 KX"!0 鯩| lVWW>8WWW8W80 VJ%0 bbbY" ЩSЩSY% b"bbYK0 ۸l0lX% KX%9%&""ЩS^^^9%^^^@&lJK  ^J%%cccY"馏馏&9,Y,$ccZY"Z999&Z, KZ,9!",099@9,馏bbb@"bbb@" 9 8&"!XK%dddL,==,A:  &A; ddZ3Z: AZ,: :;LALԆA!$=ccc@"ccc@" $3A:!"Y9,eeeL32311,ALA,2123;LL,eem:2Z: Ae, :,2[eeL:eA! dddL3dddA":eL3 ZZ,, mmmN3[mfN[mmmmmf[NmN:[mmN,1m: Nm1;1[mmmA, mA2eeeL3eeeL3 ;mN3 e[,3nnfN2nfnffMM**# nf:1*:܊M*[ff55:NnnN2fnnM<mmmN3mmmN3 MnfD  mN31nnfg*MOO*5nn\<*#弊fO5_M fnnM* hfhM1nnnN<nnnN< M111D\nMD11<*+OCCCCC++2fMDsst_4OOqMO ssgD*#\st_C#C<+5CC5 sgOD_qg<nnng<nnn_< t_g__gtsssqgg54oQQQQP4+_hOO yy_4yD<yOOyyqDCqy+O)).) .7>7.//>?I>.).777>>/ a?IHIHTTTTTH? .//77// T>>>>7>>>/ //777/))../7/)/HUaaUa?7IV7/?VU.)/HUUU?HaUUUUI UUaa 7HHUUU//ҶaUU7/IIUUUU?/IVUU/JWWaWӵWWW0 8IVVWI 8JJlӶW% aJWallWWV8VWalWWV%WWWWI>88888?JWVaaWW>0088VaWW>0>VWJ>WWV88JWJWW>ҴWW% @X^^^@^^X@9@J^^^^^J" JJJK ^@^^^8^^^@%^JX^^X%^^^^8X^^X@Ӹ^K l^^@bX^^@0 ^^@l^^@0"l^^9rwkSErwkSSXbbX%bbbK&bbbY" lbK@!ԅbK&㸷9bbbK&bY@9bbX%bbbX%0lbbX%Թ8lbb@bbb@% lbbK"bb9%bbK&zzkSzzkS  cccc"cccK&ԇccY"!cK@cK,@99,cccK" Z@0"ccc,cccZ, Kccc" ,999" ccc@ccK" @ccK"cc9"ccK"ͯz-̯z-dddZ3dddL3 ddZ3 ;Z&$dA,dddZA!A&ddZ,dddd, !&!!$ LddZ" $ddZ;ddZ3 AdZA!!dd;3ddL3Яz-Яz- """&&""" eee[3eeeL3eeZ3,A,1!,meA:$$1eee[,$L[:2ee[,eee[A;AL[A;LeeZ, 1ee[: :eL:Ae[L:$1ee;3eeL3ͦGͦG&&&,;;3$,11111111111123;;,&&&mmm[3mmmA3 fmm[3[mmm;: ;;;fmN:* mN21mmf:*mmmmNmmm[;Nmmm;*111*;mm[3mf;:;N[[A$1mmA2#mmN3* 323:ALeA;*N::::::::::::A1;AeLA:323 nnn[<nnnM< Nnnh<1nnmh:2nnfN<M11nnf:*nnfտnfM1NnnfM2:MMM:1#fnf[2Mnn[NfffN<1nnN<$nnN<*2223;N[mA#<պD#Am[N;3222nnnh<nnn\< gnnh<hnnn_O$nhM1MfM5nnfO* ֿh\#nng<gnnnnM*nhg1OhnnnhO12nhO<TTTaTT?)7?IHT?.TTTTT? TTTTTTT7?TTTTTT?7).ITT>TTT??TT/TT? TTT.TTTHIaT?)TT..>?IHH7  00 WJ7VUaaaUIUUHIVVUU/>HUHUUHUUUҵUU?)UUUaaU/ ?UUUUaU/./IUUUaa.UUU??UU/ UU?UUU/UUUVHUU/)UU./IUUaU7%0   J WWaVWVWW?>IWWJ00VWWJ>WW%WWI0%lWWV>WWWW>IWW>>% J?WJJ00aIWWWJIWW8 WW?WWW8WWWJ%JWWV0WW8" 8JVWVValWW8 0&""&$l!l^^b0^"^^@8^^^8&8X^^J% ^^0 ^^@"^^^K^^^^0K^^90^^K@^0^^^J"K^^8" ^^@"^^^8^^^X8Jl^@%^^8"^^^^K8 ^^K" 9"!YcYZ9",!$,!bbXY&b%&bbY9bbb@"lXbbY"bbb8& bbK"bbbY&bbbX% Kbb8%bbK8lb8!bbbY" Kbb8" !bbK"bbb9bbbX@0Kbb0%bb8" llbb9%bbX0!:$L, Z,,:d$9ccY9c:&ccY9cccK"cccY" cc9"ccK"cccY&cccc" Kcc9"ccK99&cccY"9cc9"ccK"ccc9cccYKYYcY,!cc9&Ըc9cccK&;,e:1e:3 e2dddA; LdA&ddZA! ddLYdddY3L,!ddL3ddZ3ddd3Ldd;"!ddL;ԔY!dddd, ,ddd;3 !ddL3dddAdddZA&LZdA,$!dd;&ZAAA!dddL"N3$m2$3:1 m2Zd:3$eL2$eedL1 1[e[A;eee[3 庺[:1eeL3eeed3eeem,LeeL,1eeL;L1eeee;,:Aeee;31eeL3eeeA!eeedLLLee:3 1ee;2eeeL3M*Mf1 2D1<f[3*m[31mmmN;:;NNN:$mmmN3 1mmN31mmmf3mmmm;311*Nmm[;:2**1mmN;*mmmmN;:Afmm;31mmN3*mmmA1mmmm[[[m[:21mm;2mmmN3*\5\*5D*n<n\D$f<2nnnfMMMhNMnnnN< 1nnN<5nnnf<nnnnNMD2*Nnnn[NN:11nnNM1 nnnnnnnnnnnM<1nnN<*nnnM1nnnnnnnnN<*1nn;<nnnf<1M#D+OD+q<5nMDnO2nnnnnh\<*nnn_< 1nng<5nnnh<nnnnnnn_< gnnnnnngO1nng\<O11115nnnfnnnM<1nn_<*nnn\1nnnnnnnnh<*1nnM<  nnnh<C\#D#\D_5OsODsMC ssq_s_<4sss_< Cssg<5ssst<ssssstO gsssss\#Cssg_<_DDDD<*ssssssM<#Cssg<4sss\CsssssssstDCCssM< HHTTI)?TTHTaT?)  .7IHaH> TTTTaTH/IHHTH/TTTTTTTTTTI?TT7 TTH. TT.TTI TT>TTT/TT?. ??HI?UUUUUV ?UUUUU??UI UU? IUUIҴUU/ ?UUHa촃U/ )7UUVUUU>UUUaaӃUU/)IUVVUUӳaUI)ӳUUUaa/ ?UU>)UUH. UU/aUUU UU?  UUU/UU>. ҐV//UUU/ WWWWWV0 VWWWWW?IWW% WW>WWWWJ8WWJ0IWWV0WIVJWVV>%%WWIWWWV8 WW8 JVWJ>0I҄W?>>VWWWa>IWW>0WWJ8WW>aWWWWWI%WWW8WW>0W8 JVV?0^^^^^X9X^^^^^K"K^^8!^^K"bb^^K%^^^@K^^X%K^K" lX^J9 ^^X8^^^X% X^^K" ^^^K"^JJ^^^^0K^^@8^^X9 l^K&8^^^X% l^X% l^^^90l^^@% ӄJ0"JXX@bbbbbb@8bbbbbbK" KbbY"bbK"bbbK"bbbK&KbbY"lbK" bbK9 bbb8&bbbX"YbbY& !bbY%ԑb%bbbY% Kbb@9bbX9bX%YbbbY%bX0& 0lbbb@& @bbb9%ӓb@% 8YXX8 cccccc@9cccccK" Kccc,, ccK"cccK"cccY&KccY"cK" ccK9 ccc9"cccY" KccY" &ccZ0& ,cccY" KccK9!ccZ9cc:!ccc@" ccc9& 9cccY&$cccZ9&K9,@ccK&dddddZAddZdddL"LdddA,$ddL3dddL"dddZ&LddZ3!dL3 ddL; dddA3dddZ,LdddL, ԆddL,&$dddd3LddL;!ddZAdd:dddAAddA&ddddZ&! ddd:۔dLLZddL$eeeemee[eeeL3 LeeeZ:A$meeL3eeeL3eeeZ3 Lee[,2meL3eeL; eeeA3eeee,LeeeL1eeL,21eeee3 LeeLA1eeeA,eeA1 eed;!3eeL3 meeeee32 eeZ:$eeeeeL,mmmmm,m1[m2mmmN3 NmmmmNN:fmmN3*mmm[3mmm[3 Nmmf:$;[mmN3mmN;5 mmmA3mmmm;::fmf[AN庈mm[:1*mmmm3 NmmNA1mmfA*$mmN2mmm;**mmN3 mmmm:3 mm[:[mmmmfN1nnnn1NNf*nnnN< NnnnnfNN[nnN<*nnn[<nnnf< NnnfM::NfnfM2nnNM5 nnnM<nnnnNffnfNM$彍nnfM<5nnnn< NnnNM1nnfM*n[21nnfM$nn[: nf[f:< nn[DMnnnfM*nnnn$h_h5nnng< gnnnnnnnng<*nnnh<nnnh< gnnnhhhhnnnO1nngM5 nnn\<nnnnnf_<#hܖnnhO1$ nnn< gnn_M1nnf\*n_O5OnnhOnhO$hhgMD$nn_D DfnnnnM1ssssgsg_sssg< gsssssssg<*sssg<sssq< gssssq<#ssg\5 sss\<ssss忖q\5#NsssM5+sss< _ssgMCssq\*sq\CgssqOsqM+Cqg\\\O*ss\< \qsssg5#yyyy_ty_OyyygD qyyyqOyygD4yyyqDyyyqD qyyygggq_O*yyg\5 yyy\Dyyyq\# yqD4OޖyyOByyyD \yyg\Cyyt\4tyy\DtyyyqD yt\5Oq_D+gOD4yy\CBgyytyqO+ŽvOvPƎvQ {vPĜxQ4Ž{Q~Q {~o+ŽxoB ŽvQ{OuC   ~F+Q P{o#CŽ~o4Q׎vovQŽvQo{o+#~oO+yoBO~{PyoC˜oP—vBǘvQ {oQ~{Q4˜{Q~Q {}Q#˜{oB ˜vQ~Q~P+jFFB46ؘQ+ØQ PØ{j6F˜~u4+٘{o+xPjǘ{j{xjǗxo+~o4v~~~uƘxPŘuBêu+ǘxQ }pBŞ{Q4ƞ{QØ}i}}Q'Ř{uB ŘuQØ~i}i'4xujQ6FޞoPØQ FØ}j6F˜~u4٪xP}~uPQ٘~}}~vQê~xi~o4-x~~Pؘ}j6šu6j-ơxi}i=٪}iEá{iá}i}i'Ƥ}uB šiái}i'BƤ}pE'Ϟuiái Fšj6PšoEá}}uE6ϡoPϞ}p'P}x-E桛oBɣu-i'ɣii6`ɣiEȤipi'˪` ȣ`ȣii'EϪpEiȣiEˬ6ip6ɣu='ϣuEiडpଣ`Υ|``ɥwʥw-ग़wEȬwkʥw'ɥpB-Eȥwʥw'-ȥ]rSȥw=ɥ`||-॥w-Ϭp-kᤥw|˥w'ΫzSS Ϋwʫw'ᬝwEʫ6ʫw-ΰk̫wʫw-ʫ|||6̫wʬz zᬫ`̫w'-ଫk]]ૢ|Sݮr==ݮzʮz-S̢zSʧkʮz-]ݰ|=̮zʮz'̫k̮zʮG=ᰮ]ΰkʰ]=G갮]⯯`-'䯯z̯z-zS]ͭz̯z-ͯ`گzͯz-ͰkگzگSͯSͰSͰG|ͰkrͩGzGG]󯦟Щ'G6͟66ЏGͰ=G͏6kͭݩkکzSG-ѭS6GGG-    /  ( (   ( 7//T?( ?77  H(((((((/H>>>/.? /H>>>/>HU)T/ TI.TTTTTTT/?UUH)>/H.UU??>WW>>U7UH.ҵUUU7IWWV0 0%JVWWI @Xl^%l>%WJ0 WWW8K^^X0 %%J^ l^^J" K@K9!K0X@%l^^X9KbbY% %KX%bbY" $K99Z&Ԇ"Y0&!bY@"bbbX9KccY" ,9Y"ccY"AL;,A!9c9::cY@!cccK9 LddL3 ,,ZZ!ddZ3$LA:1e3!$dAAAZLAZdZA"LeeL33,[e 1ee[3;N;3;1ՈLALeL: 3ee[ANmmN3 13Nm1mm[3NN:2:f21[N:[[N3[mmmN;NnnN< DMf21nn[<_h<*\<Mf[NfN\1 fnfMDgnng< OOh_1nnh<g<_sO5*܊nnnhM5ngM1gss_< OOhsCssq<#֍sssgO_ssgOqyy_D COgy#CyyqDyytg<yyyy\O{vQ +OvPCŽ~Q#vĎ~v5+~oP{vQ jj~vF˜~Qjǘ~v4Q}o+}vQQj~F˜~i'FŘ~xEvj}i Fp}'Fši'FšxEuii=p]`ɣi'`ɣE`uEʥw|rɥw'`ɥE|rS=-ʫr||]w-`ΫE`Gʮwk`|zz-`ήSʫ|kͯzkS|S|z-`ݯSݯrЯz-Яz-GͭzrаͭGSѦw4hO@  ' 3B OT[bhm    ) 4 > J V bk '  ''' $' 0' <' G'W' c' o' :  : : #: .: 9:?:F: R:[:j: M  M M $M 0M <M IM UM bM` ` ` %`,` 6`=` uS"""""Lpw4R@ % $ $  / !!                        #                                           "1   !                                                                                                         !       !""$                          !""$                                       !! !!!! !                                                                                                                           !!                                     w4m//============================================================================= // 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. var() scale MainScale; var() scale PostScale; var scale TempScale; // Information. var() color BrushColor; var() int PolyFlags; var() bool bColored; w4h//============================================================================= // BlockPlayers prevents players from passing, but allows monsters and projectiles to cross. //============================================================================= class BlockPlayer extends Keypoint; `kO|lOF`hDgw4w4k//============================================================================= // BlockMonsters prevents monsters from passing, but allows players and projectiles to cross. //============================================================================= class BlockMonsters extends Keypoint; `mOSnO\+`hD;aw4w4k//============================================================================= // Blocks all actors from passing. //============================================================================= class BlockAll extends Keypoint; `oO\pO6!`hD;agw4w4} //============================================================================= // Bitmap: An abstract bitmap. // This is a built-in Unreal class and it shouldn't be modified. //============================================================================= class Bitmap extends Object native noexport; // Texture format. var const enum ETextureFormat { TEXF_P8, TEXF_RGB32, TEXF_RGB64, TEXF_DXT1, TEXF_RGB24 } Format; // Palette. var(Texture) palette Palette; // Internal info. var const byte UBits, VBits; var const int USize, VSize; var(Texture) const int UClamp, VClamp; var const color MipZero; var const color MaxColor; var const int InternalTime[2]; w4O0//============================================================================= // Ammo. //============================================================================= class Ammo extends Pickup abstract native nativereplication; #exec Texture Import File=Textures\Ammo.pcx Name=S_Ammo Mips=Off Flags=2 var() travel int AmmoAmount; var() travel int MaxAmmo; var() class ParentAmmo; // Class of ammo to be represented in inventory var() byte UsedInWeaponSlot[10]; var ammo PAmmo; // Network replication // replication { // Things the server should send to the client. reliable if( bNetOwner && (Role==ROLE_Authority) ) AmmoAmount; } event float BotDesireability(Pawn Bot) { local Ammo AlreadyHas; if ( ParentAmmo != None ) AlreadyHas = Ammo(Bot.FindInventoryType(ParentAmmo)); else AlreadyHas = Ammo(Bot.FindInventoryType(Class)); if ( AlreadyHas == None ) return (0.35 * MaxDesireability); if ( AlreadyHas.AmmoAmount == 0 ) return MaxDesireability; if (AlreadyHas.AmmoAmount >= AlreadyHas.MaxAmmo) return -1; return ( MaxDesireability * FMin(1, 0.15 * MaxAmmo/AlreadyHas.AmmoAmount) ); } function bool HandlePickupQuery( inventory Item ) { if ( (class == item.class) || (ClassIsChildOf(item.class, class'Ammo') && (class == Ammo(item).parentammo)) ) { if (AmmoAmount==MaxAmmo) return true; if (Level.Game.LocalLog != None) Level.Game.LocalLog.LogPickup(Item, Pawn(Owner)); if (Level.Game.WorldLog != None) Level.Game.WorldLog.LogPickup(Item, Pawn(Owner)); if (Item.PickupMessageClass == None) Pawn(Owner).ClientMessage( Item.PickupMessage, 'Pickup' ); else Pawn(Owner).ReceiveLocalizedMessage( Item.PickupMessageClass, 0, None, None, item.Class ); item.PlaySound( item.PickupSound ); AddAmmo(Ammo(item).AmmoAmount); item.SetRespawn(); return true; } if ( Inventory == None ) return false; return Inventory.HandlePickupQuery(Item); } // This function is called by an actor that wants to use ammo. // Return true if ammo exists // function bool UseAmmo(int AmountNeeded) { if (AmmoAmount < AmountNeeded) return False; // Can't do it AmmoAmount -= AmountNeeded; return True; } // If we can, add ammo and return true. // We we are at max ammo, return false // function bool AddAmmo(int AmmoToAdd) { If (AmmoAmount >= MaxAmmo) return false; AmmoAmount += AmmoToAdd; if (AmmoAmount > MaxAmmo) AmmoAmount = MaxAmmo; return true; } function inventory SpawnCopy( Pawn Other ) { local Inventory Copy; if ( parentammo != None ) { Copy = spawn(parentammo,Other,,,rot(0,0,0)); Copy.Tag = Tag; Copy.Event = Event; Copy.Instigator = Other; Ammo(Copy).AmmoAmount = AmmoAmount; Copy.BecomeItem(); Other.AddInventory( Copy ); Copy.GotoState(''); if ( Level.Game.ShouldRespawn(self) ) GotoState('Sleeping'); else Destroy(); return Copy; } Copy = Super.SpawnCopy(Other); Ammo(Copy).AmmoAmount = AmmoAmount; return Copy; } w4w4w4L //============================================================================= // Ambushpoint. //============================================================================= class AmbushPoint extends NavigationPoint; var vector lookdir; //direction to look while ambushing //at start, ambushing creatures will pick either their current location, or the location of //some ambushpoint belonging to their team var byte survivecount; //used when picking ambushpoint var() float SightRadius; // How far bot at this point should look for enemies var() bool bSniping; // bots should snipe from this position function PreBeginPlay() { lookdir = 2000 * vector(Rotation); Super.PreBeginPlay(); } tON=tuOGw4I$@El@w4w4O//============================================================================= // Ambient sound, sits there and emits its sound. This class is no different // than placing any other actor in a level and setting its ambient sound. //============================================================================= class AmbientSound extends Keypoint; // Import the sprite. #exec Texture Import File=Textures\Ambient.pcx Name=S_Ambient Mips=Off Flags=2 `vOGwOTZ`hD Z,y@@w4w4A HPu8" uF#G#Z&u?%Qa%t!|-T'ZL>Waa%t!|-T'_L>m w4zOw4w4{Ow4w4S w4w4F//============================================================================= // Actor: The base class of all actors. // 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 Flags=2 // Flags. var(Advanced) const bool bStatic; // Does not move or change over time. var(Advanced) bool bHidden; // Is hidden during gameplay. var(Advanced) const bool bNoDelete; // Cannot be deleted during play. var bool bAnimFinished; // Unlooped animation sequence has finished. var bool bAnimLoop; // Whether animation is looping. var bool bAnimNotify; // Whether a notify is applied to the current sequence. var bool bAnimByOwner; // Animation dictated by owner. var const bool bDeleteMe; // About to be deleted. var transient const bool bAssimilated; // Actor dynamics are assimilated in world geometry. var transient const bool bTicked; // Actor has been updated. var transient bool bLightChanged; // Recalculate this light's lighting now. var bool bDynamicLight; // Temporarily treat this as a dynamic light. var bool bTimerLoop; // Timer loops (else is one-shot). // Other flags. var(Advanced) bool bCanTeleport; // This actor can be teleported. var(Advanced) bool bOwnerNoSee; // Everything but the owner can see this actor. var(Advanced) bool bOnlyOwnerSee; // Only owner can see this actor. var Const bool bIsMover; // Is a mover. var(Advanced) bool bAlwaysRelevant; // Always relevant for network. var Const bool bAlwaysTick; // Update even when players-only. var(Advanced) bool bHighDetail; // Only show up on high-detail. var(Advanced) bool bStasis; // In StandAlone games, turn off if not in a recently rendered zone turned off if bCanStasis and physics = PHYS_None or PHYS_Rotating. var(Advanced) bool bForceStasis; // Force stasis when not recently rendered, even if physics not none or rotating. var const bool bIsPawn; // True only for pawns. var(Advanced) const bool bNetTemporary; // Tear-off simulation in network play. var(Advanced) const bool bNetOptional; // Actor should only be replicated if bandwidth available. var bool bReplicateInstigator; // Replicate instigator to client (used by bNetTemporary projectiles). 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 bClientAnim; var bool bSimFall; // dumb proxy should simulate fall // 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_Rolling, PHYS_Interpolating, PHYS_MovingBrush, PHYS_Spider, PHYS_Trailer } 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 Role; var(Networking) ENetRole RemoteRole; var const transient int NetTag; // Owner. var const Actor Owner; // Owner actor. var(Object) name InitialState; var(Object) name Group; // Execution and timer variables. var float TimerRate; // Timer event, 0=no timer. var const float TimerCounter; // Counts up until it reaches TimerRate. var(Advanced) float LifeSpan; // How old the object lives before dying, 0=forever. // Animation variables. var(Display) name AnimSequence; // Animation sequence we're playing. var(Display) float AnimFrame; // Current animation frame, 0.0 to 1.0. var(Display) float AnimRate; // Animation rate in frames per second, 0=none, negative=velocity scaled. var float TweenRate; // Tween-into rate. var Animation SkelAnim; var(Display) float LODBias; //----------------------------------------------------------------------------- // 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 LevelInfo Level; // Level this actor is on. var transient const Level XLevel; // Level object. var(Events) name Tag; // Actor's tag name. var(Events) name Event; // The event this actor causes. var Actor Target; // Actor we're aiming at (other uses as well). var Pawn Instigator; // Pawn responsible for damage. var(Sound) sound AmbientSound; // Ambient sound effect. var Inventory Inventory; // Inventory chain. var const Actor Base; // Moving brush actor we're standing on. var const PointRegion Region; // Region this actor is in. var(Movement) name AttachTag; // Internal. var const byte StandingCount; // Count of actors standing on this actor. var const byte MiscNumber; // Internal use. var const byte LatentByte; // Internal latent function use. var const int LatentInt; // Internal latent function use. var const float LatentFloat; // Internal latent function use. var const actor LatentActor; // Internal latent function use. var const actor Touching[4]; // List of touching actors. var const actor Deleted; // Next actor in just-deleted chain. // Internal tags. var const transient int CollisionTag, LightingTag, OtherTag, ExtraTag, SpecialTag; // The actor's position and rotation. var(Movement) const vector Location; // Actor's location; use Move to set. var(Movement) const rotator Rotation; // Rotation. var const vector OldLocation; // Actor's old location one tick ago. var const vector ColLocation; // Actor's old location one move ago. var(Movement) vector Velocity; // Velocity. var vector Acceleration; // Acceleration. var(Filter) float OddsOfAppearing; // 0-1 - chance actor will appear in relevant game modes. //Editing flags var(Advanced) bool bHiddenEd; // Is hidden during editing. var(Advanced) bool bDirectional; // Actor shows direction arrow during editing. var const bool bSelected; // Selected in UnrealEd. var const bool bMemorized; // Remembered in UnrealEd. var const bool bHighlighted; // Highlighted in UnrealEd. var bool bEdLocked; // Locked in editor (no movement or rotation). 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. // What kind of gameplay scenarios to appear in. var(Filter) bool bDifficulty0; // Appear in difficulty 0. var(Filter) bool bDifficulty1; // Appear in difficulty 1. var(Filter) bool bDifficulty2; // Appear in difficulty 2. var(Filter) bool bDifficulty3; // Appear in difficulty 3. var(Filter) bool bSinglePlayer; // Appear in single player. var(Filter) bool bNet; // Appear in regular network play. var(Filter) bool bNetSpecial; // Appear in special network play mode. // set to prevent re-initializing of actors spawned during level startup var bool bScriptInitialized; // Editor support. var Actor HitActor; // Actor to return instead of this one, if hit. //----------------------------------------------------------------------------- // Display properties. // Drawing effect. var(Display) enum EDrawType { DT_None, DT_Sprite, DT_Mesh, DT_Brush, DT_RopeSprite, DT_VerticalSprite, DT_Terraform, DT_SpriteAnimOnce, } DrawType; // Style for rendering sprites, meshes. var(Display) enum ERenderStyle { STY_None, STY_Normal, STY_Masked, STY_Translucent, STY_Modulated, } Style; // Other display properties. var(Display) texture Sprite; // Sprite texture if DrawType=DT_Sprite. var(Display) texture Texture; // Misc texture. var(Display) texture Skin; // Special skin or enviro map texture. var(Display) mesh Mesh; // Mesh if DrawType=DT_Mesh. var const export model Brush; // Brush if DrawType=DT_Brush. var(Display) float DrawScale; // Scaling factor, 1.0=normal size. var vector PrePivot; // Offset from box center for drawing. var(Display) float ScaleGlow; // Multiplies lighting. var(Display) float VisibilityRadius;// Actor is drawn if viewer is within its visibility var(Display) float VisibilityHeight;// cylinder. Zero=infinite visibility. var(Display) byte AmbientGlow; // Ambient brightness, or 255=pulsing. var(Display) byte Fatness; // Fatness (mesh distortion). var(Display) float SpriteProjForward;// Distance forward to draw sprite from actual location. // Display. var(Display) bool bUnlit; // Lights don't affect actor. var(Display) bool bNoSmooth; // Don't smooth actor's texture. var(Display) bool bParticles; // Mesh is a particle system. var(Display) bool bRandomFrame; // Particles use a random texture from among the default texture and the multiskins textures var(Display) bool bMeshEnviroMap; // Environment-map the mesh. var(Display) bool bMeshCurvy; // Curvy mesh. var(Display) bool bFilterByVolume; // Filter this sprite by its Visibility volume. // Not yet implemented. var(Display) bool bShadowCast; // Casts shadows. // Advanced. var bool bHurtEntry; // keep HurtRadius from being reentrant var(Advanced) bool bGameRelevant; // Always relevant for game var bool bCarriedItem; // being carried, and not responsible for displaying self, so don't replicated location and rotation var bool bForcePhysicsUpdate; // force a physics update for simulated pawns var(Advanced) bool bIsSecretGoal; // This actor counts in the "secret" total. var(Advanced) bool bIsKillGoal; // This actor counts in the "death" toll. var(Advanced) bool bIsItemGoal; // This actor counts in the "item" count. var(Advanced) bool bCollideWhenPlacing; // This actor collides with the world when placing. var(Advanced) bool bTravel; // Actor is capable of travelling among servers. var(Advanced) bool bMovable; // Actor is capable of travelling among servers. // Multiple skin support. var(Display) texture MultiSkins[8]; //----------------------------------------------------------------------------- // Sound. // Ambient sound. var(Sound) byte SoundRadius; // Radius of ambient sound. var(Sound) byte SoundVolume; // Volume of amient sound. var(Sound) byte SoundPitch; // Sound pitch shift, 64.0=none. // Regular sounds. var(Sound) float TransientSoundVolume; var(Sound) float TransientSoundRadius; // 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, }; //----------------------------------------------------------------------------- // 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(Collision) bool bCollideWorld; // Collides with the world. var(Collision) bool bBlockActors; // Blocks other nonplayer actors. var(Collision) bool bBlockPlayers; // Blocks other player actors. var(Collision) bool bProjTarget; // Projectiles should potentially target this actor. //----------------------------------------------------------------------------- // 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 } 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_Unused } LightEffect; // Lighting info. var(LightColor) byte LightBrightness, LightHue, LightSaturation; // Light properties. var(Lighting) byte LightRadius, LightPeriod, LightPhase, LightCone, VolumeBrightness, VolumeRadius, VolumeFog; // 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 bLensFlare; // Whether to use zone lens flare. //----------------------------------------------------------------------------- // Physics. // Options. 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 bool bInterpolating; // Performing interpolating. var const bool bJustTeleported; // Used by engine physics - not valid for scripts. // Dodge move direction. var enum EDodgeDir { DODGE_None, DODGE_Left, DODGE_Right, DODGE_Forward, DODGE_Back, DODGE_Active, DODGE_Done } DodgeDir; // 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 rotate pawn to this if bRotateToDesired. var float PhysAlpha; // Interpolating position, 0.0-1.0. var float PhysRate; // Interpolation rate per second. var Actor PendingTouch; // Actor touched during move which wants to add an effect after the movement completes //----------------------------------------------------------------------------- // Animation. // Animation control. var float AnimLast; // Last frame. var float AnimMinRate; // Minimum rate for velocity-scaled animation. var float OldAnimRate; // Animation rate of previous animation (= AnimRate until animation completes). var plane SimAnim; // replicated to simulated proxies. //----------------------------------------------------------------------------- // Networking. // Network control. var(Networking) float NetPriority; // Higher priorities means update it more frequently. var(Networking) float NetUpdateFrequency; // How many seconds between net updates. // 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 bNetSee; // Player sees it in network play. var const bool bNetHear; // Player hears it in network play. var const bool bNetFeel; // Player collides with/feels it in network play. var const bool bSimulatedPawn; // True if Pawn and simulated proxy. 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 bClientDemoNetFunc;// True if we're client-side demo recording and this call originated from the remote. //----------------------------------------------------------------------------- // Enums. // Travelling from server to server. enum ETravelType { TRAVEL_Absolute, // Absolute URL. TRAVEL_Partial, // Partial (carry name, reset server). TRAVEL_Relative, // Relative URL. }; // 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_UnknownB9 ,IK_Semicolon ,IK_Equals , /*BC*/ IK_Comma ,IK_Minus ,IK_Period ,IK_Slash , /*C0*/ IK_Tilde ,IK_UnknownC1 ,IK_UnknownC2 ,IK_UnknownC3 , /*C4*/ IK_UnknownC4 ,IK_UnknownC5 ,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_JoyX ,IK_JoyY ,IK_JoyZ ,IK_JoyR , /*E4*/ IK_MouseX ,IK_MouseY ,IK_MouseZ ,IK_MouseW , /*E8*/ IK_JoyU ,IK_JoyV ,IK_UnknownEA ,IK_UnknownEB , /*EC*/ IK_MouseWheelUp ,IK_MouseWheelDown,IK_Unknown10E,UK_Unknown10F , /*F0*/ IK_JoyPovUp ,IK_JoyPovDown ,IK_JoyPovLeft ,IK_JoyPovRight , /*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 }; var(Display) class RenderIteratorClass; // class to instantiate as the actor's RenderInterface var transient RenderIterator RenderInterface; // abstract iterator initialized in the Rendering engine //----------------------------------------------------------------------------- // natives. // Execute a console command in the context of the current level and game engine. native function string ConsoleCommand( string Command ); //----------------------------------------------------------------------------- // Network replication. replication { // Relationships. unreliable if( Role==ROLE_Authority ) Owner, Role, RemoteRole; unreliable if( bNetOwner && Role==ROLE_Authority ) bNetOwner, Inventory; unreliable if( bReplicateInstigator && (RemoteRole>=ROLE_SimulatedProxy) && (Role==ROLE_Authority) ) Instigator; // Ambient sound. unreliable if( (Role==ROLE_Authority) && (!bNetOwner || !bClientAnim) ) AmbientSound; unreliable if( AmbientSound!=None && Role==ROLE_Authority && (!bNetOwner || !bClientAnim) ) SoundRadius, SoundVolume, SoundPitch; unreliable if( bDemoRecording ) DemoPlaySound; // Collision. unreliable if( Role==ROLE_Authority ) bCollideActors, bCollideWorld; unreliable if( (bCollideActors || bCollideWorld) && Role==ROLE_Authority ) bProjTarget, bBlockActors, bBlockPlayers, CollisionRadius, CollisionHeight; // Location. unreliable if( !bCarriedItem && (bNetInitial || bSimulatedPawn || RemoteRole 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(); //============================================================================= // Timing. // Causes Timer() events every NewTimerRate seconds. native(280) final function SetTimer( float NewTimerRate, bool bLoop ); //============================================================================= // 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 ); // 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 ); native simulated event DemoPlaySound ( sound Sound, optional ESoundSlot Slot, optional float Volume, optional bool bNoOverride, optional float Radius, optional float Pitch ); // Get a sound duration. native final function float GetSoundDuration( sound Sound ); //============================================================================= // 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 some player has a line of sight to // actor's location. // native(532) final function bool PlayerCanSeeMe(); //============================================================================= // Regular engine functions. // Teleportation. event bool PreTeleport( Teleporter InTeleporter ); event PostTeleport( Teleporter OutTeleporter ); // Level state. event BeginPlay(); //======================================================================== // 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(); native final function string GetNextInt( string ClassName, int Num ); native final function GetNextIntDesc( string ClassName, int Num, out string Entry, out string 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. native(304) final iterator function AllActors ( class BaseClass, out actor Actor, optional name MatchTag ); native(305) final iterator function ChildActors ( class BaseClass, out actor Actor ); native(306) final iterator function BasedActors ( class BaseClass, out actor Actor ); native(307) final iterator function TouchingActors( class BaseClass, out actor Actor ); 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 ); native(310) final iterator function RadiusActors ( class BaseClass, out actor Actor, float Radius, optional vector Loc ); native(311) final iterator function VisibleActors ( class BaseClass, out actor Actor, optional float Radius, optional vector Loc ); native(312) final iterator function VisibleCollidingActors ( class BaseClass, out actor Actor, optional float Radius, optional vector Loc, optional bool bIgnoreHidden ); //============================================================================= // Color operators 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. // draw on canvas before flash and fog are applied (used for drawing weapons) event RenderOverlays( canvas Canvas ); // // Called immediately before gameplay begins. // event PreBeginPlay() { // Handle autodestruction if desired. if( !bGameRelevant && (Level.NetMode != NM_Client) && !Level.Game.IsRelevant(Self) ) Destroy(); } // // Broadcast a message to all players. // event BroadcastMessage( coerce string Msg, optional bool bBeep, optional name Type ) { local Pawn P; if (Type == '') Type = 'Event'; if ( Level.Game.AllowsBroadcast(self, Len(Msg)) ) for( P=Level.PawnList; P!=None; P=P.nextPawn ) if( P.bIsPlayer || P.IsA('MessagingSpectator') ) { if ( (Level.Game != None) && (Level.Game.MessageMutator != None) ) { if ( Level.Game.MessageMutator.MutatorBroadcastMessage(Self, P, Msg, bBeep, Type) ) P.ClientMessage( Msg, Type, bBeep ); } else P.ClientMessage( Msg, Type, bBeep ); } } // // 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 Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ) { local Pawn P; for ( P=Level.PawnList; P != None; P=P.nextPawn ) if ( P.bIsPlayer || P.IsA('MessagingSpectator') ) { if ( (Level.Game != None) && (Level.Game.MessageMutator != None) ) { if ( Level.Game.MessageMutator.MutatorBroadcastLocalizedMessage(Self, P, Message, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject) ) P.ReceiveLocalizedMessage( Message, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject ); } else P.ReceiveLocalizedMessage( Message, 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 net client simulated event PostNetBeginPlay(); // // Hurt actors within the radius. // final function HurtRadius( float DamageAmount, float DamageRadius, name DamageName, 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 ) { if( Victims != self ) { 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), DamageName ); } } bHurtEntry = false; } // // Called when carried onto a new level, before AcceptInventory. // event TravelPreAccept(); // // Called when carried into a new level, after AcceptInventory. // event TravelPostAccept(); // // Called when a scripted texture needs rendering // event RenderTexture(ScriptedTexture Tex); // // Called by PlayerPawn when this actor becomes its ViewTarget. // function BecomeViewTarget(); // // Returns the string representation of the name of an object without the package // prefixes. // function String GetItemName( string FullName ) { local int pos; pos = InStr(FullName, "."); While ( pos != -1 ) { FullName = Right(FullName, Len(FullName) - pos - 1); pos = InStr(FullName, "."); } return FullName; } // // Returns the human readable string representation of an object. // function String GetHumanName() { 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, texture NewTexture, bool bLighting, bool bEnviroMap ) { Style = NewStyle; texture = NewTexture; bUnlit = bLighting; bMeshEnviromap = bEnviromap; } function SetDefaultDisplayProperties() { Style = Default.Style; texture = Default.Texture; bUnlit = Default.bUnlit; bMeshEnviromap = Default.bMeshEnviromap; } w4M%w4w4g9e!# R75::$Le!#$" w4@Pw4w4APw4w4w4w4yI%u-)I%)J#)H#w4zxOI#z* I#-Oo$^-i gz6 C?,(Bq!?6'N-O6 ?,q!?8} 6})@yaK#z} (wy*q!?8u!a333?(v!o$ w4b9i9?s w4w4w4BPD#t.K )D#)C#w4PPL Pg[q-F :I:$  ~Ir!p:L :$ ի?W~ II*:L :$ իW~ II*:L :$ ի?WI ~~**:L :$ իWI ~~6  CXF$?'HD?R L Y$o$ w4CMPEPXԇW)-iQ6 {-h'H6'[-Oo$Uq!?8 w4FPE#}/#)E#)B#)A#)@#)")~")}"w4Tm S0.:I:$n &#q!S w4zbRi!z GU i!-Oo$q!i w4A KPs8 U-T(:I:$w-Fn-M76 6 6 6 ?Bthsa%t6 6 6 6 ?s!|a-T'ZL>V-jMs!| s!H s!e s!|b=-T'Sms!| s!H s!e s!|-T'X=AU w4|Q KтN-hm? AQ @;;6 6N ?&ma7mc);c;cc)6N 6 i ;c;cSm AQ @33>?-h(;;?&m7am_b_b__@fff?Q _b__fff?Q _b_b?, _bL-} oQ ?'offf?offf?bBoB?*C w4yPkLi| w4h9@w8*s@ 6@%a+@7)-F(-e(-O(-o(v!8P  -u' w4CLPm!XhZE8Xm!;:Y:$Y$j =CY$ w4IP{"w0 ){")z")|"w4O\Ps"^q~$"au!88^s"t"u" w4A WPB*B w4w4w4QPy"d1 #)y")x")w")v")q")p")r"w4TPw4w4\RPVPX!.77,-oa8XVPTP w4rGPt!(+d^N&&u!-M?6w!t!?b:i :$ :I:$Y$:i :$ :i :$Pi -ex :I:$a%t!P-F:Z%-F'B:Z%N#-F(X=]-FZ-T {?%a%t!H&#a%t!|a%t!ea%t!|-T'X=ZZ6 6 6 6 ?a%t!e<a%t!|9-M {?%-T'xZZ-M-T'ZL>N#&#h-M&# {=B w4^Pw4w4Q{PtP$"t -O' w4eXPz!Kqxe-kF#z! w4ePR#s|du>Su>Ra @?% m?%` #?e` #j qR?a+j::$LR` $"(R` $"-e( w4UPo"c2 )o")n"w4_Pw4w4w4w4]Pl"u3A )l")k")m"w4w4w4|PJQ] J w4l9qgr{*u2Y#Y$-F(-M(-e(W:I:$o$eaa w4`PJ%x4 #)J%)L#)^")\")[")Z")X"w4ufP_"wjz~8w_"`"a"-b"-c"-d"-e"-f"-g"-h"i"j"6 ,6 , Bw4ekP]"KPx#*-kF#]" w4w4w4gPw4hw4Y"w4w4oPE 9vQ$::$ 3%q![ O-ou!877-o'O  w4rjPiP(IxB--O-e6Y"?%E &# w4dPV"m5n -)V")U")W")S")R")T")P")O")Q"w4A rP8!tB::$ $3%q![ q!?vB w4w4w4CmPnPX/uC(::$aF$>(HD?3-i {-h' w4puPAt w4w4w4b pPqPTt w4w4w4w4w4CZPsO*nt -O' w4lPM: yyOOPPp p N N l l D D J J kkGG-{(-M#(U*? \Os 6wPuó+VF:wC \'&$A)$B}dI w4w4j9_~$0 )_)Ow4DPOPS tM[zP2w4 |(@w4w4zK"zs K"-Oo$q!i w4~PaPs  w4h I"aT wI"fH" w4Pw4w4w40`Lm,Z 6@Q!3HTJ $?I$ ER$gh&$PB)$HB;S}SaSgS@Sw4w4ubPJk LLSBQmREw4w4]OMCQGڹw4w4HLP$ %6>64>352+I' *6A59E82G/ ?$E &G":< 0 8U52Y-BF#O@ K>ETCAR?@X<:X65_0,]&3d-%WPTTG IWGGZEDYAE]B@_<;^7;d66h0,b%L Ca?.g&O J`GBd>Af;>i7IwBAz9D=8y/:~0:0>41&mZtVO~IoU~POGF=@51&.#*$~'7,!|0#vz+ ),' !#1#%+ #"&`x]njc^hdsnWQaYYRI@NEE:WLB6M@G:;/;,7)G89)<,?/2!3"+6#*$/;)%zvmfd[^QL=Q@I7(zj^*bTR?9$A-**{qm`I4D/)T?-}seS<%/vk[5ъue' ӛsw4@    +++  ///373333'/3#3##7#';'';'777/#7;7+C+ ' /3';;;;?;7;7+C++G++K+ + 7;/;?//K/7C3;sg[K?3'?K#O 7 73O3C ; C ? ? G#W#;K;GGCCCC3O33S3#[# C '_#?GGGGKGK G OCKKK7W7 G SWO[K K GOOO7[7;_;KKSSSSSSKSK O _SWcSWWWWW+ '[+_[[[//g'#_##c______33gkccc k ggggggkkkooo{{{CC''++__CC++++++//++//////////ccGGCCGG33// GGGGKKKKkkccggKKKKOOKKKKookkkkwwoowwoo{{oosswwsssswwssoooooow4@ w4@kw4@   #+/3 7 ; C GKOSW_#c#g'k'o+w+{+//3377;#;#;#?#?'C'C'G'G+G+K+K+O/S3W3[7_?cCgCoKsOwS{W[_cgksWQ" " " " * y*Z"Ԫow4]@nnnnnnnnnn WQ" " " " *z*Z"] aow4(b@nnnnnnnnnn WQ" " " " * y*Z"ow4{f@nnnnnnnnnn w4zS@w4w4w4w4@Tw4w4w4w4aT@w4w4w4w4AT@w4w4eT@w4w4w4w4w4w4JTw4w4OTw4w4NTw4w4HT@w4w4QTw4w4`T@w4w4LTw4w4KTw4w4ITw4w4w4w4ETw4w4VTw4w4MTw4w4DTw4w4PTw4w4h-WT`4z߬je -}Spp /([) was kicked from the server:WT!U4a w4@w4[Tw4{S@w4w4S@w4w4CTw4w4@w4w4RTUT\4bS[] dSSS~S: -}Spp /([) was banned from the server:UT!U4pAdding IP Ban for: SAT% ATzAT  ATHATAT pDENY,S ba w4|S@w4w4GR@+w4a$Z4]4^4[4V4w4ST@w4w4^T@w4w4_T@w4w4FT@w4w4}S@w4w4\T@w4w4XT~S_47 -5 ~SVw~S*~S-w.~S*w..~SL* pp S~S B,)~S /~S~SU! w4oh2d)'::$ ::$a@' w4RcTH+){z w * }% w4BTw4w4g-YTb4m -5 |SVkw|S*:r|STT|S-w|S *w.|S*w..|SL* zS|S BYTF -}Sp /kicked|S /.|S[fromV~V..unr!U4|Sa |S|SU! w4O-TTd4 -5 {SVw{S*:r{S{S-w{S *w.{S*w..{SL* zS{S BTT@T.{S[Q d@T@T@T~@T:pAdding IP Ban for: @TBT%nBTdzBT nBT.BTBT pDENY,@T9 -}Sp /banned{S /.{S[duringV~V..unr!U4 b -}Sp /kicked{S /.{S[fromV~V..unr!U4{Sa {S{SU! w4iT@w4w4g @w4w4Nw4w4lTy4 -#n5HideLog$::$x4pppUTracing changed to T at U$ w4x.x4p"7/::$ -f y4 XQ1L1Z2L1OL1g2L1j2L1h2^2wL1b2L1a2L1o2^2LL1L1L1r2L1f2h2LQ1L1e2L1c1o2T-L1\2h2R-h2O-e2L1o2V-L1oL1Qo2`.^2L1X2Z2L1{.L1R1Z2MZ2m.L1A/L1}.L1^2f2ML1u.L1c2Z2q.^2Br2h.r2i.r2^.Z2{4L1_L1v.L1b1L1P/^2]2L1|.L1@/L1v0L1.Z2n.Z2l.L1H/^2t.L1y.Z2z4L1w.k'CR gn.hU|.} MxyL[ KKDo!OF~R!Nr^J @NnKn @ J}Q k"N {-` xur JDZg J+SA  T ze B$x N @I KI P%Z a-j O%| uDFK YmQ G-~ u*N `_ q!q T sA X#Q m!` qr t!D &T )d ,u Jr]D Oa @ Cq K/t b E }bV Ox iH ]X oh G!x R G M. W k0d B0v c E e0V UWg h!~ ! +P _ D q%m O| m,L |-] "n A%K K([ h X!k D0z RI s bZ JHO| ZK =\ J1l m2z @2H S-X ~ S-h -K(x k E&H M"X H$h zQ-x -h'H k#W /x&g g!w oH ~W H f Wv OD X!T Pb xq ZA ~P _ [ W@} E} 7Q Ud Igt +`%[ Tk Oz DJ X&\ n%l K}'| iL h[ 0v*k `| QK aX[ { ws f#B }.S Vd -}(r gB -b'S Vc r+r iD H S Wc 5Dt \D Ey(T xd BOt HD wS l-c LQP Q+a or U,A T wQ a U~ E0M w\ -Jl O| OL M!\ -xk -E)y ZYI ub Q-q iu+A ]sQ D bT he wt zH C @OS I+c JlPs I%C Y-S {b }q W1B A+R B+c `r^s X-Q 7O` 7E-p v@ JTP t0d l$t w0C I0S n/b <[_q Z!P `_F` _f P_w W~$DV ZZ ti f"x OF @-V ne Tu }E OV Q-f o,v RjG Gq R0B ^"Q \"a i p ]@ zO W ] R\ l @OH XX h Y-p al Ks'k u+{ c i K [ X-[ T!j Y-y OH T _W wg O1v qE KT u-s A0B ].P J0_ U En Us gOC wS uc dq lMO EO^ Gn H%~ Q2L ^.Z i { E&y MUI bX ^h  B w S-F gU Wf ebv [F s,U ~e Wt u+C US Sb I!q ]A 6,P  O^ B m ~ u+| -ML O r[ W E-k  wz -Y(I OX Nh @-x nH Q-Z {j d z B2I x0W B g Q-w E-E rK1T \b k F&r [ Y-B HQ D G1b  q . G1B rQ T_ D n Y,} T vL ){,\ Yk a{ l%K f\ S#k @Ty fM g rL aw[ zj F"z x1I JX {.g zZw L/G -i'V -Of \u  OD nT L$f uwu _e'D I!S ic  wr s"A 5|Q `S` D&s [C pR n a EMr D"@ h.O @,_ On f} ` [ \ih w4 @w vI IO#W v$e h$u h'C M S Ka az#p @V&@ XQ @-` O o K0~ W$N `'^ r!m $| plK g[ Dj UZz R |J `- Z Mg \x w GG 5]1W h-g vs,v OE 5EU wd as UB "wP O$_ O bo ]~ O-M x ] fwj A1y T I ewX T+g -vw ?P-G m$V ?L-f R-v c0F L0U Ad n$s XY-C rQ w` p&o E xO \_ wn rQ-} H\M V&i Qz NI k D&W {,g c'v -D)D C"T yc G r A,C |  V R lh bx -VH }(Z -Y!j MO$K }([ Ik k){ xJ OX D)h a a"y Y.I eIY AYi Y-B Y-P f w^ \.n |+} Us,M T] fl w}  u+M uX.\ u%k TOz N0J _#Y *}h |e W.u bY-E {#S ^#d nI"s |B Ut,R ~ Xa 5[p Y {N 5M\ $}k wh u+w D OF rU d @t O X-C g,Q 5h` kEp Ou IL#E SX IG#g l%x OI H2X  ^%f  a%u ^&D 5gR zb b-p w  wN a] 2 k%m -k| wJ [ w%Y Q-h cw ($F ]$j YO&x -J H T ER ua m R+p k G1 LN Q] w4r u+k u$z u+H k H&W k y%f n-u n[C C^ W#l O!{ > hJ bY y#g [&w \&F YOU Ge }t u+C x0R ] a fWq 2HH `/V Gd KZs ^-B Kt'R F z'b F {'q F |'@ bN C(] A1n @+} Y-L MZ E-i Cx n!F a0U Q-d S(u w4gG xy(V u+f Y-u W#C T0R S0a {,p j Y'N Z#\ Q0k [#z T(I gX ]#i aSx zG ^f O0t ]C G0R /]%a /wq 8@ ZY-] qk {{ kM*Z wEi kfy ^ZH B*W S,h ]"v i/E #T xc -Y-s 7L-A M/Q 7M-b O-q ?iA +P C0_ mY-n Q| K.K Fi[ {,j t,y 'G DY-e %s FN-Q |*_ >E-n Ul} JM y,] . ym O| s.L t0[ Nj \Y'{ y1I A"X lTg ^0x MG 5rU <b)d G`s P&S F0c j!r [E 1X.U |d @B -FQ  a O MO k G&^  `%n k B} MN S-] z1m o U+| 5nL k r[ 9 F#j o u+z nI ["Y Th m H y w0I xX [ ~%g Mv s E zT _Y-d K\r Kj'A ~ MP JPe^ K^C xR Kl'b Guq G  MW$_ oSo VB U X.Q u+_ C o b0~ a l$M o ] U rn b-} `Uj 8 P wN Q O*^ ^n l$} `0L e![ Y-j xy VH k GW zM1g cv |$E X0S `b [2q _"@ Y-P ^_ _0n Ti} OL q)\ TC j l%z -E-K -lZ d#h T1v P0E JT bd  B t IN#D K%S -Nd B!s AB b mP -W(^ <Y-n O| wK O[ Mk ez V0I 0O$X vh Lx Y+H iW \g _v E2E #MS Qa @q @ WO wp)_ jo T} `1N V!] L!m w4c!| X+K - wY ci -]x -WH -hV r,d e~t A!B -nQ -L(_ @!m &$q| Km x&*q| rm A*~ ~uM ]%B l%R <j)c Mq -w@ a S"N }F^ Vd H0r  A {,P R._ [m ]I+| ~ L V[ ~X.i y#y l_I P!Y Y1h F!x @Y-G kU -hc i"K J[^Z zN1x y G uV @E-e x&u F E jT Jy[c Wv%D~ zZ.B c OP O` Lio S&~ ^f$N N!\ gOk -L{ X.J nX | [g H.w -PG F"X Zf Bv k L&E p!T 5Fb e q%q @Y- oN M&] xx(l ^&{ M0J VH'Y [ %g -Wu -XG w4BV bd [ }%s R [$B T zQ Ex(` ]0o U y%~ \0L w1[ p-j b{ > _K q1[ l%j 2TO huc cr kB I$Q Y-` > dn im} t-L 7 PZ Li Y-w g` F TU TDe w-i Oz vI mY D f$i `x @G D r%U nd ^.s \A {$O J%] v1m D@)| H!M R-] aE-l O| S-L  q[ R-j Ez ~J *X dh  ww T @F I+V Oe }u VtG xP{ wL {S!\ al e{ EPJ r[ v-j g@-{ uQ-J Z0Z Q.i ~Y-x zG Y wV ze zt ~C ~ NR uY-b _q v@ Y0P Y-_ q2n y} aML E1[ Q.k /R)z l)J OY Yqi u+Z e}i {Q!x X.H U#X _h E%w jOF jLV ^Ge rl w} a[$L W[ U#k L{ MK Zo[ {bJ OZ Q.j [y gJ x&X gw+h  w)y WMH f0W Z`+g Bv fG [XQX R E-i gz+x T 20I  \.y gS I pn"X bcg ]+u wD 0 yT une wD+u &MD yS M@b HO&p S-@ E-O -i+^ kT(m -M(} V(K pi"Z g%i g x /FI F(Y h h h0y /Q)M fc/\ c.K M_[ 0W$k G!{ 0[$L 0N[ 0T$k S"y w4MR-I T YY ^h vw MQ%V MMf T Hu cO-E 0]U ^k 9x&} dM fF [ T ej ay VsH R u { a"J T MY -Uh ]%z Y-I g-W nX.f Nu d.E D1T V1d -s y*C R#S Vc z*s 7MB ER la Amq E^ Ml 5\{ }"J 5BY lR%i i&w lR-G {*W +@'f <_)v gLE 5GT }*c !r {"A -n(_ Oo U _&O -B^ cn I.M n\ E(k @0z WMI XX <a)w 5\F lN%U nf MScE { Oh ]&x OF wRe \.w x,G `(W <c)f E!u W+D aRR lQ%a x,q u ^.A F"O J-^ yn ld| YKw@-Zf1iN"wP"E OV Y&e_'s wC W&RJbO-q bAf Q/`}o Q&~ Y La Z"[G ka mza vJsYc Oj ^%yn"G} VV,e{ s| BUi"Qo/`Y-n[+~x MB\ T/ja1ykH7cWH fm/vj/EgTHc Y-s\a'A&OQ\_'` Y$p~+~ Z$O\^ \$lg O{\O-K g$[ w$j ty i$H~VIfL%C[ |%W[ {%fe1uF%D_]%V zemtNDC#S E!bs0q|0@WNvauJ}pNmmB ]/Rza ^$od1~~.MZ O*]Wlg"|gJ Y-[n"i`#x}GFcU i&dD$tuClQUn"a_%pS11Y-N m\ X.li"{nX!Jz,Xddha'LTx\Nl]{OJIM#Zyj@yY-J2 m%Y6 k%g2 l%v]E`?S6 l%RVOa.wg0Ogk%^gl%mW|_ D+Kgm%YU G1givu^&EbS{Ubx/sVOCD s%SfcBh%rOAE-PX._x{(nEz(|KOKQ Q*iQ dxeGQ sU@LdKN-tZaQ T*p+e$@ X.PZq_ xn B ~KMY-]Q-l k-zP2H^.Vy0eT2u U&DE{(SD"+b uMfe^ kCnRE~(aZ sp ^_,NH1\ M%kJ,|OLE-\U x%kQzA)JSfgYKr'@u_&O;^MouE-~R#MKn'\|kn+{ EKOZ\Kjc Oz]I j$Wvh\R-x{HD#W og e$uO)E mSe A&aP+pBmV1lVh%{ e+K~Y0x NH o#V V$dN7r U$i_&w ]F fT[ckqK$Af+Pp,_soc~X1Mw\xz(jD"7y_&pP#/w(M m]emTb|sLTE-[tjc+y WH@E-XO'g{ E-N J]S!mq#}n#NT,]j#k B zU1I<`)WtfuK1t[ Ct O-ak I&qx@t R-Pn` E-p^@ ^N]E-\kgkk J&RY#aabpUr,@f p PlXg^Uu,EOSq ]"cl$rk K&B^qQav#_ On<f)~nO O^BnfqW,N<g)^SfKo<h)za bK [hk<i)Jn1ZJ nK2~Owo)aooS<fmM l$zwE-JR-Z~t)j~E-yE-IS2X^tfE-ZI1jJo{c sj~v)]uJ'mY)T[0}t)LRA[EH\C kE-yv)II1Y_2j E-{ iJx)Y@*gkJ*viGkL*UF2dF/s T%b(q}p@gp|*^&NW']Q"kA|l%[i+lL^+{<IX(g_ hugO,CP GTW%cP E-sD_BOal%po!AgZ R\cbwa!Gr.VO-eWug[ EzVl$fmv LFGYVGc$eg^ uOFbIVw4H _D!oO@gQ,PK!aBI\p x#LC![Z/iWO-zWR-JF-ZWR-if.y SGw,VS-e X$tE~DX/BaR-RW/baO-r7iBJ Q7b`WO-ph E!@PC _Nd*m|| iKC Z Fil x-jI\W@hr-wOEV.ULhhdI-L X^gliz~Kx-ZciS.x XG-l(Ur eOxO.G-AUw4p ec p sL.AgPT x_T RoZ.}Q/Ms \OiOw{1E NTYE-c!rw4 E-A G.P_&^t1mu1|QKvr,Y; Oi Oy RHXX~ VfQvJEWS U-aTspac rrw4UA~!O`^}m~wPw bPqgb@tBQE OSMbMO-q R-A O-QMX$ag\ q&R-B_R Ob6{!r0bA6z!QK`6y!o6f/~V M {m&H |B/LO]h a l}`1z Ok Oz MImX ^/f xu iDOS> Ob8 LpYBW "tM- i.ATgQ {x[.G5iV-r(e5kuN.DvERU!WT bf Pu_nC _!qD ^.M G[T TjK{aOIe-<GY e`|"oX~ MLX.[ E-j5Ay VIE!YX.iF xY OG OW eeAs"qQl@`lO-oh Y!m M-m^od=lu"in) yMy5bFX'V5Nemt VD^&Z&O-i5Wy5cH5RW5jg5nv5TF5YW5df y uJRCD@#GQ U5kd:q$s5oC y S H!b J-r {BX.QO!_g!@ R-awSq}D J-SJcj@J-Oy _H!n _~5O^ X.nVg|~@#zeH TWR#f ]ut UDCYrhNxw H!FR*VV1d: Ss{SAvOD#_  o:y$O:z$]MW.l^|\LN S^MY.lMQ.|Me!K\ZchOW.vOY.FUO:Vs~PT ANOQ.]Z%lu Q"zk,H:x$WR!hvIxXU EfLk^p{_  kn wo$.Iw bF @%VJs[eo@pOK"^K"m m|y iJoYu!xy bYc/h Ex@ [H CW? Bft Lu FD IT HdOrLFBr \+H*N&YJ"g: ey_G9 BW9 [f=Q uH"Db8SgE KqPK_ O~mNN/^A M^ Y\^ ^lBr|I J;I!XBtgcv^ SEB[XR*g ]v\ D^ R bkrx-AnnQ!}bMS!]KqmT^oo f~uMm \Qvz_pA@^ zOh 3_F"R F ` Xo a~G"MZ T*]F"m^ y{oTJ^ u^E"mi0}mLsZj JiT*s fC PQo0bu0q aAz0P X` Oo{.} ZLl[^&j_&ysHN&WB1fL"v;z-FO&V WeatY"Rj`cok2~v `M@&[i2j; Syg X.G{.VZfO X.uN&DR-SO-boh5qH tfx'uS\ Oj|cx, ^.G{.U|Zd Es|SDiSv!bN&pXBR-A xP_ xn S}O-KX Z|Qiw{cE{s.TO&bv VrSHxcVE eR&tyVCT&Y_/hlx\.GX*VHe ^.tIB ^.Qqc_" ^.nf| ^.KZ&Y ^.h^&v& ^.Ed'S) Ob_&pA OR-Mc\^'m X.|\'JZ X.YXgGv[jEO-oOe!~8x!MmP\_ Olv>z^ Oxy$Fz$Td X.cq$qx$Av gRX.yKMHr?Wc MV[g8w!Esc/Tw QdSLuMAtRaWaaw#pud0MYOap#h`Rrwp ^.iB%w ^.QeR#_{ foh}| fOev]ameD#~eV1N G]\k GJe^Ynkf@#zi^.I X.X"guI Q-YmMiiE-v e-Fr^.TrE-dkztx^.n ^.~xE-Mk A\z^.]zE-mW}jK{W"i{U"wU0G ^.Vx `di *r^.\{Lj Oy{R G OW@ Be OtN YB O[K"i e-x{vF e-W? [e. Ot|U"B8 OQU0`~& od0{bKR M[|LlO{|R K|v[G"l}U"{: _J}LZ: di}R xt OH |X}vgvxS"Gq WLgwK^wKUR evuzN0FYB8vR nv}o kNR yvHR Y Y-hdXxvPqa_!w#@BcR qvA iRx.azow~^/Mw\^/kn"xz[-r7 J_7 [nt}7 a$KsZmpibYSilx[Ga c"WUgSv_ ]"EE*T^ UjPzG"I^ NX&hpNK] mk b{HKQiCyT-WLe^tP COcxriBbQi`1 jns|RKi\OkQ{T-KnYLh^wOFRUQfK*v0mFT-VBwdt[Li^xUGOX^.gE"uGME0 ^/Te NcRqQB} RdaioC~e]wlKC%JuXkhgMw| EMT &blHtX lguvH"E{TmdBsIDE"TVdLtG cCMQ_`vpA@DPI_MoV}mMA]bllL|@ &LfrNQSpuO/ x,_HW2oHV2}=R-L=O-ZO&i;lyR-HO-VO-e,Ft,O2C,D2S,M2a,R/q,N2@,R-P,O-_,L2n$D2}+_K$J2[$I2j$R-y&MH$O-V%re%Dt%hD%kT%jc%\r%dA%WP%Y_%cn%T}%RN _&^ `2m ^&|G2JN&XT&g\.vR&ESSKbcrZ&@^&O_&^O&mC2}E-LD2\ R&j T&x \.G Z&V ^&e _&tA2CN&Q O&`R-pL@^&Ol]_&mb|$C2Lg[\1jgxc_GDOWRXgUXvcR-EcLUcC eUF1tPMBOC1PI@1_IXmLX|QKMLZPjXxUG`Vae@tAC(MRc`OoW0~ k.Ms\&LkMzOIfYX&gOwe/GWUG&2Cle2b/Q2a/`Mp H  mO F_ KnM}@bfK Sq o.@ p.R_aWLoU w%~y-Mx-[x#id-xf-FgG1Ugo%dj,si,BfQK,aN,r yAnP {` Go w} t$LcZ j!i{m+y MH _W{Zgnu lE _$T Mc `$q Q$@ R$Oa#^kClWLzS U"IS Q#Y~u)i~Wx~s)HO U"XO Q#hII#x<d)GX)WW)fv$uL)EK)VM)gdxu(Ft(Tq cS"ss(CV"Rf(a Gq? O\KN.]U(K MY _hH G.xf FBf MBCPe l`2L$E-[R-kaLyKH6HXI1g Ox H Gl%WuhW'w iF MT Wb br I+B K'R Hbx,q O@sI1Osl%`ZGq eZE!NO^OXlFX{C}0JCXXrgDvhF`V7F'eF (t9X.\6X.j~yrITXRiNy_HOW ifOtODOTOd k!t l!C I/R Gal/p l!{kN iy I/G k!V Me]!Cls_ %u_ O-T R-d Lt i!CU/R waY/qE/@ a&NC/]Sk X$He B&WV cfV I+uV bEV WUV ie R!sP.BT PJ.pB.~]MI\c-x\-SFoZ-Y G.gl-u6 m%b#p_ %[S6 G1nr}-w[mRn cpm~Fb\?bl?c|# e-KE:Y.tS Ob Or*@ M^NlF-z O-I R-Y Li$x rV ne hu kE jT \c dr WA YP c_ Tn RR-OO-^Lmp x{iJ wXR,hX,wdEhSAa X$o[~ uL D%]}+l|SzjMn[Oj ~z |I }X ^.g Cu GD AR Bakpp+~lM{l+[njWyuOGj+W q#f xt_ %qBs sV+D S$THcC$tE$Ck Ru#d}#tbBQ!R0~bkDr\/Agg!OR<1`z)Qu)`Wor)S h.QgT `g{+q& X.@& F O& @#^gV l) E!{) X.K) F Z])iv$y' x,H' H!X' y h' J-wtnF7 ^U7 V1g7 D#v7 vF7 R#VO h.e~r)tv$F(vV9y&g+ X.u+ F D+ @#Sf.a E!O X._ F nIH#|t"M/ H!]/ y m/ J-|I)K ^\ V1n D#} vM R#]slD|}Ky&Yh"ggx+u"x&FgM V^(Sgge+zY-I-S XU#e-Y uQ--E' PE G.\j jKTJ-k`hoD Z.KS+Y|P@h-q'x@#FO'Uxd}tMDk/R m*a h&q cA-X(PS/^ t*m Z|wOK `&[-zj-{z-|J-Z(Z Oj@z b!W g.e `!t g.Ck C&Qw,`e G1oz Z.~SLM[:B j6 o%yyeHQ"mohL{LFG V%M-Q\-Rn-S-TPq w,a U%p-d s NB"NY] d$vn*FxTo#eq,s(R DN)SD}(eE|(uuvDT2z"y&H nVxegL sgED OUE-e OtI CT(Q ca bq [As2PL^1OmKm'|l%KU\I1l O}@XML\ESk m!~ r&N n\_.ku"y O[z wk n{ S%JnY]ci xxN+G MVM$d cs I+B)X.Rt faJ$ol,~ OO O_kN*oG~ OL n\grk i|)!J OX i!h `!w OF nVI1e| ~v Ot uDDRG$n} E-~f GNh Y'U-gC|f k j.j #xh Y'[D-"rBet-fAS j.Tf Lb j.n O|X*L-kGvh Y]}h Y'Z-QGAa <VHJ5^ bS icj.q-^}  W|F>L| - @JIEJqNOhN Yh]CLEI:Q j.Ko vSZM&mH:SUoMw P|t-OgLJWs-iXJY+b-uCM "P@rj*A-hJPh Y'ZH#A h.d-Dsp }Co-dV@bWVA:m-ksg-jBZx*\-IGk-}QrsxCmT{ j.Of 8]~_U@ St wGtV-vsex ~X{OV-JHeh 2mj &_a-AEEg&JaAmpi /] j.LD6[b+SQEBd OfD -{kta*_{ (Iz 5qRfv*uo vD_# Oc`s| 5C j.xnGu)W "@# nbG+qQ@J!\aN}zUK|H`_=hn  eg\,E j.VDg"nd-qGRw\PYZ FiF8od0gh6 YFWk c]OlUc|g6_l6U -K; j.xH j.Fa6 <XTjL!lQ$?M OL`G[ cbq 6 H%qs 6 C1VH-GfOY-IIhPQ qD o LBD"GNRyUR-rNLE@~ ZEbot_-\QS j.dC"N SNroQ@ R*QXwP` sp| 7m)vUQ!_@`/@ug oODOn)SSJ|cFL\TSVp EFbTD"igQO $OP% M_b O T/pVf_F*E NoA I+~H8NF FROfVOuSfbDMdf-GJO#ZIG}JGDD#K[d n} j.RI0aMQ@`~N~wL`c\? j.~_nM f${ wI j.W] ''e-CLoo \nG KW1RTICs )Lj^uETSq "gC&Izio|2Xa j.JftXE6L^ufBB6hUZ.^pl`AJebKyOm`m|cviw4G_os{V ]naqK-y'|Sf'J T$qw4`@ b_t poHY_ |xrhGa6olueM>Zg{XoStbqnjS}S}D"MPM!B|]uZ"Ybc {l q^=j.Opi]F&Fe9K1l n]{lb9c{}Zj.ij.xk)FfvoBeD8AK(ylDaF eg -tsa{rO @P ^-o'|-p'KeK1Zj)Kt-toa_+p-f@Pp^o&m'mk&r#Th&8wEoc*u$~ j.bf rpFbD""qodLSD"S_[rFqA Y-_ j.nFS | Y-[_ %Fj| pq~aMl\N kaz}!Hu!WPf TviG OVr(/dASZ1SdY.wQFyUpHcSkJz{V6JQ$9@iyaGU2WWfC*7v Omph{ccpdrf&Vf cgn2Fp2TLbe"rm@KOc_yXBj"Zl"hm"z{RLo"^p"pq"iOh`i /qJR2`v"Rcg/cJR|Ra"x,s] 'rCLuRE~"U"dcsbBdQ` _) @#lBO5zIWoSiFboI+- uO% O^{_nG\ MD blg_{I bLD x[T 2kK q0JL Szf bIikF2yIK#XL Jh]~ xN nXfcgI]&FqllWXzrhI^&ZL"&@I+fk ivk WDk I+Tk bdntWODIg-RIvoE=nF{ka j.fgxuQ|mI^EiNnII-L] e 'Byf M{Rg~Jn x"Hn oWc gZSFw4wY Ox j.G\#Vt iet xsZ/C> er{ MAc OX (`ej.HW M@WzWe#vMDg#Rh#ci#q A#@IOl#nm#}B#LF O[ OiKwC*7Fj } WOr#^iv !ms#NZ]t#m\_|S3[|# NuZ"[j.} iMj.\ bjF$ziI]o2X WJ iYV  h bH cXVdgN$K~Ywx j.UY[cj.~egLhj !siTt c~`qT Y-Qb`cpfY.]Sl@ N0{Jk^j.{^x#JYh !Y^Pz^PI j.Xv fCMu^SBnj.Q PaFIpeW K1yj.jQ @y K*yx#HPWPfW.uC^ "E{bg k$I IZFk?h GgAuS l!D Te~W avrW (/U\T!D ceOs LA[Pb T _{V6Ti BuJk !w nX^ m gb s"Ge IVuP _f!O fo{W V6UOKsiYtBRO $`iDtb9S G%LH&^q@D` XDy |,\? bHOWhe]-sOAQT_fsBAe_UmdKX qYlJ X%h? xw? iGsVO oJt b~l ONu JU\nZquO wxK |lCcoR #~O #@aS O l!a yB j._ qnm j.[j.j py j.x j.GA WWTgj&EeO K1kL&\ SB \OP j._X_nCO *%M X.rod(@R"hYO v "J nLl' ix ]GF% U!MbO S"[\O T!}d^+ i}@X.K8 i[cjBj.IIiX pOf8 bu3 iD. j.R lb`aBA iaW'o hKV8 xaFO 2qA bPZ&`U&FA clG{[WFW 2sI I+RcO bC SAX(O {C wG SzD rHuWQ"vcW XI cv S ]EK j.bN npbO cJx.^l qLIw} S3tR G1gTv j_GC ;fo-aZ K*NZ R*^cNm dP{D mK[ j.x@.Gvonua B c\rh j.QA"f2`g j.R eI` j.itObwkYe j.Dm j.S zfb j.H^MWo j.dNZsk j.Mr j.]ZUmu+B]dQXFuw u+{X%KH %pS0U| wE xT R;L wG nV ~ j.u qC j.b vXp [IH Z`Q u\q W[M P] dAl c%m L,R aa cL@ ZL L&\ Ol j.{ PK x,j Xpy J-i j.y y H LW u|v J-r ZdA y e H!t x,D z T Y1b z S T1a vHR RIZ AmCc if {)t j.] TAn YJo Tfy L w#_ ]aB Xc s.A d(O iw OF j.V \!d e&E `U j.e c4s Mg ] EZ}!@#W!F e! Plt! !`! j.o!X.~!E!M!@#]!F k!u+Jz!+bY! xx!EG!&[U! j.e!bu!YE!+BeT!j.y!uw?J!WI!dX!+D@g!\g!jv!pAE!kd!7j.s!cB!b T P!C*%p!OU!K*c!Q$sM!q}@!w Pt}! Oq!M@!+T!^!Ay!nx!j.G!+V9U!bcN!X [.m!+@E[!9T`!m"t!9#oV!LE!$j.b!hNp!L'~!M'M!N'\!K k!P'K!R9#Z!Q'}!gL!S'[!T'm!3O|!V'K!u9Z"Z!X'|!iJ!gi!5_&P!5^&_!r-n!5V1[!5D#j!5vz!a5 J!j.j!V1x!D#G!vW!C&g!j.M!Y"[!Dq!}!DV1M!DD#\!pl!Dj.}!cMK!cTZ!Mj.k!H)z!Oj.c!C)r!X#[!PV1~!PD#M!Pv]!{0m!b#|!P_!U^&o!U`'~!Uj.M!c[!ZV1z!Zj.I!BW!As!`@O!M@O!#OO!t-^!r(pK!a[{!L[]K! Ah!ebKFw!9M0}!M5m!}b!Kj.~!#L L!oj.X!m&mwf!{]!sj.z!K[H!KZW!z f!uj.F!y T!Ku't!Kv' C!Kw' N!Kx'Z!UvPl!}j.|!F Y-K!xZ!ww!j.S!KX|b!v ^!KN6~!DK"Bt!@(v!A(F!KzpU!oKdjE!j.o!D(~!KR>M!t&K!Xq!KZ'@!j.g!KQ(u!itp]!HM!K[<\! j.X"j.f"KMKt"j."j.N"KMV\"p&r"KYBX"j.Z"KTNh"o v"KVsV"j.I"K^:W"bQ"n `"m @"K_P`"l p"k#P"i#s"Ks?V"g#U"Kalx"d#d"h0G"l0U"] K'C c"Mf"j0u"n0D"E-S"m0b"KC Sr"RE"B"T"T 2c"@"B"q0R"KS-b"VOO"\KO.m"O["xy"uI"$KR.W"~$OE"bc"x,A"H!Q"y a"\(p"`"F ^"Xm"a|"_(J"r0Y"] ~ i"1I"4X"/g"c(v"d(F"f0U"e(e""k,t"g(B"h(R"i(b"j(r"k(B"@Q"O`"m(o"~"o(M"p(\"q(k"K,z""J-f""y v""H!E"bU"I+e"Fu"v(T"j.d"c  r"p0Q" w(a" j.q"~0" nO"[X%^"^1C"R"S"[1b"{r"g1A"Dx"_Q"D x{kp"h1["j.j"T"y"wI"k1X"R2h"b"v"D"d2V"l2e"DE"|t"D E{Cp"Vs"j.B"X"R"e b"M,q"IA"w"P"DJ_"DD"6n"D\Od"G,s"D D{DB"IF"j.U"F,d"C)s"B,C"B)SR"Le"At"f*D"On"n~"bN}M"J J"S l!Z"}{"H)K"G)SZ"Cs"m#t+O#f^#en#N}#yM#_#\#x#v+N#s+^#D"?n#\sm#p`#E*ud o#O+S#i*b#/j.q#N(@#uO#/P)^#E(m#H(|#qK#bNVZ#k'p#% n#f_N#<Om#<n}#R'M#_ %L\#_h#\w#qF#}$SU#D {ph#>j.X#Ej.f#EY-v#^j.E#I xT#S)d#It#T)C#uJ2Q#vC#I iR#U)Sa#uJ/t#D ic#Zr#V)SA#L Y.T#Y)c#Z)r#[)B#\)R#IJ#a#uJPp#<^)@#caQ#`O&r#uB#vsa#Kj.A(9#O(CNr({ A$@(Bm%^(} A*l(Dm%K(AQ8Y(Fj.Q(A@_(a_(I[~(yVM(_ #c(LP+F(Q'U(Nj.|(U \J(L)f(T GO(q V(@t(u+R(^*b( #Oq(D/@( j.N(r\(y |+j(j.U(vc(j.q(M(_G/^(_j.m(\{( I+I(wj.Y(].i(l&--w(i&f%Cd(Hg(Ju(~f'C(|j(kOI(KUX(f&l.m(ynyS[(_*n(`*}(J/SL(a*_(N/n(O/~(Uk{M(NH(vj.W(Nf(}#bZv(NP)zj.`){4n)Nb)}j.p)}D~) I+B)j.Q)wd__)N~)j.L)N\)Nl)||)NK)P![)Nb*|)V/M)d/])d/l)O|)e*Z)tOBb)f*d)j.l) j.z)h*I)k*Q)l*Y) ka) [/L)y[)Oz)bJ)r (=Y)o*V)C+^)I "f)bH)mX) Wg)G+w)@"@ FF) iL)L+Z)D2"8i)2nGa)^[%h)R#M) j.\)Z+j)Cy)2F-H)R"u)H&%@W)g+W)zztf)k+Z)D,i)E,x)sG)2[-z)t#Cgg)H,N)C])|  "l)g/N)I+])bm)W})iM)R)[),D)Z,p)],~)h/SM) ~8`)^X) v,j) |,x) },G) ~,V) Ye)od_u)] '\T) F3p)G-c)fQP)Oa)nq)u-@)fQm) H0~)nn)f-})fSj) I+})nM)g-\)fdI) Nm)nL)ovf[)'.A)no)h-~)RFk)fdq)y&U)nd)x&s) j.C)sR)t"a)s/q)K6B)j.x)t/F)u/V)`)f)z/t){/B)v/dJ)w4+G6n,w4|/ d,}/ m,~/ v, ,@, H/P, A-`, v0p, B-A, HR, C-d, D-u,1[-4TF,[-4ScZ,[-4Qm-[-4M ~0D[-4NK0I[-4kNY0[-4e D1[-4di1B[-4ZM1[-4r=g1_ bgY1[-4Mr@1[-4p0M2[-4|}3K[-4Aly3[-4Hwz3+]9B4[-4n({4[-4Wi5[-4n@6I dGn6_ @bu6[-4z6W6[-4BWǀr(Z UȀ%NoрQ9$%~рeK1cҀ9#TTӀc#hր%bK׀%E[׀u&i׀<xO؀#]^؀p}؀x2mڀu9wx_ۀe9K5W݀+ALހ+T[ހ+Mlހ9E V{ހr9(QQm8bA 98LZ/mfC9XVup9AK2cjb 9T x8j.XOgC9*%uMyZsBS~#US-x[`ez9z7E#s |a-[#f'H#g'XZMgu#JtSXSMXkB^CRg aJN[H ec\Kr g}"xL| [t{\/Ja#Yb#hc#wd#FN-TZ|2AZN&OZY-^Z}2mW{2D|Zz2@v2Ox2ImYQv2YvD""Ou2%qw20Vw4~2Fy2Uw4+I3cfG3r+H3@E3&Pb1Qvkj.U+D3~cB3aC3#oF3R0A3!`ml%AmI1Pmu_mj.n g3|+]3Liw\ wk Y3zz.`IB iS-xZ3GI"V[3ec3tZ3Ca3Rwaipd3x,Nb3^C&nwV3}_3RG1`R#nv~D#NV1^^mb3BOF `x,oqb3NO^H nY3~@#NF ]Zlx|x,Lb\X.l@#{E!J+M3BZj.\r,n IjS3#s+P3fR=d'Y-ab4mpd4b ]D `%D a%ND Y-]y4slx4H_