*~m@M,Ӭ;.^G-tHMmNoneClientMessageColor CheckWeapon GUISelectMapEndVoteFireBSEMapVote_0_42AltFireCoreSystemEngine ScrollDown ScrollUp LightingSetProgressTimeSetProgressMessage Collision Movement LightColorForceColour NextWeapon PrevWeapon CheatMessage VoteLineTextKarmaClearProgressMessagesPredictNextMapSyncInheritedMapList SwitchWeapon KilledBy StripColours MOTDLineGetNominatedMapNameClientUpdateLocalMapListSpawnHUDPluginDefaultGameMutatorBroadcastToAllExceptMe RegisterServerPlayerCheatsReBuildVoteLineArrayU2GetKeysPerformCheatingTestUpdateVoteKeys TeamColor GetPollOwner GetMapListGetLocalPlayerControllerGetPredefinedMapList GetAllMapsQueuedMapMessageDrawPrettyLogoShowMapVotePollAlreadyQueuedMessageGetTeamTryToRegisterVotedMapDeferredDisplayMapSelectionGUI ServerTravelMapvote RequestMapClientClearLocalMapList DrawVoteUIClientUpdateVotableMapListClientDisplayGUI MapRequestServerDisplayMapListDrawExtendedVoteHUDCanvasXgreyGetServerMapName MapVoteCfg BeginStateTickPostNetReceive PreBeginPlay Constructedbracketspacing numspacing linespacingVoteGUINumRowsAlreadyQueuedMsg QueuedMapMsgGetPredefinedMapAtIndex RemoteRoleWarningColorStrUserWhiteBlackRedGreenBlueMapVoteMutator BroadcastBroadcastLocalized TakeDamageMapVoteHUDPluginMapVoteGameReplicationInfoMapVoteControllerDead GameEndedExtendedMapListYellowPlayerTurretingSwitchToBestWeapon GetStringPlayerDrivingKickBanKickbAlwaysRelevant UpdateVotes CheaterPRI MOTDAlphaPlayerWaitingPlayerController DrawColor KickRequestMOTDDisplayTime LifetimeGetMessageSound GetNextMapWoundedMOTD StartVote semitransbigfontCheckRegistered DescriptionRegisterRenderListenerUICanvasY MessageSound GetLifeTime FriendlyName SmallFont TinyFontWaitingToDeploy ShowPoll Viewport PositionCanvasVoteFailedMsgPlayerReplicationInfoClass KickPctTotal KickPctTeam VoteTime MinVoteTimeGameReplicationInfoClassSetPosBroadcastHandlerMaps GameMessageControllerListGamebCenterClipYMapNum CurrentMapMapList MapListClassNextMapCurrentPlayerControllerClass MapPrefix MapListTypebBotbAdmin KickTeamNumTeamPlayers NumPlayersbBan RequestorPRI bKickBan NumVotesNumVotesRequiredVoteTimeRemaining PollOwner PendingKickFont bPendingVote GameClassNextSizeParam2 GameType PlayerName PlayerIDValue TimeSeconds WeaponClassPCPXLYLLevelOptionalObject RelatedPRI_2 RelatedPRI_1Num Momentum HitLocationEventInstigator DeltaTimeposoffsetStartCommandbPendingDelete ENetRoleMessagingSpectatorOwnerClipX HUD_Fonts EuroExt14 ReplaceText UIConsole CodeMonkey UIHelperPawn GetUIConsole MakeColorHelpers FirstMapTestMap SubTFontsEE16ActorU2PlayerController MapListXMPTotalU2XMPA EnergyNotifyEnergyWarningRocketLauncher SniperRifle FlamethrowerShotgunPistolGrenadeLauncher AssaultRifle EnergyRifleWeaponsRocketLauncherExGrenadeLauncherMediumGrenadeLauncherLightGrenadeLauncherHeavy DeployablesWeaponRocketTurretWeaponAutoTurretLoader TempItemeq2PlayerStyleDamageSoundMapName eq2Loader LocalMessage FireTime DamageTypeMutator Controller registeredRegisteredTime theLevelspc bReplacedMessageGameReplicationInfoPlayerReplicationInfo GameInfo SendEvent LevelInfoWeaponRemoveAllTimers PendingMapPendingMapDeferred QueuedMap AddTimerdeferbTestPerformed bServerInitDynamicLoadObject WasCheatingMaxTick TickCountMsgMeSw ColorCodeL DefPrimary DefSecondaryhcheatTop VoteableMapstempA MapNumberRole NextMapNumClassPackageAllMapsMyGRIMapsInRotation logodoneBC DisableGUIResultbDisplayMapChooserSwitch AdminOnly VoteLines ScriptText ReturnValuejtQuestion_BoolIFQuestion_Object TextBufferNot_PreObjectparamsObjectEnum MyMapList Question_Str FunctionStateVectorStruct StrPropertyStructProperty MyHUDPlugin scrollbarpct scrollbarabs maxWidthArrayPropertyClassPropertyObjectPropertyFloatProperty BoolProperty IntPropertySmyOwnerV bNetDirtyLocalCodeMonkey VoteKeys VoteYesKey VoteNoKeyRRCheckVerify RREnabled ByteProperty StrArraynextController)HCed"3#-&#9:9:$Bd#8OPEREFPJF!㪓㪆3Y 3Y@8/@8/3Y3Y㪓㪆㪆@8/㪓   @Uu@h>P@#= @DVe6B o79:9:$Bd7h OPEREFP:9:9:$Bd: OPEREFP>9:9:$Bd>l OPEREFP 6[ˑ`JFDDHIDDDDDDDDDDDDDHIDDDHIDDDDDHIDHIDDDDHIDDHIDNy"@8/ O O O O O O@8/@8/Ny"Ny"@8/ O@8/@8/Ny"DJFDDDDJFJFJFJFJFHI+ YU]DBVote Failed: Cannot start a map vote because $1 is already queuedT]32Vote Failed: $1 is already queued as the next mapS"R"Q"2P" &'BIc,HI fhˠ,,,DDDDDDDDDD˃DD˃DD˃DD˃DD˃DD˃DDD,,,D @IJZ*H*[*\*]*^*i**/*/G"E"}Y]98This server is running the BSE Map Vote mutator ver 0.4*]www.teambse.co.uk* *]Type MAPVOTE in your*]console to start a map vote*x"s@{m@S @5Euh'Ny"dw@8/@8/@8/@8/@8/ O O O@8/@8/@8/JF@8/JF@8/@8/@8/JF+ @ODv;@ @JQ@pc@$@G! @K@dW@Zf".@%@t@w-1@Eh H&@@x@F@u+bi4RY`Ui@l@@n@_Y@L|r %9:9:$BdOPEREFP2^u}r㪆3Y3Y㪋 㪗3Y㪗3Y@8/ze 3Y MtaKd sa@q8\:@j<@C@[ @@6IIFt}~E/z^@Zc@RCA@*gM@X"9@@Y@""Hk@Z3 @Wb^2@Ne~{jl@po@Ha2rqeE@BdN2 EFP-BdOz LET-OO ==BdOq EFP-BdP LET-PP ?̌?BdP EFP-BdQ LET-QQ q=?q=?BdQ EFP-BdR: LET-RR q=?q=?BdR1 EFP-BdSw LET-SS {n?= ?BdSn EFP-BdT LET-TT ?BdT EFP-BdU LET-UU =?BdU EFP-BdV< LET-VV q=?q=?BdV3 EFP-BdW LET-WW q=?q=?BdWv EFP-BdX LET-XX q=?q=?BdX EFP-BdY LET-YY q=?q=?BdY EFP-BdZX LET-ZZ q=?q=?BdZO EFP-Bd[_ SIMPLEIF-Bd] LET?,Bd_ LET-r'Bd` LETqBda LETI,dbTBdc SIMPLEIFTc?%Bdc OPEREFPeIBde OPEREFPBdf SIMPLEIFTfIqBdf OPEREFPBdi LETI%j?Bdj OPEREFPk)k2Bdk EFP?Bdk EFPBdoRETURNNOTHING BdoPREVSTACKT@wCY.cBdY.NEWSTACKBdY/LET-'BdZ/RETURNNOTHING BdZ/PREVSTACK%ynBR<.lBdR<.NEWSTACKBdRZ.LETn'oBdS^.RETURNNOTHING BdS^.PREVSTACK%}G.aBd.aNEWSTACKBd.hLET-T(Bd/sLET-U(Bd0ySIMPLEIF0%GbBd0OPEREFPBd2LET%GbBd5uLET-T'Bd7SIMPLEIFX7&GaBd7OPEREFPBd9LET&GaBd<LET-U'Bd>RETURN>-T-UBd>PREVSTACKBd?RETURNNOTHING Bd?PREVSTACKzk$Ly-lBdLy-NEWSTACKBdL-LETklBdM-RETURNNOTHING BdM-PREVSTACK%@F,WBdF,NEWSTACKA%7BdG,RETURNNOTHING BdG,PREVSTACK%JA>xBd>NEWSTACKBd>SIMPLEIF-Bd8?LET-(BdC?RETURNNOTHING BdC?PREVSTACKBd?LETe9?9?S Bd?OPEREFP&Bd?OPEREFPBd?OPEREFPBd?LETp9De9? Bd?OPEREFPBdh@LET9D9?,Bdb@OPEREFP,9Bdh@OPEREFPBd@LET)zi9?,Bd@OPEREFP9?, Bd@OPEREFPBd@EFP(aAvailable Maps'Bd@EFPA9?Bd%AOPEREFP9? BdDAOPEREFPBdEAOPEREFPBdFAEFP@aUse mouse wheel to make your selection'BdAEFPA9?BdAOPEREFP9? BdAOPEREFPBdAOPEREFPBdAEFPRaUse primary fire to vote, secondary to vote for next map'BdBEFP(B9?Bd1BOPEREFP9? BdPBOPEREFPBdQBOPEREFPBdRBEFPHaMAPVOTE again to exit, MAPVOTECFG to configure'BdBEFPBdBSIMPLEIF7BdBOPEREFPBd)CLET7 Bd)COPEREFPBd2CSIMPLEIF%Bd=COPEREFPBdHCLET%BdQCSIMPLEIFL 7BdjCOPEREFPBdCLET 7&BdCOPEREFPBdCSIMPLEIF %BdCOPEREFPBdCLET %BdCLET-(BdDFORINIT %BdDFOREVAL 7Bd-DOPEREFP1a6" ddBd`DEFPBdDLET69Dd6BdDEFPBd.DFORINC Bd2DOPEREFPBd ELET-9D9?,BdDOPEREFP6,Bd EOPEREFPBd EOPEREFPBdFEFORINIT %BdLEFOREVALD  Bd_EOPEREFPBdELET# BdEOPEREFPBdESIMPLEIF. #7BdEOPEREFPBdEBREAKFORDBdFLET)y9?-vBd8FOPEREFP9? BdPFOPEREFPBdQFOPEREFPBdRFEFP*a9S6/#'BdFEFPBdFSIMPLEIF # BdFOPEREFPBdGLET)@9?-tBdEGOPEREFP9? Bd]GOPEREFPBd^GOPEREFPBd_GEFPa['BdzGEFP 9?  -6Bd GOPEREFPtBd GOPEREFP9?   Bd GOPEREFPBd GOPEREFPBd GEFP a]'Bd GEFPBd*HSIMPLEIFc -6Q#BdhHLET)~BdoHSIMPLEIF |6"#!BdHOPEREFPBdHLET)|f9?-9? BdHOPEREFPBdHOPEREFPBdHEFP(a6"#'Bd IEFP9?-6BdKIOPEREFPvBdWIOPEREFP9? BdoIOPEREFPBdpIOPEREFPBdqIEFPBdxISIMPLEIF pBdIOPEREFPBdILET)ya#'BdIEFPBdJLET)}all'Bd"JEFPBd`EFORINC BddEOPEREFP]Bd!/JRETURNNOTHING Bd!/JPREVSTACKsgLs8Bds8NEWSTACKBds:SIMPLEIFns9:9:$BdsQOPEREFPu-BduyEFPwgBdwEFPBdxRETURNNOTHING BdxPREVSTACKDh)(sBd(NEWSTACK('h rjBd(EFPBd)RETURNNOTHING Bd)PREVSTACK_@BeI8*SBd8*NEWSTACKBd8+LET_8U2.XMPGame Bd8+EFPBd9|+LETM9_ Bd9{+EFPBd;+SIMPLEIF;wM*Bd;+OPEREFPBd=+RETURNeMBd=+PREVSTACKBd?+RETURNNOTHING Bd?+PREVSTACKN4MBd4NEWSTACK---------- Default Game 03 Mutator functionality loading started.. ----------BdEFPBdLET  ^Bd"LET  ^BdtLET  ^---------- Default Game 03 Mutator functionality loading complete. ----------BdEFPBdSIMPLEIF9:9:$BdOPEREFPBdSIMPLEIF!a BdMEFPBdNOPEREFPBdLET Bd!SIMPLEIF!!a Bd!EFPBd!OPEREFPBd"@LET Bd$LETBSEMapVote_0_42.ExtendedMapList'Bd'EFPBd(RETURNNOTHING Bd(PREVSTACK`CV?%GBd%NEWSTACKBd%SIMPLEIF{VBd%OPEREFPBd:&LETY.11Bd9&EFPBdD&SIMPLEIF+YBdP&OPEREFPBdz&LET!YBdz&EFPKBd&LET!unknownBd&SIMPLEIF3-i%|V!Bd&OPEREFPBd'EFP@Bd.'EFP%8Bd`'EFP $$$Bd'EFPBd'EFPBd(LET\.*DV-iBd(EFPBd (SIMPLEIFC \%Bd *(OPEREFP"Bd"k(EFP#@Bd#(EFP$% $$$$Bd$(EFPBd$(EFP&Bd&(SIMPLEIF&\&Bd&(OPEREFP(Bd(8)EFP)@Bd)Q)EFP*%*5Bd*)EFP *$$$Bd*)EFPBd*)EFPBd.)RETURNNOTHING Bd.)PREVSTACKBJn>!Bd!NEWSTACKBd!SIMPLEIFm|[nextBd!OPEREFPBd"LET-k'Bd "SIMPLEIFJn&Bd"OPEREFPBd%"SIMPLEIF-Bd^"LET-(DEBd"EFPBd"SIMPLEIFD-ShowConsoleBd"EFPBd #LET-(Bd%#FORINIT:%Bd+#FOREVALa:7Bd@#OPEREFPBd^#SIMPLEIF+6/:nBd}#OPEREFPBd#LETj6":BdA#FORINC:BdE#OPEREFP?j-kBd#EFPBd#SIMPLEIF-HideConsoleBd#EFPBd $RETURNNOTHING Bd $PREVSTACKr['BdNEWSTACKBdSIMPLEIF9:9:$BdOPEREFPBdFORINITBdFOREVALw*BdOPEREFPBdLETOBd&SIMPLEIF[wO*Bd4OPEREFP*O-BdCOPEREFP&r.*BdbOPEREFPBdqSIMPLEIF[[BdOPEREFP&a/!uBdEFPAa[._b[BdUEFPBdFORINCBdLET}Bd$oRETURNNOTHING Bd$oPREVSTACK@q&{*-KBd-KNEWSTACKBd-KSIMPLEIF]-7%Bd-KOPEREFPA%7Bd0KFORINIT%Bd0KFOREVAL0, Bd0LOPEREFPBd2LSIMPLEIF2{'Bd2+LOPEREFPBd4CLLET6/4&Bd4CLOPEREFPBd5aLLET6"'Bd6LLET77>Bd7LOPEREFP:Bd:LBREAKFOR:Bd0LFORINC0Bd0 LOPEREFPyBd>LFORINIT%Bd>LFOREVAL>7Bd>LOPEREFPBd@ MSIMPLEIFG@{Bd@&MOPEREFPBdB?MLET6/B, BdB?MOPEREFPBdDIMSIMPLEIFDzD&BdDeMEFP_BdDlMOPEREFPBdFMLET-6Q'BdGMLET6"GGG}BdGMEFP&BdGMOPEREFPBdGMEFPJBdK'NLET-6Q(BdLHNLET6"BdOuNLET7P>BdP~NOPEREFPScBdSNBREAKFORSBd>LFORINC>Bd>MOPEREFP BdWNSIMPLEIFCW>%BdWNOPEREFPBdYNLET6/%BdZNLET6"Sorry, no maps availableBd[NLET%Bd^OLETS>Bd_ORETURNNOTHING Bd_OPREVSTACK%F&?SVJ`Bd`NEWSTACKV 9Bd~EFPBdSIMPLEIF|%9disableguiBdOPEREFPBdSIMPLEIF-BdRETURNNOTHING BdPREVSTACKBdLET-'BdLET-(BdEFP@Bd*EFP%Map Vote GUI is now disabled $$$BdEFPBdEFPMap Vote GUI is now disabledBdEFPHideConsoleBdEFPBdSIMPLEIF|%9enableguiBdOPEREFPBdSIMPLEIF-BdOPEREFPBd%RETURNNOTHING Bd%PREVSTACKBd>LET-(Bd]LET-(BdyEFP@BdEFP%Map Vote GUI is now enabled $$$BdEFPBdEFPMap Vote GUI is now enabledBd#EFPHideConsoleBd@EFPBdPSIMPLEIF|%9menusizeBdhOPEREFPBdLET 9J&9BdLET %BdLET%BdSIMPLEIF ,BdOPEREFPBdLET ,BdSIMPLEIF$ , BdOPEREFPBd LET , BdSIMPLEIF %Bd*OPEREFPBdGLET ,Bd^LET-'BdLET-(HideConsoleBdEFPShowConsoleBdEFPBdEFPUsage: MapVoteCfg enablegui - enables the graphical mapvote (default)BdfEFP MapVoteCfg disablegui - disables the graphical mapvoteBdEFP MapVoteCfg menusize - set the number of items to display on the map vote menuBdE EFPBda EFPbBdw EFPBd{ RETURNNOTHING Bd{ PREVSTACKGTlQBdlQNEWSTACKBdlQSIMPLEIF-n>6/ TBdnQEFPBdoQRETURN(BdoQPREVSTACKBdrQRETURN'BdrQPREVSTACKBdsQRETURNNOTHING BdsQPREVSTACKKO xARtBdxARNEWSTACKBdxCRSIMPLEIF-BdzdRSIMPLEIFz %BdznROPEREFPz BdzuROPEREFPBd{|RSIMPLEIF{ Bd{ROPEREFPBd{RLET Bd|RRETURN(Bd|RPREVSTACKBdRRETURN'BdRPREVSTACKBdRRETURNNOTHING BdRPREVSTACKNQ SBdSNEWSTACKBdSSIMPLEIFT-Bd5SSIMPLEIF S&BdGSOPEREFPBdGSOPEREFP BdNSOPEREFPBdUSSIMPLEIF'  BduSOPEREFPBduSOPEREFPBd~SOPEREFPBdSRETURN(BdSPREVSTACKBdSRETURN'BdSPREVSTACKBdSRETURNNOTHING BdSPREVSTACKPSxTBdxTNEWSTACKBdzTSIMPLEIFhBdTEFPSBdTEFPBdTRETURNNOTHING BdTPREVSTACKhL<WBdWNEWSTACKBd]RETURN-BdkOPEREFP-BdPREVSTACKBdRETURNNOTHING BdPREVSTACKRR UBd UNEWSTACKBd"USIMPLEIFnnextBd8UEFPRBdJUEFPBdNURETURNNOTHING BdNUPREVSTACK@TUBdUNEWSTACKBdUSIMPLEIFc BdUEFPBdUEFPBdURETURNNOTHING BdUPREVSTACKVbVBdbVNEWSTACKBddVSIMPLEIFc BdrVEFPBdVEFPBdVRETURNNOTHING BdVPREVSTACKW^f+YBd,YPREVSTACKZ XJBdXNEWSTACKBdXRETURNNOTHING BdXPREVSTACKY\XJBdXNEWSTACKBdXRETURNNOTHING BdXPREVSTACK[XdBdXNEWSTACK BdXEFPBdXRETURNNOTHING BdXPREVSTACK]YdBdYNEWSTACK Bd$YEFPBd)YRETURNNOTHING Bd)YPREVSTACKXltZBdZPREVSTACKabYJBdYNEWSTACKBdYRETURNNOTHING BdYPREVSTACKbcde`kYJBdYNEWSTACKBdYRETURNNOTHING BdYPREVSTACKfQYBdYNEWSTACKBdYSIMPLEIFhBdYEFPQBdYEFPBdZRETURNNOTHING BdZPREVSTACKsU#BdNEWSTACKBdLET.Bd RETURN BdPREVSTACKBdRETURNNOTHING BdPREVSTACKgP9ZBd9ZNEWSTACKBd;ZSIMPLEIFnnextBdQZEFPPBdcZEFPBdhZRETURNNOTHING BdhZPREVSTACKiZdBdZNEWSTACK BdZEFPBdZRETURNNOTHING BdZPREVSTACKkZdBdZNEWSTACK BdZEFPBdZRETURNNOTHING BdZPREVSTACK_w|S\BdT\PREVSTACK o [JBd[NEWSTACKBd[RETURNNOTHING Bd[PREVSTACKnq#[JBd#[NEWSTACKBd#[RETURNNOTHING Bd#[PREVSTACKpOX[BdX[NEWSTACKBdZ[SIMPLEIFhBdj[EFPOBdy[EFPBd~[RETURNNOTHING Bd~[PREVSTACKj;+Bd+NEWSTACKBdbLET.BdoRETURN-=BdPREVSTACKBdRETURNNOTHING BdPREVSTACKrN[Bd[NEWSTACKBd[SIMPLEIFnnextBd[EFPNBd[EFPBd[RETURNNOTHING Bd[PREVSTACKt \dBd \NEWSTACK Bd\EFPBd\RETURNNOTHING Bd\PREVSTACKv@\dBd@\NEWSTACK BdL\EFPBdQ\RETURNNOTHING BdQ\PREVSTACKmCK ^Bd!^PREVSTACK z \JBd\NEWSTACKBd\RETURNNOTHING Bd\PREVSTACKy|\JBd\NEWSTACKBd\RETURNNOTHING Bd\PREVSTACK{K\~Bd\NEWSTACK%Bd\EFPBd\EFPBd\RETURNNOTHING Bd\PREVSTACK}M%]Bd%]NEWSTACKBd']SIMPLEIFhBd7]EFPMBdF]EFPBdK]RETURNNOTHING BdK]PREVSTACKFu7h.BdhNEWSTACKBdLET.BdRETURN-$BdOPEREFP- BdOPEREFP+{ BdOPEREFPBdPREVSTACKBdRETURNNOTHING BdPREVSTACK~L]Bd]NEWSTACKBd]SIMPLEIFnnextBd]EFPLBd]EFPBd]RETURNNOTHING Bd]PREVSTACK@]dBd]NEWSTACK Bd]EFPBd ]RETURNNOTHING Bd ]PREVSTACKB  ^dBd  ^NEWSTACK  Bd ^EFPBd^RETURNNOTHING Bd^PREVSTACKxGm^Bd^PREVSTACKKl^Bdl^NEWSTACKBdn^SIMPLEIFhBd~^EFPKBd^EFPBd^RETURNNOTHING Bd^PREVSTACKHALBdNEWSTACKBdLET.BdRETURNBdEFP+z Bd0OPEREFPBd0PREVSTACKBd3RETURNNOTHING Bd3PREVSTACKBEJ^Bd^NEWSTACKBd^SIMPLEIFnnextBd^EFPJBd^EFPBd^RETURNNOTHING Bd^PREVSTACKK6gBdgNEWSTACKBdgSIMPLEIFi-uBdgRETURNNOTHING BdgPREVSTACKBdiLET-u'Bdk SIMPLEIFkrk2BdkBEFPBdkJOPEREFPm+-----------------------------------------------------------------+BdmEFPn| .-------------. .-------------. .-------------. |BdnEFPo| | | | | | | |Bdo\EFPp| '---------. | | .---------' | .---------' |BdpEFPq| .---------' | | '---------. | '---------. |BdqEFPr| | < | | | | |BdrgEFPs| '---------. | '---------. | | .---------' |BdsEFPt| .---------' | .---------' | | '---------. |BdtEFPu| | | | | | | |BdurEFPv| '-------------' '-------------' '-------------' |BdvEFPw| |Bdw$EFPx| o o o |Bdx}EFPy| ooooo ooooo oooo o ooooo oooo ooooo ooooo oooo ooooo |BdyEFPz| o o o ooo ooooo o o o o o o o ooo ooo o o o o |Bdz/EFP{| ooo o oooo oooo o ooooo o o ooo oooo ooooo o o o |Bd{EFP|| oooo |Bd|EFP}+-----------------------------------------------------------------+Bd}:EFP~| MAP VOTE MUTATOR VERSION 0.4 |Bd~EFP+-----------------------------------------------------------------+BdEFPBdRETURNNOTHING BdPREVSTACKDLj)_Bd)_PREVSTACKI"G_Bd"G_NEWSTACKBd"I_SIMPLEIFh"Bd"Y_EFP"IBd"h_EFPBd#m_RETURNNOTHING Bd#m_PREVSTACKM%O BdO NEWSTACKBdO SIMPLEIFO.BdO OPEREFPQ6BdQ EFPBdS SIMPLEIFSSEBdS$ OPEREFPBdS% OPEREFPUSpawning HUD PluginBdUV EFPBdW LETE E X(BdX EFPBdZ SIMPLEIFZEBdZ OPEREFP[HUD Plugin successfully spawnedBd[ EFP]]HUD Plugin creation failedBd]3EFPBd`FRETURNNOTHING Bd`FPREVSTACKJq'_Bd'_NEWSTACKBd'_SIMPLEIFn'nextBd'_EFP'qBd'_EFPBd(_RETURNNOTHING Bd(_PREVSTACK{MG( dBdG( NEWSTACKG%BdG8 EFPBdH< RETURNNOTHING BdH< PREVSTACK IQg6`Bd6`PREVSTACKE/`Bd/`NEWSTACKBd/`SIMPLEIFh/Bd/.`EFP/EBd/=`EFPBd0B`RETURNNOTHING Bd0B`PREVSTACKADlC(BdCNEWSTACKBdIRETURNppppCWBd|OPEREFP was using Fire Rate hack!!! (Auto message BdOPEREFP9SDBdOPEREFP)BdOPEREFPBdPREVSTACKBdRETURNNOTHING BdPREVSTACK OB4x`Bd4x`NEWSTACKBd4z`SIMPLEIFn4nextBd4`EFP4BBd4`EFPBd5`RETURNNOTHING Bd5`PREVSTACKXNT5@aBd@aNEWSTACKBd@aLET.BdAaLET]FB]$1BdBbEFPBdD+bRETURN]BdD/bPREVSTACKBdE3bRETURNNOTHING BdE3bPREVSTACK]@@{SW8N4cBdN4cNEWSTACKBdNJcLETXAOX$1!BdOjcEFPBdQvcRETURNXBdQzcPREVSTACKBdR~cRETURNNOTHING BdR~cPREVSTACKX@\[y@P_G}BdNEWSTACKBdRETURN9?`BdPREVSTACKBdRETURNNOTHING BdPREVSTACK |`]bz{BdNEWSTACKBdRETURN^BdPREVSTACKBdRETURNNOTHING BdPREVSTACK id7fBqxQ9 BdxQNEWSTACKBdxSSIMPLEIFx%BdxkOPEREFPBdzvSIMPLEIFz{ BdzOPEREFPzMap vote timed outBdzEFP{Bd{EFPBd|RETURNNOTHING Bd|PREVSTACKBdSIMPLEIFBdOPEREFP*-BdOPEREFPBdCLETw9BdCEFPBdMFORINITBddFOREVAL>BdgOPEREFPBdLET5.BdSIMPLEIF5BdOPEREFPBBdOPEREFPBdSIMPLEIF59BdEFPwBdOPEREFPxBdOPEREFPBdhFORINCBd{LETBdLET9D9?BBdOPEREFP9D9?xBdOPEREFPBdEFP,BdEFPBdSIMPLEIFBdOPEREFPBdOPEREFPBdSIMPLEIFBdOPEREFPBd,SIMPLEIF-nBd]EFPoBdEFPBdEFPBdSIMPLEIFBdOPEREFPBdOPEREFPBd EFP Bd(SIMPLEIF  Bd4OPEREFPBdeFORINITBd|FOREVALBdOPEREFPBdLET5.BdSIMPLEIF5BdOPEREFPBBdOPEREFPBdFORINCBdLETBd$LET9D9?BBdOPEREFP&Bd$EFPBd+SIMPLEIF BdJOPEREFPBdZOPEREFPBdgSIMPLEIF4 BdOPEREFPBdSIMPLEIF-=BdLET ppMap vote succeeded: Bd2OPEREFP is queued as the next mapBdPOPEREFPBdQEFP pMap vote succeeded: Switching to BdOPEREFPBdEFP = (BdEFPBdEFP BdSIMPLEIF Bd OPEREFPBdOPEREFPMap vote was not successful: ending voteBdEFPBdEFP BdEFPBdRETURNNOTHING BdPREVSTACKre+Bde+NEWSTACKeBde:EFPBdgULET*BdhkLET BdiLET-=(BdjRETURNNOTHING BdjPREVSTACKL@jkloo{$+Bd$NEWSTACK$Bd$EFPBd' SIMPLEIF[''''Bd'(OPEREFP-'Bd'7OPEREFP6'Bd'ZOPEREFP;'.Bd'OPEREFPBd)LETA.Bd-/ SIMPLEIF-zABd-> OPEREFPBd-\ LETA-Bd-\ EFPBd/h RETURNABd/p PREVSTACKBd0t RETURNNOTHING Bd0t PREVSTACK@UA@m]39j Bd9j NEWSTACKBd9o FORINIT3%Bd9u FOREVAL93, Bd9| OPEREFPBd: LET3]3oBd9} FORINC93Bd9 OPEREFP2Bd; RETURNNOTHING Bd; PREVSTACK @v\wZ2BdZ2NEWSTACKBdZ`LET-LZ\Z-HBdZ`EFPBd[iSIMPLEIF-LBd[LET Bd]RETURN-LBd]PREVSTACKBd^RETURNNOTHING Bd^PREVSTACK@zg4ABdNEWSTACKBdLET2a BdEFPBdSIMPLEIFz2Bd)OPEREFPBd4RETURNNOTHING Bd4PREVSTACKBdyLET@(b2%BdyEFPBdLET@BdWHILE |@mBdOPEREFPBdOPEREFP"{@BdOPEREFPBdSIMPLEIF|}BdEFP,BdOPEREFPBdEFPp2-tutorialBdOPEREFPBdOPEREFPBdOPEREFPBd:LETCBdDSIMPLEIFa|,BdVEFP.unrBd`OPEREFPBdLETC}BdEFP,BdOPEREFPBdEFP}BdLETCBdLET7ggCBd0LET+b2&Bd0EFPBdFLETm1BdNRETURNNOTHING BdNPREVSTACK 0D.Bd.NEWSTACKBd.SIMPLEIF.-Bd0 SIMPLEIFn-fBd20 LET033p3p3p. queued map Bd3` OPEREFP0Bd3j OPEREFP as next in rotationBd3 OPEREFPBd3 EFPBd4 SIMPLEIFh4{ Bd4 OPEREFP4Bd4 EFP7 8=0(Bd8 EFPBd9 SIMPLEIF9{ Bd9 OPEREFP9Bd9 EFPBd; RETURN,Bd; PREVSTACKBd>7 SIMPLEIF>%Bd>N OPEREFPBd? RETURN%Bd? PREVSTACKBdA SIMPLEIFA{BdA OPEREFPBdB RETURN&BdB PREVSTACKDDpDp. inititated a vote for map BdD$ OPEREFP0BdD- OPEREFPBdD. EFPE`.EpEpEp.E,BdE~ EFPBdE OPEREFP inititated a vote for map BdE OPEREFP0BdE OPEREFPBdE EFPBdH LET*BdI" LET 0BdJ@ LET-=-fBdL[ LET.M~BdMj EFPBdNt RETURN,BdNv PREVSTACKBdOz RETURNNOTHING BdOz PREVSTACKpfVB| BdB| NEWSTACKBdB RETURNfoBdB PREVSTACKBdC RETURNNOTHING BdC PREVSTACK h"//=============================================================================// // Map Vote Mutator v0.4.2 Copyright(C) 2005 Adam Mummery-Smith B.S.E. // //=============================================================================// class MapVoteMutator extends Mutator; //=============================================================================// // Class: MapVoteMutator | Date: December 2005 // //-----------------------------------------------------------------------------// // Project: Map Vote Mutator | Author: Adam Mummery-Smith // //-----------------------------------------------------------------------------// // Description: Map Vote Mutator: adds map voting funtionality to XMP // //-----------------------------------------------------------------------------// // Usage: Run on your server like any other mutator // //-----------------------------------------------------------------------------// // Note: Still very much alpha code, there is no pretty UI or anything // // like that... sorry. // //=============================================================================// simulated function PreBeginPlay() { Log("---------- Default Game 03 Mutator functionality loading started.. ----------"); class'Controller'.default.PlayerReplicationInfoClass=class'CheaterPRI'; class'PlayerController'.default.PlayerReplicationInfoClass=class'CheaterPRI'; class'U2PlayerController'.default.PlayerReplicationInfoClass=class'CheaterPRI'; Log("---------- Default Game 03 Mutator functionality loading complete. ----------"); if (Role == ROLE_Authority) { if( !ClassIsChildOf(Level.Game.PlayerControllerClass, class'MapVoteController') ) Level.Game.PlayerControllerClass = class'MapVoteController'; if( !ClassIsChildOf(Level.Game.GameReplicationInfoClass, class'MapVoteGameReplicationInfo') ) Level.Game.GameReplicationInfoClass = class'MapVoteGameReplicationInfo'; Level.Game.MapListType = "BSEMapVote_0_42.ExtendedMapList"; } Super.PreBeginPlay(); } Um(B BdB NEWSTACKBdB LET7mBdC4 LET.pETrying to register the HUD Plugin every 2 secondsBdEu EFPG!:@'BdG EFPBdH RETURNNOTHING BdH PREVSTACKFc_Bd_NEWSTACKBdLETcU2.XMPGame BdEFPBd LETKc Bd EFPA%7Bd8FORINIT4%Bd>FOREVAL|47KBdcOPEREFPBdLET44KBddFORINC4BdhOPEREFPBdLETKbBdEFPBdRETURNNOTHING BdPREVSTACK@yJ:R ?BdR NEWSTACKBdR SIMPLEIFRR-&BdR OPEREFP9RRBdR EFPBdR OPEREFPBdT FORINITJ%BdTFOREVALyTJ7TBdTEFPBdT'OPEREFPBdV9SIMPLEIFCV.JVBdVZEFPBdVgOPEREFPXHUD Plugin registration failed because an instance of the Plugin already exists in the UIBdXEFPBdYLET-&'ZBdZEFPBd[/RETURNNOTHING Bd[/PREVSTACKBdT(FORINCTJBdT,OPEREFP_HUD Plugin is trying to register itself with the UIBd_EFP`Bd`EFP0`CDrawExtendedVoteHUDBd`EFPb BdbSIMPLEIF-&dHUD Plugin registration failed because the Plugin is already registeredBdd>EFPeBdeWEFPh iHUD Plugin registration failed because the UI did not respondBdiEFPBdkRETURNNOTHING BdkPREVSTACKx@_2}P7 A3Y `@8/@8/@8/@8/@8/ H] BSE Map VoteB]"!Allows players to vote for maps.pW|Oo7zBdo7NEWSTACKBdoILET-&(obBdoWEFPBdoZRETURNNOTHING BdoZPREVSTACK ~@At'|Bdt'NEWSTACKBdt-RETURN-&Bdt8PREVSTACKBdt;RETURNNOTHING Bdt;PREVSTACKFBdNEWSTACKBdSIMPLEIF -&BdOPEREFPHUD Plugin is registered successfullyBd+EFPBdAEFPBdWLET-&'Bd^SIMPLEIF 7BdfOPEREFPBdLETh7BdtSIMPLEIFNBd~OPEREFP!-cBdOPEREFPBdLET-N(/a0 `MBdITERATOREFPBdSIMPLEIFL.`BdOPEREFPBdLET-N'Bd$BREAKFOREACHM10Bd SIMPLEIF8BdOPEREFPBdOPEREFPBd,FORINIT %Bd2FOREVAL 7BdEEFPBdTOPEREFPBdfSIMPLEIF. BdEFPBdOPEREFPBdLET8. BdEFPBdUFORINC BdYOPEREFPBd7LETG9DBdJLET*9DBdUSIMPLEIFBd_OPEREFP$7BdiOPEREFPBdLET$BdLETBdLET-'BdSIMPLEIF 9:<%BdOPEREFPBd/LETR7hBd.OPEREFPBdmSIMPLEIFWR9?lBdOPEREFPBdLET<9C9<$R9?lBdOPEREFP<BdOPEREFPBdOPEREFPBdSIMPLEIF9:<, BdOPEREFPBdLET<$BdFORINIT %BdFOREVAL  7WBdOPEREFPBdlSIMPLEIFd-NBdSIMPLEIF| &BdOPEREFP BdOPEREFPBdSIMPLEIF ,BdOPEREFPBdLETPBdLETP*a9?P ,BdOPEREFPBdOPEREFPBdEFPaC9? ,BdOPEREFPBdOPEREFPBdEFPBdALET6Y WBd\LET6<(a6X W'BdEFPBdFORINC Bd OPEREFPBdSIMPLEIF7BdEFP.Bd_EFPBd}LETzBdLET6$BdSIMPLEIFR ;BdEFP^9?*,BdOPEREFP,BdOPEREFPBdEFPap!0Bd)EFPBd*EFP has initiated a vote for BdIOPEREFP'BdQEFP^9?*,BdqOPEREFP,BdvOPEREFPBdwEFPtap#BdEFP to be queued as the next mapBdOPEREFP'BdEFP ^9?*,BdOPEREFP,BdOPEREFPBdEFPapp!0BdPEFPBdQEFP has initiated a vote for map BduOPEREFP#BdEFPBdOPEREFP'BdEFP^9?*,BdOPEREFP,xBdOPEREFPBdEFPappppPress [%BdOPEREFP] for yes.Press [BdOPEREFP$BdOPEREFP] for no.Bd'OPEREFP'Bd/EFPBdSIMPLEIF<BdEFP ABd EFPBd LET6$B9?*, Bd!OPEREFPBd!EFPa 'Bd"!EFPPlugin registered but no owner :(Bdo!EFPBd|!RETURNNOTHING Bd|!PREVSTACKBi//=============================================================================// // Map Vote Mutator v0.4.2 Copyright(C) 2005 Adam Mummery-Smith B.S.E. // //=============================================================================// class MapVoteHUDPlugin extends UIHelper; //=============================================================================// // Class: MapVoteHUDPlugin | Date: December 2005 // //-----------------------------------------------------------------------------// // Project: Map Vote Mutator | Author: Adam Mummery-Smith // //-----------------------------------------------------------------------------// // Description: Since there is no UI functionality for map voting, this class // // is responsible for displaying the map vote message when // // necessary. It also displays a quick 'Message of the Day' to // // let players know how to start a map vote. // //-----------------------------------------------------------------------------// // Usage: An instance of this class is spawned by the Player // // Controller. // //-----------------------------------------------------------------------------// // Note: Integration with non-standard UIs may be poor. Not tested on // // all resolutions but tries to be as faithful to the player // // kick-voting screen as possible. // //=============================================================================// //----------------------------------------------------------------------------- // Declarations // Fonts var Font bigfont, smallfont, tinyfont; // Colours var Color white, grey, black, red, green, blue, yellow, semitrans; var Color teamColor[2]; // Local references to replicated game objects var LevelInfo Level; var MapVoteController myOwner; var bool registered; var int CanvasX, CanvasY; // Message of the day var config array< struct MOTDLine { var() String Text; var() Color Colour; } > MOTD; var config int MOTDDisplayTime; var byte MOTDAlpha; // Make a note of when we become registered - and use to decided how long to display the MOTD var float RegisteredTime; // To determine the vote key bindings we need to find a CodeMonkey. This variable keeps track of it. var CodeMonkey LocalCodeMonkey; // Vote key bindings, retrieved from the CodeMonkey var array VoteKeys; var string VoteYesKey, VoteNoKey; // Variables to help this plugin coexist with the RaptorRace HUD plugin var bool RRCheckVerify; var bool RREnabled; //----------------------------------------------------------------------------- // This function is called by owner to the tell the object to begin trying to register // itself as a render listener. simulated function Register(coerce LevelInfo theLevel, coerce Actor owner) { Level = theLevel; myOwner = MapVoteController(owner); Log("Trying to register the HUD Plugin every 2 seconds"); AddTimer( 'TryToRegister', 2, True ); } //----------------------------------------------------------------------------- // This function tries to register the HUD plugin at pre-defined intervals and stops when // it detects that the plugin has been registered successfully simulated function TryToRegister() { local int i; if (!registered && GetUIConsole()?) { for (i = 0; i < GetUIConsole().Helpers.length; i++) { if (MapVoteHUDPlugin(GetUIConsole().Helpers[i])?) { Log("HUD Plugin registration failed because an instance of the Plugin already exists in the UI"); registered = true; RemoveAllTimers(); return; } } Log ("HUD Plugin is trying to register itself with the UI"); GetUIConsole().RegisterRenderListener(self, "DrawExtendedVoteHUD"); } else if (registered) { Log("HUD Plugin registration failed because the Plugin is already registered"); RemoveAllTimers(); } else { Log("HUD Plugin registration failed because the UI did not respond"); } } //----------------------------------------------------------------------------- simulated event Constructed() { registered = false; SaveConfig(); } //----------------------------------------------------------------------------- // Called by the owner to check whether registration has been successful simulated function bool CheckRegistered() { return registered; } //----------------------------------------------------------------------------- // This is the function which (once the plugin is registered) will perform the extra draw tasks required simulated interface function DrawExtendedVoteHUD( Canvas C ) { local int i, j; local float t; local Loader L; // If this function is called, we know that registration is successful. So set the registered flag. if (!registered) { Log("HUD Plugin is registered successfully"); RemoveAllTimers(); registered = true; if (Level?) RegisteredTime = Level.TimeSeconds; } // Since the MOTD may clash with the RaptorRace MOTD, we will detect RaptorRace and then adjust the // MOTD accordingly. Here we search for loaders and if we find an eq2Loader, we know that RaptorRace // is running. if (myOwner? && !RRCheckVerify) { RREnabled = false; ForEach myOwner.AllActors(class 'Loader', L) { if (eq2Loader(L)?) { RREnabled = true; break; } } //RRCheckVerify = true; } // We can retrieve key bindings from the CodeMonkey. So let's grab ourselves a reference to it. // CodeMonkey will be alongside us in the UI Helpers array, so we search that. if (!LocalCodeMonkey?) { for (i = 0; i < GetUIConsole().Helpers.length; i++) { if (CodeMonkey(GetUIConsole().Helpers[i])?) { LocalCodeMonkey = CodeMonkey(GetUIConsole().Helpers[i]); } } } // Because I'm lazy and I think it looks neater CanvasX = C.ClipX; CanvasY = C.ClipY; if (myOwner? && Level?) { C.Style = 5; C.Font = BigFont; C.bCenter = True; // Draw the Message Of The Day (MOTD) for a pre-defined time if (MOTDAlpha > 0) { t = (Level.TimeSeconds - RegisteredTime); // Process the fade out after the allotted time if (t > MOTDDisplayTime) MOTDAlpha = 255 - ((t - MOTDDisplayTime) / 0.007843); if (MOTDAlpha < 10) MOTDAlpha = 0; for (i=0; i < MOTD.Length; i++) { // If RaptorRace is detected, adjust the MOTD so that the MOTDs don't clash if (RREnabled) { if (i == 1) i++; if (i > 2) j = 270; else j = 298; C.SetPos(0, j + (i*17)); } else { C.SetPos(0, 145 + (i*17)); } C.DrawColor = MOTD[i].Colour; C.DrawColor.A = MOTDAlpha; C.DrawText( MOTD[i].Text, True ); } } // If we should be displaying a poll, display a poll if (myOwner.ShowMapVotePoll()) { // Get the current keybindings assigned to VoteYes and VoteNo UpdateVoteKeys(); C.DrawColor = Green; C.DrawColor.A = 255; if (myOwner.VotedMapDeferred()) { C.SetPos(0, CanvasY/2 - 159); C.DrawText( StripColours(myOwner.GetPollOwner()) $ " has initiated a vote for ", True ); C.SetPos(0, CanvasY/2 - 142); C.DrawText( myOwner.GetNominatedMapName() $ " to be queued as the next map", True); } else { C.SetPos(0, CanvasY/2 - 142); C.DrawText( StripColours(myOwner.GetPollOwner()) $ " has initiated a vote for map " $ myOwner.GetNominatedMapName(), True ); } C.SetPos(0, CanvasY/2 - 120); C.DrawText( "Press [" $ VoteYesKey $ "] for yes.Press [" $ VoteNoKey $ "] for no.", True ); } // The Map Vote GUI is drawn by the PlayerController itself. When necessary, call the // function to display the GUI. if (myOwner.DisplayMapSelectionGUI()) { myOwner.DrawVoteUI(C, self); } // This is necessary because the last thing drawn by a HUD plugin always seems to have a higher // DrawOrder than the menu system. So we draw a transparent space. C.DrawColor.A = 255; C.SetPos(0, CanvasY - 10); C.DrawText(" ", True ); } else { Log("Plugin registered but no owner :("); } } //----------------------------------------------------------------------------- // Queries the Local CodeMonkey and gets the key assignments of the VoteYes and VoteNo commands function UpdateVoteKeys() { local int i; if (LocalCodeMonkey?) { VoteYesKey = ""; VoteNoKey = ""; VoteKeys = LocalCodeMonkey.GetKeys("voteyes"); for (i = 0; i < VoteKeys.Length; i++) { if (VoteYesKey != "") VoteYesKey = VoteYesKey $ "/"; VoteYesKey = VoteYesKey $ VoteKeys[i]; } VoteKeys = LocalCodeMonkey.GetKeys("voteno"); for (i = 0; i < VoteKeys.Length; i++) { if (VoteNoKey != "") VoteNoKey = VoteNoKey $ "/"; VoteNoKey = VoteNoKey $ VoteKeys[i]; } } } //----------------------------------------------------------------------------- // Take the colour codes ("^#.") out of a name string. From the XMPSummoner mut. static function string StripColours(string S) { local int i; local bool bReplaced; do { bReplaced = False; for (i = 0; i < Len(S); i++) { if (Mid(S, i, 2) ~= "^#") { S = Left(S, i) $ Right(S, Len(S) - i - 3); bReplaced = True; } } } until (!bReplaced); return S; } cc//=============================================================================// // Map Vote Mutator v0.4.2 Copyright(C) 2005 Adam Mummery-Smith B.S.E. // //=============================================================================// class MapVoteGameReplicationInfo extends GameReplicationInfo; //=============================================================================// // Class: MapVoteGameReplicationInfo | Date: December 2005 // //-----------------------------------------------------------------------------// // Project: Map Vote Mutator | Author: Adam Mummery-Smith // //-----------------------------------------------------------------------------// // Description: Oddly enough, in XMP, voting is handled by the GRI. So in // // order to implement map voting, we extend this class to // // include the map voting functionality. // //-----------------------------------------------------------------------------// // Usage: N/A // //-----------------------------------------------------------------------------// // Note: // //=============================================================================// //----------------------------------------------------------------------------- // Declarations // The map being voted for var string PendingMap; var bool PendingMapDeferred; // Once a map is successfully voted as next map, it is stored here until the next rotation var string QueuedMap; //----------------------------------------------------------------------------- replication { reliable if ( bNetDirty && (Role == ROLE_Authority) ) PendingMap, PendingMapDeferred; } //----------------------------------------------------------------------------- // Called by the client to start a map vote function int MapRequest(string MapName, PlayerReplicationInfo Requestor, optional bool defer) { // If the player is an admin, don't bother starting a poll, just immediately switch // or immediately queue the requested map. Over-rides all active map votes. if (Requestor.bAdmin) { if (defer) { QueuedMap = MapName; Log(Requestor.PlayerName $ " queued map " $ MapName $ " as next in rotation"); if (PendingMap != "") EndVote(); } else { Level.ServerTravel(MapName, false); if (PendingMap != "") EndVote(); } return 2; // Success } if (VoteTimeRemaining > 0) // only allow one poll at any given time. return 0; if (QueuedMap != "") // only allow votes if no map has been voted as next return 1; Log(Requestor.PlayerName $ " inititated a vote for map " $ MapName); Level.Game.Broadcast( Requestor.Owner, Requestor.PlayerName $ ColorCode(138) $ " inititated a vote for map " $ MapName ); // This is necessary to stop vote-kicks interfering with map-votes PendingKick = None; PendingMap = MapName; PendingMapDeferred = defer; PollOwner = Requestor; StartVote(); return 2; } //----------------------------------------------------------------------------- // We have to intercept this request to prevent vote-kicks that follow map votes from // making it look like we've triggered the map vote again. If the vote request succeeds, // we clear the PendingMap variable. function bool KickRequest( PlayerReplicationInfo P, PlayerReplicationInfo Requestor, optional bool bBan ) { local bool temp; temp = Super.KickRequest( P, Requestor, bBan ); if (temp) PendingMap = ""; return temp; } //----------------------------------------------------------------------------- // Ends the current vote... honest function EndVote() { Super.EndVote(); PendingKick = None; PendingMap = ""; PendingMapDeferred = false; } //----------------------------------------------------------------------------- // I know it's ugly, but I have just extended the UpdateVotes() function by overriding // it completely. Maybe in a later version I'll change it and add a call to Super.UpdateVotes() function UpdateVotes() { local int NumPlayers, NumTeamPlayers; local Controller C; local PlayerController PC; local int KickTeam; // Abort vote if time expired. if (VoteTimeRemaining <= 0) { if (PendingMap != "") Log("Map vote timed out"); EndVote(); return; } // Existing kick/ban functionality if (PendingKick? && !PendingKick.bPendingDelete) { KickTeam = PendingKick.GetTeam(); for (C=Level.ControllerList; C?; C=C.NextController) { PC = PlayerController(C); if (PC?) { NumPlayers++; if (PC.GetTeam() == KickTeam) NumTeamPlayers++; } } // Maximize for games with few people, minimize for games with lots of people. NumVotesRequired = Max(Min((NumPlayers * KickPctTotal),(NumTeamPlayers * KickPctTeam)),2); if ((VoteTime - VoteTimeRemaining) >= MinVoteTime) { if (NumVotes >= NumVotesRequired) { if (bKickBan) Level.Game.KickBan(PendingKick); else Level.Game.Kick(PendingKick); EndVote(); } else if (-NumVotes >= NumVotesRequired) // cancel early if enough people vote no. { EndVote(); } } } else if (PendingMap?) { // New map vote functionality for (C=Level.ControllerList; C?; C=C.NextController) { PC = PlayerController(C); if (PC?) { NumPlayers++; } } NumVotesRequired = Max((NumPlayers * KickPctTotal), 1); if ((VoteTime - VoteTimeRemaining) >= MinVoteTime) { if (NumVotes >= NumVotesRequired) { // If the vote succeeds, change map immediately. if (PendingMapDeferred) { QueuedMap = PendingMap; Log("Map vote succeeded: " $ QueuedMap $ " is queued as the next map"); } else { Log("Map vote succeeded: Switching to " $ QueuedMap); Level.ServerTravel(PendingMap, false); } EndVote(); } else if (-NumVotes >= NumVotesRequired) // cancel early if enough people vote no. { Log("Map vote was not successful: ending vote"); EndVote(); } } } else // nothing left to vote on. { EndVote(); } } G//=============================================================================// // Map Vote Mutator v0.4.2 Copyright(C) 2005 Adam Mummery-Smith B.S.E. // //=============================================================================// class MapVoteController extends U2PlayerController; //=============================================================================// // Class: MapVoteController | Date: December 2005 // //-----------------------------------------------------------------------------// // Project: Map Vote Mutator | Author: Adam Mummery-Smith // //-----------------------------------------------------------------------------// // Description: This class adds the user-interaction part to the map vote // // system, since it contains the exec function which makes it // // all possible... but you knew that - didn't you? // //-----------------------------------------------------------------------------// // Usage: N/A // //-----------------------------------------------------------------------------// // Note: GUI is still ugly, no textures yet. Will make it look nicer // // in the next release. // //=============================================================================// //----------------------------------------------------------------------------- // Declarations // HUD Plugin manages all the drawing to canvas that we require var MapVoteHUDPlugin h; var MapVoteGameReplicationInfo MyGRI; // Local (client-side) copy of map rotations var string VoteableMaps[10], next; var array MapsInRotation; // Make sure we only draw the ASCII logo once var bool logodone; // Error message: a map is already queued var localized string QueuedMapMsg, AlreadyQueuedMsg; // Voting UI Support var config bool DisableGUI; // Set true to use the old-style command-line interface var config int VoteGUINumRows; // Number of rows to display in the vote GUI var bool bDisplayMapChooser; // Set as a flag to let the HUD plugin know we want to // display the vote GUI var array< struct VoteLine { var() int Num; var() String Text; var() bool AdminOnly; var() Color Colour; } > VoteLines; var int pos, start, total; var int linespacing, numspacing, bracketspacing; //----------------------------------------------------------------------------- replication { unreliable if( Role params; StrArray(command, " ", params); if (params[0] ~= "disablegui") { if (DisableGUI) return; DisableGUI = true; bDisplayMapChooser = false; ClearProgressMessages(); SetProgressTime(6); SetProgressMessage(0, "Map Vote GUI is now disabled", class'Canvas'.Static.MakeColor(255,0,0)); ClientMessage("Map Vote GUI is now disabled"); SendEvent("HideConsole"); } else if (params[0] ~= "enablegui") { if (!DisableGUI) return; DisableGUI = false; bDisplayMapChooser = false; ClearProgressMessages(); SetProgressTime(6); SetProgressMessage(0, "Map Vote GUI is now enabled", class'Canvas'.Static.MakeColor(0,255,0)); ClientMessage("Map Vote GUI is now enabled"); SendEvent("HideConsole"); } else if (params[0] ~= "menusize") { VoteGUINumRows = int(params[1]); pos = 0; start = 0; if (VoteGUINumRows < 3) VoteGUINumRows = 3; if (VoteGUINumRows > 12) VoteGUINumRows = 12; if (VoteGUINumRows == 0) { VoteGUINumRows = 8; DisableGUI = true; } else { DisableGUI = false; } SendEvent("HideConsole"); } else { SendEvent("ShowConsole"); ClientMessage(""); ClientMessage("Usage: MapVoteCfg enablegui - enables the graphical mapvote (default)"); ClientMessage(" MapVoteCfg disablegui - disables the graphical mapvote"); ClientMessage(" MapVoteCfg menusize - set the number of items to display on the map vote menu"); ClientMessage(""); } SaveConfig(); } //----------------------------------------------------------------------------- // Execute a map vote or retrieve a list of maps exec function Mapvote(optional int MapNumber, optional string param2) { local bool defer; local string MapName; local int i; // If the player specifies the "next" option, try to defer the map selection if (param2 ~= "next") defer = true; if (MapNumber < 1) { if (bDisplayMapChooser) { bDisplayMapChooser = false; } else { ServerDisplayMapList(); if (DisableGUI) SendEvent("ShowConsole"); } } else { bDisplayMapChooser = false; for (i = 0; i < VoteLines.Length; i++) { if (VoteLines[i].Num == MapNumber) MapName = VoteLines[i].Text; } RequestMap(MapName, defer); if (DisableGUI) SendEvent("HideConsole"); } } //----------------------------------------------------------------------------- // Replicated function, executed on the server. Tries to initiate a map vote and notifies // the user if the vote is unsuccessful (a vote is already in progress) function RequestMap(string MapName, optional bool defer) { local int result; local ExtendedMapList MyMapList; // If we've managed to retrieve a valid map name, attempt to start the poll if (MapName != "") { MyMapList = ExtendedMapList(Level.Game.GetMapList(Level.Game.MapListType)); if (MyMapList?) next = MyMapList.PredictNextMap(); // Tries to get the name of the next map in rotation else next = "unknown"; if (defer && Mapname ~= next) { ClearProgressMessages(); SetProgressTime(6); SetProgressMessage(0, AlreadyQueuedMessage(), class'Canvas'.Static.MakeColor(255,255,255)); } else { result = MapVoteGameReplicationInfo(GameReplicationInfo).MapRequest(MapName, PlayerReplicationInfo, defer); if (result == 0) // Poll already in progress { ClearProgressMessages(); SetProgressTime(6); SetProgressMessage(0, VoteFailedMsg, class'Canvas'.Static.MakeColor(255,255,255)); } else if (result == 1) // Map already queued { ClearProgressMessages(); SetProgressTime(6); SetProgressMessage(0, QueuedMapMessage(), class'Canvas'.Static.MakeColor(255,255,255)); } } } } //----------------------------------------------------------------------------- // Gets a map name from the map list (not used any more) function string GetServerMapName(int MapNumber) { local class GameClass; local class MapListClass; GameClass = class(DynamicLoadObject("U2.XMPGame", class'Class')); MapListClass = class(DynamicLoadObject(GameClass.default.MapListType, class'Class')); if (MapListClass != None) { return MapListClass.Default.Maps[MapNumber]; } } //----------------------------------------------------------------------------- // Called by the server to clear the locally cached map rotation list simulated function ClientClearLocalMapList() { MapsInRotation.Remove(0,MapsInRotation.Length); } // Called by the server to add maps to the locally cached map rotation list simulated function ClientUpdateLocalMapList(int position, string value) { MapsInRotation[position] = value; } // Called by the server to add maps to the locally cached votable map list simulated function ClientUpdateVotableMapList(int position, string value) { VoteableMaps[position] = value; } // Called by the server once maplist propogation is complete to notify the // client to display the GUI simulated function ClientDisplayGUI() { bDisplayMapChooser = true; } //----------------------------------------------------------------------------- // Replicated function, executed on the server. Dumps the current map rotation and // pre-defined map list to the client's console, and updates the locally cached versions. function ServerDisplayMapList() { local class GameClass; local class MapListClass; local array AllMaps; local ExtendedMapList MyMapList; local string spc; local int i, j, size; // Fetch the pre-defined map list from the ini class'ExtendedMapList'.static.GetPredefinedMapList(VoteableMaps); // Send the votable maplist to the client for (i = 0; i < 10; i++) ClientUpdateVotableMapList(i, VoteableMaps[i]); GameClass = class(DynamicLoadObject("U2.XMPGame", class'Class')); MapListClass = class(DynamicLoadObject(GameClass.default.MapListType, class'Class')); ClientMessage("============================================================================="); ClientMessage(" LISTING AVAILABLE MAPS "); ClientMessage("============================================================================="); ClientMessage(" Pre-defined map choices"); ClientMessage("-----------------------------------------------------------------------------"); for (i = 0; i < 10; i++) { if (i == 9) spc = " "; else spc = " "; if (VoteableMaps[i] != "") { ClientMessage(spc $ (i + 1) $ ": " $ VoteableMaps[i]); j++; } else break; } if (j == 0) ClientMessage(" --- sorry, no pre-defined maps available --- "); ClientMessage("============================================================================="); ClientMessage(" Maps in server rotation"); ClientMessage("-----------------------------------------------------------------------------"); if (MapListClass != None) { size = MapListClass.Default.Maps.length; MapsInRotation.Remove(0,MapsInRotation.Length); ClientClearLocalMapList(); for (i = 0; i < MapListClass.Default.Maps.length && MapListClass.Default.Maps[i] != ""; i++) { if (i < 989) spc = " "; if (i < 89) spc = " "; // Display each maplist entry ClientMessage(spc $ (i + 11) $ ": " $ MapListClass.Default.Maps[i]); MapsInRotation[MapsInRotation.Length] = MapListClass.Default.Maps[i]; // Send each maplist entry to the client ClientUpdateLocalMapList(MapsInRotation.Length - 1, MapListClass.Default.Maps[i]); j++; } } MyMapList = ExtendedMapList(Level.Game.GetMapList(Level.Game.MapListType)); if (MyMapList?) next = MyMapList.PredictNextMap(); // Tries to get the name of the next map in rotation else next = "unknown"; ClientMessage("-----------------------------------------------------------------------------"); ClientMessage(" " $ j $ " map(s) available. Next map is " $ next); ClientMessage(" To initiate a map vote, use MAPVOTE "); ClientMessage("============================================================================="); // Admins get a list of ALL the server's maps appended to the rotation list if ( PlayerReplicationInfo.bAdmin ) { MyMapList.GetAllMaps(AllMaps, "U2.XMPGame"); for (i = 0; i < AllMaps.length; i++) { MapsInRotation[MapsInRotation.Length] = AllMaps[i]; ClientUpdateLocalMapList(MapsInRotation.Length - 1, "_" $ AllMaps[i]); } } // Tell the client to rebuild the GUI list ReBuildVoteLineArray(); // Tell the client to display the GUI ClientDisplayGUI(); } //----------------------------------------------------------------------------- // Called by the HUD Plugin when the client wants to display the vote GUI simulated function DrawVoteUI(Canvas C, MapVoteHUDPlugin MyHUDPlugin) { local float xl, yl, scrollbarpct; local int i, current, scrollbarabs; local int maxWidth, offset, top; if (DisableGUI) { // If the GUI is disabled, don't display it bDisplayMapChooser=false; return; } // Calculate the psuedo-scrollbar position scrollbarpct = float(start) / float(total - VoteGUINumRows + 1); scrollbarabs = int(scrollbarpct * float(VoteGUINumRows)); // Calculate the top co-ordinate for the GUI (should be just below the reticle) top = (C.ClipY / 2) + 57; // Draw the GUI title C.DrawColor = MyHUDPlugin.Green; C.SetPos(0, C.ClipY/2 + 32); C.DrawText( "Available Maps", True ); // and some help messages C.SetPos(0, 8 + top + (linespacing * VoteGUINumRows)); C.DrawText( "Use mouse wheel to make your selection", True ); C.SetPos(0, 25 + top + (linespacing * VoteGUINumRows)); C.DrawText( "Use primary fire to vote, secondary to vote for next map", True ); C.SetPos(0, 42 + top + (linespacing * VoteGUINumRows)); C.DrawText( "MAPVOTE again to exit, MAPVOTECFG to configure", True ); // Do some checking to make sure we're not out of bounds if (start >= VoteLines.Length) start = VoteLines.Length - VoteGUINumRows; if (start < 0) start = 0; if (pos >= VoteLines.Length) pos = VoteLines.Length - 1; if (pos < 0) pos = 0; C.bCenter = False; // Since we're going to centre the text manually, find the widest element for (i = 0; i < VoteLines.Length; i++) { C.TextSize(VoteLines[i].Text, xl, yl); maxWidth = Max(xl, maxWidth); } // Offset will be half the width of the sceen minus half the width of the widest element offset = (C.ClipX / 2) - (maxWidth / 2); // Draw the current segment of the map list for (i = 0; i < VoteGUINumRows; i++) { current = start + i; // Don't read past the end of the array!!! if (current >= VoteLines.Length) break; // Draw the number C.DrawColor = MyHUDPlugin.White; C.SetPos(offset - numspacing, top + (i * linespacing)); C.DrawText(VoteLines[current].Num, True); // If this is the currently highlighted element, highlight it and put brackets around it if (current == pos) { C.DrawColor = MyHUDPlugin.Yellow; C.SetPos(offset - bracketspacing, top + (i * linespacing)); C.DrawText("[", True); C.SetPos(offset + maxWidth + bracketspacing, top + (i * linespacing)); C.DrawText("]", True); } // Unlisted maps drawn in blue, current map drawn in red if (VoteLines[current].AdminOnly) C.DrawColor = MyHUDPlugin.Blue; if (VoteLines[current].Text ~= next) C.DrawColor = MyHUDPlugin.Red; C.SetPos(offset, top + (i * linespacing)); C.DrawText(VoteLines[current].Text, True); // Draw the 'scroll bar' C.SetPos(offset + maxWidth + numspacing, top + (i * linespacing)); if (i == scrollbarabs) { C.DrawColor = MyHUDPlugin.White; C.DrawText("#", True); } else { C.DrawColor = MyHUDPlugin.Grey; C.DrawText("ll", True); } } } //----------------------------------------------------------------------------- // Called by the server once the maplists have been sent to the client, instructs // the client to rebuild its GUI map list simulated function ReBuildVoteLineArray() { local int i, j; local VoteLine v; // Clear the version we have already if (VoteLines.Length > 0) VoteLines.Remove(0,VoteLines.Length); // Add the predefined maps to the list for (i = 0; i < 10; i++) { if (VoteableMaps[i] != "") { v.Num = i + 1; v.Text = VoteableMaps[i]; VoteLines[VoteLines.Length] = v; j++; } else break; } // Add the rotation maps to the list for (i = 0; i < MapsInRotation.Length; i++) { if (MapsInRotation[i] != "") { v.Num = i + 11; if (Left(MapsInRotation[i], 1) == "_") // Admin-only maps are prefixed with '_' { v.AdminOnly = True; v.Text = Right(MapsInRotation[i], Len(MapsInRotation[i]) - 1); } else { v.AdminOnly = False; v.Text = MapsInRotation[i]; } VoteLines[VoteLines.Length] = v; j++; } else break; } if (j == 0) { v.Num = 0; v.Text = "Sorry, no maps available"; VoteLines[0] = v; } total = j; } //----------------------------------------------------------------------------- // The 3 GUI action functions below return a boolean value which indicates whether // the calling function should make a call to Super(). For example, the Fire() function // calls GUISelectMap(). GUISelectMap() reports FALSE to indicate that it intercepted // and used the call for it's own purposes. If the GUI is not in use, GUISelectMap() // returns TRUE and the Fire() function makes the call to Super.Fire() // Try to start a vote with the currently selected map simulated function bool GUISelectMap(optional string param2) { if ( bDisplayMapChooser ) { MapVote(VoteLines[pos].Num, param2); return false; } return true; } // Scroll up one position simulated exec function bool ScrollUp() { if ( bDisplayMapChooser ) { if ( pos > 0) pos--; if ( pos < start ) start = pos; return false; } return true; } // Scroll down one position simulated exec function bool ScrollDown() { if ( bDisplayMapChooser ) { if ( pos < total - 1) pos++; if ( pos >= start + VoteGUINumRows) start++; return false; } return true; } //----------------------------------------------------------------------------- // Intercept calls to Fire() so that the we can use them to control the GUI exec function Fire( optional float F ) { if (GUISelectMap()) Super.Fire(F); } // Intercept calls to AltFire() so that the we can use them to control the GUI exec function AltFire( optional float F ) { if (GUISelectMap("next")) Super.AltFire(F); } // Intercept calls to PrevWeapon() so that the we can use them to control the GUI exec function PrevWeapon() { if (ScrollUp()) Super.PrevWeapon(); } // Intercept calls to NextWeapon() so that the we can use them to control the GUI exec function NextWeapon() { if (ScrollDown()) Super.NextWeapon(); } //----------------------------------------------------------------------------- // Some states set the functions we need to control the GUI (Fire, AltFire, // PrevWeapon and NextWeapon) to ignore and/or over-ride them with functions which // perform special operations (such as locking into a deploy). We want to intercept // calls to these functions in all states in which they are implemented so that // the MapVote GUI works regardless of what state the player is actually in. state Dead { ignores SeeEnemy, HearNoise, KilledBy, SwitchWeapon; exec function PrevWeapon() { ScrollUp(); } exec function NextWeapon() { ScrollDown(); } } auto state PlayerWaiting { ignores SeeEnemy, HearNoise, NotifyBump, TakeDamage, PhysicsVolumeChange, SwitchToBestWeapon; exec function Fire( optional float F ) { if (GUISelectMap()) Super.Fire(F); } exec function AltFire( optional float F ) { if (GUISelectMap("next")) Super.AltFire(F); } exec function PrevWeapon() { ScrollUp(); } exec function NextWeapon() { ScrollDown(); } } state Wounded { ignores SeeEnemy, HearNoise, KilledBy, SwitchWeapon; exec function Fire( optional float F ) { if (GUISelectMap()) Super.Fire(F); } exec function AltFire( optional float F ) { if (GUISelectMap("next")) Super.AltFire(F); } exec function PrevWeapon() { ScrollUp(); } exec function NextWeapon() { ScrollDown(); } } state WaitingToDeploy { ignores SeeEnemy, HearNoise, KilledBy, SwitchWeapon; event BeginState() { SpawnHUDPlugin(); Super.BeginState(); } exec function Fire( optional float F ) { if (GUISelectMap()) Super.Fire(F); } exec function AltFire( optional float F ) { if (GUISelectMap("next")) Super.AltFire(F); } exec function PrevWeapon() { ScrollUp(); } exec function NextWeapon() { ScrollDown(); } } state PlayerDriving { exec function Fire( optional float F ) { if (GUISelectMap()) Super.Fire(F); } exec function AltFire( optional float F ) { if (GUISelectMap("next")) Super.AltFire(F); } } state PlayerTurreting { exec function Fire( optional float F ) { if (GUISelectMap()) Super.Fire(F); } exec function AltFire( optional float F ) { if (GUISelectMap("next")) Super.AltFire(F); } } state GameEnded { exec function Fire( optional float F ) { if (GUISelectMap()) Super.Fire(F); } exec function AltFire( optional float F ) { if (GUISelectMap("next")) Super.AltFire(F); } } //----------------------------------------------------------------------------- // Returns the localized "vote failed because a map is queued" message with the map name inserted function string QueuedMapMessage() { local string msg; MyGRI = MapVoteGameReplicationInfo(GameReplicationInfo); msg = QueuedMapMsg; ReplaceText(msg, "$1", MyGRI.QueuedMap); return msg; } //----------------------------------------------------------------------------- // Returns the localized "vote failed because map is alread queued" message with the map name inserted function string AlreadyQueuedMessage() { local string msg; msg = AlreadyQueuedMsg; ReplaceText(msg, "$1", next); return msg; } Sa//=============================================================================// // Map Vote Mutator v0.4.2 Copyright(C) 2005 Adam Mummery-Smith B.S.E. // //=============================================================================// class ExtendedMapList extends MapListXMP config; //=============================================================================// // Class: ExtendedMapList | Date: December 2005 // //-----------------------------------------------------------------------------// // Project: Map Vote Mutator | Author: Adam Mummery-Smith // //-----------------------------------------------------------------------------// // Description: In order for the "vote for next map" functionality to work, // // we need to intercept calls to retrieve the next map in // // rotation. This class steps in to do that. It also gives us a // // handy place to keep the pre-defined map list. // //-----------------------------------------------------------------------------// // Usage: N/A // //-----------------------------------------------------------------------------// // Note: Bug fixed: now keeps this class' maplist in line with the // // superclass'. // //=============================================================================// //----------------------------------------------------------------------------- // Declarations var config string VoteableMaps[10]; // The list of pre-defined maps //----------------------------------------------------------------------------- // We intercept calls to GetNextMap so that if a map is queued we can return that instead function string GetNextMap() { local string NextMap; // Synchronise our maplist with the superclass!!! SyncInheritedMapList(); // If a map is queued, get that instead if (Level? && Level.Game? && Level.Game.GameReplicationInfo? && MapVoteGameReplicationInfo(Level.Game.GameReplicationInfo)?) { NextMap = MapVoteGameReplicationInfo(Level.Game.GameReplicationInfo).QueuedMap; } // Otherwise, return the next map in rotation if (NextMap == "") NextMap = Super.GetNextMap(); return NextMap; } //----------------------------------------------------------------------------- // Returns an array containing the pre-defined maps (if any) set by the admin static function GetPredefinedMapList(out string Maps[10]) { local int i; for (i = 0; i < 10; i++) Maps[i] = default.VoteableMaps[i]; } //----------------------------------------------------------------------------- // Returns the pre-defined map at a specific location static function string GetPredefinedMapAtIndex(int MapNumber) { return default.VoteableMaps[MapNumber]; } //----------------------------------------------------------------------------- // Returns the next map without incrementing the counter function string PredictNextMap() { local string CurrentMap; local int i, NextMapNum; // Synchronise our maplist with the superclass!!! SyncInheritedMapList(); if (Level? && Level.Game? && Level.Game.GameReplicationInfo? && MapVoteGameReplicationInfo(Level.Game.GameReplicationInfo)? && MapVoteGameReplicationInfo(Level.Game.GameReplicationInfo).QueuedMap != "") { return MapVoteGameReplicationInfo(Level.Game.GameReplicationInfo).QueuedMap; } // Fixes an array access out of bound error if the maplist is empty if ( Maps.Length < 1) return ""; NextMapNum = MapNum; CurrentMap = GetURLMap(); if ( CurrentMap != "" ) { if ( Right(CurrentMap,4) ~= ".unr" ) CurrentMap = CurrentMap; else CurrentMap = CurrentMap$".unr"; for ( i=0; i Maps.Length - 1 ) NextMapNum = 0; if ( Maps[NextMapNum] == "" ) NextMapNum = 0; return Maps[NextMapNum]; } //----------------------------------------------------------------------------- // Had to add this function after it turned out that because lots of classes use // GameType.default.MapListType (including the WebAdmin), maplist was being updated in the // superclass but not here. This clears the 'local', inherited maplist and syncs it with // the parent classes maplist. function SyncInheritedMapList() { local class GameClass; local class MapListClass; local int i; GameClass = class(DynamicLoadObject("U2.XMPGame", class'Class')); MapListClass = class(DynamicLoadObject(GameClass.default.MapListType, class'Class')); Maps.Remove(0,Maps.Length); for (i = 0; i < MapListClass.Default.Maps.length; i++) Maps[i] = MapListClass.Default.Maps[i]; MapListClass.Default.MapNum = MapNum; SaveConfig(); } //----------------------------------------------------------------------------- // Used by the admin maplist compiler to get a list of all the maps on the server. // Doesn't have to be here but might as well be. This was adapted from a function in // the WebAdmin that compiles the "exclude" maplist. function GetAllMaps(out arrayAllMaps, String GameType) { local class GameClass; local string FirstMap, NextMap, TestMap; local string TempItem; GameClass = class(DynamicLoadObject(GameType, class'Class')); if(GameClass.Default.MapPrefix == "") return; FirstMap = Level.GetMapName(GameClass.Default.MapPrefix, "", 0); NextMap = FirstMap; while (!(FirstMap ~= TestMap) && FirstMap != "") { if(!(Left(NextMap, Len(NextMap) - 4) ~= (GameClass.Default.MapPrefix$"-tutorial"))) { TempItem = NextMap; if(Right(NextMap, 4) ~= ".unr") TempItem = Left(NextMap, Len(NextMap) - 4); else TempItem = NextMap; AllMaps[AllMaps.Length] = TempItem; } NextMap = Level.GetMapName(GameClass.Default.MapPrefix, NextMap, 1); TestMap = NextMap; } } wMN BdN NEWSTACKNBdN EFPBdP SIMPLEIFPPPPPBdP OPEREFP-PBdP OPEREFP6PBdP" OPEREFP;P.BdPa OPEREFPBP{.BdP OPEREFPBdR RETURN.BdRPREVSTACKBdVXSIMPLEIF!V7&BdVjOPEREFPBdVrRETURNBdVuPREVSTACKBdXLETBdZLET Zb#BdZEFPBd[SIMPLEIFc[{ Bd[OPEREFPBd]SIMPLEIF]|] ,Bd]EFP.unrBd]OPEREFPBd^LET `YBd`<LET `p .unrBd`<OPEREFPBdbHFORINIT;%BdbMFOREVALcb;7Bdb[OPEREFPBddnSIMPLEIF-d| ;BddOPEREFPBdfLET;BdgBREAKFORgcBdb\FORINCb;Bdb`OPEREFPulBdlOPEREFPBdnSIMPLEIFnn7&BdnOPEREFPBdnOPEREFPBdo LET%BdpSIMPLEIFKpzBdp*OPEREFPBdq=LET%BdsIRETURNBdsZPREVSTACKBdt^RETURNNOTHING Bdt^PREVSTACKA.d"Bdd"NEWSTACKBdf"SIMPLEIF8Bdx"OPEREFPBd"LET%Bd"LET$Bd"LET18#,voteyesBd"EFPBd"FORINIT%Bd"FOREVAL 71Bd"OPEREFPBd #SIMPLEIF{%Bd#OPEREFPBd;#LET%p%/Bd;#OPEREFPBd f#LET% p%1Bd f#OPEREFPBd"FORINCBd#OPEREFPBd #LET18" ,votenoBd #EFPBd #FORINIT%Bd #FOREVAL 71Bd #OPEREFPBd#SIMPLEIF{$Bd#OPEREFPBd$LET$p$/Bd$OPEREFPBd+$LET$p$1Bd+$OPEREFPBd #FORINC Bd #OPEREFPhBd8$RETURNNOTHING Bd8$PREVSTACK[//============================================================================= // CheatMessage. //============================================================================= class CheatMessage extends GameMessage; var(CheatMessage) Color DrawColor; var(CheatMessage) int Lifetime; var(CheatMessage) sound MessageSound; var(CheatMessage) string WarningColorStr; static function string GetString( optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ) { return RelatedPRI_1.playername $ default.WarningColorStr $ " was using Fire Rate hack!!! (Auto message " $ string(Switch) $ ")"; } static function float GetLifeTime(int Switch) { return default.LifeTime; } static function sound GetMessageSound( int Switch, PlayerReplicationInfo RelatedPRI_1, PlayerReplicationInfo RelatedPRI_2, Object OptionalObject ) { return default.MessageSound; } G(!>%Bd>%NEWSTACKBdY%LET-Z(Bd e%FORINIT,%Bd k%FOREVAL , }(Bd v%EFPBd v%OPEREFPBd"%SIMPLEIF"|"(,,Bd"%EFP^#Bd"%OPEREFPBd$%LET($p$(,Bd$%EFP$($$$}(Bd$%EFP,Bd$%OPEREFP,Bd$%OPEREFPBd$%EFPBd$%OPEREFPBd%%LET-Z'Bd w%FORINC ,Bd {%OPEREFPK))-ZBd)&OPEREFPBd+&RETURN(Bd+&PREVSTACKBd,"&RETURNNOTHING Bd,"&PREVSTACK vsEj+1Bdj+1NEWSTACK j3'Bdjk1EFPBdm1FORINIT%Bdm1FOREVALm, Bdm1OPEREFPnB'Bdn1EFPBdm1FORINCmBdm1OPEREFPZBdp:2LETspU2.XMPGame Bdp92EFPBdq2LETqs Bdq2EFPs=============================================================================Bds3EFPt LISTING AVAILABLE MAPS Bdtg3EFPu=============================================================================Bdu3EFPv Pre-defined map choicesBdv3EFPw-----------------------------------------------------------------------------Bdwb4EFPBdym4FORINIT%Bdys4FOREVALy, Bdyz4OPEREFPBd{4SIMPLEIF {, Bd{4OPEREFPBd{4LET+ {*Bd{4LET+ Bd}4SIMPLEIF-}{'Bd}4OPEREFPppp+9S&Bd4OPEREFPBd4OPEREFP: Bd5OPEREFP'Bd5OPEREFPBd5EFPHBd5OPEREFPIBd35BREAKFORBdy{4FORINCyBdy4OPEREFPxBd?5SIMPLEIF!H%BdG5OPEREFP --- sorry, no pre-defined maps available --- Bd5EFP=============================================================================Bd6EFP Maps in server rotationBd?6EFP-----------------------------------------------------------------------------Bd6EFPBd6SIMPLEIFt w*Bd6OPEREFPBd6LETi7A%7@BdL7EFPBdX7FORINIT%Bd^7FOREVALt 7Bd7OPEREFP1{Bd7OPEREFPBd7SIMPLEIFBd7OPEREFPBd7LET+ Bd7SIMPLEIF,YBd7OPEREFPBd7LET+ ppp+9S, Bd;8OPEREFPBd=8OPEREFP: BdD8OPEREFPBdb8OPEREFPBdc8EFPBd8LET7$7&Bd9OPEREFPBd39EFPHBd<9OPEREFPBd7FORINCBd7OPEREFPBd9LETF.11Bd9EFPBd9SIMPLEIFO FBd9OPEREFPBd9LET!FBd9EFPo Bd-:LET!unknown-----------------------------------------------------------------------------Bd:EFPppp 9SHBd:OPEREFP map(s) available. Next map is Bd:OPEREFP!Bd:OPEREFPBd:EFP To initiate a map vote, use MAPVOTE Bd&;EFP=============================================================================Bd;EFPBd;SIMPLEIF-F+4DU2.XMPGameBd5<EFPBdA<FORINIT%BdG<FOREVAL7DBdZ<OPEREFPBd<LET7D$7&Bd<OPEREFPp_DBd<OPEREFPBd<EFPBd[<FORINCBd_<OPEREFP *Bd9=EFPCBdz=EFPBd~=RETURNNOTHING Bd~=PREVSTACKB,@_://============================================================================= // CheaterPRI. //============================================================================= class CheaterPRI extends PlayerReplicationInfo; var bool bTestPerformed; var bool bServerInit; var(DefaultGameMutator) int WasCheating; var(DefaultGameMutator) ENetRole RemoteRole; var(DefaultGameMutator) bool bAlwaysRelevant; var int MaxTick,TickCount; replication { reliable if(Role Message,int Sw) { local Controller C; local PlayerReplicationInfo PRI; if (Role==ROLE_Authority) { for( C=Level.ControllerList;C!=None;C=C.NextController ) { PRI = C.PlayerReplicationInfo; if( (PRI != None) && !PRI.bBot && MessagingSpectator(C)== None) { if ((Me.PlayerReplicationInfo.PlayerID!=C.PlayerReplicationInfo.PlayerID) && (C.IsA('PlayerController'))) { Level.Game.Broadcasthandler.BroadcastLocalized(Me, PlayerController(C), Message, Sw, Me.PlayerReplicationInfo); } } } } } function ServerPlayerCheats(PlayerController C,int Sw) { BroadcastToAllExceptMe(C,class'CheatMessage',Sw); } simulated function bool CheckWeapon(class WeaponClass,float DefPrimary,float DefSecondary) { local bool a,b; a=False; b=False; if (WeaponClass.default.FireTime[0]!=DefPrimary) { WeaponClass.default.FireTime[0]=DefPrimary; //log("----- Primary Haxor!!! " $ String(WeaponClass)); //NotifyMeCheating("<< " $ String(WeaponClass) $ " primary fire rate modified!"); a=True; } if (WeaponClass.default.FireTime[1]!=DefSecondary) { WeaponClass.default.FireTime[1]=DefSecondary; //log("----- Secondary Haxor!!! " $ String(WeaponClass)); //NotifyMeCheating("<< " $ String(WeaponClass) $ " secondary fire rate modified!"); b=True; } return a || b; } /*simulated function NotifyMeCheating(string Msg) { Level.GetLocalPlayerController().Say(Chr(12) $ "" $ Msg); }*/ simulated function PerformCheatingTest() { local bool cheat; if (!bTestPerformed) { //log("--------- Performing Cheating Test ----------"); cheat=False; cheat=CheckWeapon(class'AssaultRifle', 0.1, 1.0) || cheat; cheat=CheckWeapon(class'EnergyRifle', 0.3, 2.0) || cheat; cheat=CheckWeapon(class'Flamethrower', 0.1, 0.1) || cheat; cheat=CheckWeapon(class'Pistol', 0.6, 1.1) || cheat; cheat=CheckWeapon(class'RocketLauncherEx', 1.08, 1.08) || cheat; cheat=CheckWeapon(class'RocketLauncher', 1.08, 1.08) || cheat; cheat=CheckWeapon(class'Shotgun', 0.93, 1.18) || cheat; cheat=CheckWeapon(class'SniperRifle', 1.0, 0.0) || cheat; cheat=CheckWeapon(class'WeaponAutoTurret', 0.1, 1.0) || cheat; cheat=CheckWeapon(class'WeaponRocketTurret',1.08, 1.08) || cheat; cheat=CheckWeapon(class'GrenadeLauncher', 1.33, 1.33) || cheat; cheat=CheckWeapon(class'GrenadeLauncherHeavy', 1.33, 1.33) || cheat; cheat=CheckWeapon(class'GrenadeLauncherLight', 1.33, 1.33) || cheat; cheat=CheckWeapon(class'GrenadeLauncherMedium', 1.33, 1.33) || cheat; if (cheat) { WasCheating=15; } bTestPerformed=True; MaxTick=500; TickCount=100; } else { if (WasCheating>0) { TickCount++; if (TickCount>MaxTick) { //NotifyMeCheating(PlayerName $ " WAS USING FIRE RATE HACK (Auto message " $ String(WasCheating) $ ")"); TickCount=0; WasCheating--; ServerPlayerCheats(Level.GetLocalPlayerController(),WasCheating); } } } } simulated function Tick(float DeltaTime) { if (Role < ROLE_Authority) //Client { PerformCheatingTest(); } super.Tick(DeltaTime); } @ t t sO sP sL sU sS sf ss s_ su sT sa t+ s\ sQ sg \F sR s^ PH tD sJ s] \\ ZY sU PW S tu Uv s[ s[ s] QK sV jq \Q \u P_ Qt sQ Q| sI sZ P_ _r \R PT Tg \Q P` Qm Qj Za sj s\ sI Tf Qg _q T} _s s^ ]G sv \l __ [Q P Qf PW \[ sF jo ]^ P sZ P P P P P P P P ^i P P sS P P P PL P PK P PL sC P [e sh PO PZ PJ PE P{ tz [V _~ t} ]@ ]R PN _T SR ]W _U Pw ^] P s} \v ^c ]S Pl P[ PG vI Pz PO ^h Pf td sH sU vze vrY sM tj Qg tX TP ^w \t Pk Pk ^p P P sX \X ^S P P MT P P PM P P Pb ttk C]l \V sv sm sn so ss st sp sq sr sw sx sy jA s| s{ \@ Pq t sIEz ]\k j\JF v\dTC]Az Wb@dbwrbF AcAF McS ZcF fcO rcX~ceLda Kvv XvcG evbl5c zQ G} T{ `%z lhpyZ il uzAJbOGF ^R jFr wF` CyO{ ]d jg wf DK Pm ]I` iVvE DJN QIF ]P j6nv{J D6D Pe\5xj0F y:F E%BQY _F kd xKEF SFF _skYyC G^` S5b `-c l%l x5~ EJuQj `JN mAzJC I^b V<F b:bn2n |bHi Vo bAC o{ |AD Ii Vo by oD {}Hc WN cIO pd|| Jc WrScxvAgEi Sh `:xmD |W I6\ U5ubL q\ }D J\ Vx c5c op |m IX U^a a^] nJx{P Ix UQ b%j o%k {ZG]Uc\wHE^S@aipT ~G JIV~ dG qU }G J2m V G cG oG {G GG SG _G kG wG CG OG [{ g"tR IX U a n2n{{ I2CV0Y dFpPy O5| \e hh tE Ap N7p [N hztJz Be NN Z g9MsN A N9V Z G gLs^-^B ]Du jC~vBDt^Dx$C|@oAC7n^LUq^)HFB NIL[=NZ gvA?kO>V z^'O P9K _^p k*Hx^W@^^ OJh[}CB @B L {XB S z_B Yre<zWxQB InUnCfEq fvM\gjG Q}^}[tDXbg\B CMPL_KnH}kgLrs#rexWB O}[}X|DU fYMgMG trA;ssxfB ^}j}gKDd fhMNg\G CKVPrf7kXxCB {}G}DmDAqELpvxf6r^jDP qT%WE x\M~TgERqWl}HxEH}5lKB w@D8NRB `Gm{ {IHJWB fGYr[K~ YB fzWr!~ IV/ dqg%qX2B Ww d!Ip!H~!GL!BZ{ChW}k-B y3FFgu LwCX6B [1e g4xsDRkVZ}=A4s"W(JEI7B N:iZ_qCOTtAVH?B ^Fh:jA4uRA4ncGA4SuA4^aH tf .~ Z A4fX !@ ~ ES7~ IB Q ^A4j:] FB G