*E`Nswl2 5DN4+,INNNoneScreenSlideMapScreen ScreenSlideSetTextCoreSystemCreateControlScreenSlideRankingGetClientHeightTotalGetClientWidthTotalReplaceScreenSlidePage ArgumentDrawprepareEngineUWindow TextHeightCreatedScreenSlidePageWebColorAddItemNoneHex FadeColor TextWidth Component InStrFromSetDescriptionArgumentNumberEntitySetFontTileTickbAlwaysRelevantArgumentAlignUMenuArgumentColorFindInventoryType EntitiesClientPaddingBottomClientPaddingLeftClientPaddingRightDrawTagScreenSlidePageItemText ArgumentFont CacheLoad CacheSave IsDisplayed ClientHeight ClientWidthWrap PreBeginPlayScreenTriggerAddPageGetSelectedIndexClientPaddingTopRenderNotifyStartText DrawIconRenderTexture SendTextHeightTriggerInfoCaptionColorTeamOpenConsoleCommandCloseSlideEffect_SlideTopSlideEffect_Replace bNoDelete CaptionFont EntryPadding EntryHeightSlideScroll_WrapNetworkGameOnlyFontHeadingColorFontNormalColor FontHeading GetLocalURL FontBigBoldFontBigFontNormalBoldTextAlign_Right bAlwaysTickStructTextFormat CoordDepth CoordVert MapRightMapLeft MapBottomShowGoldInvisibleShowGreenInvisibleMapTopShowRedInvisibleShowNeutralInvisibleShowBlueInvisible ShowGreen ShowBlue ShowGold ShowNeutralPlayerDisplayAlignVertShowRedPlayerDisplayPlayerIconsHeightPlayerDisplayAlignHorzFontPlayersColorWidthPlayerIconsWidth FontPlayersZoneDisplay_OutsideZoneDisplay_InsideDisplayAlignVert_BottomPaintGetLookAndFeelTextureDisplayAlignVert_MiddleDisplayAlignVert_TopDisplayAlignHorz_RightDisplayAlignHorz_Center SetEditableDisplayAlignHorz_LeftSetSelectedIndexCoordSelection_ZCoordSelection_YCoordSelection_XSlideAction_ExitingEffectExitSpeedEffectEntrySpeedScrollVertSpeedScrollHorzSpeed ScrollVertSlideAction_NoneSlideAction_EnteringBackgroundTileBackgroundScroll AlignVert AlignHorzSlideAlignVert_BottomAdjacentSlideAlignVert_TopAdjacentSlideAlignVert_BottomSlideAlignVert_Middle SetMultiLineSlideAction_ScrollingSlideAlignHorz_RightAdjacentCaptionSlideAlignHorz_LeftAdjacentSlideAlignHorz_RightSlideAlignHorz_CenterSlideAlignHorz_LeftSlideEffect_FadeSlideEffect_SlideBottomSlideEffect_SlideRightSlideAlignVert_TopSlideEffect_SlideLeftIpDrv EntryCountCached ReceivedText BindPortIpAddrToStringClosedOpenedResolveFailed ResolvedConfigNetwork_AlwaysResolveConfigNetwork_Network AddressPort InfoColor AddressPathScreenUIPageNetworkScreenUIScrollClientAbout FontNormalExecuteScreenSlidePageItemImage StructSwitchConfigNetwork_Never AddSlideSlideScroll_NoneScreenSlidePageItemBotpack CaptionColor AddressHost InfoFontTextAlign_CenterTextAlign_LeftScreenUIScrollClientNetworkScreenUIMenuItemScreenUIFramedWindowScreenUIPageAbout PlayerIcons ScrollHorzSlideScroll_BounceScreenUIClientWindow PlayerLocalTextureBackground ByParentCanvasBackgroundNoneObjectPropertyUT_invisibilityFloatPropertyCanvas ButtonCloseFontLevel LabelTitle ThisPawn ControlEventControl UT_StealthPlayerReplicationInfoClientScriptedTexture BoolPropertyGameReplicationInfoPagesBuffer AddressIpAddressLocalPortEnumSlideAction MenuItemTcpLink InternetLinkNetworkNoneIpAddrUMenuModMenuItem Viewport IntProperty SlideSwitch SlideCurrentScreenBackgroundScreenForegroundNoneUWindowPulldownMenuItemUpdateSlideCurrentAckSwitchTriggeredPaletteOriginalDirectionHorzDirectionVert CountSlidesOffsetTopSlideOffsetLeftSlideTimeDisplayedFade OffsetTop OffsetLeft Triggers timeDeltaFlagCompletedQueryEventInstigator IndexSlideClientWidthTotalClientHeightTotalClientWidthDisplayedClientHeightDisplayedOffsetTopTargetSlideImageUWindowClientWindowOffsetTopTotalOffsetLeftTotalOffsetRightTotalOffsetBottomTotalDirectionVertPrevDirectionHorzPrevThisOffsetTopThisOffsetLeft ThisSlideThisSlidePrev ActionPrevActorPawn ColorDebug ScreenMaster TextureTile FlagTiled StrPropertyOffsetLeftTexture LinkMode NewSlideSlidePreviousEnumSlideScrollPort BackgroundPage SmallFont ZoneInfoHealth GameInfoFixedAreaClassRootWinTopEnumSlideAlignHorz WinWidth WinHeightWinLeft DrawUpBevel WindowTitleEnumSlideAlignVert LevelInfo CreateWindowGetPlayerOwnerUWindowLabelControlUWindowPulldownMenuUWindowWindowUWindowDialogControlUWindowRootWindowUWindowComboControlBackgroundColor PlayerPawnScriptedTextureBitmapPaletteUWindowFramedWindowUWindowDialogClientWindow EffectEntry EffectExitUWindowSmallButtonUWindowSmallCloseButtonEnumConfigNetworkUWindowScrollingDialogClient SlideNext SlideOverlay FlagSeenPlayer TextOriginal TextSearch TextReplace IndexCharIndexCharLast TextResultVSize ColorFade ColorResult ScreenFonts Tahoma10 Tahoma20 TahomaB10 TahomaB20 Condensed30ScriptedScreenTimeEnumCoordSelection ClientClassLeftDynamicLoadObjectEnumDisplayAlignHorz NamePropertyClassPropertyStaticSaveConfigEnumDisplayAlignVert bIsSpectator ReturnValueGEnumZoneDisplayTopRBAction TalkTextureNewItemDeaths PlayerID ScriptTextLinkFormatOwnerNetMode TimeSecondsRegionYZonebWaitingPlayerNone StartTimeTileTopScore TileMaster CoordHorz TileLeft PlayerNameCoordDepthMinCoordDepthMax ZoneClass ZoneDisplayLocationPlayer HealthPlayerFlagPlayerVisible ZonePlayer IndexInfoFlagDisplayedCoordLeftPlayerCoordTopPlayerCoordDepthPlayerOffsetLeftPlayerOffsetTopPlayerUSize WidthIcon HeightIcon TextDisplayOffsetLeftTextOffsetTopText WidthText HeightTextNoneNoneTextureStructPropertyEnumTextAlign PRIArray FlagDebugTextureCanvasIndex FontText ColorText AlignTextFlagUnderline TextCapsResultOther SelectionNoneFlagCompletedVertFlagCompletedHorzZ TextCached ItemFirst ThisItem ItemLastItemNew ItemCurrentItemLinestart AlignPrev ImageNew CountItems IndexFormatIndexFormatCurrentIndexCharStart HeightLineHeightPadding WidthLine WidthIndent WidthMax LengthText PositionLeft PositionTop CharPrev CharCurrentTagTextTagName TagArguments TextArgument TextChunkTextNormalized TextPackageFlagLinebreakDoneFlagLinebreakBeforeFlagLinebreakAfter FlagTruncate FlagTrimFlagWhitespaceFlagWhitespacePrevRole HaystackNeedleTag Truncate LengthWrapLengthCurrent WidthWrap WidthCurrent TextCurrentMapEventClass TextEntityTextCharacterPackage LengthMax LengthPrevConst ArgumentList ArgumentName CharQuote FlagQuoted ArgumentText TextBufferNumberDefault NumberResultObject AlignDefaultEnum ColorDefault Function FontDefaultVectorTextHexEnumSlideEffect PointRegion CacheTextStruct TextEscaped IndexSlotName LocationTeamX CaptionCapsbMaskedOffsetLeftTargetOffsetTopDisplayed InfoCapsOffsetLeftDisplayed ByteProperty CountRankedInfoPlayerRanked InfoPlayerInfoPlayerSwapNoneNoneNone IndexPawn IndexRanked TimePlayerHeightTextCaptionHeightTextInfo TextInfo TextCaption ColorCaption ThisScreenNoneLabelCopyrightLabelSuggestions LabelMailNoneLabelDescription1LabelDescription2LabelDescription3LabelDescription4 ComboNetworkOffsetTopTexture ColorBase ItemNextTextUnderlineOffsetUnderlinePadIndexUnderlineLengthUnderlineWidthTextUnderlineHeightTextUnderlineNoneFormattedDrawCenteredPlaceholdersPlayerPlaceholdersTeam DisplayInitReloadDisplayCached Placeholdersrank RankCompareFormattedWidthDisplayVersion VersionCheck RankIncludeFormattedDraw PostRender AddMutator DestroyedVersionPlayerDisplayPaddingLeftPlayerDisplayPaddingRightDrawTextCentered SetCaption WindowShownScreenMutator RemoteRoleRegisterHUDMutatorSpawnedVersionLatestColorDisplayBlueColorDisplayWhiteFontDisplayBoldFlagDisplayVersionFontDisplayNormalColorDisplayGray TimeLastFlagDisplayCachedFactorOpacity TimeFadeWidthTextAccubFlashVersionDisplayServerFlagVersionAckTimeDisplayVersion OwnerTabVersionDisplayClientThisScreenMutator ThisMutator ParentWindow CoordTopTextUWindowPageControlPageMutatorScreen FlagBoldIndexCharSeparator BaseMutatorUWindowPageControlUWindowPageWindow CoordTop CoordLeftPlayerDisplayPaddingTopPlayerDisplayPaddingBottom ThisGameVersionServer ShowDead InfoGameOffsetTopIconOffsetLeftIconOffsetTopIconSourceOffsetLeftIconSourceTextPlaceholders TimeUpdateInfoPlayerLeadingInfoPlayerLocal ThisInfo TextPrefix TimePlaying IndexTeamIndexParameterValueParameterTextParametersVersionCurrent FlagCachedFlagReloading TimeUpdatedIndexInfoInsertIndexInfoShift InfoFirst InfoSecondLabelPermissionsButtonWebsite PageNetwork PageAboutClipTop ClipLeft ClipWidth ClipHeight bHUDMutatorStyle TimeDisplaySetPosCurXVersionClient FontBoldUWindowTabControlItemMutator DrawColorClipXClipYCurYNoneScreenSlidePageChat InternalTimeAddText GetItemNextScreenTcpLinkWeb ParseTokenScreenTcpLinkChatScreenSlidePageServerUClampUBitsVBitsVClampScreenUdpLinkServerMipZeroGetItemScreenSlideMapAnchoredGetPlayerIndexMessageSendCtcpResponse MaxColorTimeOut CalcOffsetParseResponseTimerDrawMap BeginStateSetInfoMessageSendRawMessageFormat ResolvingSay InfoServerPlayersSorting GetInfoGameReceiveInfoServer AddChannelMessageSendCtcpQueryPlayersCompareReceiveInfoGame MessageSendGetInfoGetInfoServerParseNicknameSender RetryCountAddressServer ShowSelfAddressChannel UpdateSoundTPlayerPlayersSort_PingPlayersSort_TeamPlayersSort_NameIconsType_TeamsUpdateSoundVolumePlayersSort_ScoreTeamSayPlayersSort_IdViewportAnchorPositionVert TimeCreateViewportAnchorPositionHorz PlayersSort PlayersCountGetLocationPlayerSendSayScreenUpdLinkServerTemplatePlayer TemplateMessageSendPublicIconsType_ClassesMessageConnect MessageError MessageJoin MessageLeaveMessageNicknameMessageReceiveActionMessageReceivePrivateMessageReceivePublicMessageSendActionMessageSendPrivate ScreenClient PlayersSwap TimeTick SendWatching ModifyPlayer RetryDelayRegisterMessageMutatorMutatorTeamMessageActorSlidePageChatActorSlideMapIRC_ERR_NOSUCHSERVERIRC_ERR_TOOMANYCHANNELSIRC_ERR_BANNEDFROMCHANCoordsIRC_ERR_BADCHANMASKPageChannelNextTextScrollback IdPlayerPrev CoordsAnchor SendSayTeam TextAdded NameStateActorSlidePageTextArguments TextChatIRC_ERR_NOSUCHCHANNEL TextRequest AnimCurrentIRC_ERR_NOORIGIN AnimNextIRC_RPL_ENDOFMOTD TextQuery RotationIRC_ERR_ALREADYREGISTEREDIRC_ERR_CHANNELISFULLFlagFormatUnderline FlagTagCloseIRC_ERR_INVITEONLYCHANIRC_ERR_BADCHANNELKEY CharMessageTextFormattedTextTagIndexScrollbackOldest TextTagStackTextTagStackCompleteActorSlidePageServer FlagUpdateEnumPlayersSort Palette1 NameTypeOffsetTopItemIRC_ERR_ERRONEOUSNICKNAME nextPawnStateSoundIndexScrollbackNextNonePlayersSortReverseIndexScrollbackEngineVersion FlagDisabledFlagConnectedTextRecipientZonePlayerAck IpAddrSender IdPlayer TextItemName TextPlayerTextPlayerListTextNicknameRecipientVectorAnchorHorz IndexPlayer2IpAddrResolvedPlayer1Player2UpdateSyncBackground PlayerTempTextureIconsAckSlideMapMaster TextItems TextName TextDefaultOffsetTopAnchor TextItemActorSlidePageWebFlagFormatBold PawnPlayerCountTagStack PageChannel Palette3 ActorScreen VectorItemActorSlideRankingIndexTagStackYAxisTextTagArgumentsOffsetLeftAnchorVectorAnchorVertProjId ActorSenderUdpLinkCountNicknameTries Palette11 SlideSource Palette15RotatorEnumIconsType VectorNormalTextNicknameBase TextToken TextColor bTeamGameOffsetLeftItem IpAddrServerVectorAnchorHorzProjPingXAxis TextReceivedViewportScaleVectorAnchorVert ActorTriggerAddr TextUsernameViewportAnchor Palette7VectorNormalProj FlagMasterPlayers CharUsernameScaleViewportLocationPlayerAck FlagBeepTextureBackgroundNext CountPlayersLocationAnchorAck PawnListTextNicknameSenderIRC_ERR_NOMOTD ActorSlideUpdateSyncIcons TextNicknameTextNicknameSuffixOrigin Palette5 TextResponse TextMessageTextureIconsNext Palette9 TextCommandTextureBackgroundAck TextLineCRLF Translocator PawnReceiver IndexPlayer Palette13 ReturnTargetHealthPlayerAckRotationAnchorAckCoordDepthItemIRC_ERR_NICKNAMEINUSEUpdateIntervalViewportDirectional Palette17 FlagBoundIRC_ERR_NICKCOLLISIONPlayerIconsType ThisPlayer ThisClient IndexPlayer1FlagPlayerVisibleAckNone LevelEntryGetEntryLevelNoneNextHUDMutator^hGU[LKJI3"2"9"*"+")"CFE$ AD$ AC$ AB$ AJ]JVVVVZ @VcVVkg{(::$::$w6Mz*H =GGGGGGGGGGGGu ]Z!Z!Z!Z!Z!Z!Z!Z!Z!Z!Z! = =G =GZ! = = = =Z! =Z! = =Z! =GGGG = = = =GG = =GG = =G = =G =G = = = =Z! =Z! = =Z! = =G = =GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGZ!=$:ex~"o"A"X]lVRQwi0xWi0i0i0i0i0VVKV)VVVVbVV VVbVVd@VVCVVUVVfVV&@VV@VVtVHf-KA@i0VVpVVVVV~VVD@VVRVVJVVVV>VVAVV@@VVkVV%VV'VVGVVNVVVV VVSVV+@VV@VVlVVYVV/VVQVV-VV@VVVV7V VVVVqVzVV@VVZ@VV VVVVs@VV,VVVVMVoVNVVY@VVhVVvVVW@VVrVV@VV|VVzVVKVVqVVWVV VVOVVVVVVC VVBVVWVVHVVnVV[@VVTVVVV4VPVFV\Ve@VVyVV^V(VVpVVC@VVRVVHV[ VVSVVhVVbVG @ViVg@VVVVVuVDVV}VVl Vz VaVj!@ VVV_ VVEVVW V bV@VV}VVx VVCVVVVVV"VVVoVJVVVV.VVI@VVEVV0VV @VV`VJVf@VVxVVVV^ VVcV{VVtVVd VVs@VVx@VV~V{VY@VV\VVz@VVuVV` VVVV^V]V`VVVV`VVJVlVZVV` VoVVIVVmVVVV@VVVVb@VV|VVVV]VVU@VVVVA VVj@VVVVVV@~VLVVwVVpVV_@VV}|WVyVV{@VVFVV;VVOVEVVVVAV~VVxVVP VeG~] ::$@JTLLeot%> Yz +z +z +z +z +u ]> Y = =z] mb.link-m.dek"Pm]/screen/news.html`O=]76

[No Data]

