Įƒ*žE˜`Ns¼wl2–ō “5D¬”«²ƒN4+,Ę™I“N–N˜NoneScreenSlideMapScreen 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Ž^h’’’’’’’’’’’’’’’’’’G¤ŽU[„Ś„LKJÓIÓ3"Ų2"Ų9"*"+")"CFE$ AD$ AC$ AB$ AJÓ]JVVVŠVZ @VcVVŠkg{(š:Į:$‚š:Į:$w6Mz*’’’’’’’’’’H =Š‘ĖG¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤u ]§‘Óļü‹ėŠZ!‹ėŠZ!‘Óļü‹ėŠZ!‹ėŠZ!‘Óļü‹ėŠZ!‹ėŠZ!‹ėŠZ!‹ėŠZ!‹ėŠZ!‹ėŠZ!‹ėŠZ! = =G¤‘Óļü =G¤‹ėŠZ!‘Óļü =‘Óļü = = =‹ėŠZ! =‹ėŠZ! = =‹ėŠZ! =G¤G¤G¤G¤ = = = =G¤G¤ = =G¤G¤ = =G¤ = =G¤ =G¤ =‘Óļü = = =‹ėŠZ! =‹ėŠZ! = =‹ėŠZ!‘Óļü = =G¤ = =G¤G¤G¤G¤G¤G¤G¤Ž”G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤G¤‹ėŠZ!Ž”ͩ٫Æ=$:eͩ٫x„~"„o"A"XÓ]lV„RQw’’’’’’’’’’’’’’’’’’i0섵ĻxWi0ģi0ģi0ģi0ģi0ģ„VVKV)VVVVbVV VVbVVd€@VVCVVUVVfVV&@VV@VVt€VHf-’’’’’’’’’’’’’’’’’’KA@i0ģ‘Óļü‘Óļü‘Óļü‘Óļü„VVpV¤VVVV~VVD@VVRVVJ€V…VVŠV>VVAVV@@VVkVV%VV'VVGVVNVVVV V…VSVV+@VV@VVlVVYVV/VVQVV-VV@VVVV7V VVV–VqVz€V‹V@VVZ@VV VVVµVs€@VV,VVVVMVoVNVVY@VVhVVvVVW@VVrVV@VV|VVzVVKVVqVVWVV €V‘VOVVVVVVC VVBVVWVVHVVn€V‘V[@VVTVVVV4VPVFV\Ve€@VVyVV^V(VVpVVC@VVRVŠVHŠV[ VVS€VVhVVbVG @ViVg@VVVVŠVuVDVV}V¤Vl Vz VaVj!@ VVŠV_ VVEVVW V bV@VV}VVx VVCVVVVVV"€VVVoVJVVVV.VVI@VVEVV0VV @VV`‹VJ‹Vf€@VVxVVVV^ V’VcV{€V‘VtVVd V‹Vs@VVx€@VV~V{VY@VV\€VVz@VVuV‹V` VæV€VV^V]V`VVVV`VVJVl‹VZ€VV` ¤VoVVIVVmVVVV@VVVVb€@VV|VVVŠV]VVU€@VVVVA VVj@VVV‘VVŠV@~VLV”VwV”VpVV_@VV}|WVyVŠV{€@VVF€VV;VVO•æVEVVVVAæV~€VVxV”VP V¦eG~] š:Į:$@’’’’’’’’’’JÓTLLe‘ot%’> £YŽ”z ‹¢+z ‹¢+z ‹¢+z ‹¢+z ‹¢+u ]§’> £Y• =Ž”• =Ž”„z] mb.link-m.dek"Pm]/screen/news.html`ÓOÓ=]76

[No Data]