XE ]DVVDVV<VVNV8VVcB VaVNVwVIUrT.i0Z!VVMVXVV@VVBVV]VV]VMVZV#VV[V5VVJVVt VcVVdVVVVVwVVfVVhVVB VVTVVnVV VVm VVhVVVVXVVoVV\VV?VV}VV]VVzVVHVV|VVVVwVVVVkVVJ @@VVqVVOVVVVo@VVFVVB@VVVV@VVKVqVVMV\ VJVz WVj VVR VVSVVlVV$VVDVVV VVTVVvDNVs VdhV\@VV@ VVvVVM@VVVVVVH VlVVqrw  VgTv  ::$Yeot%GT.T.T.T.Z!T.Z!T.T.T.T.i0T.i0T.i0i0i0i0KA@i0KA@KA@KA@i0i0i0i0i0KA@KA@i0KA@KA@i0i0i0i0i0i0i0i0i0i0i0i0i0i0i0i0i0i0i0i0> Y{#U{#U{#U{#U{#U{#U{#U> Y> Y> Y'n 6'n 6{#U{#U{#U{#U{#U{#U{#U{#U{#U{#U{#U{#U=]Enter text here.pVUTRQ*P*#]YVVxVVCVXIH][ZYVkM1 VG@VV_VKVGHRAVV{VzaV=VVAVVVVS VV{VVuVVf@VVx@VVQ`VgVV*VV}VVeVV[VVRVVNV @VVSViVPV^|zyV]@VcVQVPVGV_VmVOVS@VVR@VV3VVy@VVfVXsrVIxwtVD XVLVV\VVAVVYIVuVeVa\PONMVhXWVUSV^V{2YV\hV[ VLVhVVi@VVuVV_ ! VK VVVVvVoVVp@VVwVVY V`VV[ Vq VVVwXVZXVVVUVVyVXyn"{I2˵_4 = = = =_4_4_4_4_4_4_4 =VVVVVV:VVLvVBVV@VVYVV] Va VVVVH@q~E G)~7`7`7` = =M]M]VVgVFoa@2JHMo o VVjvVVVdVVIV@VvVLVVR@VV}V{VT@VCV6ikAV9I˕ = => Y> Y?{ =7XÕ = =7XVV_Vf VVxVV[@VVNVV~VVVV@VVa ViVViMsVd!@Ve!Vd!@V^VV@VlVVohjtVvVK% VUVHbom9[`$VEc~nfz$VVOBzaT?O $D6B )$D6B :$D6B  Vc5G9-d/-p : n:$9::$ -g: n:$::$|  VFVVz 9/^N%N, 9N@Bz9&"99&iz9&"99}9&N@pp"9"p9N'&&\&%&&& npp&, &, Crpp&, &, uqpp&"&, p&&&&}%vb VPg}i)gahbliDb VYZ..Z 1 -2 2 !-1 '3 .-0 5+0 ;4 H+1e N5 U+2 [6 b+3 h7 u+4a [ VbVVt~6 %~~B%B}~E~B&E ^0 ,  y1 ,&  2 ,,  3 ,,  4 ,,  5 ,,  6 ,,  !7 ,,  =8 ,,  Y9 ,,   uA ,,   B ,,   C ,,   D ,,   E ,,  F ,,  B  VrVVVVsn%sk)naor`pD` VBVVza8m{ae&&a@e&@e,uza@&;Iae@e&@)}I%aI     " " < < > > & & ä  5ö  Lü  cÄ  zÖ  Ü  ß   Ippae ae}I VV{Vr0 vk'\6%kpp\\&, '~, %pp\n&k '~, % pp\r&W'~"+%Wpp\q& %C%C, C@pp""Ceb VVVk@VVdVVB // ============================================================================ // ScreenUIScrollClientNetwork // Copyright 2001 by Mychaeel // // Scrolling client area for Network tab in Screen user interface. // ============================================================================ class ScreenUIScrollClientNetwork extends UWindowScrollingDialogClient; // ============================================================================ // Created // ============================================================================ function Created() { ClientClass = class 'ScreenUIPageNetwork'; FixedAreaClass = None; Super.Created(); } Vz // ============================================================================ // ScreenUIScrollClientAbout // Copyright 2001 by Mychaeel // // Scrolling client area for About tab in Screen user interface. // ============================================================================ class ScreenUIScrollClientAbout extends UWindowScrollingDialogClient; // ============================================================================ // Created // ============================================================================ function Created() { ClientClass = class 'ScreenUIPageAbout'; FixedAreaClass = None; Super.Created(); } Vn falseVVVSp ~6v-C(UpU=r%r}pDoopr&zo" zo'-C zgo-C-Cgoz-CzzzD zD zpr}UUJpr}UgJ&[zg" zg'JJ&~pJ&ggwJJ~pJ  r!(J Vn` hR1`^`c`P VOs Qu d% QaX}\CQaX}~gR|%sd w(*Qa?{?R?_?_?(?(((-tD?O?(,<NX-I( $6=,6$6$X $6$6$6=,X $$6$6=,6$X U$6=,6=,6$X +S+ +%p(+ +%sSD(+ +%dSD(+ +%tSt-T++Q4a?{_,?R+C*F* *%p(* *%sSD(* *%dSD(* *%tSt -H**QBa?{_,?R_~*gCR_F[ VVVi1^uN-#-[ U %!-wQ :O:$drA**Q a/A)rD*rQ Dv:O:$frA*,Q a/A)rD*wQ Dl:%-^#@ %-QE:&-u#@ %-OF:,-V#@ %-_F:,-f#@ %-eF:,-b#@ %-L V\r4jdF=N&N}=kGG=N&FFN&FrFNAFs-[ B%zG  {k N}=BN=FNBB5B}=+{=B& 5BI=B==BsrIA\FI VVViVV|l(fhs@o%8o}lllool VaN!ic<z:N8%DyDND8%Nia??D?8?8?8?888--UD8I"-U:8  V_ VVIe 5$ %rW*WG::$H x/a0 uJ [[10rJ *J a u/a0 e 10we *e  |J e n J  VXVVVV`L&ʀzL&#6=L&,6=L,,6=L,,:6%:6%:6%f L BLACK6$6$6$  MAROON6$6$6$  QGREEN6$6$6$  OLIVE6$6$6$  NAVY6$6$6$  PURPLE6$6$6$  TEAL6$6$6$  SGRAY6$6$6$  SILVER6$6$6$  RED6=,6$6$  LIME6$6=,6$  &YELLOW6=,6=,6$  ZBLUE6$6$6=,  FUCHSIA6=,6$6=,  AQUA6$6=,6=,  WHITE6=,6=,6=,  f VB // ============================================================================ // ScreenUIMenuItem // Copyright 2001 by Mychaeel // // Menu item for Screen user interface. // ============================================================================ class ScreenUIMenuItem extends UMenuModMenuItem; // ============================================================================ // Execute // ============================================================================ function Execute() { MenuItem.Owner.Root.CreateWindow(class 'ScreenUIFramedWindow', 0, 0, 300, 220, , true); } ZC2[idє;aGնmo %VVZBl`9i~RBS*i%iiB VU^B"NG/a0 pD6MpzU6xpz10 V_VVpVVlQ$'~;Q LEFT$ #CENTER$ 0RIGHT$ R V7o GScreen Configuration?,?, VZ V* V` {* VHVVOU F%{U'vFF~{FyHF%Fv{pp{Fx{F}yF}x{ VF@VVB Aurj k*"fw"*"-a"-a'k"""]rk*A]AA]"k]AA-a'"w"*"-a"-a(""] VeV6uC<6i?:6V:6iX6uC<6i?:6V:6iX6uC<6i?:6V:6iXu Vha>3H rl* _ %b %_ c$`:i,b m:im $riQ b %Q -*:i:Q b m,b m i@ %_ b@ lb,v hm,aGa?v ?@ ?m?b?b ?_ ?m?bll- Vjbj. AA?,(?j)Screen ComponentS xj &B . A0B?,(?B 4Free for noncommercial use and distribution.}. A`B?,(?}:Feedback, bug reports and suggestions are welcome.w. AB?,(?w=Copyright 2001 by Mychaeel, mychaeel@planetunreal.comS . AB C?S Visit the Screen Website` G  xS Update Screen Component V P;EI P S :L, G  x>Fstart http://www.planetunreal.com/screen/download.html1Fstart http://www.planetunreal.com/screen/  VK^{-HJ^%zSH^H+M VV"6x::$ ,wa* t.Irt* B@r*qr6Mz* 6MzL*6Mz*r6Mz :@:$6Mz*wL@$B$Lw* t. ,/ ,Q/ O. $.'/|&%}$%x'UPw*'|, &Screen: Too many layered slides, starting with slideW tq r$QQ' o $' //'o $' U ,//'QQ' o 3$' U //'o l$' UQQ' o z $OO$  $$ ..$ .$$ U ,..$OO$  g$$ U ..$ $$ UOO$  |}$|x'|UPH%2H|H}.Hx/H0Q/-O.Y0%4]-%7q $ $%% $%4,/ $ $%40 z $ $#%D "$#7,.D '$ A$#7-D G#%7E%%4_j:@:B@ ;$5? ?% ?#Z $8 $ ?78 $ ?48 $ ?08 "$ ?-8 5$58 _ \$_M&K&_ B@@ F $Z $-' $ ]  ?#- ?# ,$ ]  ?%- ?% w$ ]  ?%- ?% $ ]  ?#- ?#  $5]B55?-5? C - ?# ?%@$ $w w $ ?#-W'C  $-W-7 ?# -W  ?-?% ?7 Z  ?--W ?-?%C @ $WK-W-7 ?#= -W K& ?-?G]K  K ?GK&  K& Z  Z  ?G]-?G-WKWC v o $ ?%-V';  $-V04 ?% -V  ?0?% ?4 \  ?0-V ?0?%; 8 $TM-V04 ?%5 -V M& ?0?EYM  M ?EM&  M& \  \  ?EY0?E-VMT; --V-W ->_mw]*w6Mz*@$ $d $-' $ ^- ?-?% F$ ^- ?0?% ~$ ^- ?4 $ ^- ?7 $5^B55?-5  v:@:B:@:$-gr6Mz*6Mz]*(Switching to slideW6Mz VmS ZNP1S[SPSM VI // ============================================================================ // ScreenUIFramedWindow // Copyright 2001 by Mychaeel // // Dialog box frame for Screen user interface. // ============================================================================ class ScreenUIFramedWindow extends UWindowFramedWindow; // ============================================================================ // Created // ============================================================================ function Created() { ClientClass = class 'ScreenUIClientWindow'; WindowTitle = "Screen Configuration"; Super.Created(); WinLeft = (Root.WinWidth - WinWidth) / 2; WinTop = (Root.WinHeight - WinHeight) / 2; } VI@VV^// ============================================================================ // ScreenUIClientWindow // Copyright 2001 by Mychaeel // // Dialog box content for Screen user interface. // ============================================================================ class ScreenUIClientWindow extends UWindowDialogClientWindow; // ============================================================================ // Controls // ============================================================================ var UWindowPageControl Pages; var UWindowSmallCloseButton ButtonClose; var UWindowTabControlItem PageNetwork; var UWindowTabControlItem PageAbout; // ============================================================================ // Created // ============================================================================ function Created() { WinWidth += 4; Pages = UWindowPageControl(CreateWindow(class 'UWindowPageControl', 0, 0, WinWidth, WinHeight - 24)); Pages.SetMultiLine(true); PageNetwork = Pages.AddPage("Network", class 'ScreenUIScrollClientNetwork'); PageAbout = Pages.AddPage("About", class 'ScreenUIScrollClientAbout'); if (class 'Screen'.default.VersionLatest > class 'Screen'.default.Version) { PageAbout.SetCaption("Update"); PageAbout.bFlash = true; } ButtonClose = UWindowSmallCloseButton(CreateControl(class 'UWindowSmallCloseButton', WinWidth - 53, WinHeight - 21, 48, 16)); Super.Created(); } // ============================================================================ // Paint // ============================================================================ function Paint(Canvas CanvasBackground, float X, float Y) { local Texture TextureBackground; TextureBackground = GetLookAndFeelTexture(); DrawUpBevel(CanvasBackground, 0, 0, WinWidth, WinHeight, TextureBackground); } VVVw// ============================================================================ // ScreenTrigger // Copyright 2001 by Mychaeel // // Provides a trigger that switches a Screen actor to a given slide. // ============================================================================ class ScreenTrigger extends Triggers; // ============================================================================ // Compiler Directives // ============================================================================ #exec texture import file=Textures\ActorTrigger.bmp mips=off flags=2 // ============================================================================ // Properties // ============================================================================ var() ScreenSlide SlideSwitch; // ============================================================================ // Trigger // ============================================================================ function Trigger(Actor Other, Pawn EventInstigator) { local Screen ThisScreen; foreach AllActors(class 'Screen', ThisScreen, Event) { ThisScreen.SwitchTriggered.SlideSwitch = SlideSwitch; ThisScreen.SwitchTriggered.Update++; } } // ============================================================================ // Default Properties // ============================================================================ Vzz. AA?,(?zNetwork Accessz &<. A,B?,(?<Live Content Downloads<Full Access<Restricted Access<No Access<{(<}: nH. AB?,(?x. AB?,(?w. AB?,(?L. AB?,(? Vt;<  rH* <8 %H<Grants live-feed screens permission to download livex=content from the Internet even in single player mode.wALive-feed screens usually voluntarily restrict themselvesLto network games. &H=Restricts all Internet access of live-feed screens tox:network games (when you join a network game or runw8a listen server) even if they request otherwise.L ,HAPrevents all live content downloads by live-feed screens.xNot recommended.wL  Vuf;]V)f $<!:^&'  VVVr@VVvEGlz<8 )% n$] A& n$] Z, n$]  -E s]6@{8 P = =]HVVK?,K. ?,KQ'a K7Network n` K7About m G  x` B Update` -'D. ?,5?,@BA V}_u72tv_t Vs@VVAVVtVVuVVq#>! JC\C ' Vh// ============================================================================ // ScreenSlideRanking // Copyright 2001 by Mychaeel // // Implements a ScreenSlide that displays the current player ranking. // ============================================================================ class ScreenSlideRanking extends ScreenSlide; // ============================================================================ // Compiler Directives // ============================================================================ #exec texture import file=Textures\ActorSlideRanking.bmp mips=off flags=2 #exec obj load file=Textures\ScreenFonts.utx package=ScreenFonts // ============================================================================ // Properties // ============================================================================ var() int EntryCount; var() int EntryHeight; var() int EntryPadding; var() string Caption; var() bool CaptionCaps; var() Font CaptionFont; var() Color CaptionColor; var() bool CaptionColorTeam; var() string Info; var() bool InfoCaps; var() Font InfoFont; var() Color InfoColor; var() bool ShowNeutral; var() bool ShowRed; var() bool ShowBlue; var() bool ShowGreen; var() bool ShowGold; // ============================================================================ // Variables // ============================================================================ var PlayerPawn PlayerLocal; var float TimeUpdated; var int CountRanked; var PlayerReplicationInfo InfoPlayerRanked[32]; // ============================================================================ // Prepare // ============================================================================ simulated function Prepare(ScriptedTexture TextureCanvas) { if (TimeUpdated == 0.0 || Level.TimeSeconds - TimeUpdated >= 0.1) { Rank(); TimeUpdated = Level.TimeSeconds; } if (CountRanked > 0) ClientHeight = CountRanked * EntryHeight + (CountRanked - 1) * EntryPadding; else ClientHeight = 0; } // ============================================================================ // Rank // // Determines the current player rankings and fills the global variables with // this information. This function isn't necessarily called each time the slide // is rendered. // ============================================================================ simulated function Rank() { local GameReplicationInfo InfoGame; local PlayerReplicationInfo InfoPlayerSwap; local PlayerReplicationInfo ThisInfo; local int IndexInfo; local int IndexInfoInsert; local int IndexInfoShift; if (PlayerLocal == None) foreach AllActors(class 'PlayerPawn', PlayerLocal) if (Viewport(PlayerLocal.Player) != None) break; InfoGame = PlayerLocal.GameReplicationInfo; if (InfoGame == None) return; CountRanked = 0; for (IndexInfo = 0; IndexInfo < ArrayCount(InfoGame.PRIArray); IndexInfo++) { ThisInfo = InfoGame.PRIArray[IndexInfo]; if (ThisInfo == None) break; if ((ThisInfo.bIsSpectator && !ThisInfo.bWaitingPlayer) || !RankInclude(ThisInfo)) continue; for (IndexInfoInsert = CountRanked; IndexInfoInsert > 0; IndexInfoInsert--) if (RankCompare(InfoPlayerRanked[IndexInfoInsert - 1], ThisInfo) > 0) break; for (IndexInfoShift = CountRanked; IndexInfoShift > IndexInfoInsert; IndexInfoShift--) InfoPlayerRanked[IndexInfoShift] = InfoPlayerRanked[IndexInfoShift - 1]; InfoPlayerRanked[IndexInfoInsert] = ThisInfo; CountRanked++; } CountRanked = Min(CountRanked, EntryCount); } // ============================================================================ // RankInclude // // Returns whether this player should be included in the ranking. // ============================================================================ simulated function bool RankInclude(PlayerReplicationInfo Info) { return (Info.Team == 0 && ShowRed) || (Info.Team == 1 && ShowBlue) || (Info.Team == 2 && ShowGreen) || (Info.Team == 3 && ShowGold) || (Info.Team == 255 && ShowNeutral); } // ============================================================================ // RankCompare // // Compares two players and returns a positive value if the first item is // larger than the second, a negative value if the first item is smaller than // the second, or zero if both are equal. // ============================================================================ simulated function int RankCompare(PlayerReplicationInfo InfoFirst, PlayerReplicationInfo InfoSecond) { if (InfoFirst.Score > InfoSecond.Score || (InfoFirst.Score == InfoSecond.Score && (InfoFirst.Deaths < InfoSecond.Deaths || (InfoFirst.Deaths == InfoSecond.Deaths && (InfoFirst.PlayerID < InfoSecond.PlayerID))))) return 1; return -1; } // ============================================================================ // Draw // ============================================================================ simulated function Draw(ScriptedTexture TextureCanvas, int Left, int Top, float Fade) { local int IndexPawn; local int IndexRanked; local int PositionTop; local int TimePlayer; local float HeightTextCaption; local float HeightTextInfo; local float WidthText; local string TextInfo; local string TextCaption; local Color ColorCaption; if (CountRanked <= 0) return; TextureCanvas.TextSize("X", WidthText, HeightTextCaption, CaptionFont); TextureCanvas.TextSize("X", WidthText, HeightTextInfo, InfoFont); PositionTop = Top; for (IndexRanked = 0; IndexRanked < CountRanked; IndexRanked++) { if (InfoPlayerRanked[IndexRanked].TalkTexture != None) TextureCanvas.DrawTile(Left, PositionTop, EntryHeight, EntryHeight, 0, 0, InfoPlayerRanked[IndexRanked].TalkTexture.USize, InfoPlayerRanked[IndexRanked].TalkTexture.VSize, InfoPlayerRanked[IndexRanked].TalkTexture, InfoPlayerRanked[IndexRanked].TalkTexture.bMasked); TimePlayer = (Level.TimeSeconds + PlayerLocal.PlayerReplicationInfo.StartTime - InfoPlayerRanked[IndexRanked].StartTime) / 60; ColorCaption = CaptionColor; if (CaptionColorTeam) switch (InfoPlayerRanked[IndexRanked].Team) { case 0: ColorCaption.R = 255; ColorCaption.G = 0; ColorCaption.B = 0; break; case 1: ColorCaption.R = 0; ColorCaption.G = 0; ColorCaption.B = 255; break; case 2: ColorCaption.R = 0; ColorCaption.G = 255; ColorCaption.B = 0; break; case 3: ColorCaption.R = 255; ColorCaption.G = 255; ColorCaption.B = 0; break; } TextCaption = Caption; TextCaption = Replace(TextCaption, "%p", InfoPlayerRanked[IndexRanked].PlayerName); TextCaption = Replace(TextCaption, "%s", int(InfoPlayerRanked[IndexRanked].Score)); TextCaption = Replace(TextCaption, "%d", int(InfoPlayerRanked[IndexRanked].Deaths)); TextCaption = Replace(TextCaption, "%t", TimePlayer); if (CaptionCaps) TextCaption = Caps(TextCaption); TextureCanvas.DrawColoredText(Left + EntryHeight + 16, PositionTop, TextCaption, CaptionFont, FadeColor(ColorCaption, Fade)); TextInfo = Info; TextInfo = Replace(TextInfo, "%p", InfoPlayerRanked[IndexRanked].PlayerName); TextInfo = Replace(TextInfo, "%s", int(InfoPlayerRanked[IndexRanked].Score)); TextInfo = Replace(TextInfo, "%d", int(InfoPlayerRanked[IndexRanked].Deaths)); TextInfo = Replace(TextInfo, "%t", TimePlayer); if (InfoCaps) TextInfo = Caps(TextInfo); TextureCanvas.DrawColoredText(Left + EntryHeight + 16, PositionTop + EntryHeight - HeightTextInfo, TextInfo, InfoFont, FadeColor(InfoColor, Fade)); PositionTop += EntryHeight + EntryPadding; } } // ============================================================================ // Default Properties // ============================================================================ EM1FyrpG{#U{#UZ!{#UZ!{#U{#UZ!> Y{#U{#U{#U{#U{#U{#U{#U{#U{#U{#U{#U{#U{#U{#U{#U{#U{#U{#U{#U{#U{#U{#U{#U{#U> Y> Y'n 6'n 6{#U{#U_"M" L"T-%pKy*DC]%s frags, %d deaths, %t min{l*hjfeg#]FVV]t// ============================================================================ // ScreenSlidePageWeb // Copyright 2001 by Mychaeel // // Implements a ScreenSlidePage that gets its data dynamically from the web. // ============================================================================ class ScreenSlidePageWeb extends ScreenSlidePage perobjectconfig; // ============================================================================ // Compiler Directives // ============================================================================ #exec texture import file=Textures\ActorSlidePageWeb.bmp mips=off flags=2 // ============================================================================ // Replication // ============================================================================ replication { reliable if (Role == ROLE_Authority) VersionLatest, AddressHost, AddressPort, AddressPath; } // ============================================================================ // Properties // ============================================================================ var() string AddressHost; var() int AddressPort; var() string AddressPath; var() bool Cached; var() bool NetworkGameOnly; // ============================================================================ // Configuration // ============================================================================ var config string CacheText[32]; // ============================================================================ // Variables // ============================================================================ var PlayerPawn PlayerLocal; var ScreenTcpLinkWeb Link; var ScreenMutator MutatorScreen; var int VersionLatest; var int VersionCurrent; var bool FlagCached; var bool FlagReloading; // ============================================================================ // PreBeginPlay // ============================================================================ simulated function PreBeginPlay() { Super.PreBeginPlay(); if (Cached) CacheLoad(); FlagCached = class 'Screen'.default.Network == ConfigNetwork_Never || (Level.NetMode == NM_Standalone && (NetworkGameOnly || class 'Screen'.default.Network == ConfigNetwork_Network)) || (Level.NetMode == NM_DedicatedServer); VersionCurrent = -1; } // ============================================================================ // Tick // ============================================================================ simulated function Tick(float TimeDelta) { Super.Tick(TimeDelta); if (PlayerLocal == None) foreach AllActors(class 'PlayerPawn', PlayerLocal) if (Viewport(PlayerLocal.Player) != None) break; if (VersionLatest > VersionCurrent && PlayerLocal != None) Reload(); } // ============================================================================ // Trigger // ============================================================================ function Trigger(Actor Other, Pawn EventInstigator) { Super.Trigger(Other, EventInstigator); VersionLatest++; } // ============================================================================ // Draw // ============================================================================ simulated function Draw(ScriptedTexture TextureCanvas, int Left, int Top, float Fade) { if (MutatorScreen == None) foreach AllActors(class 'ScreenMutator', MutatorScreen) break; if (FlagCached) MutatorScreen.DisplayCached(); Super.Draw(TextureCanvas, Left, Top, Fade); } // ============================================================================ // Reload // // Reloads the slide's content. // ============================================================================ simulated function Reload() { if (FlagReloading) return; VersionCurrent = VersionLatest; if (FlagCached) return; FlagReloading = true; Link = PlayerLocal.GetEntryLevel().Spawn(class 'ScreenTcpLinkWeb'); Link.Page = Self; Link.AddressHost = AddressHost; Link.AddressPort = AddressPort; Link.AddressPath = AddressPath; Link.Start(); } // ============================================================================ // CacheLoad // // Retrieves all information from the cache. // ============================================================================ simulated function CacheLoad() { local string TextChunk; local string TextEscaped; local int IndexChar; local int IndexSlot; for (IndexSlot = 0; IndexSlot < ArrayCount(CacheText); IndexSlot++) { TextChunk = CacheText[IndexSlot]; if (Left (TextChunk, 1) == "\"") TextChunk = Mid (TextChunk, 1); if (Right(TextChunk, 1) == "\"") TextChunk = Left(TextChunk, Len(TextChunk) - 1); CacheText[IndexSlot] = "\"" $ TextChunk $ "\""; TextEscaped = TextEscaped $ TextChunk; } while (true) { IndexChar = InStrFrom(IndexChar, TextEscaped, "\\"); if (IndexChar < 0) break; switch (Mid(TextEscaped, IndexChar + 1, 1)) { case "n": TextEscaped = Left(TextEscaped, IndexChar) $ Chr(10) $ Mid(TextEscaped, IndexChar + 2); break; case "r": TextEscaped = Left(TextEscaped, IndexChar) $ Chr(13) $ Mid(TextEscaped, IndexChar + 2); break; case "q": TextEscaped = Left(TextEscaped, IndexChar) $ "\"" $ Mid(TextEscaped, IndexChar + 2); break; default: TextEscaped = Left(TextEscaped, IndexChar) $ Mid(TextEscaped, IndexChar + 1); break; } IndexChar++; } if (Len(TextEscaped) > 0) Text = TextEscaped; SaveConfig(); } // ============================================================================ // CacheSave // // Saves all cacheable information in a, well, cache. // ============================================================================ simulated function CacheSave() { local string TextEscaped; local int IndexChar; local int IndexSlot; TextEscaped = Text; while (true) { IndexChar = InStrFrom(IndexChar, TextEscaped, "\\"); if (IndexChar < 0) break; TextEscaped = Left(TextEscaped, IndexChar) $ "\\\\" $ Mid(TextEscaped, IndexChar + 1); IndexChar += 2; } while (true) { IndexChar = InStr(TextEscaped, Chr(10)); if (IndexChar < 0) break; TextEscaped = Left(TextEscaped, IndexChar) $ "\\n" $ Mid(TextEscaped, IndexChar + 1); } while (true) { IndexChar = InStr(TextEscaped, Chr(13)); if (IndexChar < 0) break; TextEscaped = Left(TextEscaped, IndexChar) $ "\\r" $ Mid(TextEscaped, IndexChar + 1); } while (true) { IndexChar = InStr(TextEscaped, "\""); if (IndexChar < 0) break; TextEscaped = Left(TextEscaped, IndexChar) $ "\\q" $ Mid(TextEscaped, IndexChar + 1); } IndexChar = 0; for (IndexSlot = 0; IndexSlot < ArrayCount(CacheText); IndexSlot++) { CacheText[IndexSlot] = "\"" $ Mid(TextEscaped, IndexChar, 1022) $ "\""; IndexChar += 1022; } SaveConfig(); } // ============================================================================ // Default Properties // ============================================================================ VK%// ============================================================================ // ScreenSlidePageItemText // Copyright 2001 by Mychaeel // // Implements a ScreenSlidePageItem that contains and displays an atomic chunk // of text. // ============================================================================ class ScreenSlidePageItemText extends ScreenSlidePageItem; // ============================================================================ // Variables // ============================================================================ var string Text; var Font FontText; var Color ColorText; var bool FlagUnderline; var string TextUnderline; var int OffsetUnderlinePad; // ============================================================================ // Prepare // ============================================================================ simulated function Prepare(ScriptedTexture TextureCanvas) { local int IndexUnderline; local int LengthUnderline; local float WidthTextUnderline; local float HeightTextUnderline; if (FlagUnderline) { TextureCanvas.TextSize("_", WidthTextUnderline, HeightTextUnderline, FontText); TextUnderline = ""; LengthUnderline = Width / WidthTextUnderline; for (IndexUnderline = 0; IndexUnderline < LengthUnderline; IndexUnderline++) TextUnderline = TextUnderline $ "_"; OffsetUnderlinePad = Max(0, Width - WidthTextUnderline); } } // ============================================================================ // Draw // ============================================================================ simulated function Draw(ScriptedTexture TextureCanvas, int OffsetLeft, int OffsetTop, float Fade) { local Color ColorFade; ColorFade.R = ColorBase.R + (ColorText.R - ColorBase.R) * Fade; ColorFade.G = ColorBase.G + (ColorText.G - ColorBase.G) * Fade; ColorFade.B = ColorBase.B + (ColorText.B - ColorBase.B) * Fade; TextureCanvas.DrawColoredText(OffsetLeft + Left, OffsetTop + Top, Text, FontText, ColorFade); if (FlagUnderline) { TextureCanvas.DrawColoredText(OffsetLeft + Left, OffsetTop + Top, TextUnderline, FontText, ColorFade); TextureCanvas.DrawColoredText(OffsetLeft + Left + OffsetUnderlinePad, OffsetTop + Top, "_", FontText, ColorFade); } } Vi// ============================================================================ // ScreenSlidePageItemImage // Copyright 2001 by Mychaeel // // Implements a ScreenSlidePageItem that contains and displays an image. // ============================================================================ class ScreenSlidePageItemImage extends ScreenSlidePageItem; // ============================================================================ // Variables // ============================================================================ var Texture Image; var int ClipTop; var int ClipLeft; var int ClipWidth; var int ClipHeight; // ============================================================================ // Draw // ============================================================================ simulated function Draw(ScriptedTexture TextureCanvas, int OffsetLeft, int OffsetTop, float Fade) { TextureCanvas.DrawTile(Left + OffsetLeft, Top + OffsetTop, Width, Height, ClipLeft, ClipTop, ClipWidth, ClipHeight, Image, Image.bMasked); } VVVVV@VVNVVOVVPVVVVjk?Nk0kk>>(rR*R kkRRRk' Vv#// ============================================================================ // ScreenSlidePageItem // Copyright 2001 by Mychaeel // // Abstract base class for a single positioned atomic item to be displayed on a // ScreenSlideText slide for a Screen actor. // ============================================================================ class ScreenSlidePageItem extends Object abstract; // ============================================================================ // Variables // ============================================================================ var int Top; var int Left; var int Width; var int Height; var Color ColorBase; var ScreenSlidePageItem ItemNext; // ============================================================================ // Prepare // // Performs any preparation that is needed for drawing the item. This method is // called only once immediately after the item is set and placed. // ============================================================================ simulated function Prepare(ScriptedTexture TextureCanvas) { // implemented in subclasses } // ============================================================================ // Draw // // Draws the item, shifted by the given offsets. // ============================================================================ simulated function Draw(ScriptedTexture TextureCanvas, int OffsetLeft, int OffsetTop, float Fade) { // implemented in subclasses } // ============================================================================ // AddItem // // Adds an item to the item list. The item list is ordered by the position of // the upper-left corner of the item to allow for some optimizations when // displaying the items. Returns whether the new item was added after the // one for which this method was called. // ============================================================================ function bool AddItem(ScreenSlidePageItem NewItem) { if (NewItem.Top < Top || (NewItem.Top == Top && NewItem.Left < Left)) return false; if (ItemNext == None || !ItemNext.AddItem(NewItem)) { NewItem.ItemNext = ItemNext; ItemNext = NewItem; } return true; } VVVj// ============================================================================ // ScreenSlidePage // Copyright 2001 by Mychaeel // // Implements a ScreenSlide that can be used to display arbitary formatted // text and other items on a Screen. // ============================================================================ class ScreenSlidePage extends ScreenSlide; // ============================================================================ // Compiler Directives // ============================================================================ #exec texture import file=Textures\ActorSlidePage.bmp mips=off flags=2 #exec obj load file=Textures\ScreenFonts.utx package=ScreenFonts // ============================================================================ // Replication // ============================================================================ replication { reliable if (Role == ROLE_Authority) Text, TextCaps; } // ============================================================================ // Types // ============================================================================ enum EnumTextAlign { TextAlign_Left, TextAlign_Center, TextAlign_Right, }; struct StructTextFormat { var string Tag; var Font FontText; var Color ColorText; var EnumTextAlign AlignText; var bool FlagUnderline; }; // ============================================================================ // Properties // ============================================================================ var() string Text; var() bool TextCaps; var() bool TextPlaceholders; var() Font FontNormal; var() Font FontNormalBold; var() Font FontBig; var() Font FontBigBold; var() Font FontHeading; var() Color FontNormalColor; var() Color FontHeadingColor; // ============================================================================ // Variables // ============================================================================ var string TextCached; var ScreenSlidePageItem ItemFirst; var PlayerPawn PlayerLocal; var float TimeUpdate; // ============================================================================ // Prepare // ============================================================================ simulated function Prepare(ScriptedTexture TextureCanvas) { local string TextResult; if (TimeUpdate > 0.0 && Level.TimeSeconds - TimeUpdate < 0.1) return; TimeUpdate = Level.TimeSeconds; if (TextPlaceholders) TextResult = Placeholders(Text); else TextResult = Text; if (TextResult != TextCached) { ItemFirst = Render(TextureCanvas, TextResult, ClientWidth, ClientHeight); TextCached = TextResult; } } // ============================================================================ // Placeholders // // Replaces all placeholders in the text by their values. // ============================================================================ simulated function string Placeholders(string TextOriginal) { local GameReplicationInfo InfoGame; local PlayerReplicationInfo InfoPlayerLeading; local PlayerReplicationInfo InfoPlayerLocal; local PlayerReplicationInfo ThisInfo; local int IndexInfo; if (PlayerLocal == None) foreach AllActors(class 'PlayerPawn', PlayerLocal) if (Viewport(PlayerLocal.Player) != None) break; InfoGame = PlayerLocal.GameReplicationInfo; if (InfoGame == None) { PlaceholdersPlayer(TextOriginal, "", None); PlaceholdersPlayer(TextOriginal, "l", None); return TextOriginal; } InfoPlayerLocal = PlayerLocal.PlayerReplicationInfo; for (IndexInfo = 0; IndexInfo < ArrayCount(InfoGame.PRIArray); IndexInfo++) { ThisInfo = InfoGame.PRIArray[IndexInfo]; if (ThisInfo == None) break; if (ThisInfo.bIsSpectator && !ThisInfo.bWaitingPlayer) continue; if (InfoPlayerLeading == None || ThisInfo.Score > InfoPlayerLeading.Score || (ThisInfo.Score == InfoPlayerLeading.Score && (ThisInfo.Deaths < InfoPlayerLeading.Deaths || (ThisInfo.Deaths == InfoPlayerLeading.Deaths && (ThisInfo.PlayerID < InfoPlayerLeading.PlayerID))))) InfoPlayerLeading = ThisInfo; } if (InfoPlayerLocal == None || InfoPlayerLeading == None) { PlaceholdersPlayer(TextOriginal, "", None); PlaceholdersPlayer(TextOriginal, "l", None); } else { PlaceholdersPlayer(TextOriginal, "", InfoPlayerLocal); PlaceholdersPlayer(TextOriginal, "l", InfoPlayerLeading); } return TextOriginal; } // ============================================================================ // PlaceholdersPlayer // // Replaces some player-specific placeholders given this player's current info. // ============================================================================ simulated function PlaceholdersPlayer(out string TextOriginal, string TextPrefix, PlayerReplicationInfo Info) { local int TimePlaying; if (Info == None) { TextOriginal = Replace(TextOriginal, "%" $ TextPrefix $ "p", "?"); TextOriginal = Replace(TextOriginal, "%" $ TextPrefix $ "s", "?"); TextOriginal = Replace(TextOriginal, "%" $ TextPrefix $ "t", "?"); TextOriginal = Replace(TextOriginal, "%" $ TextPrefix $ "d", "?"); TextOriginal = Replace(TextOriginal, "%" $ TextPrefix $ "i", "MyLevel.UnknownPlayerIcon"); TextOriginal = Replace(TextOriginal, "%" $ TextPrefix $ "c", PlaceholdersTeam(255)); return; } TimePlaying = (Level.TimeSeconds + PlayerLocal.PlayerReplicationInfo.StartTime - Info.StartTime) / 60; TextOriginal = Replace(TextOriginal, "%" $ TextPrefix $ "p", Info.PlayerName); TextOriginal = Replace(TextOriginal, "%" $ TextPrefix $ "s", int(Info.Score)); TextOriginal = Replace(TextOriginal, "%" $ TextPrefix $ "t", TimePlaying); TextOriginal = Replace(TextOriginal, "%" $ TextPrefix $ "d", int(Info.Deaths)); TextOriginal = Replace(TextOriginal, "%" $ TextPrefix $ "i", Info.TalkTexture); TextOriginal = Replace(TextOriginal, "%" $ TextPrefix $ "c", PlaceholdersTeam(Info.Team)); } // ============================================================================ // PlaceholdersTeam // // Returns a string describing the given team color. // ============================================================================ simulated function string PlaceholdersTeam(int IndexTeam) { switch (IndexTeam) { case 0: return "red"; case 1: return "blue"; case 2: return "green"; case 3: return "yellow"; } return "gray"; } // ============================================================================ // Draw // ============================================================================ simulated function Draw(ScriptedTexture TextureCanvas, int Left, int Top, float Fade) { local ScreenSlidePageItem ThisItem; for (ThisItem = ItemFirst; ThisItem != None; ThisItem = ThisItem.ItemNext) { if (Top + ThisItem.Top + ThisItem.Height <= 0 || Left + ThisItem.Left + ThisItem.Width <= 0 || Left + ThisItem.Left > TextureCanvas.USize) continue; if (Top + ThisItem.Top > TextureCanvas.VSize) break; ThisItem.Draw(TextureCanvas, Left, Top, Fade); } } // ============================================================================ // Render // // Simple html renderer that supports the following tags. Produces a linked // list of ScreenSlidePageItem objects and returns the first of them. // // Default colors for text // Paragraph with large font and alignment //