XÓE ]DVVDVŹV<V”VNV8€V‘VcB„œ VaVN‹Vw€VIUr’’’’’’’’’’’’’’’’’’T¾.˜i0ģ‘Óļü‹ėŠZ!„VVMVX€VŠV@V·VB€VV]VV]VMVZV#VV[V5VVJ€VVt ¤Vc€V‘Vd€VVV€VVw€VVf€VVh€V…VB V”VT€VVnVV VVm VVh€VVVVX€V…Vo€V‘V\VV?VV}VV]VVzVVHV”V|€VV€V‘VwV”VVVk€VVJ @@VVqVVO€V¦VVVo@VVFVVB@VVVV@VVKVq€V‘VMV\ VJVz WVj VVR VVSVVlVV$VVD€VVV €VVTVVvDNVs ŠVdhV\@VV@ VVvVVM€@VVVVVVH VlVVqrw  VgTv Ø š:Į:$’’’’’’’’’’Ye‘ot%G¤‘Óļü‘ÓļüŽ”T¾.˜T¾.˜T¾.˜T¾.˜‹ėŠZ!T¾.˜‹ėŠZ!T¾.˜T¾.˜T¾.˜T¾.˜i0ģT¾.˜i0ģT¾.˜i0ģi0ģi0ģi0ģKA@i0ģKA@KA@KA@i0ģi0ģi0ģi0ģi0ģKA@KA@i0ģKA@KA@i0ģi0ģi0ģi0ģi0ģi0ģi0ģi0ģi0ģi0ģi0ģi0ģi0ģi0ģi0ģi0ģi0ģ‘Óļüi0ģ‘Óļüi0ģi0ģŽ”’> £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.pŚVłUųTČRöQ*ĄĄĄP*ĄĄĄ#Ó]YVVx€VŠVC¤VXIH][ZYVkM1 VG@VV_‹VK¤VGHRAVV{VzaV=€V‘VA€VVV‹VS V”V{VVuV”Vf€@VVx€@VVQ`VgVV*VV}VVe€VV[€V¤VR€VVN¤V @VVSViVP‹V^|zyV]@VcŠVQVPVGV_VmVOVS€@VVR€@VV3€VVy€@VVfVXsrVIxwtVD XVL€VV\€VVA€VVYIVuVeVa\PONMVhXWVUSV^V{2YV\hV[ VLVh€V‘Vi€@VVu€V¤V_ ! VK €V‘VVVvVo€V‘Vp€@VVw€V¤VY ¤V`VV[ ŠVq ¤VVVwXVZXVVVU€VVy€VĄXyn’’’’’’’’’’’’’’’’’’"{I2šūĄōŒĒ˵_ć‰4• =• =• =• =µ_ć‰4”Ģą£”Ģą£”Ģą£”Ģą£”Ģą£”Ģą£”Ģą£”Ģą£”Ģą£”Ģą£”Ģą£”Ģą£”Ģą£”Ģą£µ_ć‰4µ_ć‰4µ_ć‰4µ_ć‰4µ_ć‰4µ_ć‰4• =„VV€VVVV:€VVLvVB€VV@€V‘VY€VV] ŠVa VčVVVH@Õq~E’’’’’’’’’’’’’’’’’’ G÷Ŗ)€ÕŚćĢ~Ź“č7`Ź“č7`Ź“č7`• =• =Ēģ§M]Ēģ§M]„VVgVFÅoa@’’’’’’’’’’’’’’’’’’2J›čHÅüM»ļķo ūķo ū„VVjvV€VVd€VVIŠV@€VvVL€VŹVR€@VV}€V{VT@VCV6ĄikA’’’’’’’’’’’’’’’’’’V9IŅĄōŒĒĖ• =• =’> £Y’> £YĄōŒĒĖō?{”Ģą£• =”Ģą£”Ģą£”Ģą£”Ģą£Ņ×7Xƕ =• =Ņ×7XĆ„VV_Vf €VVx€V‘V[€@VVN€V¤V~VV€VV@€VVa ¤Vi€V‘ViMsVd!@Ve!Vd!@V^€VŹV@Vl€VVohjtVvVK%Ž VU€V±Hbo’’’’’’’’’’’’’’’’’’m9[`€±Ń$„V±Ec~’’’’’’’’’’’’’’’’’’nfzį±Ń$„VVOBzaT?O $D6īB )$D6÷B :$D6÷B ’’ V¶c5G9“¶-d/-p „„š: n:$9‚š:Ÿ¼:$ „-gš: n:$š:Ÿ¼:$| ’’’’ VFVVz 9/­^ÅN% –N, 9N@Bz€9&"99&izź9&"9€9“}9&N@pp"9"p9„NØ'&&\Ė–&%Ø’&&& npp€&ģ, ’&,ž Crpp€&ģ, ’&,ž uqpp€&"’&,ž ’’p€&’&&ž„& Ą—}%vb VPg}i)gaÜhbliDb VYZ..Š€Z 1 -2 2 !-1 '3 .-0 5+0 ;4 H+1e N5 U+2 [6 b+3 h7 u+4a ’’[ Vb€VVt~6 %~ė~B%–B}~E~B&E ^0  ,  y1 ’ ,&  •2 ’ ,,  ±3 ’ ,,  Ķ4 ’ ,,  é5 ’ ,,  6 ’ ,,  !7 ’ ,,  =8 ’ ,,  Y9 ’ ,,   uA ’ ,,   ‘B ’ ,,   ­C ’ ,,   ÉD ’ ,,   åE ’ ,,  F ’ ,,  ’’’’’’„B  Vr€VV€VŠVsn%sk)naÜor`pD` VB€VVza8²mä{ae&&a@’e&–@’e,uza@&;Iae’“@e&„@)’š}I%aI °   · Ē" "· Ü< <· ń> >· & &· ä ä· 5ö ö· Lü ü· cÄ Ä· zÖ Ö· ‘Ü Ü· ©ß ß· ’’ Ipp€ae a’e}I V€V{Vr0Ų ³vk'\6–%kpp€\\’&”, ŗ'~ģ, Ž–%ŗpp€\n’&k '~ģ, Ż–% pp€\r’&ŗW'~"+–%Wpp€\q’& %C%®–C, C@pp"ž"”ž„Ceb V€VVk€@VVd€V‘VB // ============================================================================ // 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 falseV€VVSp ~6v’-C(UpėU=r%„–r}pDoopr&§‚„zo" zo'„-C zgo-C-Cgoz³-Czz‚„zD zD zėpr}UUJp’r}Ug€J&[„zg" zg'JJ&~pJ&ggwJ€J~pJ  „„r!(J Vn` hR1’’`^`c`P VOs Qµżu ˜d% QaÜX}\CQaÜX}~gR|%s–d w(Č*Q“aŁ?{?R?_?_?(Ȱ?(Ȳ(Č(Č-»t‘DÆ®Ÿ©?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_~*gC”R’_F„[ V€V¤Vi1^uNĀ‚‚‚‚-Ģ#„-[ —žU %!„-wQ «ī„‚š:O:$d‚„rA**žQ a/AÖ)„rD*ržQ Dv‚š:O:$f‚„rA*,žQ a/AÖ)„rD*wžQ Dl„„„„‚‚š:§%-^#„›ž@ %-QE‚‚š:§&-u#„›ž@ %-OF‚‚š:§,-V#„›ž@ %-_F‚‚š:§,-f#„›ž@ %-eF‚‚š:§,’-b#„›ž@ %-L V\r4éjd‡F=N&÷˜N}=kGG=N&FF“N&Fr€FNA؂—Fs„-[ —B%÷ķ„‚zG  {k šN}=BN=F„NBB5–B}=+{=B& 5„BI€=B==BsrIA\FI VVVi€VV|l(fhs@o%8–o}lllo„ol VaN!ßic<z:–N°—’8°%Dy–DN²ī—’D8²%NiaŁ??D?8°?8²?8°?8²88-»ü-U”D8²I"-U:”8°  V_ €VV¶Ie 5„$ ȶ%rW*WūįG›:Ÿ¼:$H x/a0 uJ [[10ĘrJ *J a u/a0 Ķe ‰‰10Ęwe *e Ō |J e n J  VX€VV€VV`L&ÓŹ€«z€L&#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); } ŻZC’’’’’’’’’’’’’’’’’’2[id”ŻєŠĻĢ;aG°ŽÕ¶mźķo ū%„VVZBĖl`9i~RBS*–i%i’iB VĪU^B"NG/a0 pÕD6MpzU„6xpz10 V_€VŒVp€V–VlQ$¾'~;ėQ LEFT$ #CENTER$ 0RIGHT$ ’’R VĄ7oź G×Screen ConfigurationĄß¬ÆģØØ?,ł¬ÆģÓÓ?, VąZÄ VŠ*ą Vą`Ä {Š*ą VH€VVOU ”‹F%{U•'vFF~{FyH–F%•”Fv{pp€{Fx{’F}y”F}x{ VF€@VVB Aurj k*"f‚w"*"-a"-a'k"""]“rk*A]A»A]"k]AA-a'"‚w"*"-a"-a(""]× VeV°³6šuC®<6ši«?“:6šV:6šiX6›uC®<6›i«?“:6›V:6›iX6™uC®<6™i«?“:6™V:6™iXu Vha>3•H™ rl* _ %b %_ c$`˜:i§,b ’m:i§mö ó$ŠriQ «b %šå‚Q ×-č*š:i§:Q «§b m,šb mö ’’šiž@ %_ b@ “l‘b,v “h‘m,aGaŁ?v ?@ ?m?b?b ?_ ?m?bll-» VŁjÕbj.” ” AˆAÆØ?,(€?j)ØScreen ComponentS xj &B .” ” A0BÆØ?,(€?B 4Free for noncommercial use and distribution.}.” ” A`BÆØ?,(€?}:Feedback, bug reports and suggestions are welcome.w.” ” A¦BÆØ?,(€?w=Copyright 2001 by Mychaeel, mychaeel@planetunreal.comS .Ņ Ņ AöB 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.htmlÅĒ1Fstart http://www.planetunreal.com/screen/Ė ’’ VK^¬Ż{-HJ^%zSH^H+M V¹V"»6 xš:Ÿ¼:$ ,wa* t.‘ūIrt* B@”r*qr6Mz* 6MzL*6Mz*Ăr6Mz ›:@:$6Mz*īwL@$B$Lžw* t.‘ ,/‘ ,Q’/ O’. $.'/|&%}$%x'UPīw*'š|“, &ēØScreen: Too many layered slides, starting with slideWÖī tq r$QśQ’' o ž$¢' /ł/'o ś$”'‘“ U ,/ł/'QśQ’' o 3$”'“ U /ł/'o l$”' UQśQ’' o ’’z ¦$OśO’$ £ Ņ$¢$ .ł.$£ .$”$‘“ U ,.ł.$OśO’$ £ g$”$“ U .ł.$£  $”$ UOśO’$ £ ’’|}$|x'„|UPĮH%2–H|¢H}.¢Hx/„Hõ0“Q/-“O.Yū0%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«¬]ČB5ö5€?-“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-W›KWC ’’v o $ ?%-V';  $-V‚˜04“ ?% -VÄ ²® ?0?% ?4¹ «\ õ ?0-V²® ?0?%; 8 $TM-V‚˜04“ ?%5 -VŠ ‚šM&²® ?0?’EYM’’’’ū µ ‚šM’’’’³ ?EM&ū ß šM&¹ «\ū ø «\ ö ?“’EY0?E-V›MT; ’’-‚-V-W¦ ‚->„‚³_mw]*w6Mz*@$ $d Ī $-' $¹ «^-²® ?-?% F$¹ «^-²® ?0?% ~$ø «^-³ ?4 ¶$ø «^-³ ?7 $¹5«¬^ČB5ö5€?-“5 ’’ ’’vš:@:Bž‚š:@:$-gr6Mz*6Mz]*ž(ēØSwitching to slideW6MzÖ VmS ZNP1’’S[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); } V€V‘Vw// ============================================================================ // 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 // ============================================================================ VŁzčžz.” ” AˆAÆØ?,(€?zNetwork Accessz &<.µ µ A,BÆØ?,(€?<Live Content Downloads<Full Access<Restricted Access<No Access<{(<}: nH.” ” A”BÆØ?,(€?x.” ” A¬BÆØ?,(€?w.” ” AÄBÆØ?,(€?L.” ” AÜBÆØ?,(€? 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– ’’ VĆuf;]V)f $<!š:^&' ’’ V€VVr€@VVÅvEGlĄz<8 )% n$] A& n$] Z, n$] ’’ šÅ-E ņs]6’’’’’’’’@’’’’’’’’’’{8±é ņ޹ųP = =„]HVVŁK‹øØ?,K.Źü ŹØÆÓ?,KQ'a K7Network n` K7About m֗ G  x` B Update` -Ę'D.č 诨?,5ÆÓ?,@B€AŁ Vą}_u72tvŅ_ØÓt Vs@VVA€VVt€VVu€VŠVäq#>åāģ!ü J–C\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 // ============================================================================ EM’’’’’’’’’’’’’’’’’’1FyīrpG¤‘Óļü‘Óļü…{#Uæ‘Óļü…{#Uæ‹ėŠZ!…{#Uæ‹ėŠZ!…{#Uæ…{#Uæ‹ėŠZ!Ž”’> £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-%pKČy*ĄĄĄDÓC]%s frags, %d deaths, %t min{Śl*ĄĄĄhÓjÓfÓeÓgÓ#Ó]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); } V€VV€V‘V@€VVN€V‘VO€VVP€VV€VVjk?—N„–k0‚šk–k>>(“„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; } V€VVjÉ// ============================================================================ // 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%c’d_“d&F‚c% V€V‘VhD// ============================================================================ // 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); } V€VV_P:4Ö&62%6%e6p%Y6V%$YŸSY€Y~pY??YY’~Y/&f%-~'%s–} s &-C-~-~„„zsģ,  zsģ,  zs H‚-~ -CWppW f“f ii‚-~-Cf„£—-~WpW f Wu%-'-[(-(Ō„—} % -[ *-A(p6VV z€ &<~ >.–%Ōj &“&  ’&~pj  ė€jDj’&Éz€&/& ŲBODY-'-'{ ßH1 ęH2 ķH3 ōH4 ūH5 H6 FP-'-'EśEPX6{ OFONT WBIG aSMALL gB xU-({ ’’?Ę—?%¼z62?“?&ʦ?†S  ^BODY%62%6%e6p%& DtextY6V%$-6~%(-'-'S eH1 lH2 sH3 zH4 H5 _H6„“&626q6ps6V$ Dalign$-'-'\w@*EśEPX6S RP?®—?%¤z62?P“?&®¦?p-'-'ōw@*EśEPX6„%626V$ Dalign$S œBR‰šI%”EPX6-'-'S Ļ IMGY Dsrco~Y?ā–o%o}YzY’o&Y€Yo>zė€Y,MYLEVEL.YppY.Y,Z.‹įY ‹Ģ wZ*  T.T SZ.T d %.T t %.T T Z°.T R Z²Y % –Y ,o~z,5–o%o}zCšo% A J€zoY }%.T T A ā &.T R A ā ¾,.T t A ā ß,.T d A ā ’’zz’o& š}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€ å -jHėHŃ—}H%  -qšI%P'> -> z€H& HH&  ,“dI. T4PH ,6-q|. s6. }6p. -y-6~6„-q— ,%P-q'I%-' -A™|“dI lPX6  l  “}Hœ‚- -[°‚w;*;a/!-g}.;Ta—g%W{.;T“g&& a¦g#¢h“;,P€.;Tg.;sp Ę$m% ä$m‘“dh, ž$m“dh ’’byswb*”b’ry”b>mb PbbR I%”ryy%h%-['§w *„uÕ-”rEE%y  >I hi”h ,”I ,yśy ]r;*@ q;R ‡ry*y ; -[(--AŃ‚š} % -[-'-[(Į稨pØRendered slideWÖ,SuitemsZ’ry@ 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 >= C