New paragraph with alignment //
New line // Displays a texture as an image // Sets font color and size // Sets font size // Sets boldfaced font // // All other tags are skipped and ignored, so this parser should in theory be // able to take any existing web page. I don't make any claims about how that // will look, though. // ============================================================================ simulated function ScreenSlidePageItem Render(ScriptedTexture TextureCanvas, string Text, int Width, out int Height) { local ScreenSlidePageItem ItemFirst; local ScreenSlidePageItem ItemLast; local ScreenSlidePageItem ItemNew; local ScreenSlidePageItem ItemCurrent; local ScreenSlidePageItem ItemLinestart; local EnumTextAlign AlignPrev; local StructTextFormat Format[32]; local Texture ImageNew; local int CountItems; local int IndexFormat; local int IndexFormatCurrent; local int IndexChar; local int IndexCharStart; local int IndexCharSeparator; local int IndexParameter; local int HeightLine; local int HeightPadding; local int WidthLine; local int WidthIndent; local int WidthMax; local int LengthText; local int PositionLeft; local int PositionTop; local int ValueParameter; local string CharPrev; local string CharCurrent; local string TagText; local string TagName; local string TagArguments; local string TextArgument; local string TextParameters; local string TextChunk; local string TextNormalized; local string TextPackage; local bool FlagLinebreakDone; local bool FlagLinebreakBefore; local bool FlagLinebreakAfter; local bool FlagTruncate; local bool FlagTrim; local bool FlagWhitespace; local bool FlagWhitespacePrev; // ================================================================ // Initialization // ================================================================ Format[0].Tag = ""; Format[0].FontText = FontNormal; Format[0].ColorText = FontNormalColor; Format[0].AlignText = TextAlign_Left; TextPackage = Level.GetLocalURL(); TextPackage = Left(TextPackage, InStr(TextPackage $ "?", "?")); TextPackage = Mid (TextPackage, InStr(TextPackage, "/") + 1); // ================================================================ // Normalize // ================================================================ IndexCharStart = 0; FlagWhitespace = true; for (IndexChar = 0; IndexChar < Len(Text); IndexChar++) { CharCurrent = Mid(Text, IndexChar, 1); FlagWhitespacePrev = FlagWhitespace; FlagWhitespace = (CharCurrent == Chr(10) || CharCurrent == Chr(13) || CharCurrent == " "); if (FlagWhitespace && !FlagWhitespacePrev) TextNormalized = TextNormalized $ Mid(Text, IndexCharStart, IndexChar - IndexCharStart) $ " "; else if (!FlagWhitespace && FlagWhitespacePrev) IndexCharStart = IndexChar; } if (!FlagWhitespace) TextNormalized = TextNormalized $ Mid(Text, IndexCharStart); Text = TextNormalized; // ================================================================ // Tokenize and Interpret // ================================================================ CountItems = 0; FlagTrim = true; FlagLinebreakDone = false; FlagLinebreakBefore = false; while (Len(Text) > 0 || !FlagLinebreakDone) { ItemNew = None; FlagLinebreakAfter = false; // ==================================================== // Tag // ==================================================== AlignPrev = Format[IndexFormatCurrent].AlignText; if (Left(Text, 1) == "<") { IndexChar = InStr(Text, ">"); if (IndexChar < 0) break; TagText = Mid(Text, 1, IndexChar - 1); Text = Mid(Text, IndexChar + 1); IndexChar = InStr(TagText $ " ", " "); TagName = Caps(Left(TagText, IndexChar)); TagArguments = Mid(TagText, IndexChar + 1); if (Left(TagName, 1) == "/") { TagName = Mid(TagName, 1); switch (TagName) { case "BODY": FlagTrim = true; FlagLinebreakBefore = true; break; case "H1": case "H2": case "H3": case "H4": case "H5": case "H6": case "P": FlagTrim = true; FlagLinebreakBefore = true; HeightPadding = Max(HeightPadding, TextHeight(TextureCanvas, "X", Format[IndexFormatCurrent].FontText)); break; case "FONT": case "BIG": case "SMALL": case "B": case "U": FlagTrim = false; break; } for (IndexFormat = IndexFormatCurrent; IndexFormat > 0; IndexFormat--) if (Format[IndexFormat].Tag == TagName) { IndexFormatCurrent = IndexFormat - 1; break; } } else { switch (TagName) { case "BODY": IndexFormatCurrent = 0; Format[0].Tag = TagName; Format[0].FontText = FontNormal; Format[0].ColorText = ArgumentColor(Argument(TagArguments, "text"), FontNormalColor); Format[0].AlignText = TextAlign_Left; Format[0].FlagUnderline = false; FlagTrim = true; FlagLinebreakBefore = true; break; case "H1": case "H2": case "H3": case "H4": case "H5": case "H6": IndexFormatCurrent++; Format[IndexFormatCurrent] = Format[IndexFormatCurrent - 1]; Format[IndexFormatCurrent].Tag = TagName; Format[IndexFormatCurrent].FontText = FontHeading; Format[IndexFormatCurrent].ColorText = FontHeadingColor; Format[IndexFormatCurrent].AlignText = ArgumentAlign(Argument(TagArguments, "align"), TextAlign_Left); FlagTrim = true; FlagLinebreakBefore = true; if (ItemFirst != None) HeightPadding = Max(HeightPadding, TextHeight(TextureCanvas, "X", Format[IndexFormatCurrent].FontText)); break; case "P": for (IndexFormat = IndexFormatCurrent; IndexFormat > 0; IndexFormat--) if (Format[IndexFormat].Tag == "P") { IndexFormatCurrent = IndexFormat - 1; break; } FlagTrim = true; FlagLinebreakBefore = true; if (ItemFirst != None) HeightPadding = Max(HeightPadding, TextHeight(TextureCanvas, "X", Format[IndexFormatCurrent].FontText)); IndexFormatCurrent++; Format[IndexFormatCurrent] = Format[0]; Format[IndexFormatCurrent].Tag = TagName; Format[IndexFormatCurrent].AlignText = ArgumentAlign(Argument(TagArguments, "align"), TextAlign_Left); break; case "BR": if (PositionLeft == 0) HeightPadding += TextHeight(TextureCanvas, "X", Format[IndexFormatCurrent].FontText); FlagTrim = true; FlagLinebreakBefore = true; break; case "IMG": TextArgument = Argument(TagArguments, "src"); IndexCharSeparator = InStr(TextArgument, "?"); if (IndexCharSeparator < 0) IndexCharSeparator = Len(TextArgument); TextParameters = Mid (TextArgument, IndexCharSeparator + 1); TextArgument = Left(TextArgument, IndexCharSeparator); if (Caps(Left(TextArgument, 8)) == "MYLEVEL.") TextArgument = TextPackage $ "." $ Mid(TextArgument, 8); ImageNew = Texture(DynamicLoadObject(TextArgument, class 'Texture')); if (ImageNew != None) { ItemNew = new class 'ScreenSlidePageItemImage'; ScreenSlidePageItemImage(ItemNew).Image = ImageNew; ScreenSlidePageItemImage(ItemNew).ClipTop = 0; ScreenSlidePageItemImage(ItemNew).ClipLeft = 0; ScreenSlidePageItemImage(ItemNew).ClipWidth = ImageNew.USize; ScreenSlidePageItemImage(ItemNew).ClipHeight = ImageNew.VSize; for (IndexParameter = 0; IndexParameter < 4; IndexParameter++) { IndexCharSeparator = InStr(TextParameters, ","); if (IndexCharSeparator < 0) IndexCharSeparator = Len(TextParameters); if (IndexCharSeparator == 0) continue; ValueParameter = int(Left(TextParameters, IndexCharSeparator)); switch (IndexParameter) { case 0: ScreenSlidePageItemImage(ItemNew).ClipWidth = ValueParameter; break; case 1: ScreenSlidePageItemImage(ItemNew).ClipHeight = ValueParameter; break; case 2: ScreenSlidePageItemImage(ItemNew).ClipLeft = ValueParameter; break; case 3: ScreenSlidePageItemImage(ItemNew).ClipTop = ValueParameter; break; } TextParameters = Mid(TextParameters, IndexCharSeparator + 1); if (Len(TextParameters) == 0) break; } ItemNew.Width = ArgumentNumber(Argument(TagArguments, "width"), ScreenSlidePageItemImage(ItemNew).ClipWidth); ItemNew.Height = ArgumentNumber(Argument(TagArguments, "height"), ScreenSlidePageItemImage(ItemNew).ClipHeight); if (PositionLeft + ItemNew.Width >= Width) FlagLinebreakBefore = true; ItemNew.Top = -ItemNew.Height; } break; case "FONT": FlagTrim = true; IndexFormatCurrent++; Format[IndexFormatCurrent] = Format[IndexFormatCurrent - 1]; Format[IndexFormatCurrent].Tag = TagName; Format[IndexFormatCurrent].FontText = ArgumentFont (Argument(TagArguments, "size"), Format[IndexFormatCurrent - 1].FontText); Format[IndexFormatCurrent].ColorText = ArgumentColor(Argument(TagArguments, "color"), Format[IndexFormatCurrent - 1].ColorText); break; case "BIG": FlagTrim = true; IndexFormatCurrent++; Format[IndexFormatCurrent] = Format[IndexFormatCurrent - 1]; Format[IndexFormatCurrent].Tag = TagName; Format[IndexFormatCurrent].FontText = FontBig; break; case "SMALL": FlagTrim = true; IndexFormatCurrent++; Format[IndexFormatCurrent] = Format[IndexFormatCurrent - 1]; Format[IndexFormatCurrent].Tag = TagName; Format[IndexFormatCurrent].FontText = FontNormal; break; case "B": FlagTrim = true; IndexFormatCurrent++; Format[IndexFormatCurrent] = Format[IndexFormatCurrent - 1]; Format[IndexFormatCurrent].Tag = TagName; switch (Format[IndexFormatCurrent - 1].FontText) { case FontNormal: Format[IndexFormatCurrent].FontText = FontNormalBold; break; case FontBig: Format[IndexFormatCurrent].FontText = FontBigBold; break; } break; case "U": FlagTrim = true; IndexFormatCurrent++; Format[IndexFormatCurrent] = Format[IndexFormatCurrent - 1]; Format[IndexFormatCurrent].Tag = TagName; Format[IndexFormatCurrent].FlagUnderline = true; break; } } } // ==================================================== // Text // ==================================================== else if (Len(Text) > 0) { if (FlagTrim) while (Left(Text, 1) == " ") Text = Mid(Text, 1); FlagTrim = false; IndexChar = InStr(Text, "<"); if (IndexChar < 0) IndexChar = Len(Text); TextChunk = Left(Text, IndexChar); if (TextCaps) TextChunk = Caps(TextChunk); if (Len(TextChunk) > 0) { ItemNew = new class 'ScreenSlidePageItemText'; FlagTruncate = (PositionLeft == 0); while (true) { if (FlagLinebreakBefore) while (Left(TextChunk, 1) == " ") TextChunk = Mid(TextChunk, 1); ItemNew.Width = Width - PositionLeft; ScreenSlidePageItemText(ItemNew).Text = Wrap(TextureCanvas, TextChunk, ItemNew.Width, Format[IndexFormatCurrent].FontText, FlagTruncate, WidthMax); ScreenSlidePageItemText(ItemNew).FontText = Format[IndexFormatCurrent].FontText; ScreenSlidePageItemText(ItemNew).ColorText = Format[IndexFormatCurrent].ColorText; ScreenSlidePageItemText(ItemNew).FlagUnderline = Format[IndexFormatCurrent].FlagUnderline; if (FlagTruncate || ItemNew.Width > 0) break; FlagTruncate = true; PositionLeft = 0; FlagLinebreakBefore = true; } FlagLinebreakAfter = (WidthMax >= Width - PositionLeft); ItemNew.Height = TextHeight(TextureCanvas, "X", Format[IndexFormatCurrent].FontText); ItemNew.Top = -ItemNew.Height; Text = Mid(Text, IndexChar - Len(TextChunk)); } } // ==================================================== // Place New Item // ==================================================== if (FlagLinebreakBefore && !FlagLinebreakDone) { if (ItemLast != None && ItemLast.IsA('ScreenSlidePageItemText')) { for (LengthText = Len(ScreenSlidePageItemText(ItemLast).Text); LengthText > 0; LengthText--) if (Mid(ScreenSlidePageItemText(ItemLast).Text, LengthText - 1, 1) != " ") break; WidthLine -= ItemLast.Width - TextWidth(TextureCanvas, Left(ScreenSlidePageItemText(ItemLast).Text, LengthText), ScreenSlidePageItemText(ItemLast).FontText); } switch (AlignPrev) { case TextAlign_Left: WidthIndent = 0; break; case TextAlign_Center: WidthIndent = (Width - WidthLine) / 2; break; case TextAlign_Right: WidthIndent = Width - WidthLine; break; } for (ItemCurrent = ItemLinestart; ItemCurrent != None; ItemCurrent = ItemCurrent.ItemNext) { ItemCurrent.Top += PositionTop + HeightLine; ItemCurrent.Left += WidthIndent; ItemCurrent.Prepare(TextureCanvas); } PositionLeft = 0; PositionTop += HeightLine; HeightLine = 0; WidthLine = 0; FlagLinebreakDone = true; } if (ItemNew != None) { CountItems++; if (FlagLinebreakBefore) { PositionTop += HeightPadding; HeightPadding = 0; ItemLinestart = ItemNew; } ItemNew.Left = PositionLeft; ItemNew.ColorBase = BackgroundColor; WidthLine += ItemNew.Width; PositionLeft += ItemNew.Width; HeightLine = Max(HeightLine, -ItemNew.Top); if (ItemLast == None) ItemFirst = ItemNew; else ItemLast.ItemNext = ItemNew; if (ItemLinestart == None) ItemLinestart = ItemNew; ItemLast = ItemNew; FlagLinebreakDone = false; FlagLinebreakBefore = FlagLinebreakAfter; } if (Len(Text) == 0 && !FlagLinebreakDone) { FlagLinebreakBefore = true; FlagLinebreakDone = false; } } Log("Rendered slide" @ Name $ "," @ CountItems @ "items"); Height = PositionTop + HeightLine; return ItemFirst; } // ============================================================================ // InStrFrom // // Same as the built-in InStr function, except for the addition of a parameter // that specifies the start position of the search. Should, actually, be // readily available in any decent scripting language. // ============================================================================ simulated function int InStrFrom(int Start, string Haystack, string Needle) { local int IndexChar; IndexChar = InStr(Mid(Haystack, Start), Needle); if (IndexChar < 0) return IndexChar; return IndexChar + Start; } // ============================================================================ // Wrap // // Calculates and returns the substring of characters in the given string that // fits into the given width, wrapping only at whitespace characters. Removes // the substring and all trailing whitespace from the Text argument and returns // the wrapped text chunk's actual width in the Width argument. // ============================================================================ simulated function string Wrap(ScriptedTexture TextureCanvas, out string Text, out int Width, Font FontText, bool Truncate, out int WidthMax) { local string CharPrev; local string CharCurrent; local int LengthWrap; local int LengthCurrent; local int WidthWrap; local int WidthCurrent; local string TextCurrent; local string TextResult; TextCurrent = Text; for (LengthCurrent = 1; LengthCurrent <= Len(Text); LengthCurrent++) { CharPrev = CharCurrent; CharCurrent = Mid(Text, LengthCurrent, 1); TextCurrent = Entity(TextCurrent, LengthCurrent - 1); WidthCurrent = TextWidth(TextureCanvas, Left(TextCurrent, LengthCurrent), FontText); if (WidthCurrent > Width && (!Truncate || LengthWrap > 0)) break; if ((CharCurrent == " " && CharPrev != " ") || LengthCurrent == Len(Text)) { LengthWrap = LengthCurrent; Text = TextCurrent; } } for (LengthWrap = LengthWrap; LengthWrap < Len(Text); LengthWrap++) if (Mid(Text, LengthWrap, 1) != " ") break; TextResult = Left(Text, LengthWrap); Text = Mid(Text, LengthWrap); Width = TextWidth(TextureCanvas, TextResult, FontText); WidthMax = WidthCurrent; return TextResult; } // ============================================================================ // TextWidth // // Returns the pixel width of a chunk of text in the given font. // ============================================================================ simulated function int TextWidth(ScriptedTexture TextureCanvas, string Text, Font FontText) { local float WidthText; local float HeightText; TextureCanvas.TextSize(Text, WidthText, HeightText, FontText); return WidthText; } // ============================================================================ // TextHeight // // Returns the pixel width of a chunk of text in the given font. // ============================================================================ simulated function int TextHeight(ScriptedTexture TextureCanvas, string Text, Font FontText) { local float WidthText; local float HeightText; TextureCanvas.TextSize(Text, WidthText, HeightText, FontText); return HeightText; } // ============================================================================ // Entity // // Returns a string that represents the given string with the entity at the // given position replaced by its corresponding character. // ============================================================================ simulated function string Entity(string Text, optional int Index) { local string TextEntity; local string TextCharacter; local int IndexChar; if (Mid(Text, Index, 1) != "&") return Text; for (IndexChar = Index + 1; IndexChar < Index + 8; IndexChar++) if (Mid(Text, IndexChar, 1) == ";") { TextEntity = Mid(Text, Index, IndexChar - Index + 1); break; } if (Len(TextEntity) == 0) return Text; switch (TextEntity) { case " ": TextCharacter = " "; break; case """: TextCharacter = "\""; break; case "<": TextCharacter = "<"; break; case ">": TextCharacter = ">"; break; case "&": TextCharacter = "&"; break; case "ä": TextCharacter = ""; break; case "ö": TextCharacter = ""; break; case "ü": TextCharacter = ""; break; case "Ä": TextCharacter = ""; break; case "Ö": TextCharacter = ""; break; case "Ü": TextCharacter = ""; break; case "ß": TextCharacter = ""; break; default: TextCharacter = TextEntity; } return Left(Text, Index) $ TextCharacter $ Mid(Text, Index + Len(TextEntity)); } // ============================================================================ // Entities // // Replaces some generic entities by their corresponding characters. // ============================================================================ simulated function string Entities(string Text) { local int IndexChar; local int LengthMax; local int LengthPrev; for (IndexChar = 0; IndexChar < Len(Text); IndexChar++) Text = Entity(Text, IndexChar); return Text; } // ============================================================================ // Argument // // Extracts an argument from an html tag's argument list and returns that // argument's string value. Returns an empty string if no matching argument is // found. // ============================================================================ simulated function string Argument(string ArgumentList, string ArgumentName) { local int IndexChar; local string CharPrev; local string CharCurrent; local string CharQuote; local bool FlagQuoted; local string ArgumentText; FlagQuoted = false; ArgumentName = Caps(ArgumentName) $ "="; for (IndexChar = 0; IndexChar < Len(ArgumentList); IndexChar++) { CharPrev = CharCurrent; CharCurrent = Mid(ArgumentList, IndexChar, 1); if ((CharCurrent == "\"" || CharCurrent == "'") && (!FlagQuoted || CharQuote == CharCurrent)) { FlagQuoted = !FlagQuoted; CharQuote = CharCurrent; continue; } if (FlagQuoted) continue; if ((CharPrev == "" || CharPrev == " ") && Caps(Mid(ArgumentList, IndexChar, Len(ArgumentName))) == ArgumentName) { ArgumentText = Mid(ArgumentList, IndexChar + Len(ArgumentName)); CharQuote = Left(ArgumentText, 1); if (CharQuote == "\"" || CharQuote == "'") ArgumentText = Mid(ArgumentText, 1, InStr(Mid(ArgumentText, 1) $ CharQuote, CharQuote)); else ArgumentText = Left(ArgumentText, InStr(ArgumentText $ " ", " ")); break; } } return Entities(ArgumentText); } // ============================================================================ // ArgumentNumber // // Converts an argument into a number and returns this value. Returns the // given default number if the argument is invalid. // ============================================================================ simulated function int ArgumentNumber(string ArgumentText, int NumberDefault) { local int NumberResult; NumberResult = int(ArgumentText); if (string(NumberResult) == ArgumentText) return NumberResult; else return NumberDefault; } // ============================================================================ // ArgumentAlign // // Converts an argument into a text alignment value and returns this value. // Returns the given default alignment if the argument is invalid. // ============================================================================ simulated function EnumTextAlign ArgumentAlign(string ArgumentText, EnumTextAlign AlignDefault) { switch (Caps(ArgumentText)) { case "LEFT": return TextAlign_Left; case "CENTER": return TextAlign_Center; case "RIGHT": return TextAlign_Right; default: return AlignDefault; } } // ============================================================================ // ArgumentColor // // Converts an argument into a Color value and returns that value. Returns the // given default color if the argument didn't represent a valid color. // ============================================================================ simulated function Color ArgumentColor(string ArgumentText, Color ColorDefault) { local Color ColorResult; if (Left(ArgumentText, 1) == "#") { ColorResult.R = Hex(Mid(ArgumentText, 1, 2)); ColorResult.G = Hex(Mid(ArgumentText, 3, 2)); ColorResult.B = Hex(Mid(ArgumentText, 5, 2)); if (ColorResult.R < 0 || ColorResult.G < 0 || ColorResult.B < 0) ColorResult = ColorDefault; } else { switch (Caps(ArgumentText)) { case "BLACK": ColorResult.R = 0x00; ColorResult.G = 0x00; ColorResult.B = 0x00; break; case "MAROON": ColorResult.R = 0x80; ColorResult.G = 0x00; ColorResult.B = 0x00; break; case "GREEN": ColorResult.R = 0x00; ColorResult.G = 0x80; ColorResult.B = 0x00; break; case "OLIVE": ColorResult.R = 0x80; ColorResult.G = 0x80; ColorResult.B = 0x00; break; case "NAVY": ColorResult.R = 0x00; ColorResult.G = 0x00; ColorResult.B = 0x80; break; case "PURPLE": ColorResult.R = 0x80; ColorResult.G = 0x00; ColorResult.B = 0x80; break; case "TEAL": ColorResult.R = 0x00; ColorResult.G = 0x80; ColorResult.B = 0x80; break; case "GRAY": ColorResult.R = 0x80; ColorResult.G = 0x80; ColorResult.B = 0x80; break; case "SILVER": ColorResult.R = 0xc0; ColorResult.G = 0xc0; ColorResult.B = 0xc0; break; case "RED": ColorResult.R = 0xff; ColorResult.G = 0x00; ColorResult.B = 0x00; break; case "LIME": ColorResult.R = 0x00; ColorResult.G = 0xff; ColorResult.B = 0x00; break; case "YELLOW": ColorResult.R = 0xff; ColorResult.G = 0xff; ColorResult.B = 0x00; break; case "BLUE": ColorResult.R = 0x00; ColorResult.G = 0x00; ColorResult.B = 0xff; break; case "FUCHSIA": ColorResult.R = 0xff; ColorResult.G = 0x00; ColorResult.B = 0xff; break; case "AQUA": ColorResult.R = 0x00; ColorResult.G = 0xff; ColorResult.B = 0xff; break; case "WHITE": ColorResult.R = 0xff; ColorResult.G = 0xff; ColorResult.B = 0xff; break; default: ColorResult = ColorDefault; } } return ColorResult; } // ============================================================================ // ArgumentFont // // Returns a font that matches the given font size as closely as possible. // Returns the given default font if no valid font size is given. // ============================================================================ simulated function Font ArgumentFont(string ArgumentText, Font FontDefault) { switch (ArgumentText) { case "1": case "-2": case "2": case "-1": case "3": case "-0": case "+0": case "4": case "+1": return FontNormal; case "5": case "+2": case "6": case "+3": case "7": case "+4": return FontBig; default: return FontDefault; } } // ============================================================================ // Hex // // Returns the numerical value that corresponds to a hexadecimal number or a // negative value if no valid hexadecimal value was given. // ============================================================================ simulated function int Hex(string TextHex) { local int IndexChar; local string CharCurrent; local int Result; Result = 0; TextHex = Caps(TextHex); for (IndexChar = 0; IndexChar < Len(TextHex); IndexChar++) { CharCurrent = Mid(TextHex, IndexChar, 1); switch (CharCurrent) { case "0": Result = Result * 0x10; break; case "1": Result = Result * 0x10 + 0x01; break; case "2": Result = Result * 0x10 + 0x02; break; case "3": Result = Result * 0x10 + 0x03; break; case "4": Result = Result * 0x10 + 0x04; break; case "5": Result = Result * 0x10 + 0x05; break; case "6": Result = Result * 0x10 + 0x06; break; case "7": Result = Result * 0x10 + 0x07; break; case "8": Result = Result * 0x10 + 0x08; break; case "9": Result = Result * 0x10 + 0x09; break; case "A": Result = Result * 0x10 + 0x0A; break; case "B": Result = Result * 0x10 + 0x0B; break; case "C": Result = Result * 0x10 + 0x0C; break; case "D": Result = Result * 0x10 + 0x0D; break; case "E": Result = Result * 0x10 + 0x0E; break; case "F": Result = Result * 0x10 + 0x0F; break; default: return -1; } } return Result; } // ============================================================================ // Default Properties // ============================================================================ VjSA`AUa?>@?B?,?l?t ?d ?T ?R SS- VcWW@:J^ ^ =t^ {d%cd_d&Fc% VVVhD// ============================================================================ // ScreenUIPageNetwork // Copyright 2001 by Mychaeel // // Content of Network tab in Screen user interface. // ============================================================================ class ScreenUIPageNetwork extends UWindowPageWindow; // ============================================================================ // Controls // ============================================================================ var UWindowLabelControl LabelTitle; var UWindowLabelControl LabelDescription1; var UWindowLabelControl LabelDescription2; var UWindowLabelControl LabelDescription3; var UWindowLabelControl LabelDescription4; var UWindowComboControl ComboNetwork; // ============================================================================ // Created // ============================================================================ function Created() { LabelTitle = UWindowLabelControl(CreateControl(class 'UWindowLabelControl', 20, 17, WinWidth - 40, 1)); LabelTitle.SetText("Network Access"); LabelTitle.SetFont(F_Bold); ComboNetwork = UWindowComboControl(CreateControl(class 'UWindowComboControl', 20, 43, WinWidth - 40, 1)); ComboNetwork.SetText("Live Content Downloads"); ComboNetwork.AddItem("Full Access"); ComboNetwork.AddItem("Restricted Access"); ComboNetwork.AddItem("No Access"); ComboNetwork.SetEditable(false); ComboNetwork.SetSelectedIndex(int(class 'Screen'.default.Network)); LabelDescription1 = UWindowLabelControl(CreateControl(class 'UWindowLabelControl', 20, 74, WinWidth - 40, 1)); LabelDescription2 = UWindowLabelControl(CreateControl(class 'UWindowLabelControl', 20, 86, WinWidth - 40, 1)); LabelDescription3 = UWindowLabelControl(CreateControl(class 'UWindowLabelControl', 20, 98, WinWidth - 40, 1)); LabelDescription4 = UWindowLabelControl(CreateControl(class 'UWindowLabelControl', 20, 110, WinWidth - 40, 1)); SetDescription(); } // ============================================================================ // SetDescription // // Sets the description text for the currently selected network access option. // ============================================================================ function SetDescription() { if (LabelDescription1 == None) return; switch (ComboNetwork.GetSelectedIndex()) { case 0: LabelDescription1.SetText("Grants live-feed screens permission to download live"); LabelDescription2.SetText("content from the Internet even in single player mode."); LabelDescription3.SetText("Live-feed screens usually voluntarily restrict themselves"); LabelDescription4.SetText("to network games."); break; case 1: LabelDescription1.SetText("Restricts all Internet access of live-feed screens to"); LabelDescription2.SetText("network games (when you join a network game or run"); LabelDescription3.SetText("a listen server) even if they request otherwise."); LabelDescription4.SetText(""); break; case 2: LabelDescription1.SetText("Prevents all live content downloads by live-feed screens."); LabelDescription2.SetText("Not recommended."); LabelDescription3.SetText(""); LabelDescription4.SetText(""); break; } } // ============================================================================ // Notify // ============================================================================ function Notify(UWindowDialogControl Control, byte ControlEvent) { switch (Control) { case ComboNetwork: if (ControlEvent == DE_Change) SetDescription(); break; } } // ============================================================================ // Close // ============================================================================ function Close(optional bool ByParent) { switch (ComboNetwork.GetSelectedIndex()) { case 0: class 'Screen'.default.Network = ConfigNetwork_Always; break; case 1: class 'Screen'.default.Network = ConfigNetwork_Network; break; case 2: class 'Screen'.default.Network = ConfigNetwork_Never; break; } class 'Screen'.static.StaticSaveConfig(); Super.Close(ByParent); } VVV_P:4&62%6%e6p%Y6V%$YSYY~pY??YY~Y/&f%-~'%s} s &-C-~-~zs,  zs,  zs H-~ -CWppW ff ii-~-Cf-~WpW f Wu%-'-[(-(} % -[ *-A(p6VV z &<~ >.%j &&  &~pj  jDj&z&/& BODY-'-'{ H1 H2 H3 H4 H5 H6 FP-'-'EEPX6{ OFONT WBIG aSMALL gB xU-({ ??%z62??&?S  ^BODY%62%6%e6p%& DtextY6V%$-6~%(-'-'S eH1 lH2 sH3 zH4 H5 _H6&626q6ps6V$ Dalign$-'-'\w@*EEPX6S RP??%z62?P?&?p-'-'w@*EEPX6%626V$ Dalign$S BRI%EPX6-'-'S IMGY Dsrco~Y?o%o}YzYo&YYo>zY,MYLEVEL.YppY.Y,Z.Y  wZ*  T.T SZ.T d %.T t %.T T Z.T R ZY % Y ,o~z,5o%o}zCo% A JzoY }%.T T A  &.T R A  ,.T t A  ,.T d A  zzo& }z% Y  , Dwidth.T T  l Dheight.T R  I ,d-'  lS FONT-'&626. Dsize6&6p& Dcolor6p&S BIG-'&626aS S SMALL-'&626eS B-'&626& e6` a6t S P U-'&62-6~'S } % - z &   &l -(~ < %} H  -jHH}H%  -qI%P'> -> zH& HH&  ,dI. T4PH ,6-q|. s6. }6p. -y-6~6-q ,%P-q'I%-' -A|dI lPX6  l  }H- -[w;*;a/!-g}.;Tag%W{.;Tg&& ag#h;,P.;Tg.;sp $m% $mdh, $mdh byswb*bryb>mb PbbR I%ryy%h%-['w *u-rEE%y  >I hih ,I ,yy ]r;*@ q;R ry*y ; -[(--A} % -[-'-[(稨pRendered slideW,SuitemsZry@ VS// ============================================================================ // ScreenSlideMap // Copyright 2001-2002 by Mychaeel // // Implements a ScreenSlide that displays the positions of players in a map // on a map of that map. Much legacy code here; if designed from scratch this // class would be much more efficient. Compatibility is the name of the game. // ============================================================================ class ScreenSlideMap extends ScreenSlide; // ============================================================================ // Compiler Directives // ============================================================================ #exec texture import file=Textures\ActorSlideMap.bmp mips=off flags=2 #exec obj load file=Textures\ScreenFonts.utx package=ScreenFonts #exec obj load file=Textures\ScriptedScreen.utx package=ScriptedScreen // ============================================================================ // Replication // ============================================================================ replication { reliable if (Role == ROLE_Authority) FlagMaster, InfoPlayer, LocationPlayer, HealthPlayer, FlagPlayerVisible, ZonePlayer; } // ============================================================================ // Types // ============================================================================ enum EnumCoordSelection { CoordSelection_X, CoordSelection_Y, CoordSelection_Z, }; enum EnumIconsType { IconsType_Teams, IconsType_Classes, }; enum EnumDisplayAlignHorz { DisplayAlignHorz_Left, DisplayAlignHorz_Center, DisplayAlignHorz_Right, }; enum EnumDisplayAlignVert { DisplayAlignVert_Top, DisplayAlignVert_Middle, DisplayAlignVert_Bottom, }; enum EnumZoneDisplay { ZoneDisplay_Inside, ZoneDisplay_Outside, }; // ============================================================================ // Properties // ============================================================================ var() Font FontPlayers; var() Color FontPlayersColor; var() Texture Map; var() Texture PlayerIcons; var() EnumIconsType PlayerIconsType; var() int PlayerIconsWidth; var() int PlayerIconsHeight; var() string PlayerDisplay; var() EnumDisplayAlignHorz PlayerDisplayAlignHorz; var() EnumDisplayAlignVert PlayerDisplayAlignVert; var() int PlayerDisplayPaddingTop; var() int PlayerDisplayPaddingLeft; var() int PlayerDisplayPaddingRight; var() int PlayerDisplayPaddingBottom; var() bool ShowNeutral; var() bool ShowRed; var() bool ShowBlue; var() bool ShowGreen; var() bool ShowGold; var() bool ShowNeutralInvisible; var() bool ShowRedInvisible; var() bool ShowBlueInvisible; var() bool ShowGreenInvisible; var() bool ShowGoldInvisible; var() bool ShowDead; var() bool ShowSelf; var() int MapTop; var() int MapLeft; var() int MapRight; var() int MapBottom; var() EnumCoordSelection CoordHorz; var() EnumCoordSelection CoordVert; var() EnumCoordSelection CoordDepth; var() int CoordDepthMin; var() int CoordDepthMax; var() float UpdateInterval; var() Sound UpdateSound; var() float UpdateSoundVolume; var() bool UpdateSyncBackground; var() bool UpdateSyncIcons; var() ZoneInfo Zone; var() class ZoneClass; var() EnumZoneDisplay ZoneDisplay; // ============================================================================ // Variables // ============================================================================ var bool FlagMaster; var PlayerPawn PlayerLocal; var ScreenSlideMap SlideMapMaster; var PlayerReplicationInfo InfoPlayer[32]; var vector LocationPlayer[32]; // individual arrays for better replication var int HealthPlayer[32]; var int FlagPlayerVisible[32]; var ZoneInfo ZonePlayer[32]; var vector LocationPlayerAck[32]; var int HealthPlayerAck[32]; var int FlagPlayerVisibleAck[32]; var ZoneInfo ZonePlayerAck[32]; var float TimeCreate; var float TimeTick; var float TimeUpdate; var bool FlagUpdate; var Texture TextureBackgroundAck; var Texture TextureBackgroundNext; var Texture TextureIconsAck; var Texture TextureIconsNext; // ============================================================================ // PreBeginPlay // ============================================================================ event PreBeginPlay() { local ScreenSlideMap ThisSlide; foreach AllActors(class 'ScreenSlideMap', ThisSlide) if (ThisSlide.FlagMaster) break; if (ThisSlide == None) FlagMaster = true; else RemoteRole = ROLE_None; } // ============================================================================ // Tick // ============================================================================ event Tick(float TimeDelta) { local int IndexPlayer; local Pawn ThisPawn; if (!FlagMaster || Level.TimeSeconds < TimeTick + 0.1) return; for (IndexPlayer = 0; IndexPlayer < ArrayCount(InfoPlayer); IndexPlayer++) InfoPlayer[IndexPlayer] = None; for (ThisPawn = Level.PawnList; ThisPawn != None; ThisPawn = ThisPawn.NextPawn) if (ThisPawn.PlayerReplicationInfo != None && !ThisPawn.PlayerReplicationInfo.bIsSpectator && ThisPawn.PlayerReplicationInfo.PlayerID < ArrayCount(InfoPlayer)) SetInfo(ThisPawn.PlayerReplicationInfo.PlayerID, ThisPawn); IndexPlayer = 0; for (ThisPawn = Level.PawnList; ThisPawn != None; ThisPawn = ThisPawn.NextPawn) if (ThisPawn.PlayerReplicationInfo != None && !ThisPawn.PlayerReplicationInfo.bIsSpectator && ThisPawn.PlayerReplicationInfo.PlayerID >= ArrayCount(InfoPlayer)) { while (IndexPlayer < ArrayCount(InfoPlayer) && InfoPlayer[IndexPlayer] != None) IndexPlayer++; if (IndexPlayer >= ArrayCount(InfoPlayer)) break; SetInfo(IndexPlayer, ThisPawn); } TimeTick = Level.TimeSeconds; } // ============================================================================ // SetInfo // // Fills the element at the given index of the various replicated arrays with // information about the given player. Overwrite this function if you need to // store and replicate your own information in subclasses. // ============================================================================ function SetInfo(int IndexPlayer, Pawn PawnPlayer) { InfoPlayer [IndexPlayer] = PawnPlayer.PlayerReplicationInfo; LocationPlayer[IndexPlayer] = PawnPlayer.Location; ZonePlayer [IndexPlayer] = PawnPlayer.Region.Zone; HealthPlayer [IndexPlayer] = PawnPlayer.Health; FlagPlayerVisible[IndexPlayer] = int(PawnPlayer.FindInventoryType(class 'UT_Invisibility') == None && PawnPlayer.FindInventoryType(class 'UT_Stealth') == None); } // ============================================================================ // GetInfo // // Fills the element at the given index of the various replicated arrays with // information taken from the given master slide. Called on all clients. // Overwrite this function if you need to store and replicate your own // information in subclasses. // ============================================================================ simulated function GetInfo(int IndexPlayer, ScreenSlideMap SlideSource) { InfoPlayer [IndexPlayer] = SlideSource.InfoPlayer [IndexPlayer]; LocationPlayer [IndexPlayer] = SlideSource.GetLocationPlayer(IndexPlayer); HealthPlayer [IndexPlayer] = SlideSource.HealthPlayer [IndexPlayer]; FlagPlayerVisible[IndexPlayer] = SlideSource.FlagPlayerVisible[IndexPlayer]; ZonePlayer [IndexPlayer] = SlideSource.ZonePlayer [IndexPlayer]; } // ============================================================================ // GetLocationPlayer // // Access method for an element of the LocationPlayer array. It's the only one // that cannot be directly accessed because it's too large. // ============================================================================ simulated final function vector GetLocationPlayer(int IndexPlayer) { return LocationPlayer[IndexPlayer]; } // ============================================================================ // Prepare // ============================================================================ simulated function Prepare(ScriptedTexture TextureCanvas) { local int IndexPlayer; local GameReplicationInfo InfoGame; if (PlayerLocal == None) foreach AllActors(class 'PlayerPawn', PlayerLocal) if (Viewport(PlayerLocal.Player) != None) break; InfoGame = PlayerLocal.GameReplicationInfo; if (InfoGame == None) return; for (IndexPlayer = 0; IndexPlayer < ArrayCount(InfoGame.PRIArray); IndexPlayer++) { if (InfoGame.PRIArray[IndexPlayer] == None) break; if (InfoGame.PRIArray[IndexPlayer].bIsSpectator || InfoGame.PRIArray[IndexPlayer].PlayerID >= ArrayCount(InfoPlayer)) continue; InfoPlayer[InfoGame.PRIArray[IndexPlayer].PlayerID] = InfoGame.PRIArray[IndexPlayer]; } if (TimeCreate < 0.0) TimeCreate = Level.TimeSeconds; if (SlideMapMaster == None && Level.TimeSeconds < TimeCreate + 1.0) foreach AllActors(class 'ScreenSlideMap', SlideMapMaster) if (SlideMapMaster.FlagMaster) break; if (SlideMapMaster == None || SlideMapMaster == Self) return; for (IndexPlayer = 0; IndexPlayer < ArrayCount(InfoPlayer); IndexPlayer++) GetInfo(IndexPlayer, SlideMapMaster); } // ============================================================================ // Draw // ============================================================================ simulated function Draw(ScriptedTexture TextureCanvas, int Left, int Top, float Fade) { local GameReplicationInfo InfoGame; local int IndexPlayer; local int IdPlayerPrev; local int FlagDisplayed[32]; local int CoordTopPlayer; local int CoordLeftPlayer; local int CoordDepthPlayer; local int OffsetTopPlayer[32]; local int OffsetLeftPlayer[32]; DrawMap(TextureCanvas, Left, Top); if (MapTop == MapBottom || MapLeft == MapRight) return; if (Level.TimeSeconds > TimeUpdate + UpdateInterval) { TimeUpdate = Level.TimeSeconds; Update(); } InfoGame = PlayerLocal.GameReplicationInfo; if (InfoGame == None) return; for (IndexPlayer = 0; IndexPlayer < ArrayCount(InfoPlayer); IndexPlayer++) { if (InfoPlayer[IndexPlayer] == None) continue; IdPlayerPrev = InfoPlayer[IndexPlayer].PlayerID; InfoPlayer[IndexPlayer].PlayerID = IndexPlayer; if (IsDisplayed(InfoPlayer[IndexPlayer]) && CalcOffset(LocationPlayerAck[IndexPlayer], OffsetLeftPlayer[IndexPlayer], OffsetTopPlayer [IndexPlayer])) { DrawTag(TextureCanvas, InfoPlayer[IndexPlayer], Left + OffsetLeftPlayer[IndexPlayer], Top + OffsetTopPlayer [IndexPlayer], PlayerIconsWidth, PlayerIconsHeight, Fade); FlagDisplayed[IndexPlayer] = 1; } InfoPlayer[IndexPlayer].PlayerID = IdPlayerPrev; } for (IndexPlayer = 0; IndexPlayer < ArrayCount(InfoPlayer); IndexPlayer++) if (FlagDisplayed[IndexPlayer] != 0) { IdPlayerPrev = InfoPlayer[IndexPlayer].PlayerID; InfoPlayer[IndexPlayer].PlayerID = IndexPlayer; DrawIcon(TextureCanvas, InfoPlayer[IndexPlayer], Left + OffsetLeftPlayer[IndexPlayer], Top + OffsetTopPlayer [IndexPlayer], Fade); InfoPlayer[IndexPlayer].PlayerID = IdPlayerPrev; } } // ============================================================================ // Update // // Updates all information that is displayed on the slide with current // information replicated by the server. // ============================================================================ simulated function Update() { local int IndexPlayer; for (IndexPlayer = 0; IndexPlayer < ArrayCount(LocationPlayer); IndexPlayer++) { LocationPlayerAck [IndexPlayer] = LocationPlayer [IndexPlayer]; HealthPlayerAck [IndexPlayer] = HealthPlayer [IndexPlayer]; FlagPlayerVisibleAck[IndexPlayer] = FlagPlayerVisible[IndexPlayer]; ZonePlayerAck [IndexPlayer] = ZonePlayer [IndexPlayer]; } if (UpdateInterval == 0.0) return; if (UpdateSound != None) PlaySound(UpdateSound, , UpdateSoundVolume); if (Background != TextureBackgroundAck) { if (TextureBackgroundAck != None) TextureBackgroundAck.AnimNext = TextureBackgroundNext; TextureBackgroundNext = Background.AnimNext; TextureBackgroundAck = Background; Background.AnimNext = None; } if (PlayerIcons != TextureIconsAck) { if (TextureIconsAck != None) TextureIconsAck.AnimNext = TextureIconsNext; TextureIconsNext = PlayerIcons.AnimNext; TextureIconsAck = PlayerIcons; PlayerIcons.AnimNext = None; } if (UpdateSyncBackground && Background != None && TextureBackgroundNext != None) Background.AnimCurrent = TextureBackgroundNext; if (UpdateSyncIcons && PlayerIcons != None && TextureIconsNext != None) PlayerIcons.AnimCurrent = TextureIconsNext; } // ============================================================================ // CalcOffset // // Fills in the pixel offsets on the slide that corresponds to the given // location. Returns a boolean value that tells whether the given location is // within the displayed bounds or not. // ============================================================================ simulated function bool CalcOffset(vector VectorItem, optional out int OffsetLeftItem, optional out int OffsetTopItem) { local float CoordDepthItem; CoordDepthItem = Component(VectorItem, CoordDepth); if (CoordDepthMin < CoordDepthMax && CoordDepthItem != Clamp(CoordDepthItem, CoordDepthMin, CoordDepthMax)) return false; OffsetLeftItem = (Component(VectorItem, CoordHorz) - MapLeft) * ClientWidth / (MapRight - MapLeft); OffsetTopItem = (Component(VectorItem, CoordVert) - MapTop) * ClientHeight / (MapBottom - MapTop); return (OffsetLeftItem == Clamp(OffsetLeftItem, 0, ClientWidth)) && (OffsetTopItem == Clamp(OffsetTopItem, 0, ClientHeight)); } // ============================================================================ // DrawMap // // Draws the background map on the slide. // ============================================================================ simulated function DrawMap(ScriptedTexture TextureCanvas, int Left, int Top) { if (Map != None) TextureCanvas.DrawTile(Left, Top, ClientWidth, ClientHeight, 0, 0, Map.USize, Map.VSize, Map, Map.bMasked); } // ============================================================================ // DrawTag // // Draws the player's text tag on the screen with the given parameters at the // given position. // ============================================================================ simulated function DrawTag(ScriptedTexture TextureCanvas, PlayerReplicationInfo Info, int OffsetLeft, int OffsetTop, int WidthIcon, int HeightIcon, float Fade) { local string TextDisplay; local int OffsetLeftText; local int OffsetTopText; local int OffsetLeftIcon; local int OffsetTopIcon; local float WidthText; local float HeightText; TextDisplay = PlayerDisplay; TextDisplay = Replace(TextDisplay, "%p", Info.PlayerName); TextDisplay = Replace(TextDisplay, "%h", HealthPlayerAck[Info.PlayerID]); TextDisplay = Replace(TextDisplay, "%s", int(Info.Score)); if (Len(TextDisplay) > 0) { TextureCanvas.TextSize(TextDisplay, WidthText, HeightText, FontPlayers); OffsetTopIcon = OffsetTop - HeightIcon / 2; OffsetLeftIcon = OffsetLeft - WidthIcon / 2; switch (PlayerDisplayAlignHorz) { case DisplayAlignHorz_Left: OffsetLeftText = OffsetLeftIcon - PlayerDisplayPaddingRight - int(WidthText); if (OffsetLeftText < 0) OffsetLeftText = OffsetLeftIcon + WidthIcon + PlayerDisplayPaddingLeft; break; case DisplayAlignHorz_Center: OffsetLeftText = OffsetLeft - int(WidthText / 2); break; case DisplayAlignHorz_Right: OffsetLeftText = OffsetLeftIcon + WidthIcon + PlayerDisplayPaddingLeft; if (OffsetLeftText + WidthText >= ClientWidth) OffsetLeftText = OffsetLeftIcon - PlayerDisplayPaddingRight - int(WidthText); break; } switch (PlayerDisplayAlignVert) { case DisplayAlignVert_Top: OffsetTopText = OffsetTopIcon - PlayerDisplayPaddingBottom - int(HeightText); if (OffsetTopText < 0) OffsetTopText = OffsetTopIcon + HeightIcon + PlayerDisplayPaddingTop; break; case DisplayAlignVert_Middle: OffsetTopText = OffsetTop - int(HeightText / 2); break; case DisplayAlignVert_Bottom: OffsetTopText = OffsetTopIcon + HeightIcon + PlayerDisplayPaddingTop; if (OffsetTopText + HeightText >= ClientHeight) OffsetTopText = OffsetTopIcon - PlayerDisplayPaddingBottom - int(HeightText); break; } TextureCanvas.DrawColoredText(OffsetLeftText, OffsetTopText, TextDisplay, FontPlayers, FadeColor(FontPlayersColor, Fade)); } } // ============================================================================ // DrawIcon // // Draws the player's icon on the screen with the given parameters at the given // position. // ============================================================================ simulated function DrawIcon(ScriptedTexture TextureCanvas, PlayerReplicationInfo Info, int OffsetLeft, int OffsetTop, float Fade) { local int OffsetTopIconSource; local int OffsetLeftIconSource; local int OffsetTopIcon; local int OffsetLeftIcon; if (PlayerIcons == None) return; OffsetTopIconSource = 0; OffsetLeftIconSource = 0; switch (PlayerIconsType) { case IconsType_Teams: if (Info.Team <= 4) OffsetLeftIconSource = PlayerIconsWidth + Info.Team * PlayerIconsWidth; break; case IconsType_Classes: if (Info == PlayerLocal.PlayerReplicationInfo) OffsetLeftIconSource = 0; else if (PlayerLocal.GameReplicationInfo.bTeamGame && Info.Team == PlayerLocal.PlayerReplicationInfo.Team) OffsetLeftIconSource = PlayerIconsWidth * 2; else OffsetLeftIconSource = PlayerIconsWidth; break; } if (FlagPlayerVisibleAck[Info.PlayerID] == 0) OffsetTopIconSource = PlayerIconsHeight; OffsetTopIcon = OffsetTop - PlayerIconsHeight / 2; OffsetLeftIcon = OffsetLeft - PlayerIconsWidth / 2; TextureCanvas.DrawTile(OffsetLeftIcon, OffsetTopIcon, PlayerIconsWidth, PlayerIconsHeight, OffsetLeftIconSource, OffsetTopIconSource, PlayerIconsWidth, PlayerIconsHeight, PlayerIcons, PlayerIcons.bMasked); } // ============================================================================ // IsDisplayed // // Returns whether a player with the given parameters is displayed. // ============================================================================ simulated function bool IsDisplayed(PlayerReplicationInfo Info) { return !Info.bIsSpectator && (ShowDead || HealthPlayerAck[Info.PlayerID] > 0) && (ShowSelf || Info != PlayerLocal.PlayerReplicationInfo) && ((ZoneDisplay == ZoneDisplay_Inside && ((ZoneClass == None || ZonePlayerAck[Info.PlayerID].IsA(ZoneClass.Name)) && (Zone == None || ZonePlayerAck[Info.PlayerID] == Zone))) || (ZoneDisplay == ZoneDisplay_Outside && ((ZoneClass == None || !ZonePlayerAck[Info.PlayerID].IsA(ZoneClass.Name)) && (Zone == None || ZonePlayerAck[Info.PlayerID] != Zone)))) && ((Info.Team == 0 && ShowRed && (FlagPlayerVisibleAck[Info.PlayerID] != 0 || ShowRedInvisible)) || (Info.Team == 1 && ShowBlue && (FlagPlayerVisibleAck[Info.PlayerID] != 0 || ShowBlueInvisible)) || (Info.Team == 2 && ShowGreen && (FlagPlayerVisibleAck[Info.PlayerID] != 0 || ShowGreenInvisible)) || (Info.Team == 3 && ShowGold && (FlagPlayerVisibleAck[Info.PlayerID] != 0 || ShowGoldInvisible)) || (Info.Team == 255 && ShowNeutral && (FlagPlayerVisibleAck[Info.PlayerID] != 0 || ShowNeutralInvisible))); } // ============================================================================ // Component // // Returns the selected component of a vector. // ============================================================================ simulated function int Component(vector Location, EnumCoordSelection Selection) { switch (Selection) { case CoordSelection_X: return Location.X; case CoordSelection_Y: return Location.Y; case CoordSelection_Z: return Location.Z; } } // ============================================================================ // Default Properties // ============================================================================ [on ::$l\OG{#U{#U> Y{#U11{#U{#U11{#U{#U{#U{#U{#U{#U{#U{#U{#U{#U{#U{#U{#U> Y> Y'n 6{#U> Y{#U{#UZ!{#U{#U{#UZ!Z!Z!Z!Z!Z!Z!Z!Z!Z!Z!> Y{#U{#U{#U{#U{#U{#U> Y> Y'n 6'n 6'n 6{#U'n 6{#U'n 6{#U'n 6\O\O\O\O\O\Ottttttttt{#Ut{#Ut{#Utttt{#Ut{#Ut\Oqn*Bp"l"k] %p (%h)mi"@ "hjfegcbd`_F a"]"\"^"[ZH N $?S $j $3"2"9"*"+")"#]~VVQVV`U// ============================================================================ // ScreenSlide // Copyright 2001 by Mychaeel // // Abstract base class for slides that can be displayed on a Screen texture. // ============================================================================ class ScreenSlide extends Info abstract; // ============================================================================ // Compiler Directives // ============================================================================ #exec texture import file=Textures\ActorSlide.bmp mips=off flags=2 // ============================================================================ // Types // ============================================================================ enum EnumSlideScroll { SlideScroll_None, SlideScroll_Bounce, SlideScroll_Wrap, }; enum EnumSlideEffect { SlideEffect_Replace, SlideEffect_SlideTop, SlideEffect_SlideLeft, SlideEffect_SlideRight, SlideEffect_SlideBottom, SlideEffect_Fade, }; enum EnumSlideAlignHorz { SlideAlignHorz_Left, SlideAlignHorz_Center, SlideAlignHorz_Right, SlideAlignHorz_LeftAdjacent, SlideAlignHorz_RightAdjacent, }; enum EnumSlideAlignVert { SlideAlignVert_Top, SlideAlignVert_Middle, SlideAlignVert_Bottom, SlideAlignVert_TopAdjacent, SlideAlignVert_BottomAdjacent, }; // ============================================================================ // Properties // // Some or all of these properties might be ignored when set in UnrealEd and // automatically set to whatever value suits the subclass. // ============================================================================ var() EnumSlideAlignHorz AlignHorz; var() EnumSlideAlignVert AlignVert; var() Texture Background; var() bool BackgroundScroll; var() bool BackgroundTile; var() Color BackgroundColor; var() Texture Palette; var() int ClientWidth; var() int ClientHeight; var() int ClientPaddingTop; var() int ClientPaddingLeft; var() int ClientPaddingRight; var() int ClientPaddingBottom; var() float Time; var() EnumSlideScroll ScrollHorz; var() EnumSlideScroll ScrollVert; var() EnumSlideEffect EffectEntry; var() EnumSlideEffect EffectExit; var() float ScrollHorzSpeed; var() float ScrollVertSpeed; var() float EffectEntrySpeed; var() float EffectExitSpeed; var() ScreenSlide SlideNext; var() ScreenSlide SlideOverlay; // ============================================================================ // Variables // ============================================================================ var bool FlagSeen; // used exclusively in Screen.AddSlide // ============================================================================ // Prepare // // Does whatever preparation is needed for displaying this slide. Called // immediately before Draw. After calling this function, all properties of // this slide are expected to represent whatever values will be used in the // next Draw operation, particularly in regard to ClientWidth and ClientHeight. // ============================================================================ simulated function Prepare(ScriptedTexture TextureCanvas) { // implemented in subclasses } // ============================================================================ // Draw // // Draws the slide content onto the given ScriptedTexture at the given pixel // position. // ============================================================================ simulated function Draw(ScriptedTexture TextureCanvas, int Left, int Top, float Fade) { // implemented in subclasses } // ============================================================================ // Replace // // Replaces all occurrences of a substring in a string by another string and // returns the result. // ============================================================================ simulated function string Replace(coerce string TextOriginal, coerce string TextSearch, coerce string TextReplace) { local int IndexChar; local int IndexCharLast; local string TextResult; IndexChar = 0; TextResult = TextOriginal; while (true) { IndexCharLast = IndexChar; IndexChar = InStr(Mid(TextResult, IndexChar), TextSearch); if (IndexChar < 0) break; IndexChar += IndexCharLast; TextResult = Left(TextResult, IndexChar) $ TextReplace $ Mid(TextResult, IndexChar + Len(TextSearch)); IndexChar += Len(TextReplace); } return TextResult; } // ============================================================================ // FadeColor // // Returns a shade of the given color, faded by the given amount. // ============================================================================ simulated function Color FadeColor(Color ColorFade, float Fade) { local Color ColorResult; ColorResult.R = BackgroundColor.R + (ColorFade.R - BackgroundColor.R) * Fade; ColorResult.G = BackgroundColor.G + (ColorFade.G - BackgroundColor.G) * Fade; ColorResult.B = BackgroundColor.B + (ColorFade.B - BackgroundColor.B) * Fade; return ColorResult; } // ============================================================================ // Default Properties // ============================================================================ VOl |3\w3*k33l%)3>3,%&3>|k3|3|kT33R  VkTY%X-yYa_v}sz]D?,vx%sx]zpz_xJ_%D?,v VLX?ySar*3rL* wLH*XLHXWNwK*Xa?\u?`q?4?7?K?KKK-)Lew)*w)Q*$)-N!X)Q\uSxD `qS}D )-G!X)Q\uSx`qS})-G)X\uSxD )[`qS}D )^5SNS, e))PbwJ*Xa?\u?`q?4?7?J?JJJ-(6n=,6n$6n$Xa?\?`SD?\u ?L[xSD?`q ?L^ n  Vo@VVcvkX 2j j = j c-_ K svnK v{K [\:kK Pc[K  VWVVVVj`r;Z6wC<6h?:6}:6hf6wC<6h?:6}:6hf6wC<6h?:6}:6hfr,a?o>?hTswX-yr,a?o>?hzswr1a?o>_?h_sw VGX".-z ] = f %Xf , f V *f 56w6*w6*6-6, s 6666lf %6w6*w6*6-6, f , wf V *f |f , s f 666]  VGK,_>:J: :%pq: :%hSqU : :%sSDq}:%Ka:_`nL \F,C X,] #$ZC E D_ Z%ZC F  C$ZXD_?, $ZC F ?Z_?PZC E D_ Y $TL  D`T%TL FD \ $T\D`?,\ Y$TL FD V?T`?cTL  D`\ K)a?Z?T:nK~ VY/// ============================================================================ // ScreenUIPageAbout // Copyright 2001 by Mychaeel // // Content of About tab in Screen user interface. // ============================================================================ class ScreenUIPageAbout extends UWindowPageWindow; // ============================================================================ // Controls // ============================================================================ var UWindowLabelControl LabelTitle; var UWindowLabelControl LabelPermissions; var UWindowLabelControl LabelSuggestions; var UWindowLabelControl LabelCopyright; var UWindowLabelControl LabelMail; var UWindowSmallButton ButtonWebsite; // ============================================================================ // Created // ============================================================================ function Created() { LabelTitle = UWindowLabelControl(CreateControl(class 'UWindowLabelControl', 20, 17, WinWidth - 40, 1)); LabelTitle.SetText("Screen Component" @ class 'Screen'.default.Version); LabelTitle.SetFont(F_Bold); LabelPermissions = UWindowLabelControl(CreateControl(class 'UWindowLabelControl', 20, 44, WinWidth - 40, 1)); LabelPermissions.SetText("Free for noncommercial use and distribution."); LabelSuggestions = UWindowLabelControl(CreateControl(class 'UWindowLabelControl', 20, 56, WinWidth - 40, 1)); LabelSuggestions.SetText("Feedback, bug reports and suggestions are welcome."); LabelCopyright = UWindowLabelControl(CreateControl(class 'UWindowLabelControl', 20, 83, WinWidth - 40, 1)); LabelCopyright.SetText("Copyright 2001 by Mychaeel, mychaeel@planetunreal.com"); ButtonWebsite = UWindowSmallButton(CreateControl(class 'UWindowSmallButton', 20, 123, 140, 1)); ButtonWebsite.SetText("Visit the Screen Website"); if (class 'Screen'.default.VersionLatest > class 'Screen'.default.Version) ButtonWebsite.SetText("Update Screen Component"); } // ============================================================================ // WindowShown // ============================================================================ function WindowShown() { Super.WindowShown(); UWindowPageWindow(ParentWindow).OwnerTab.bFlash = false; } // ============================================================================ // Notify // ============================================================================ function Notify(UWindowDialogControl Control, byte ControlEvent) { switch (Control) { case ButtonWebsite: if (ControlEvent == DE_Click) if (class 'Screen'.default.VersionLatest > class 'Screen'.default.Version) GetPlayerOwner().ConsoleCommand("start http://www.planetunreal.com/screen/download.html"); else GetPlayerOwner().ConsoleCommand("start http://www.planetunreal.com/screen/"); break; } } VOfbUO(cq bcd7UJ MN pa \ a oV Q rV * K %K , rK V *o K V K V K 1K V (n K ` K mK n,bK V cK mdK nmbVK Q&K V o K K %aK , WK Q%o K V K V K >bK V cK mdK nVK V o K  VL// ============================================================================ // Screen // Copyright 2001 by Mychaeel // // Provides an implementation of a ClientScriptedTexture that is able to // display slides of type ScreenSlide and its subclasses. // ============================================================================ class Screen extends ClientScriptedTexture config(Screen); // ============================================================================ // Compiler Directives // ============================================================================ #exec texture import file=Textures\ActorScreen.bmp mips=off flags=2 // ============================================================================ // Replication // ============================================================================ replication { reliable if (Role == ROLE_Authority) VersionServer; reliable if (Role == ROLE_Authority && SwitchTriggered.SlideSwitch != None) SwitchTriggered; } // ============================================================================ // Types // ============================================================================ enum EnumSlideAction { SlideAction_None, SlideAction_Entering, SlideAction_Scrolling, SlideAction_Exiting, }; enum EnumConfigNetwork { ConfigNetwork_Always, ConfigNetwork_Network, ConfigNetwork_Never, }; struct StructSwitch { var ScreenSlide SlideSwitch; var int Update; }; // ============================================================================ // Configuration // ============================================================================ var config EnumConfigNetwork Network; var config int VersionLatest; // ============================================================================ // Properties // ============================================================================ var() editconst int Version; var() ScreenSlide SlideCurrent; var() Texture ScreenBackground; var() Texture ScreenForeground; var() int Top; var() int Left; var() int Width; var() int Height; var() int TileTop; var() int TileLeft; var() Screen TileMaster; // ============================================================================ // Variables // ============================================================================ var int VersionServer; var bool FlagVersionAck; var ScreenMutator MutatorScreen; var ScreenSlide SlideCurrentAck; var StructSwitch SwitchTriggered; var Palette PaletteOriginal; var EnumSlideAction Action; var int DirectionHorz; var int DirectionVert; var int CountSlides; var int OffsetTopSlide[32]; var int OffsetLeftSlide[32]; var float TimeDisplayed; var float Fade; var float OffsetTop; var float OffsetLeft; // ============================================================================ // Constants // ============================================================================ const FlagDebug = false; // ============================================================================ // PreBeginPlay // ============================================================================ simulated function PreBeginPlay() { local GameInfo ThisGame; Super.PreBeginPlay(); if (PaletteOriginal == None) PaletteOriginal = ScriptedTexture.Palette; if (Level.NetMode != NM_Client) VersionServer = Version; foreach AllActors(class 'ScreenMutator', MutatorScreen) break; if (MutatorScreen == None) { MutatorScreen = Spawn(class 'ScreenMutator'); foreach AllActors(class 'GameInfo', ThisGame) break; if (ThisGame != None) { ThisGame.BaseMutator.AddMutator(MutatorScreen); ThisGame.RegisterMessageMutator(MutatorScreen); } } } // ============================================================================ // Tick // ============================================================================ simulated function Tick(float TimeDelta) { local ScriptedTexture TextureCanvas; local bool FlagCompleted; local bool FlagCompletedHorz; local bool FlagCompletedVert; local int IndexSlide; local int ClientWidthTotal; local int ClientHeightTotal; local int ClientWidthDisplayed; local int ClientHeightDisplayed; local int OffsetTopTarget; local int OffsetLeftTarget; local int OffsetTopDisplayed; local int OffsetLeftDisplayed; local int OffsetTopTotal; local int OffsetLeftTotal; local int OffsetRightTotal; local int OffsetBottomTotal; local int DirectionVertPrev; local int DirectionHorzPrev; local int ThisOffsetTop; local int ThisOffsetLeft; local ScreenSlide ThisSlide; local ScreenSlide ThisSlidePrev; local EnumSlideAction ActionPrev; VersionCheck(); if (Level.NetMode == NM_DedicatedServer) return; if (TileMaster != None) return; TextureCanvas = ScriptedTexture(ScriptedTexture); if (TextureCanvas == None) return; // ================================================================ // Slides Switched // ================================================================ ActionPrev = Action; if (SlideCurrent == None) { if (SwitchTriggered.SlideSwitch == None) return; SlideCurrent = SwitchTriggered.SlideSwitch; SlideCurrentAck = None; SwitchTriggered.SlideSwitch = None; } if (SwitchTriggered.SlideSwitch == SlideCurrent && Action != SlideAction_Exiting) SwitchTriggered.SlideSwitch = None; if (SlideCurrentAck != SlideCurrent) { Action = SlideAction_Entering; ActionPrev = SlideAction_None; SlideCurrentAck = SlideCurrent; } // ================================================================ // Calculate Animation // ================================================================ if (SlideCurrent != None) { // ==================================================== // Prepare Slide // ==================================================== SlideCurrent.Prepare(TextureCanvas); OffsetTopTotal = -GetClientHeightTotal(SlideCurrent) / 2; OffsetLeftTotal = -GetClientWidthTotal (SlideCurrent) / 2; OffsetRightTotal = OffsetLeftTotal + GetClientWidthTotal (SlideCurrent); OffsetBottomTotal = OffsetTopTotal + GetClientHeightTotal(SlideCurrent); ThisOffsetTop = OffsetTopTotal; ThisOffsetLeft = OffsetLeftTotal; CountSlides = 1; OffsetTopSlide [0] = ThisOffsetTop; OffsetLeftSlide[0] = ThisOffsetLeft; ThisSlidePrev = SlideCurrent; for (ThisSlide = SlideCurrent.SlideOverlay; ThisSlide != None; ThisSlide = ThisSlide.SlideOverlay) { if (CountSlides == ArrayCount(OffsetLeftSlide) - 1) { Log("Screen: Too many layered slides, starting with slide" @ SlideCurrent.Name); break; } ThisSlide.Prepare(TextureCanvas); switch (ThisSlide.AlignHorz) { case SlideAlignHorz_Left: OffsetRightTotal = Max(OffsetRightTotal, ThisOffsetLeft + GetClientWidthTotal(ThisSlide)); break; case SlideAlignHorz_LeftAdjacent: ThisOffsetLeft -= GetClientWidthTotal(ThisSlide); OffsetLeftTotal = Min(OffsetLeftTotal, ThisOffsetLeft); break; case SlideAlignHorz_Center: ThisOffsetLeft += (GetClientWidthTotal(ThisSlidePrev) - GetClientWidthTotal(ThisSlide)) / 2; OffsetLeftTotal = Min(OffsetLeftTotal, ThisOffsetLeft); OffsetRightTotal = Max(OffsetRightTotal, ThisOffsetLeft + GetClientWidthTotal(ThisSlide)); break; case SlideAlignHorz_Right: ThisOffsetLeft += GetClientWidthTotal(ThisSlidePrev) - GetClientWidthTotal(ThisSlide); OffsetLeftTotal = Min(OffsetLeftTotal, ThisOffsetLeft); break; case SlideAlignHorz_RightAdjacent: ThisOffsetLeft += GetClientWidthTotal(ThisSlidePrev); OffsetRightTotal = Max(OffsetRightTotal, ThisOffsetLeft + GetClientWidthTotal(ThisSlide)); break; } switch (ThisSlide.AlignVert) { case SlideAlignVert_Top: OffsetBottomTotal = Max(OffsetBottomTotal, ThisOffsetTop + GetClientHeightTotal(ThisSlide)); break; case SlideAlignVert_TopAdjacent: ThisOffsetTop -= GetClientHeightTotal(ThisSlide); OffsetTopTotal = Min(OffsetTopTotal, ThisOffsetTop); break; case SlideAlignVert_Middle: ThisOffsetTop += (GetClientHeightTotal(ThisSlidePrev) - GetClientHeightTotal(ThisSlide)) / 2; OffsetTopTotal = Min(OffsetTopTotal, ThisOffsetTop); OffsetBottomTotal = Max(OffsetBottomTotal, ThisOffsetTop + GetClientHeightTotal(ThisSlide)); break; case SlideAlignVert_Bottom: ThisOffsetTop += GetClientHeightTotal(ThisSlidePrev) - GetClientHeightTotal(ThisSlide); OffsetTopTotal = Min(OffsetTopTotal, ThisOffsetTop); break; case SlideAlignVert_BottomAdjacent: ThisOffsetTop += GetClientHeightTotal(ThisSlidePrev); OffsetBottomTotal = Max(OffsetBottomTotal, ThisOffsetTop + GetClientHeightTotal(ThisSlide)); break; } OffsetTopSlide [CountSlides] = ThisOffsetTop; OffsetLeftSlide[CountSlides] = ThisOffsetLeft; CountSlides++; ThisSlidePrev = ThisSlide; } for (IndexSlide = 0; IndexSlide < CountSlides; IndexSlide++) { OffsetTopSlide [IndexSlide] -= OffsetTopTotal; OffsetLeftSlide[IndexSlide] -= OffsetLeftTotal; } ClientWidthTotal = OffsetRightTotal - OffsetLeftTotal; ClientHeightTotal = OffsetBottomTotal - OffsetTopTotal; ClientWidthDisplayed = Clamp(ClientWidthTotal, 0, Width); ClientHeightDisplayed = Clamp(ClientHeightTotal, 0, Height); switch (SlideCurrent.AlignHorz) { case SlideAlignHorz_Left: case SlideAlignHorz_LeftAdjacent: OffsetLeftTarget = 0; break; case SlideAlignHorz_Center: OffsetLeftTarget = Width / 2 + OffsetLeftTotal; break; case SlideAlignHorz_Right: case SlideAlignHorz_RightAdjacent: OffsetLeftTarget = Width - ClientWidthTotal; break; } switch (SlideCurrent.AlignVert) { case SlideAlignVert_Top: case SlideAlignVert_TopAdjacent: OffsetTopTarget = 0; break; case SlideAlignVert_Middle: OffsetTopTarget = Height / 2 + OffsetTopTotal; break; case SlideAlignVert_Bottom: case SlideAlignVert_BottomAdjacent: OffsetTopTarget = Height - ClientHeightTotal; break; } OffsetTopDisplayed = Clamp(OffsetTopTarget, 0, Height); OffsetLeftDisplayed = Clamp(OffsetLeftTarget, 0, Width); TimeDisplayed += TimeDelta; // ==================================================== // Scroll Slide // ==================================================== do { if (Action != ActionPrev) { switch (Action) { case SlideAction_Entering: Fade = 1.0; OffsetLeft = OffsetLeftTarget; OffsetTop = OffsetTopTarget; switch (SlideCurrent.EffectEntry) { case SlideEffect_Replace: break; case SlideEffect_SlideTop: OffsetTop = Height; break; case SlideEffect_SlideLeft: OffsetLeft = Width; break; case SlideEffect_SlideRight: OffsetLeft = -ClientWidthTotal; break; case SlideEffect_SlideBottom: OffsetTop = -ClientHeightTotal; break; case SlideEffect_Fade: Fade = 0.0; break; } break; case SlideAction_Scrolling: TimeDisplayed = 0.0; DirectionHorz = 1; DirectionVert = 1; break; } ActionPrev = Action; } switch (Action) { // ================================================ // Entry Animation case SlideAction_Entering: switch (SlideCurrent.EffectEntry) { case SlideEffect_Replace: FlagCompleted = true; break; case SlideEffect_SlideTop: OffsetTop -= SlideCurrent.EffectEntrySpeed * TimeDelta; OffsetTop = FMax(OffsetTop, OffsetTopTarget); FlagCompleted = (OffsetTop <= OffsetTopTarget); break; case SlideEffect_SlideLeft: OffsetLeft -= SlideCurrent.EffectEntrySpeed * TimeDelta; OffsetLeft = FMax(OffsetLeft, OffsetLeftTarget); FlagCompleted = (OffsetLeft <= OffsetLeftTarget); break; case SlideEffect_SlideRight: OffsetLeft += SlideCurrent.EffectEntrySpeed * TimeDelta; OffsetLeft = FMin(OffsetLeft, OffsetLeftTarget); FlagCompleted = (OffsetLeft >= OffsetLeftTarget); break; case SlideEffect_SlideBottom: OffsetTop += SlideCurrent.EffectEntrySpeed * TimeDelta; OffsetTop = FMin(OffsetTop, OffsetTopTarget); FlagCompleted = (OffsetTop >= OffsetTopTarget); break; case SlideEffect_Fade: Fade += SlideCurrent.EffectEntrySpeed / 100.0 * TimeDelta; Fade = FClamp(Fade, 0.0, 1.0); FlagCompleted = (Fade == 1.0); break; } if (FlagCompleted) { OffsetTop = OffsetTopTarget; OffsetLeft = OffsetLeftTarget; Action = SlideAction_Scrolling; } break; // ================================================ // Scrolling case SlideAction_Scrolling: switch (SlideCurrent.ScrollVert) { case SlideScroll_None: OffsetTop = OffsetTopTarget; FlagCompletedVert = true; break; case SlideScroll_Wrap: FlagCompletedVert = (ClientHeightTotal <= Height && OffsetTop == OffsetTopTarget); if (!FlagCompletedVert) { if (OffsetTop + ClientHeightTotal <= 0) OffsetTop = Height; OffsetTop -= SlideCurrent.ScrollVertSpeed * TimeDelta; OffsetTop = FMax(OffsetTop, -ClientHeightTotal); FlagCompletedVert = (OffsetTop + ClientHeightTotal <= 0); } break; case SlideScroll_Bounce: DirectionVertPrev = DirectionVert; FlagCompletedVert = (ClientHeightTotal <= Height && OffsetTop == OffsetTopTarget); if (!FlagCompletedVert) { if (DirectionVert == 1 && OffsetTop + ClientHeightTotal <= OffsetTopDisplayed + ClientHeightDisplayed) DirectionVert = -1; else if (DirectionVert == -1 && OffsetTop >= OffsetTopDisplayed) DirectionVert = 1; else if (DirectionVert == 1) OffsetTop -= SlideCurrent.ScrollVertSpeed * TimeDelta; else OffsetTop += SlideCurrent.ScrollVertSpeed * TimeDelta; OffsetTop = FClamp(OffsetTop, OffsetTopDisplayed + ClientHeightDisplayed - ClientHeightTotal, OffsetTopDisplayed); FlagCompletedVert = (DirectionVert != DirectionVertPrev); } break; } switch (SlideCurrent.ScrollHorz) { case SlideScroll_None: OffsetLeft = OffsetLeftTarget; FlagCompletedHorz = true; break; case SlideScroll_Wrap: FlagCompletedHorz = (ClientWidthTotal <= Width && OffsetLeft == OffsetLeftTarget); if (!FlagCompletedHorz) { if (OffsetLeft + ClientWidthTotal <= 0) OffsetLeft = Width; OffsetLeft -= SlideCurrent.ScrollHorzSpeed * TimeDelta; OffsetLeft = FMax(OffsetLeft, -ClientWidthTotal); FlagCompletedHorz = (OffsetLeft + ClientWidthTotal <= 0); } break; case SlideScroll_Bounce: DirectionHorzPrev = DirectionHorz; FlagCompletedHorz = (ClientWidthTotal <= Width && OffsetLeft == OffsetLeftTarget); if (!FlagCompletedHorz) { if (DirectionHorz == 1 && OffsetLeft + ClientWidthTotal <= OffsetLeftDisplayed + ClientWidthDisplayed) DirectionHorz = -1; else if (DirectionHorz == -1 && OffsetLeft >= OffsetLeftDisplayed) DirectionHorz = 1; else if (DirectionHorz == 1) OffsetLeft -= SlideCurrent.ScrollHorzSpeed * TimeDelta; else OffsetLeft += SlideCurrent.ScrollHorzSpeed * TimeDelta; OffsetLeft = FClamp(OffsetLeft, OffsetLeftDisplayed + ClientWidthDisplayed - ClientWidthTotal, OffsetLeftDisplayed); FlagCompletedHorz = (DirectionHorz != DirectionHorzPrev); } break; } FlagCompleted = FlagCompletedHorz && FlagCompletedVert; if (FlagCompleted && ((TimeDisplayed >= SlideCurrent.Time && SlideCurrent.SlideNext != None) || SwitchTriggered.SlideSwitch != None)) Action = SlideAction_Exiting; break; // ================================================ // Exit Animation case SlideAction_Exiting: switch (SlideCurrent.EffectExit) { case SlideEffect_Replace: FlagCompleted = true; break; case SlideEffect_SlideTop: OffsetTop -= SlideCurrent.EffectExitSpeed * TimeDelta; FlagCompleted = (OffsetTop + ClientHeightTotal <= 0); break; case SlideEffect_SlideLeft: OffsetLeft -= SlideCurrent.EffectExitSpeed * TimeDelta; FlagCompleted = (OffsetLeft + ClientWidthTotal <= 0); break; case SlideEffect_SlideRight: OffsetLeft += SlideCurrent.EffectExitSpeed * TimeDelta; FlagCompleted = (OffsetLeft >= Width); break; case SlideEffect_SlideBottom: OffsetTop += SlideCurrent.EffectExitSpeed * TimeDelta; FlagCompleted = (OffsetTop >= Height); break; case SlideEffect_Fade: Fade -= SlideCurrent.EffectExitSpeed / 100.0 * TimeDelta; Fade = FClamp(Fade, 0.0, 1.0); FlagCompleted = (Fade == 0.0); break; } break; } } until (Action == ActionPrev); // ==================================================== // Switch Slides // ==================================================== if (Action == SlideAction_Exiting && FlagCompleted) { if (SwitchTriggered.SlideSwitch == None) SwitchTriggered.SlideSwitch = SlideCurrent.SlideNext; SlideCurrent = None; if (FlagDebug) Log("Switching to slide" @ SwitchTriggered.SlideSwitch.Name); } } } // ============================================================================ // GetClientWidthTotal // // Calculates and returns the total client width of a slide. // ============================================================================ simulated function int GetClientWidthTotal(ScreenSlide Slide) { return Slide.ClientPaddingLeft + Slide.ClientWidth + Slide.ClientPaddingRight; } // ============================================================================ // GetClientHeightTotal // // Calculates and returns the total client height of a slide. // ============================================================================ simulated function int GetClientHeightTotal(ScreenSlide Slide) { return Slide.ClientPaddingTop + Slide.ClientHeight + Slide.ClientPaddingBottom; } // ============================================================================ // RenderTexture // ============================================================================ simulated event RenderTexture(ScriptedTexture TextureCanvas) { local Color ColorDebug; local Screen ScreenMaster; local ScreenSlide ThisSlide; local int IndexSlide; ScreenMaster = TileMaster; if (ScreenMaster == None) ScreenMaster = Self; if (ScreenMaster.SlideCurrentAck == None) return; if (ScreenMaster.SlideCurrentAck.Palette != None) TextureCanvas.Palette = ScreenMaster.SlideCurrentAck.Palette.Palette; else TextureCanvas.Palette = PaletteOriginal; // ================================================================ // Screen Background // ================================================================ if (ScreenMaster.ScreenBackground != None) TextureCanvas.DrawTile(Left - TileLeft, Top - TileTop, ScreenMaster.Width, ScreenMaster.Height, 0, 0, ScreenMaster.ScreenBackground.USize, ScreenMaster.ScreenBackground.VSize, ScreenMaster.ScreenBackground, ScreenMaster.ScreenBackground.bMasked); // ================================================================ // Slides // ================================================================ for (ThisSlide = ScreenMaster.SlideCurrentAck; ThisSlide != None; ThisSlide = ThisSlide.SlideOverlay) { if (ThisSlide.Background != None) if (ThisSlide.BackgroundScroll) Tile(TextureCanvas, ThisSlide.Background, Left - TileLeft + ScreenMaster.OffsetLeftSlide[IndexSlide] + int(ScreenMaster.OffsetLeft), Top - TileTop + ScreenMaster.OffsetTopSlide [IndexSlide] + int(ScreenMaster.OffsetTop), ThisSlide.BackgroundTile); else Tile(TextureCanvas, ThisSlide.Background, Left - TileLeft + ScreenMaster.OffsetLeftSlide[IndexSlide], Top - TileTop + ScreenMaster.OffsetTopSlide [IndexSlide], ThisSlide.BackgroundTile); ThisSlide.Draw(TextureCanvas, Left - TileLeft + ScreenMaster.OffsetLeftSlide[IndexSlide] + int(ScreenMaster.OffsetLeft) + ThisSlide.ClientPaddingLeft, Top - TileTop + ScreenMaster.OffsetTopSlide [IndexSlide] + int(ScreenMaster.OffsetTop) + ThisSlide.ClientPaddingTop, ScreenMaster.Fade); IndexSlide++; if (IndexSlide == ArrayCount(OffsetLeftSlide)) break; } // ================================================================ // Screen Foreground // ================================================================ if (ScreenMaster.ScreenForeground != None) TextureCanvas.DrawTile(Left - TileLeft, Top - TileTop, ScreenMaster.Width, ScreenMaster.Height, 0, 0, ScreenMaster.ScreenForeground.USize, ScreenMaster.ScreenForeground.VSize, ScreenMaster.ScreenForeground, ScreenMaster.ScreenForeground.bMasked); if (FlagDebug) { ColorDebug.R = 255; ColorDebug.G = 0; ColorDebug.B = 0; TextureCanvas.DrawColoredText(Left, Top, int(Left - TileLeft + ScreenMaster.OffsetLeft + ScreenMaster.SlideCurrentAck.ClientPaddingLeft) @ "x" @ int(Top - TileTop + ScreenMaster.OffsetTop + ScreenMaster.SlideCurrentAck.ClientPaddingTop), Font 'Engine.SmallFont', ColorDebug); } } // ============================================================================ // Tile // // Draws a texture repeatedly onto another texture, starting at the given // offset. // ============================================================================ simulated function Tile(ScriptedTexture TextureCanvas, Texture TextureTile, int OffsetLeft, int OffsetTop, bool FlagTiled) { local int OffsetTopTexture; local int OffsetLeftTexture; for (OffsetLeftTexture = OffsetLeft; OffsetLeftTexture < TextureCanvas.USize; OffsetLeftTexture += TextureTile.USize) { if (OffsetLeftTexture + TextureTile.USize > 0) for (OffsetTopTexture = OffsetTop; OffsetTopTexture < TextureCanvas.VSize; OffsetTopTexture += TextureTile.VSize) { if (OffsetTopTexture + TextureTile.VSize > 0) TextureCanvas.DrawTile(OffsetLeftTexture, OffsetTopTexture, TextureTile.USize, TextureTile.VSize, 0, 0, TextureTile.USize, TextureTile.VSize, TextureTile, TextureTile.bMasked); if (!FlagTiled) break; } if (!FlagTiled) break; } } // ============================================================================ // VersionCheck // // Compares this client's Screen version with the version running on the // server and notifies the user of updates. // ============================================================================ simulated function VersionCheck() { local ScreenMutator ThisScreenMutator; local Mutator ThisMutator; if (FlagVersionAck) return; FlagVersionAck = (VersionServer > 0); if (VersionServer > Version) MutatorScreen.DisplayVersion(Version, VersionServer); VersionLatest = Max(VersionLatest, VersionServer); SaveConfig(); } // ============================================================================ // AddSlide // // Adds a slide to the end of the Screen's current slide list. If the current // last slide wraps around to a previous slide, so will the appended slide. // ============================================================================ simulated function AddSlide(ScreenSlide NewSlide) { local ScreenSlide ThisSlide; local ScreenSlide SlidePrevious; SlidePrevious = None; for (ThisSlide = SlideCurrent; ThisSlide != None && !ThisSlide.FlagSeen; ThisSlide = ThisSlide.SlideNext) { ThisSlide.FlagSeen = true; SlidePrevious = ThisSlide; } if (SlidePrevious == None) { NewSlide.SlideNext = SlideCurrent; SlideCurrent = NewSlide; } else { NewSlide.SlideNext = ThisSlide; SlidePrevious.SlideNext = NewSlide; } NewSlide.FlagSeen = true; for (ThisSlide = SlideCurrent; ThisSlide != None && ThisSlide.FlagSeen; ThisSlide = ThisSlide.SlideNext) ThisSlide.FlagSeen = false; } // ============================================================================ // Default Properties // ============================================================================ Vn@VVH VVy@VVY VVP VVwVVa VVQ VD } D )u ]=$:exxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=$:eq q q tVV~ @VV\ VVVI VVH@VVU VVN VVt @VVs @VVX VVj VVVV\ VVL VVL VVG VV| VVx@VVC  VVh VVLVuV@VV_VVF VVVV{ VVVVL VVVVVVR VV|VVK VV{ VVi VVyVVw VVC VVVV@VVdVVb VVVVpVV@ VVK VVt VVVVrVVqVVc VVE VVcVVA VVn VuVu VV|  VVX VVr VVD VVVVI VVT VVk VVVVx VVy VV@VVY VV} VVp VV~ @VVA VVbVv VVVV}VVJ VVF V VE Vu VVB VVVV] VVJ VVz VVy VVVVb VV~VVP VVVVV VU VVVVc V}VVW VVVV^ VVVm VVd VVVe VO VV` VVN VVOVS Vcvsv )9r@ */a0 @ 87w.@ *810f @ {rf *nv*nvl*va @ P %P , pP f rp*p-p-rr*prpreprBprprrpP ra * rr*nv*nvl*!nva nvlrv Vp tz>h Dtc Dt }~%I ~~|_I %I }~-s tP tQ -s -s ] ~I t?c ?h ta] K J ta] c DK ~~I &*t?h J  Vw Z w2 %1p-i 'E G Z u ^  V_n ` y T rl */a0 ul 108-p l r_` O b N  V{m{u *g H g g -i E H mqm$B ?E pAB ?E pA@@6mC<6B 6mC<6B 6mC<6B maX\ m mm333?mmqwpThis server is running |ScreenSu |.mm ?mmqwThe version of the Screen component installedmmqwpon your computer, |ScreenSG |, is outdated.mm ?mmqwPlease see the |Configure Screens| dialog in themmqw|Mod| menu for information how to update.E pA@@-i (-k mqm$mX m Ammqwcached content-k (w* {m Vf Z m[Z Z ?vZ w x y ?,zZ w x y  Vo O y:O %-d :O &-S :O ,-V :O ,-c :O ,-]  Vm M oCM %red &blue ),green 7,yellow gray Ve lnZry*l lpp%np?l lpp%ns?l lpp%nt?l lpp%nd?l lpp%niMyLevel.UnknownPlayerIconl lpp%nco, I D?@ ?y,<l lpp%npyl lpp%nsSDyl lpp%ntSI l lpp%ndSDyl lpp%niVyl lpp%nco:y Vr T Bm\ T U n  VV[ t] 9rO*/a0 O87w.O*810[ OZr[ * d%U %{U , {U [ r{*{{-{-y{q|d|%u|&({%|N dYN |N (N &(N &|({dU hddW Vi o v}}%D ~}|5D %D }}U-q o W io X -q -q o aր}D z Y L Dz }}D &L  Vj W A 7!jW a} ~ A W &W ~ ?,?{ W a} { DA  VpR "[j hR DrJ*/a0 JCBw.J*C10fn |  wJ*q Vk M uM F M F eM F BM F M F & Vq VVVVg G 5 q w 6$6$6$6\ $6\ $:6\ $6X $@6X $@6X $@ Vq p!2#' - F g  V 15.0V@VVh q -r  | n !-p  -r 'tJa z tc ts cte dt et< VVVVVg rD 'p-k ' Vf @VVjC 9'.-( Vx  3.0VTE xgY -C  -C H %BH xJ wxH G G H b V{VV@// ============================================================================ // ScreenMutator // Copyright 2001 by Mychaeel // // Displays stuff on the user's heads-up display. // ============================================================================ class ScreenMutator extends Mutator; // ============================================================================ // Compiler Directives // ============================================================================ #exec obj load file=Textures\ScreenFonts.utx package=ScreenFonts // ============================================================================ // Constants // ============================================================================ const TimeDisplay = 15.0; const TimeFade = 3.0; // ============================================================================ // Variables // ============================================================================ var float TimeLast; var Font FontDisplayNormal; var Font FontDisplayBold; var Color ColorDisplayBlue; var Color ColorDisplayWhite; var Color ColorDisplayGray; var bool FlagDisplayVersion; var float TimeDisplayVersion; var int VersionDisplayClient; var int VersionDisplayServer; var bool FlagDisplayCached; // ============================================================================ // Spawned // ============================================================================ simulated function Spawned() { FontDisplayNormal = Font 'ScreenFonts.Tahoma10'; FontDisplayBold = Font 'ScreenFonts.TahomaB10'; ColorDisplayWhite.R = 224; ColorDisplayWhite.G = 224; ColorDisplayWhite.B = 224; ColorDisplayBlue.R = 28; ColorDisplayBlue.G = 58; ColorDisplayBlue.B = 127; ColorDisplayGray.R = 64; ColorDisplayGray.G = 64; ColorDisplayGray.B = 64; } // ============================================================================ // ModifyPlayer // ============================================================================ function ModifyPlayer(Pawn PawnPlayer) { local ScreenClient ThisClient; Super.ModifyPlayer(PawnPlayer); foreach AllActors(class 'ScreenClient', ThisClient) if (ThisClient.Owner == PawnPlayer) return; PawnPlayer.Spawn(class 'ScreenClient', PawnPlayer); } // ============================================================================ // MutatorTeamMessage // ============================================================================ function bool MutatorTeamMessage(Actor ActorSender, Pawn PawnReceiver, PlayerReplicationInfo Info, coerce string TextMessage, name NameType, optional bool FlagBeep) { local ScreenClient ThisClient; if (ActorSender == PawnReceiver) foreach AllActors(class 'ScreenClient', ThisClient) if (ThisClient.Owner == ActorSender) ThisClient.Say(TextMessage, NameType); return Super.MutatorTeamMessage(ActorSender, PawnReceiver, Info, TextMessage, NameType, FlagBeep); } // ============================================================================ // PostRender // ============================================================================ simulated function PostRender(canvas Canvas) { local float TimeDelta; local float FactorOpacity; local float WidthText; local float HeightText; local int CoordTopText; if (TimeLast > 0.0) TimeDelta = Level.TimeSeconds - TimeLast; TimeLast = Level.TimeSeconds; if (FlagDisplayVersion) { TimeDisplayVersion += TimeDelta; Canvas.Font = FontDisplayNormal; Canvas.Style = ERenderStyle.STY_Translucent; FactorOpacity = 1.0; if (TimeDisplayVersion > TimeDisplay) FactorOpacity = FMax(0.0, 1.0 - (TimeDisplayVersion - TimeDisplay) / TimeFade); Canvas.DrawColor.R = ColorDisplayWhite.R * FactorOpacity; Canvas.DrawColor.G = ColorDisplayWhite.G * FactorOpacity; Canvas.DrawColor.B = ColorDisplayWhite.B * FactorOpacity; Canvas.TextSize("X", WidthText, HeightText); Canvas.CurY = Canvas.ClipY * 0.7; FormattedDrawCentered(Canvas, FontDisplayNormal, FontDisplayBold, "This server is running |Screen" @ VersionDisplayServer $ "|."); Canvas.CurY += HeightText * 0.6; FormattedDrawCentered(Canvas, FontDisplayNormal, FontDisplayBold, "The version of the Screen component installed"); FormattedDrawCentered(Canvas, FontDisplayNormal, FontDisplayBold, "on your computer, |Screen" @ VersionDisplayClient $ "|, is outdated."); Canvas.CurY += HeightText * 0.6; FormattedDrawCentered(Canvas, FontDisplayNormal, FontDisplayBold, "Please see the |Configure Screens| dialog in the"); FormattedDrawCentered(Canvas, FontDisplayNormal, FontDisplayBold, "|Mod| menu for information how to update."); if (TimeDisplayVersion > TimeDisplay + TimeFade) FlagDisplayVersion = false; } if (FlagDisplayCached) { Canvas.Font = FontDisplayNormal; Canvas.Style = ERenderStyle.STY_Translucent; Canvas.DrawColor = ColorDisplayGray; Canvas.CurY = 10; FormattedDrawCentered(Canvas, FontDisplayNormal, FontDisplayBold, "cached content"); FlagDisplayCached = false; } if (NextHUDMutator != None) NextHUDMutator.PostRender(Canvas); } // ============================================================================ // FormattedWidth // // Returns the width of basic formatted text. // ============================================================================ simulated function int FormattedWidth(canvas Canvas, Font FontNormal, Font FontBold, coerce string Text) { local bool FlagBold; local int IndexCharSeparator; local int WidthTextAccu; local float WidthText; local float HeightText; while (Len(Text) > 0) { IndexCharSeparator = InStr(Text, "|"); if (IndexCharSeparator < 0) IndexCharSeparator = Len(Text); if (FlagBold) Canvas.Font = FontBold; else Canvas.Font = FontNormal; FlagBold = !FlagBold; Canvas.TextSize(Left(Text, IndexCharSeparator), WidthText, HeightText); WidthTextAccu += WidthText; Text = Mid(Text, IndexCharSeparator + 1); } return WidthTextAccu; } // ============================================================================ // FormattedDraw // // Draws basic formatted text. // ============================================================================ simulated function FormattedDraw(canvas Canvas, Font FontNormal, Font FontBold, coerce string Text) { local bool FlagBold; local int IndexCharSeparator; local int CoordTop; local int CoordLeft; local float WidthText; local float HeightText; local string TextChunk; CoordTop = Canvas.CurY; CoordLeft = Canvas.CurX; while (Len(Text) > 0) { IndexCharSeparator = InStr(Text, "|"); if (IndexCharSeparator < 0) IndexCharSeparator = Len(Text); if (FlagBold) Canvas.Font = FontBold; else Canvas.Font = FontNormal; FlagBold = !FlagBold; TextChunk = Left(Text, IndexCharSeparator); Canvas.SetPos(CoordLeft, CoordTop); Canvas.TextSize(TextChunk, WidthText, HeightText); Canvas.DrawText(TextChunk); CoordLeft += WidthText; Text = Mid(Text, IndexCharSeparator + 1); } Canvas.CurY = CoordTop + HeightText; } // ============================================================================ // FormattedDrawCentered // // Draws centered basic formatted text. // ============================================================================ simulated function FormattedDrawCentered(canvas Canvas, Font FontNormal, Font FontBold, coerce string Text) { Canvas.CurX = (Canvas.ClipX - FormattedWidth(Canvas, FontNormal, FontBold, Text)) / 2; FormattedDraw(Canvas, FontNormal, FontBold, Text); } // ============================================================================ // DrawTextCentered // // Draws centered text on the given canvas at the given vertical position and // increases the vertical position by the text height. // ============================================================================ simulated function DrawTextCentered(canvas Canvas, out int CoordTopText, coerce string Text) { local float WidthText; local float HeightText; Canvas.TextSize(Text, WidthText, HeightText); Canvas.SetPos((Canvas.ClipX - WidthText) / 2, CoordTopText); Canvas.DrawText(Text); CoordTopText += HeightText; } // ============================================================================ // DisplayInit // // Initializes heads-up display rendering for this mutator. Can be safely // called multiple times. // ============================================================================ simulated function DisplayInit() { if (bHUDMutator) return; RegisterHUDMutator(); TimeLast = Level.TimeSeconds; } // ============================================================================ // DisplayVersion // // Displays a heads-up message notifying the user that the server is running a // newer Screen version. // ============================================================================ simulated function DisplayVersion(int VersionClient, int VersionServer) { DisplayInit(); FlagDisplayVersion = true; TimeDisplayVersion = 0.0; VersionDisplayClient = VersionClient; VersionDisplayServer = VersionServer; } // ============================================================================ // DisplayCached // // Displays a heads-up message notifying the user that they are looking at a // slide displaying cached content. // ============================================================================ simulated function DisplayCached() { DisplayInit(); FlagDisplayCached = true; } VF VuVVV\ VVM Vm|`  I !b2!U (U (U (U (U (U (> Y> Y{#U^E VVx VI Vo VVb @VVI @VVP @VVK @VG VW @VVy @VVL @VVQ @VVd @VepnZ +U (eot%I !bI !bI !bI !bI !bI !bI !bI !bI !bI !bI !bI !bI !bI !bI !bI !bI !b =I !bI !bI !bI !bI !b> Y> YI !bI !bI !bI !bI !bI !b = =E ]irc.enterthegame.comk" G ] #screen^ ]:9*** Your nickname is now %n
_ ]@?*** Unable to join (error code %e)
` ]0/*** %n has joined
a ].-*** %n has left
b ]87*** %o is now known as %n
c ]'&* %n %m
d ]<< *%n* %m
e ]<%n> %m
f ]'&* %n %m
g ]>> *%n* %m
\ ]<%n> %m
X k O=]KI

[No Server Link Established]

KFXE ]JVVI VVC @VVZ @VVv VV{ VVl @VVN @VV@@VVj@VV` @VG Vo@VG VVVO VVL@VVVVw @VV6Vjwf g v^6J (,~J (,~J (,~J (,~J (,~^k"bD "m $=m $?VVO @VVf VVL Vg V@VV@VV| @VVF VVW @` VV@Nh   ::$q U[U (U (U (U (U (VV^ VVe @^ V@VVp VVG VVu VV] f J VVks^ z +2!JTLLJTLLJTLLJTLL^VVVVA@VVo ` U Vf@Z VF VVQ VV@VVA @VV[ @VVVU Va VVM @VVR I VY VVp@Vena X ::$@J (,~eot%g v^g v^g v^g v^> Yg v^g v^g v^g v^> Y = =k"b[ ]us

%mt (%gt)
%sn

%pn people playing (%pm players max)

%pl

Z ]LJ%pp (%ps frags)
V " U O=]>=

[No Information]

]@VVVVV V\VVVX VVt VVS @VVX VVe VV@VVVVk VU VS VVD` VVVE VV` @VVVVj VVm @f V@VVz VVB @VVWVVm VVs ^ JVM VV ^ VV\V@VVh VV@VV| VVn VV@VVp VVQVVY VVe@a Vy VVV VVn VVf VVe @VVH VVN i VA@VVQ  VVVU Vm @VVBVV~ VVc VVVVX VVo f VVq Va VVb VV_ VV} VVVV@VVuVVt  VV@VVD VVw VVE VVVVSVVQ VVR VVV\V@ VVVVY VV] VVZ VVoVVEV[ Va VVIVV^ @VVU VVdVVs @@VVJVVR @VVS@VVVq VwVV@VG Vh @VG VVVw @Z Vi @VG Vn f VGf Vr VVKi VJ VV@VVjd ol0d %yd , d ` d Id U d Pd @ d jd Q d [d \  w[ *a[ EwQH wH *H Y Y QH QQ*]wlE .wE *E a a lE ll*-Y wQ* wY *QY -W wl* wa *la  Vq VVj@Z Vw!@a V~ Z VNVU VA VV\ VVD VVj @VV@VVVVk @^ VP @VV@VVVVvFW n FI V@VVVVrVVLNq 3;mkwc*NWa?O?E?P?c?c?ccc- Vx i V\VV_ VVMi Vs W n 7V ?W GLMV ?DV LM(Y W KMPNMZ W jUcJUY Y %PZ Z %c VHi VOVVEVViVV@VV@VV}@VVT @VVXVV{ @VVDVVVWVVV\VV]VVVVvM ] Vm^VVVKa Vaa Vba uVca Vd@a Vg@Z Vh@Z Vu @Z VVVk@Z Vl@Z Vm@Z Vn@Z Vo@Z Vp@Z Vq@Z VrZ VsZ VtZ VLZ VG Q L O J K VxVVq !a V@VVPVV@VVz@VVQ@VVyVVR@VVUVMVV@ VVCVV@VVy @` VYVll i e +#h l l i i h  VB f VU @VVM}@pQUITA G  CBc d S" R" b " e " g *02l *[ "s[ V@wxxyyyyyyyyyyyyyyz|u j@{<<<<<<b_PPPU VyVVs p Ko4Gs N p  w p  K U$6H #? u$6H #? $6H #? j $6H #? $6H #? $6H #? M D?cMD D?PK6H N D-HV:K:j  aa6H 6H w "@_ aa6H w "@\ aa6H w "@F  6H 6H  6H 6H z _ 6H 6H _ 6H 6H j \ 6H 6H \ 6H 6H 6H z ?&_  F _  6H j ?&\  F \  6x a ?AAa x ax a x rc*a ?Aa ?c?NM6H a 6H a  VCdm%ppClosedo :SW !`  VU@"r F-O (@+-N wJ * drL*/a0 Lcbw.L*c10qrL* ML/M a0 I J zJ o k J W w 104rJ *J Ma I J o k J W w J D~ J |   VP "476"VV "475"VI{ | B{ x } } { @-y { o 422 V^ "473"Vd "436"Vc <&k is  VO5^K S p, , : n:$9::$ -t: n:$::$-N'  VR "474"Vm "409"Vv "403"CMc d S" R" b " e " g *35[ "Qw[ V@! ~ E>>>>>>>]< E\\>>>>>]<w E 33;;;;:jMO~~#f99X!dV ~ Ewm3>>>>>>>]< Ewm3\\>>>>>]<w E ?R 33aG*h+jMO~~#fq[Dt.CIJ^L "c vduY7QU=)N} ,ot-BHK=/ AdVV`ygl00N} ,wm33VTORLL02|F ?RRTSi4P1R6 Fq[[88kW55_{~rn v('&%$zxe@spZZZb Vk  "376"V]fo &Unable to resolveo !` a V_N}$-O '_}yPi Va~ g_ r6~ W ~ b稨Resolvedo toc~ !` Local port isS~ !` E~  Vb "471"VzfC&Unable to resolves !^ a V[T @ ;I'  -E  T  T &&T  T <<T  T >>zT &/d J _ T d /ME}T %} ~ ACTIONT R nR  R %nJ X R  R %mT \ R  /MSGL J _ T }T %t L T R oR  R %nL R  R %mT \ R   t ~ T R pR  R %nJ X R  R %mT \ R  VcA"G{A}Z % /} a0 @ jiw.@ *Z @ 10z}Z % io   VS "462"Vq59>A p, ,   Vf "433"V`~t u.4J )@ppPRIVMSG~:RS  Vi "432"V@hhjKKLAAB{{|zz{ttuqqrmmnjknGJPilrABDEFH{|~yz|xy{vwyopr>AFtw|.6B59?dfiacf^`clnqkmpfhky{~xz}wy|vx{suxrtw%/<'1>+5B3=J>CJFKREJQY_gmryJMQQTXpsw'4%1 +8(4"-:#.;=Oe9J^%0=(3A'2?ARg)4A+6C,7D-8E.9F/:G0;H1J*1:/6?LWdFOZ8?H'3(4!-; ,9#/=*6%2@$0> +77I^'4B&2@=Pe)6D)5B+7DARe-9F@O`BQa2=I3>J9ERM\lERa'.6GTb-5>HUc=GR,3;LXeKWdWdsQerzqvznruwz|vwwijj`aaqqsyyyxxxuuusssnnnmmmkkkiiigggccc\\\[[[WWWTTTRRRPPPEEEVLLS n |4P ?S N NLMP ?DP LM(R DS 6H 6H ?D Q DS 6H 6H ?M R R %PQ Q %c VW "422"Vr @VVq{k c1=J 2@ppppNOTICE{:&z&S  Cgc d S" R" b " e " g *36l *[ "ͺ[ V(@ĺ Э' '䁗WWWWWWWV#%]CuNOOOONNrngj<*ƭڝHP|}}4|RQyunjA $vQUUU}|RPMHlmi_)ݮLRUU4QTN3HGk?f(ݮLQ||PMK21CABhh (ӸvPQPLIDAmBhff?[ suwwHlpif@@@@h8%5 Closojm?ff@@@Bҟ!ҨYmAConDCkApmmG` xJJJttEEtSd>=c շ0/.,+Z⪤~~ѫٸԷ &'` ;&ҥa9bba--"a:;R\zFqF{XXze^76677 VX "405"VkI u 4eI pI ,v %]v }I \ I v &\  r,-p -l -l -l W bS ,-p -n -n -n W uS ,\ I v &&y\ 0 x\ 9N \ 3z\ 1\ I v ,&3y\ 0 x\ 5N pN \ v }N N ^0N white t1N black 2N navy 3N green 4N red 5N maroon 6N purple 7N #ff8000 8N yellow &9N green <10N teal R11N aqua h12N blue 13N fuchsia 14N gray 15N silver W fontC pcolor=N S ;,G Y &!G %P pppP G Y %-l (-n (S P pP \ SS}W %p-p G Y &G %{G [ W P pppP G wP pppP G G fG Y &G [ G &[ G l G &l P pppP <G l >G Y ;G Y &G %{G [ W G ~+G %Y [ W }C %Y l W C Y l W P pppP <Y l >Y ;G Y &G %{G [ W P pppP G 9P pppP G [ W }C %G l W C G l W G G ;G Y P pppP <G l >G -p (W C v P  VV VVl @VVr "436"Vs "433"Vt "432"Vu "422"V}  "376"VZ "402"V}},wx *x -J ( V{p KTimed out retrieving game information from] !Y x m  VKVVT} g3Cr6} e Bb稨Resolveds toc} !^ Local port isSB!^ E}  V|vaq:6y 6v x  xaB ( Vr # @y \status\aB ( VExl HVCp MTimed out retrieving server information from] !f x m  V\T\ AV b TV D?V &?,@JV s s D?s &?,@vT s T V vpvT b T D?T &?,@] CAc d S" R" b " e " g *45l *[ "\[ V4@u \73333333E27DD33333E2V7 **11110L:<\\^ Kc//tb@qsI>u \7VO*3333333E27VO*D_~aE2V7 4= *yBk1i:<\\^ KRCcphm}9 H UqsIxn;r[&tboN' ]6qsI|(;r[&VO+zv{wje)rZ8 4=glf=- 8RCC..M?,,F`Y\SP U%$#"!XWdJ5TQAAAG V@hhjKKLAAB{{|yyzxxyttuqqrmmnjknilrABDEFH{|~yz|xy{vwy.6Bdfi^`ckmpfhky{~xz}vx{suxrtw>CJ'4%1(4"-:#.;=Oe%0=ARg+6C-8E.9F*1:/6?FOZ8?H'3!-;*6&2@=Pe)5B9ER3=HERa'.6-5>WdsQe%.79BKGNUFLRelsimqNPRy{}vxztvxuvw39>rz9AGwE *E a   VnT 5G/a0 \T &%T -z &10=rT *-z 'E$ V@hhjKKLAAB{{|yyzxxyttuqqrmmnjknilrABDEFH{|~yz|xy{vwy.6Bdfi^`ckmpfhky{~xz}vx{suxrtw3=JCJ'4%1 +8(4"-:#.;=Oe%0=(3A'2?ARg+6C-8E.9F/:G0;H4>J*1:/6?FOZ8?H'3!-; ,9#/=*6%2@$0> +7&2@=Pe)5B+7D9ERERa'.6-5>WdsQe9BKGNUFLRelsimqNPRy{}vxztvxuvwrzprVKKvFwv**Cqh(}c\--DwcA*,qg@} CJ'4%1 +8(4"-:#.;=Oe%0=(3AARg+6C-8E.9F*1:8AL/6?FOZ8?H'3!-; ,9#/=*6%2@$0> +7&2@=Pe)5B+7D9ERERa'.6-5>8BMWdsFP[HR]Qe)4?9BKGNU_hqFLRelsimqNPRy{}vxztvxuvwrz>_zS &&S S &hzS &&S S }S &AJ _ S A ACTIONQ kQ  Q %n] Q  Q %mu S \ Q \ kVERSIONhrJ } k ] ppVERSION ScreenS xUTMychaeel@planetunreal.com\ PINGrJ } k ] PINGS \ CLIENTINFOrJ } k ] CLIENTINFO ACTION VERSION PING CLIENTINFO URL\ YURLVrJ } k ] URL http://www.0x01.net/members/mb/screen/\ |y J X Q lQ mQ  Q %n] Q  Q %mu S \ Q f 376 422J @pJOIN~ S f 473 471 &403 .474 6475 >476 c405\  g%e@f  VC VVZq -J  t K /-q  zv  -J 'j Ka g j x j ] v j m wb %j B  V]t { LL q L  L %snh t hostnameL  L %sph t hostportL  L %mth t maptitleL  L %mnh t mapnameL  L %gth t gametypeL  L %pnh t numplayersL  L %pmh t maxplayers~q %pl%~q %gs%~q %a%j z vL j a VaIv } V^h  7{h F ] h t ~F _ct %O JF t &F F t &F  GAMESTYLEL  L %gs] h  ADMINNAMEL  L %an] h  ADMINEMAILL  L %am] h  4PLAYER_6e j O O ] h  eFRAGS_6w j O O J] h  PING_6u j O O J] h  TEAM_6p j O O J] h  FINALy n %n b dM eM  M %piS6R n O M  M %pp6e n O M  M %psS6w n O M  M %prS6u n O M  M %ptS6p n O 6p n O %M  M %pcred &M  M %pcblue ;,M  M %pcgreen a,M  M %pcyellow ,M  M %pcgray I pI M n L  L %plI vL j a ] h  Vbz 9r !l q!v  Vx B +r !x q!v  VUdo ppCloseds :Se !^ k k ~k ppp, , , , ,}k %c vk c -dc 0a VH VVZ VVcCe !9rQ */a0 Q 87w.Q *810{ Q Zr{ * Z %Z , rZ { *Z { -"Z { ,  Z { V Z { Z a9X X rL *X ?/a0 \L L -z 10rL * rL  Z %Z , A Z L Z  V@hhjKKLAAB{{|yyzxxyttuqqrmmnjknilrABDEFH{|~yz|xy{vwy.6Bdfi^`ckmpfhky{~xz}vx{suxrtw+5B3=J>CJ'4%1 +8(4"-:#.;=Oe%0=(3A'2?ARg+6C-8E.9F/:G0;H/9E4>J*1:/6?FOZ8?H'3!-; ,9*6%2@$0> +7&2@=Pe)5B+7D9ERERa'.6-5>WdsQe9BKGNUFLRelsimqNPRy{}vxztvxuvwrz // // Queries game server information. // ============================================================================ class ScreenUdpLinkServer extends UdpLink; // ============================================================================ // Properties // ============================================================================ var() ScreenSlidePageServer Page; var() string AddressServer; var() int AddressPort; var() int RetryCount; var() float RetryDelay; var() float Timeout; // ============================================================================ // Variables // ============================================================================ var bool FlagBound; var name NameState; var IpAddr IpAddrServer; // ============================================================================ // GetInfoServer // // Starts a query for server information. // ============================================================================ function GetInfoServer() { NameState = 'InfoServer'; GotoState('Resolving'); } // ============================================================================ // GetInfoGame // // Starts a query for game and player information. // ============================================================================ function GetInfoGame() { NameState = 'InfoGame'; GotoState('Resolving'); } // ============================================================================ // state Resolving // ============================================================================ state Resolving { // ========================================================================== // BeginState // ========================================================================== event BeginState() { if (FlagBound) GotoState(NameState); else Resolve(AddressServer); } // ========================================================================== // Resolved // ========================================================================== event Resolved(IpAddr IpAddrResolved) { IpAddrServer.Addr = IpAddrResolved.Addr; IpAddrServer.Port = AddressPort; if (BindPort(2000, true) == 0) { RetryCount--; if (RetryCount > 0) SetTimer(RetryDelay, false); return; } FlagBound = true; GotoState(NameState); } // ========================================================================== // ResolveFailed // ========================================================================== event ResolveFailed() { Log("Unable to resolve" @ AddressServer, 'ScreenUdpLinkServer'); Destroy(); } // ========================================================================== // Timer // ========================================================================== event Timer() { Resolved(IpAddrServer); } } // state Resolving // ============================================================================ // state InfoServer // ============================================================================ state InfoServer { // ========================================================================== // BeginState // ========================================================================== event BeginState() { SendText(IpAddrServer, "\\info\\"); SetTimer(Timeout, false); } // ========================================================================== // ReceivedText // ========================================================================== event ReceivedText(IpAddr IpAddrSender, string Text) { if (IpAddrServer.Addr != IpAddrSender.Addr) return; Page.ReceiveInfoServer(Text); SetTimer(0.0, false); } // ========================================================================== // Timer // ========================================================================== event Timer() { Log("Timed out retrieving server information from" @ AddressServer, 'ScreenUdpLinkServer'); Page.Timeout(); } } // state InfoServer // ============================================================================ // state InfoGame // ============================================================================ state InfoGame { // ========================================================================== // BeginState // ========================================================================== event BeginState() { SendText(IpAddrServer, "\\status\\"); SetTimer(Timeout, false); } // ========================================================================== // ReceivedText // ========================================================================== event ReceivedText(IpAddr IpAddrSender, string Text) { if (IpAddrServer.Addr != IpAddrSender.Addr) return; Page.ReceiveInfoGame(Text); SetTimer(Timeout, false); } // ========================================================================== // Timer // ========================================================================== event Timer() { Log("Timed out retrieving game information from" @ AddressServer, 'ScreenUpdLinkServer'); Page.Timeout(); } } // state InfoGame // ============================================================================ // Destroyed // ============================================================================ event Destroyed() { if (Page != None) Page.FlagReloading = false; } // ============================================================================ // Default Properties // ============================================================================ Vk6// ============================================================================ // ScreenTcpLinkWeb // Copyright 2001 by Mychaeel // // Gets data from the web. // ============================================================================ class ScreenTcpLinkWeb extends TcpLink; // ============================================================================ // Properties // ============================================================================ var() ScreenSlidePageWeb Page; var() string AddressHost; var() int AddressPort; var() string AddressPath; // ============================================================================ // Variables // ============================================================================ var string Buffer; // ============================================================================ // Start // // Starts the connection. // ============================================================================ function Start() { Buffer = ""; Resolve(AddressHost); } // ============================================================================ // Resolved // ============================================================================ event Resolved(IpAddr AddressIp) { local int AddressLocalPort; AddressIp.Port = AddressPort; AddressLocalPort = BindPort(); Log("Resolved" @ AddressHost @ "to" @ IpAddrToString(AddressIp), 'ScreenTcpLinkWeb'); Log("Local port is" @ AddressLocalPort, 'ScreenTcpLinkWeb'); Open(AddressIp); } // ============================================================================ // ResolveFailed // ============================================================================ event ResolveFailed() { Log("Unable to resolve" @ AddressHost, 'ScreenTcpLinkWeb'); Destroy(); } // ============================================================================ // Opened // ============================================================================ event Opened() { local string Query; Log("Opened" @ AddressHost $ ":" $ AddressPort, 'ScreenTcpLinkWeb'); Query = "GET" @ AddressPath @ "HTTP/1.0" $ Chr(13) $ Chr(10) $ "Host:" @ AddressHost $ Chr(13) $ Chr(10) $ Chr(13) $ Chr(10); LinkMode = MODE_Text; SendText(Query); } // ============================================================================ // ReceivedText // ============================================================================ event ReceivedText(string Text) { if (Len(Buffer) == 0) Log("Receiving text from" @ AddressHost $ ":" $ AddressPort, 'ScreenTcpLinkWeb'); Buffer = Buffer $ Text; } // ============================================================================ // Closed // ============================================================================ event Closed() { Log("Closed" @ AddressHost $ ":" $ AddressPort, 'ScreenTcpLinkWeb'); Buffer = Mid(Buffer, InStr(Buffer, Chr(13) $ Chr(10) $ Chr(13) $ Chr(10)) + 4); if (Len(Buffer) > 0) { Page.Text = Buffer; if (Page.Cached) Page.CacheSave(); } Destroy(); } // ============================================================================ // Destroyed // ============================================================================ function Destroyed() { Page.FlagReloading = false; } Vi_ ~ ;N&c ,$-K 6R _ 6R ` u U$-K s6e _ 6e ` u $-K 6w _ 6w ` 66w _ 6w ` s6e _ 6e ` u $-K 6u _ 6u ` 66u _ 6u ` s6e _ 6e ` u r$-K 6p _ 6p ` 66p _ 6p ` s6e _ 6e ` u -K -b Va// ============================================================================ // ScreenTcpLinkChat // Copyright 2001 by Mychaeel // // Monitors a chat. // ============================================================================ class ScreenTcpLinkChat extends TcpLink; // ============================================================================ // Properties // ============================================================================ var() ScreenSlidePageChat Page; var() string AddressServer; var() int AddressPort; var() string AddressChannel; // ============================================================================ // Constants // ============================================================================ const IRC_RPL_ENDOFMOTD = "376"; const IRC_ERR_NOMOTD = "422"; const IRC_ERR_ERRONEOUSNICKNAME = "432"; const IRC_ERR_NICKNAMEINUSE = "433"; const IRC_ERR_NICKCOLLISION = "436"; // ============================================================================ // Variables // ============================================================================ var bool FlagConnected; var int CountNicknameTries; var string TextNickname; var string TextNicknameBase; var string TextUsername; var string TextBuffer; var string CRLF; // ============================================================================ // PreBeginPlay // ============================================================================ simulated event PreBeginPlay() { CRLF = Chr(13) $ Chr(10); Super.PreBeginPlay(); } // ============================================================================ // Tick // ============================================================================ simulated event Tick(float TimeDelta) { local PlayerPawn ThisPlayer; Super.Tick(TimeDelta); if (Len(TextNicknameBase) > 0) return; foreach Page.AllActors(class 'PlayerPawn', ThisPlayer) if (Viewport(ThisPlayer.Player) != None) TextNicknameBase = ThisPlayer.PlayerReplicationInfo.PlayerName; if (Len(TextNicknameBase) == 0) return; Resolve(AddressServer); } // ============================================================================ // Resolved // ============================================================================ event Resolved(IpAddr AddressIp) { local int AddressLocalPort; AddressIp.Port = AddressPort; AddressLocalPort = BindPort(); Log("Resolved" @ AddressServer @ "to" @ IpAddrToString(AddressIp), 'ScreenTcpLinkChat'); Log("Local port is" @ AddressLocalPort, 'ScreenTcpLinkChat'); Open(AddressIp); } // ============================================================================ // ResolveFailed // ============================================================================ event ResolveFailed() { Log("Unable to resolve" @ AddressServer, 'ScreenTcpLinkChat'); Destroy(); } // ============================================================================ // Opened // ============================================================================ event Opened() { local int IndexChar; local string CharUsername; Log("Opened" @ AddressServer $ ":" $ AddressPort, 'ScreenTcpLinkChat'); CountNicknameTries = 1; TextNickname = Left(TextNicknameBase, 9); for (IndexChar = 0; IndexChar < Len(TextNickname); IndexChar++) { CharUsername = Chr(Asc(Mid(TextNickname, IndexChar, 1)) & ~0x20); if (CharUsername >= "a" && CharUsername <= "z") TextUsername = TextUsername $ CharUsername; } if (Len(TextUsername) == 0) TextUsername = "user" $ rand(10000); LinkMode = MODE_Text; SendText("NICK" @ TextNickname $ CRLF); SendText("USER" @ TextUsername @ "127.0.0.1" @ AddressServer @ ":" $ TextNickname $ CRLF); } // ============================================================================ // ReceivedText // ============================================================================ event ReceivedText(string TextReceived) { local ScreenSlidePageChat PageChannel; local int IndexCharSeparator; local string TextCommand; local string TextLine; local string TextNicknameSender; local string TextNicknameSuffix; TextBuffer = TextBuffer $ TextReceived; while (true) { IndexCharSeparator = InStr(TextBuffer, Chr(10)); if (IndexCharSeparator < 0) break; TextLine = Left(TextBuffer, IndexCharSeparator); TextBuffer = Mid (TextBuffer, IndexCharSeparator + 1); if (Right(TextLine, 1) == Chr(13)) TextLine = Left(TextLine, Len(TextLine) - 1); TextNicknameSender = ParseNicknameSender(TextLine); TextCommand = Caps(ParseToken(TextLine)); switch (TextCommand) { case "PING": SendText("PONG" @ ParseToken(TextLine) $ CRLF); break; case IRC_ERR_NICKNAMEINUSE: case IRC_ERR_ERRONEOUSNICKNAME: case IRC_ERR_NICKCOLLISION: if (CountNicknameTries == 1) TextNicknameSuffix = "-"; else TextNicknameSuffix = string(Rand(10000)); CountNicknameTries++; TextNickname = Left(TextNicknameBase, 9 - Len(TextNicknameSuffix)) $ TextNicknameSuffix; SendText("NICK" @ TextNickname $ CRLF); break; case IRC_RPL_ENDOFMOTD: case IRC_ERR_NOMOTD: FlagConnected = true; default: for (PageChannel = Page; PageChannel != None; PageChannel = PageChannel.PageChannelNext) PageChannel.ParseResponse(TextNicknameSender, TextCommand, TextLine); break; } } } // ============================================================================ // Closed // ============================================================================ event Closed() { Log("Closed" @ AddressServer $ ":" $ AddressPort, 'ScreenTcpLinkChat'); } // ============================================================================ // Destroyed // ============================================================================ simulated event Destroyed() { SendText("QUIT" $ CRLF); Close(); } // ============================================================================ // AddChannel // // Adds a channel on the same server to the list. // ============================================================================ simulated function AddChannel(ScreenSlidePageChat PageChannel) { PageChannel.PageChannelNext = Page; Page = PageChannel; if (FlagConnected) PageChannel.ParseResponse("", IRC_ERR_NOMOTD, ""); } // ============================================================================ // ParseNicknameSender // // Checks whether the given string is lead by a nickname parameter, removes it // from the string argument and returns it. // ============================================================================ simulated function string ParseNicknameSender(out string TextResponse) { local int IndexCharSeparator; local string TextNicknameSender; if (Left(TextResponse, 1) != ":") return ""; TextResponse = Mid(TextResponse, 1); IndexCharSeparator = InStr(TextResponse, " "); if (IndexCharSeparator < 0) IndexCharSeparator = Len(TextResponse); TextNicknameSender = Left(TextResponse, IndexCharSeparator); TextResponse = Mid(TextResponse, IndexCharSeparator + 1); while (Left(TextResponse, 1) == " ") TextResponse = Mid(TextResponse, 1); IndexCharSeparator = InStr(TextNicknameSender, "!"); if (IndexCharSeparator >= 0) TextNicknameSender = Left(TextNicknameSender, IndexCharSeparator); return TextNicknameSender; } // ============================================================================ // ParseToken // // Returns the next token in the given string and removes it from the string // argument. // ============================================================================ simulated function string ParseToken(out string TextResponse) { local int IndexCharSeparator; local string TextToken; if (Left(TextResponse, 1) == ":") { TextToken = Mid(TextResponse, 1); TextResponse = ""; return TextToken; } IndexCharSeparator = InStr(TextResponse, " "); if (IndexCharSeparator < 0) IndexCharSeparator = Len(TextResponse); TextToken = Left(TextResponse, IndexCharSeparator); TextResponse = Mid(TextResponse, IndexCharSeparator + 1); while (Left(TextResponse, 1) == " ") TextResponse = Mid(TextResponse, 1); return TextToken; } // ============================================================================ // Default Properties // ============================================================================ V// ============================================================================ // ScreenSlidePageServer // Copyright 2001 by Mychaeel // // Implements a ScreenSlidePage that displays information about a game server. // ============================================================================ class ScreenSlidePageServer extends ScreenSlidePage; // ============================================================================ // Compiler Directives // ============================================================================ #exec texture import file=Textures\ActorSlidePageServer.bmp mips=off flags=2 // ============================================================================ // Replication // ============================================================================ replication { reliable if (Role == ROLE_Authority) VersionLatest, AddressServer, AddressPort; } // ============================================================================ // Structures // ============================================================================ struct TPlayer { var int Id; var string Name; var int Score; var int Ping; var int Team; }; // ============================================================================ // Enumerations // ============================================================================ enum EnumPlayersSort { PlayersSort_Id, PlayersSort_Name, PlayersSort_Score, PlayersSort_Ping, PlayersSort_Team, }; // ============================================================================ // Properties // ============================================================================ var() string AddressServer; var() int AddressPort; var() string Template; var() string TemplatePlayer; var() int PlayersCount; var() EnumPlayersSort PlayersSort; var() bool PlayersSortReverse; var() bool NetworkGameOnly; // ============================================================================ // Variables // ============================================================================ var PlayerPawn PlayerLocal; var ScreenUdpLinkServer Link; var string TextResult; var int CountPlayers; var TPlayer Players[32]; var int VersionLatest; var int VersionCurrent; var bool FlagDisabled; var bool FlagReloading; // ============================================================================ // PreBeginPlay // ============================================================================ simulated event PreBeginPlay() { Super.PreBeginPlay(); FlagDisabled = class 'Screen'.default.Network == ConfigNetwork_Never || (Level.NetMode == NM_Standalone && (NetworkGameOnly || class 'Screen'.default.Network == ConfigNetwork_Network)) || (Level.NetMode == NM_DedicatedServer); VersionCurrent = -1; } // ============================================================================ // Tick // ============================================================================ simulated function Tick(float TimeDelta) { Super.Tick(TimeDelta); if (PlayerLocal == None) foreach AllActors(class 'PlayerPawn', PlayerLocal) if (Viewport(PlayerLocal.Player) != None) break; if (VersionLatest > VersionCurrent && PlayerLocal != None) Reload(); } // ============================================================================ // Trigger // ============================================================================ function Trigger(Actor Other, Pawn EventInstigator) { Super.Trigger(Other, EventInstigator); VersionLatest++; } // ============================================================================ // Reload // // Reloads the slide's content. // ============================================================================ simulated function Reload() { if (FlagReloading) return; VersionCurrent = VersionLatest; if (FlagDisabled || AddressServer == "") return; FlagReloading = true; Link = PlayerLocal.GetEntryLevel().Spawn(class 'ScreenUdpLinkServer'); Link.Page = Self; Link.AddressServer = AddressServer; Link.AddressPort = AddressPort; CountPlayers = 0; Link.GetInfoServer(); } // ============================================================================ // ReceiveInfoServer // // Called by ScreenUdpLinkServer when server info is received. // ============================================================================ simulated function ReceiveInfoServer(string TextInfo) { TextResult = Template; TextResult = Replace(TextResult, "%sn", GetItem(TextInfo, "hostname")); TextResult = Replace(TextResult, "%sp", GetItem(TextInfo, "hostport")); TextResult = Replace(TextResult, "%mt", GetItem(TextInfo, "maptitle")); TextResult = Replace(TextResult, "%mn", GetItem(TextInfo, "mapname")); TextResult = Replace(TextResult, "%gt", GetItem(TextInfo, "gametype")); TextResult = Replace(TextResult, "%pn", GetItem(TextInfo, "numplayers")); TextResult = Replace(TextResult, "%pm", GetItem(TextInfo, "maxplayers")); if (InStr(Template, "%pl") >= 0 || InStr(Template, "%gs") >= 0 || InStr(Template, "%a") >= 0) Link.GetInfoGame(); else { Text = TextResult; Link.Destroy(); } } // ============================================================================ // ReceiveInfoGame // // Called by ScreenUdpLinkServer when game info is received. // ============================================================================ simulated function ReceiveInfoGame(string TextInfo) { local int IdPlayer; local int IndexCharSeparator; local int IndexPlayer; local string TextItemName; local string TextPlayer; local string TextPlayerList; while (TextInfo != "") { TextItemName = GetItemNext(TextInfo); IndexCharSeparator = InStr(TextItemName, "_"); if (IndexCharSeparator >= 0) { IdPlayer = int(Mid(TextItemName, IndexCharSeparator + 1)); TextItemName = Left(TextItemName, IndexCharSeparator + 1); } switch (Caps(TextItemName)) { case "GAMESTYLE": TextResult = Replace(TextResult, "%gs", GetItemNext(TextInfo)); break; case "ADMINNAME": TextResult = Replace(TextResult, "%an", GetItemNext(TextInfo)); break; case "ADMINEMAIL": TextResult = Replace(TextResult, "%am", GetItemNext(TextInfo)); break; case "PLAYER_": Players[GetPlayerIndex(IdPlayer)].Name = GetItemNext(TextInfo); break; case "FRAGS_": Players[GetPlayerIndex(IdPlayer)].Score = int(GetItemNext(TextInfo)); break; case "PING_": Players[GetPlayerIndex(IdPlayer)].Ping = int(GetItemNext(TextInfo)); break; case "TEAM_": Players[GetPlayerIndex(IdPlayer)].Team = int(GetItemNext(TextInfo)); break; case "FINAL": PlayersSorting(); for (IndexPlayer = 0; IndexPlayer < Min(CountPlayers, PlayersCount); IndexPlayer++) { TextPlayer = TemplatePlayer; TextPlayer = Replace(TextPlayer, "%pi", Players[IndexPlayer].Id); TextPlayer = Replace(TextPlayer, "%pp", Players[IndexPlayer].Name); TextPlayer = Replace(TextPlayer, "%ps", Players[IndexPlayer].Score); TextPlayer = Replace(TextPlayer, "%pr", Players[IndexPlayer].Ping); TextPlayer = Replace(TextPlayer, "%pt", Players[IndexPlayer].Team); switch (Players[IndexPlayer].Team) { case 0: TextPlayer = Replace(TextPlayer, "%pc", "red"); break; case 1: TextPlayer = Replace(TextPlayer, "%pc", "blue"); break; case 2: TextPlayer = Replace(TextPlayer, "%pc", "green"); break; case 3: TextPlayer = Replace(TextPlayer, "%pc", "yellow"); break; case 255: TextPlayer = Replace(TextPlayer, "%pc", "gray"); break; } TextPlayerList = TextPlayerList $ TextPlayer; } TextResult = Replace(TextResult, "%pl", TextPlayerList); Text = TextResult; Link.Destroy(); break; default: GetItemNext(TextInfo); break; } } } // ============================================================================ // Timeout // // Called by ScreenUdpLinkServer when a query times out. // ============================================================================ simulated function Timeout() { Link.Destroy(); } // ============================================================================ // PlayersSorting // // Sorts the array of players according to the current sorting criteria. // ============================================================================ simulated function PlayersSorting() { local int IndexPlayer1; local int IndexPlayer2; for (IndexPlayer1 = 0; IndexPlayer1 < CountPlayers - 1; IndexPlayer1++) for (IndexPlayer2 = CountPlayers - 1; IndexPlayer2 > IndexPlayer1; IndexPlayer2--) if (PlayersCompare(Players[IndexPlayer2], Players[IndexPlayer1])) PlayersSwap(Players[IndexPlayer2], Players[IndexPlayer1]); } // ============================================================================ // PlayersCompare // // Compares the given two players according to the current sorting criteria. // Returns whether the first should be sorted before the second. // ============================================================================ simulated function bool PlayersCompare(TPlayer Player1, TPlayer Player2) { local bool Result; switch (PlayersSort) { case PlayersSort_Id: Result = (Player1.Id < Player2.Id); break; case PlayersSort_Name: Result = (Caps(Player1.Name) < Caps(Player2.Name)); break; case PlayersSort_Score: Result = (Player1.Score < Player2.Score) || (Player1.Score == Player2.Score && (Caps(Player1.Name) < Caps(Player2.Name))); break; case PlayersSort_Ping: Result = (Player1.Ping < Player2.Ping) || (Player1.Ping == Player2.Ping && (Caps(Player1.Name) < Caps(Player2.Name))); break; case PlayersSort_Team: Result = (Player1.Team < Player2.Team) || (Player1.Team == Player2.Team && (Caps(Player1.Name) < Caps(Player2.Name))); break; } return (Result != PlayersSortReverse); } // ============================================================================ // PlayersSwap // // Swaps the given two players. // ============================================================================ simulated final function PlayersSwap(out TPlayer Player1, out TPlayer Player2) { local TPlayer PlayerTemp; PlayerTemp = Player1; Player1 = Player2; Player2 = PlayerTemp; } // ============================================================================ // GetPlayerIndex // // Returns the index of a player info array entry corresponding to the given // player id. If such an entry isn't found, clears and initializes a new one // and returns its index. // ============================================================================ simulated function int GetPlayerIndex(int Id) { local int IndexPlayer; for (IndexPlayer = 0; IndexPlayer < CountPlayers; IndexPlayer++) if (Players[IndexPlayer].Id == Id) return IndexPlayer; Players[CountPlayers].Id = Id; Players[CountPlayers].Name = ""; Players[CountPlayers].Score = 0; Players[CountPlayers].Ping = 0; Players[CountPlayers].Team = 255; return CountPlayers++; } // ============================================================================ // GetItem // // Gets a named item from the given list of items. If the item isn't present, // returns the given default value instead. // ============================================================================ simulated function string GetItem(string TextItems, string TextName, optional string TextDefault) { local int IndexChar; IndexChar = InStr(Caps(TextItems), "\\" $ Caps(TextName) $ "\\"); if (IndexChar < 0) return TextDefault; TextItems = Mid(TextItems, IndexChar + Len(TextName) + 2); return GetItemNext(TextItems); } // ============================================================================ // GetItemNext // // Gets the next item name or value from the given list of items, returns it // and removes it from the list. // ============================================================================ simulated function string GetItemNext(out string TextItems) { local int IndexChar; local string TextItem; if (Left(TextItems, 1) == "\\") TextItems = Mid(TextItems, 1); IndexChar = InStr(TextItems $ "\\", "\\"); TextItem = Left(TextItems, IndexChar); TextItems = Mid(TextItems, IndexChar + 1); return TextItem; } // ============================================================================ // Default Properties // ============================================================================ VK VVd// ============================================================================ // ScreenSlidePageChat // Copyright 2001 by Mychaeel // // Implements a ScreenSlidePage that monitors a chat. // ============================================================================ class ScreenSlidePageChat extends ScreenSlidePage; // ============================================================================ // Compiler Directives // ============================================================================ #exec texture import file=Textures\ActorSlidePageChat.bmp name=ActorSlidePageChat mips=off flags=2 // ============================================================================ // Properties // ============================================================================ var() string AddressServer; var() int AddressPort; var() string AddressChannel; var() string MessageConnect; var() string MessageError; var() string MessageJoin; var() string MessageLeave; var() string MessageNickname; var() string MessageReceiveAction; var() string MessageReceivePrivate; var() string MessageReceivePublic; var() string MessageSendAction; var() string MessageSendPrivate; var() string MessageSendPublic; var() bool SendSay; var() bool SendSayTeam; var() bool SendWatching; var() bool NetworkGameOnly; // ============================================================================ // Constants // ============================================================================ const IRC_RPL_ENDOFMOTD = "376"; const IRC_ERR_NOSUCHSERVER = "402"; const IRC_ERR_NOSUCHCHANNEL = "403"; const IRC_ERR_TOOMANYCHANNELS = "405"; const IRC_ERR_NOORIGIN = "409"; const IRC_ERR_NOMOTD = "422"; const IRC_ERR_ERRONEOUSNICKNAME = "432"; const IRC_ERR_NICKNAMEINUSE = "433"; const IRC_ERR_NICKCOLLISION = "436"; const IRC_ERR_ALREADYREGISTERED = "462"; const IRC_ERR_CHANNELISFULL = "471"; const IRC_ERR_INVITEONLYCHAN = "473"; const IRC_ERR_BANNEDFROMCHAN = "474"; const IRC_ERR_BADCHANNELKEY = "475"; const IRC_ERR_BADCHANMASK = "476"; // ============================================================================ // Variables // ============================================================================ var PlayerPawn PlayerLocal; var ScreenTcpLinkChat Link; var ScreenSlidePageChat PageChannelNext; var bool FlagDisabled; var bool FlagDisplayed; var bool FlagConnected; var string TextScrollback[64]; var int IndexScrollbackOldest; var int IndexScrollbackNext; var string CRLF; // ============================================================================ // PreBeginPlay // ============================================================================ simulated event PreBeginPlay() { CRLF = Chr(13) $ Chr(10); Super.PreBeginPlay(); if (class 'Screen'.default.Network == ConfigNetwork_Never || (Level.NetMode == NM_Standalone && (NetworkGameOnly || class 'Screen'.default.Network == ConfigNetwork_Network)) || (Level.NetMode == NM_DedicatedServer)) FlagDisabled = true; } // ============================================================================ // Tick // ============================================================================ simulated event Tick(float TimeDelta) { local LevelInfo LevelEntry; FlagDisplayed = false; Super.Tick(TimeDelta); if (FlagDisabled || Link != None) return; if (PlayerLocal == None) foreach AllActors(class 'PlayerPawn', PlayerLocal) if (Viewport(PlayerLocal.Player) != None) break; if (PlayerLocal == None) return; LevelEntry = PlayerLocal.GetEntryLevel(); foreach LevelEntry.AllActors(class 'ScreenTcpLinkChat', Link) if (Link.AddressServer == AddressServer && Link.AddressPort == AddressPort) break; if (Link == None) { Link = LevelEntry.Spawn(class 'ScreenTcpLinkChat'); Link.AddressServer = AddressServer; Link.AddressPort = AddressPort; Link.AddressChannel = AddressChannel; } Link.AddChannel(Self); } // ============================================================================ // Draw // ============================================================================ simulated function Draw(ScriptedTexture TextureCanvas, int Left, int Top, float Fade) { FlagDisplayed = true; Super.Draw(TextureCanvas, Left, Top, Fade); } // ============================================================================ // AddText // // Adds text to the slide, potentially purging old text from the buffer. // ============================================================================ simulated function AddText(string TextAdded) { local int IndexScrollback; TextScrollback[IndexScrollbackNext] = TextAdded; IndexScrollbackNext = (IndexScrollbackNext + 1) % ArrayCount(TextScrollback); if (IndexScrollbackNext == IndexScrollbackOldest) IndexScrollbackOldest = (IndexScrollbackOldest + 1) % ArrayCount(TextScrollback); Text = ""; for (IndexScrollback = IndexScrollbackOldest; IndexScrollback != IndexScrollbackNext; IndexScrollback = (IndexScrollback + 1) % ArrayCount(TextScrollback)) Text = Text $ TextScrollback[IndexScrollback]; } // ============================================================================ // ParseResponse // // Parses a single line of response from the server. // ============================================================================ simulated function ParseResponse(string TextNicknameSender, string TextCommand, string TextArguments) { local string TextChat; local string TextMessage; local string TextRecipient; local string TextRequest; switch (TextCommand) { case "JOIN": if (Link.ParseToken(TextArguments) ~= AddressChannel) { if (TextNicknameSender == Link.TextNickname) AddText(Replace(MessageConnect, "%n", Link.TextNickname)); else AddText(Replace(MessageJoin, "%n", TextNicknameSender)); FlagConnected = true; } break; case "PART": if (Link.ParseToken(TextArguments) ~= AddressChannel) AddText(Replace(MessageLeave, "%n", TextNicknameSender)); break; case "QUIT": AddText(Replace(MessageLeave, "%n", TextNicknameSender)); break; case "NICK": TextMessage = MessageNickname; TextMessage = Replace(TextMessage, "%n", Link.ParseToken(TextArguments)); TextMessage = Replace(TextMessage, "%o", TextNicknameSender); AddText(TextMessage); break; case "PRIVMSG": TextRecipient = Link.ParseToken(TextArguments); if (FlagConnected && (TextRecipient ~= AddressChannel || TextRecipient ~= Link.TextNickname)) { TextChat = Link.ParseToken(TextArguments); TextChat = Replace(TextChat, "&", "&"); TextChat = Replace(TextChat, "<", "<"); TextChat = Replace(TextChat, ">", ">"); if (Left(TextChat, 1) == Chr(1)) { TextChat = Mid(TextChat, 1); if (Right(TextChat, 1) == Chr(1)) TextChat = Left(TextChat, Len(TextChat) - 1); TextRequest = Caps(Link.ParseToken(TextChat)); switch (TextRequest) { case "ACTION": TextMessage = MessageReceiveAction; TextMessage = Replace(TextMessage, "%n", TextNicknameSender); TextMessage = Replace(TextMessage, "%m", MessageFormat(TextChat)); AddText(TextMessage); break; case "VERSION": if (Link.Page == Self) MessageSendCtcpResponse(TextNicknameSender, "VERSION Screen" $ class 'Screen'.default.Version @ "UT" $ Level.EngineVersion @ "Mychaeel@planetunreal.com"); break; case "PING": if (Link.Page == Self) MessageSendCtcpResponse(TextNicknameSender, "PING" @ TextChat); break; case "CLIENTINFO": if (Link.Page == Self) MessageSendCtcpResponse(TextNicknameSender, "CLIENTINFO ACTION VERSION PING CLIENTINFO URL"); break; case "URL": if (Link.Page == Self) MessageSendCtcpResponse(TextNicknameSender, "URL http://www.0x01.net/members/mb/screen/"); break; } } else { if (TextRecipient ~= Link.TextNickname) TextMessage = MessageReceivePrivate; else TextMessage = MessageReceivePublic; TextMessage = Replace(TextMessage, "%n", TextNicknameSender); TextMessage = Replace(TextMessage, "%m", MessageFormat(TextChat)); AddText(TextMessage); } } break; case IRC_RPL_ENDOFMOTD: case IRC_ERR_NOMOTD: Link.SendText("JOIN" @ AddressChannel $ CRLF); break; case IRC_ERR_INVITEONLYCHAN: case IRC_ERR_CHANNELISFULL: case IRC_ERR_NOSUCHCHANNEL: case IRC_ERR_BANNEDFROMCHAN: case IRC_ERR_BADCHANNELKEY: case IRC_ERR_BADCHANMASK: case IRC_ERR_TOOMANYCHANNELS: AddText(Replace(MessageError, "%e", TextCommand)); break; } } // ============================================================================ // MessageSend // // Sends a message to the chat and parses some client commands. // ============================================================================ simulated function MessageSend(string TextChat) { local string TextCommand; local string TextMessage; local string TextNicknameRecipient; if (!FlagConnected) return; TextChat = Replace(TextChat, "&", "&"); TextChat = Replace(TextChat, "<", "<"); TextChat = Replace(TextChat, ">", ">"); if (Left(TextChat, 1) == "/") { TextCommand = Caps(Link.ParseToken(TextChat)); switch (TextCommand) { case "/ME": if (Len(TextChat) > 0) { MessageSendCtcpQuery(AddressChannel, "ACTION" @ TextChat); TextMessage = MessageSendAction; TextMessage = Replace(TextMessage, "%n", Link.TextNickname); TextMessage = Replace(TextMessage, "%m", TextChat); AddText(TextMessage); } break; case "/MSG": TextNicknameRecipient = Link.ParseToken(TextChat); if (Len(TextChat) > 0) { MessageSendRaw(TextNicknameRecipient, TextChat); TextMessage = MessageSendPrivate; TextMessage = Replace(TextMessage, "%n", TextNicknameRecipient); TextMessage = Replace(TextMessage, "%m", TextChat); AddText(TextMessage); } break; } } else { MessageSendRaw(AddressChannel, TextChat); TextMessage = MessageSendPublic; TextMessage = Replace(TextMessage, "%n", Link.TextNickname); TextMessage = Replace(TextMessage, "%m", TextChat); AddText(TextMessage); } } // ============================================================================ // MessageSendRaw // // Sends a message to a given recipient without parsing. // ============================================================================ simulated function MessageSendRaw(string TextNicknameRecipient, string TextChat) { Link.SendText("PRIVMSG" @ TextNicknameRecipient @ ":" $ TextChat $ CRLF); } // ============================================================================ // MessageSendCtcpQuery // // Sends a ctcp query to another user. // ============================================================================ simulated function MessageSendCtcpQuery(string TextNicknameRecipient, string TextQuery) { Link.SendText("PRIVMSG" @ TextNicknameRecipient @ ":" $ Chr(1) $ TextQuery $ Chr(1) $ CRLF); } // ============================================================================ // MessageSendCtcpResponse // // Sends a ctcp query to another user. // ============================================================================ simulated function MessageSendCtcpResponse(string TextNicknameRecipient, string TextResponse) { Link.SendText("NOTICE" @ TextNicknameRecipient @ ":" $ Chr(1) $ TextResponse $ Chr(1) $ CRLF); } // ============================================================================ // MessageFormat // // Converts color and formatting codes to formatting tags and returns the // result. // ============================================================================ simulated function string MessageFormat(string TextMessage) { local bool FlagFormatBold; local bool FlagFormatUnderline; local bool FlagTagClose; local int CountTagStack; local int IndexChar; local int IndexTagStack; local string CharMessage; local string TextColor; local string TextFormatted; local string TextTag; local string TextTagArguments; local string TextTagStack[3]; local string TextTagStackComplete[3]; TextMessage = TextMessage $ Chr(0x0f); for (IndexChar = 0; IndexChar < Len(TextMessage); IndexChar++) { CharMessage = Mid(TextMessage, IndexChar, 1); switch (Asc(CharMessage)) { case 0x02: FlagTagClose = FlagFormatBold; FlagFormatBold = !FlagFormatBold; TextTag = "b"; break; case 0x1f: FlagTagClose = FlagFormatUnderline; FlagFormatUnderline = !FlagFormatUnderline; TextTag = "u"; break; case 0x03: CharMessage = Mid(TextMessage, IndexChar + 1, 1); if (CharMessage >= "0" && CharMessage <= "9") { TextColor = CharMessage; if (CharMessage == "1") { CharMessage = Mid(TextMessage, IndexChar + 2, 1); if (CharMessage >= "0" && CharMessage <= "5") TextColor = TextColor $ CharMessage; } IndexChar += Len(TextColor); switch (TextColor) { case "0": TextColor = "white"; break; case "1": TextColor = "black"; break; case "2": TextColor = "navy"; break; case "3": TextColor = "green"; break; case "4": TextColor = "red"; break; case "5": TextColor = "maroon"; break; case "6": TextColor = "purple"; break; case "7": TextColor = "#ff8000"; break; case "8": TextColor = "yellow"; break; case "9": TextColor = "green"; break; case "10": TextColor = "teal"; break; case "11": TextColor = "aqua"; break; case "12": TextColor = "blue"; break; case "13": TextColor = "fuchsia"; break; case "14": TextColor = "gray"; break; case "15": TextColor = "silver"; break; } TextTag = "font"; TextTagArguments = "color=" $ TextColor; } break; case 0x0f: for (IndexTagStack = CountTagStack - 1; IndexTagStack >= 0; IndexTagStack--) TextFormatted = TextFormatted $ ""; CountTagStack = 0; FlagFormatBold = false; FlagFormatUnderline = false; break; default: TextFormatted = TextFormatted $ CharMessage; break; } if (Len(TextTag) > 0) { if (FlagTagClose) { for (IndexTagStack = CountTagStack - 1; IndexTagStack >= 0 && TextTagStack[IndexTagStack] != TextTag; IndexTagStack--) TextFormatted = TextFormatted $ ""; TextFormatted = TextFormatted $ ""; for (IndexTagStack = IndexTagStack; IndexTagStack < CountTagStack - 1; IndexTagStack++) { TextTagStack [IndexTagStack] = TextTagStack [IndexTagStack + 1]; TextTagStackComplete[IndexTagStack] = TextTagStackComplete[IndexTagStack + 1]; TextFormatted = TextFormatted $ "<" $ TextTagStackComplete[IndexTagStack] $ ">"; } CountTagStack--; } else { for (IndexTagStack = CountTagStack - 1; IndexTagStack >= 0 && TextTagStack[IndexTagStack] != TextTag; IndexTagStack--); if (IndexTagStack < 0) { TextTagStack[CountTagStack] = TextTag; if (Len(TextTagArguments) > 0) TextTagStackComplete[CountTagStack] = TextTag @ TextTagArguments; else TextTagStackComplete[CountTagStack] = TextTag; TextFormatted = TextFormatted $ "<" $ TextTagStackComplete[CountTagStack] $ ">"; CountTagStack++; } else { for (IndexTagStack = CountTagStack - 1; IndexTagStack >= 0 && TextTagStack[IndexTagStack] != TextTag; IndexTagStack--) TextFormatted = TextFormatted $ ""; TextFormatted = TextFormatted $ ""; TextTagStack[IndexTagStack] = TextTag; if (Len(TextTagArguments) > 0) TextTagStackComplete[IndexTagStack] = TextTag @ TextTagArguments; else TextTagStackComplete[IndexTagStack] = TextTag; for (IndexTagStack = IndexTagStack; IndexTagStack < CountTagStack; IndexTagStack++) TextFormatted = TextFormatted $ "<" $ TextTagStackComplete[IndexTagStack] $ ">"; } } FlagTagClose = false; TextTag = ""; TextTagArguments = ""; } } return TextFormatted; } // ============================================================================ // Default Properties // ============================================================================ Ve|} />J 3@ppppPRIVMSG|:&Q&S  VVVc} c -r ( Vv u l NPu /a0 q f 76rf u 0 10u a q u  VFg j w4-[ %@[ b 66R [ O g [ [ 6R b O g 6e b O 6w b O %6u b O %6p b O ,b  VYi A Bi V i f V i If Ci i Pi f Pi ji f ji [i f [ V[ VVSg// ============================================================================ // ScreenSlideMapAnchored // Copyright 2001 by Mychaeel // // Implements a ScreenSlideMap anchored at a given actor. // ============================================================================ class ScreenSlideMapAnchored extends ScreenSlideMap; // ============================================================================ // Properties // ============================================================================ var() Actor ViewportAnchor; var() float ViewportAnchorPositionHorz; var() float ViewportAnchorPositionVert; var() bool ViewportDirectional; var() float ViewportScale; // ============================================================================ // Variables // ============================================================================ var vector LocationAnchorAck; var rotator RotationAnchorAck; var coords CoordsAnchor; var int OffsetTopAnchor; var int OffsetLeftAnchor; var float ScaleViewport; // ============================================================================ // Update // ============================================================================ simulated function Update() { local GameReplicationInfo InfoGame; local PlayerReplicationInfo InfoPlayer; local int IndexInfo; local vector VectorNormal; local vector VectorNormalProj; local vector VectorAnchorHorz; local vector VectorAnchorHorzProj; local vector VectorAnchorVert; local vector VectorAnchorVertProj; Super.Update(); LocationAnchorAck = ViewportAnchor.Location; RotationAnchorAck = ViewportAnchor.Rotation; switch (CoordHorz) { case CoordSelection_X: CoordsAnchor.XAxis = vect(1.0, 0.0, 0.0); break; case CoordSelection_Y: CoordsAnchor.XAxis = vect(0.0, 1.0, 0.0); break; case CoordSelection_Z: CoordsAnchor.XAxis = vect(0.0, 0.0, 1.0); break; } switch (CoordVert) { case CoordSelection_X: CoordsAnchor.YAxis = vect(1.0, 0.0, 0.0); break; case CoordSelection_Y: CoordsAnchor.YAxis = vect(0.0, 1.0, 0.0); break; case CoordSelection_Z: CoordsAnchor.YAxis = vect(0.0, 0.0, 1.0); break; } OffsetTopAnchor = ClientHeight * ViewportAnchorPositionVert; OffsetLeftAnchor = ClientWidth * ViewportAnchorPositionHorz; CoordsAnchor.Origin = LocationAnchorAck; if (ViewportDirectional) { if (CoordHorz == CoordVert) return; VectorNormal = (CoordsAnchor.YAxis cross CoordsAnchor.XAxis) >> RotationAnchorAck >> rot(0, 16384, 0); VectorAnchorHorz = CoordsAnchor.XAxis >> RotationAnchorAck >> rot(0, 16384, 0); VectorAnchorVert = CoordsAnchor.YAxis >> RotationAnchorAck >> rot(0, 16384, 0); VectorNormalProj = (VectorNormal dot CoordsAnchor.XAxis) * CoordsAnchor.XAxis + (VectorNormal dot CoordsAnchor.YAxis) * CoordsAnchor.YAxis; VectorAnchorHorzProj = (VectorAnchorHorz dot CoordsAnchor.XAxis) * CoordsAnchor.XAxis + (VectorAnchorHorz dot CoordsAnchor.YAxis) * CoordsAnchor.YAxis; VectorAnchorVertProj = (VectorAnchorVert dot CoordsAnchor.XAxis) * CoordsAnchor.XAxis + (VectorAnchorVert dot CoordsAnchor.YAxis) * CoordsAnchor.YAxis; CoordsAnchor.XAxis = Normal(VectorAnchorHorzProj * (1 - VectorAnchorHorz dot VectorNormal) - VectorNormalProj * (VectorAnchorHorz dot VectorNormal)); CoordsAnchor.YAxis = Normal(VectorAnchorVertProj * (1 - VectorAnchorVert dot VectorNormal) - VectorNormalProj * (VectorAnchorVert dot VectorNormal)); if (ViewportScale == 0.0) ScaleViewport = 1.0 / 16.0; else ScaleViewport = ViewportScale; } else { if (ViewportScale > 0.0) ScaleViewport = ViewportScale; else if (Map == None) ScaleViewport = 1.0 / 16.0; else ScaleViewport = float(Map.USize) / (MapRight - MapLeft); } CoordsAnchor.XAxis *= ScaleViewport; CoordsAnchor.YAxis *= ScaleViewport; } // ============================================================================ // CalcOffset // ============================================================================ simulated function bool CalcOffset(vector VectorItem, optional out int OffsetLeftItem, optional out int OffsetTopItem) { local float CoordDepthItem; CoordDepthItem = Component(VectorItem - LocationAnchorAck, CoordDepth); if (CoordDepthMin < CoordDepthMax && CoordDepthItem != Clamp(CoordDepthItem, CoordDepthMin, CoordDepthMax)) return false; OffsetLeftItem = (VectorItem - CoordsAnchor.Origin) dot CoordsAnchor.XAxis + OffsetLeftAnchor; OffsetTopItem = (VectorItem - CoordsAnchor.Origin) dot CoordsAnchor.YAxis + OffsetTopAnchor; return (OffsetLeftItem == Clamp(OffsetLeftItem, 0, ClientWidth)) && (OffsetTopItem == Clamp(OffsetTopItem, 0, ClientHeight)); } // ============================================================================ // DrawMap // ============================================================================ simulated function DrawMap(ScriptedTexture TextureCanvas, int Left, int Top) { if (Map == None) return; TextureCanvas.DrawTile(Left, Top, ClientWidth, ClientHeight, (CoordsAnchor.Origin.X - MapLeft) * ScaleViewport - OffsetLeftAnchor, (CoordsAnchor.Origin.Y - MapTop) * ScaleViewport - OffsetTopAnchor, ClientWidth / ScaleViewport / (MapRight - MapLeft) * Map.USize, ClientHeight / ScaleViewport / (MapBottom - MapTop) * Map.VSize, Map, Map.bMasked); } // ============================================================================ // Destroyed // ============================================================================ simulated event Destroyed() { if (TextureBackgroundAck != None) TextureBackgroundAck.AnimNext = TextureBackgroundNext; if (TextureIconsAck != None) TextureIconsAck.AnimNext = TextureIconsNext; Super.Destroyed(); } // ============================================================================ // Default Properties // ============================================================================ Vuv h O0^H ~v pp\e \1H %Sv v H }e ,] v  \xFi  zjt\OZ!Z!Z!Z!Z!ԝXԝXZ!T $?R $?VVt o ` zRr c /a0 q C QPrC  C w _ ^ 10 c J_ ^ -I VBc _ "s ,zc &:m c &c m b ~c  Tb %b }c m c b c c b &zc & c c &{m  VH @VCgc d S" R" b " e " g *35[ "q 3[ VG@xyyzzzzzzzzzzzzzz{}t i@|<<<<<<a^OOOT Vy| ] 2bz| &\| | &G ~p| \\} | G | | G &}  VL// ============================================================================ // ScreenClient // Copyright 2001 by Mychaeel // // Client-side bridge head for replication purposes. // ============================================================================ class ScreenClient extends Info nousercreate; // ============================================================================ // Replication // ============================================================================ replication { reliable if (Role == ROLE_Authority) Say; } // ============================================================================ // Say // // Receives player messages from ScreenMutator and passes them to all // ScreenSlidePageChat actors around. // ============================================================================ simulated function Say(string TextMessage, name NameType) { local ScreenSlidePageChat ThisSlide; foreach AllActors(class 'ScreenSlidePageChat', ThisSlide) if ((ThisSlide.FlagDisplayed || !ThisSlide.SendWatching) && ((ThisSlide.SendSay && NameType == 'Say') || (ThisSlide.SendSayTeam && NameType == 'TeamSay'))) ThisSlide.MessageSend(TextMessage); } VG @VV@hhjKKLAAB{{|yyzxxyttuqqrmmnjknilrABDEFH{|~yz|xy{vwy.6Bdfi^`ckmpfhky{~xz}vx{suxrtw+5B3=J>CJ'4%1 +8(4"-:#.;=Oe%0=(3A'2?ARg+6C-8E.9F/:G0;H/9E4>J*1:/6?FOZ8?H'3!-; ,9#/=*6%2@$0> +7&2@=Pe)5B+7D9ERERa'.6-5>WdsQe9BKGNUFLRelsimqNPRy{}vxztvxuvwrz>>>>>>Q=&'BPP>>>>>Q=&h'B 66<<<<;^EGnnp*W|:: {L( UI n'B h`6>>>>>>>Q=&'B h`6Ǩxt=&h'B!?H MywuEGnnp*WcO0Zq3D)Tg$ r]4Fm'1 Xs~D3oAƎ [Y4Fm'1 hd\2z45lC!K%H8#CcOO99_J77Rvkneag$/.-,+!"ji}V@fbNNNS V@---6qqshhjKKLAAB{{|yyzxxyttuqqrmmn!#9 !(,1C*-6jkn$,? "&ilrABDEFH{|~yz|xy{vwy!0G.6Bdfi^`ckmpfhky{~xz}vx{suxrtw#H|>CJ Gv'4%1(4"-:=Oe%0=ARg+6C-8E.9F*1:/6?FOZ8?H'3!-;*6&2@=Pe&2?)5B5CR9ERERa'.6-5>WdsQe9BKGNUFLRels!#imqNPRy{}vxztvxuvw~&Lrz+#pNse{AUa#;G6nK2Zj*DOKz5:;Pbd*++vwwLg\2ORJ++Lw)}:3/P-J* yGe5Lw)rkUMPJJ+-vI E7A6Qg/N,P1 In[Y84iT00_{uxol q'&%$#ts~dFpmXXX` V@hhjKKLAAB{{|yyzxxyttuqqrmmnjknilrABDEFHQRT{|~yz|xy{vwy.6B5>Kdfi^`ckmpfhky{~xz}vx{suxrtw+5B>CJ'4%1 +8(4"-:#.;=Oe%0=(3A'2?ARg+6D,7E'1=BSg+6C,7D-8E.9F0;H3>K/9E*1:6?J/6?18A07@FOZ8?H'3!-; ,9#/=*6%2@ +7&2@=Pe&2?)5B2>K9ERFSbERaFSa'.6=HT-5>WdsQe9BK;DMGNUFLRelsimqNPRy{}vxztvxuvwrz*)(:/ ,]y֔\R<@'$470W y[֕\\`2%5613. Jyryy]\lFA?;98&LK[]z O!"--#HDrmyyy\YhfgIEMeosty]x\\\x]yyos}n֧Zx\x\ZZy֤ V@UTV223//0HHI~~\\]WY_NPTKMQXZ^&6diqVY^psx)0:/5>nrx/9F.4MS[VY]mptknrruy#.<"-:0?Q)4B*5B.9F1P/?Q$0>2BT'3A *5(4B2@P+7D/IXKa;Rl%=~"~*{ Ayr4U zgOr4j^#bHr4CW{QZ{o k{;