From 0d4b230285f67777272e373ffbdb1dbd064b911a Mon Sep 17 00:00:00 2001 From: ChocoTaco Date: Sun, 27 Jan 2019 12:04:31 -0500 Subject: [PATCH] Added DM and DMSLOnlyMode --- Classic/evoClassicTaco.vl2 | Bin 67587 -> 67632 bytes Classic/scripts/DMGame.cs | 607 +++++++++++++++++++++++++++++++++++++ 2 files changed, 607 insertions(+) create mode 100644 Classic/scripts/DMGame.cs diff --git a/Classic/evoClassicTaco.vl2 b/Classic/evoClassicTaco.vl2 index 6c9257b9493e8cc729ff16005a889d8de371325f..22f278f8a650ffe22e77ef38810d44fb24f7fbd1 100644 GIT binary patch delta 4800 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 delta 4726 zcmY+IRag{U*M^y)yJ19zl$K`bRzW(4PLY%bX&Ab@h90`4QDO)whfqp71w&ih(av&pdpwM&M9(UgdR@i={(I)j0h0+!!- z%p|0}#X#J6K&Wb(_nmWQU`<3_Dp&w)lQ6{AEZl}!VR*CD)s_Bq$&&(iK%wLHGHcrF zLp`~}v9|YZC<+G4vyP=-rZtbNhVS-wIe%Q(HaGEY!G zx%&+z@qg~&d!_TmlQ!JGJ|_bk-M!ULGGarrOUjJRFXl=jl0YK`BwJ(+eK16EodH=9 zw)IFbyPpckj9!ULZH;ikEZx9+a{tlW4z!eqj!I)K6!;X&`Z1OwFYS|LHr>K*vvVFZD24XnJT{8UkZ!ArY0s=)neCxLEbtNx@3e%rdrPN?pHG4b5P zvkmiZwu<>SsEY-QKx*j(jW2dEZbhmsr}D_i^^}&5@>g~AJK8BZ5qv}4)>6uIigg*> zUf~AyuL;NNP8^-AkK+>%-uu1NCmt)^Dln{z4I|^QhldkU zSQ5@Gt6x6)?W3%ZTovrHG$l1wM3DMkjyt!u_n)1VUEvFhV$KzVhKr)6DjWPH(bx(W zx3)#C`FE3;=+3ZnY{am`Z}SMJO($n#+9KVP0;NE*-xDO&$#l6&0L0$&h)e|=hQZ=u zq#Awcz4)2Dh6LTz8jR_XDbY6Zy+4xU^S)*gt92q{S=+pO5@aP>~+$a`MqsEz-##VQ+swZhJw@V@hX0G%MPyibKj&>$+}H^ zlh5Zh;LlXpFjCAaN_b2JgGFIeBY+jq8DITbqH-k3wS&y}eX3yeh$OW!CUJuPpfY&AMl`cyh4tJL;028yLBQ46Zi%gzKe8@~+lf|Y)0)wkJ zofa%wCXiI-3cr0j+}{L{J1%~6P0g7}p2{4mzo%OS3yo0Zi%t1ayOBCO^EgNCmA-7U z96gvS-P1DQ=NZmH2Y!cRDh?mjXFx{D_8I#Ia9kPYXF5weI6?Pd9`>&8MLBXK{Q(~X zRDfHQ0I>c()?+qWDMxvUmKyIr@6@p*+db{##iuOI6tqBzoON~2HPs|&UvN6^N{r4T zQdBKr-P+RYMn_gzBe}NEs~M9?FTA!5M=vKF^yLfJhPCt7U$!&?IrtgLXFCYY3A3uc zGeW$597jxQT3bqE@BqV-!-4L!qpX#(<+uXXFi>yS3<>4S^bb11w!t=F*>^;L-r2%S ze!6hAu|@qUnzZZn8a#VmX)(gyA`LY}tK09vZaG!j+pqXpxx+QVRZlU;(n*C6K^Tno zuGJ&ov|KTr=JWzzr*k*3-Hrk3ms6f^@9XU7dr>rR^KZc$v)|(nNKJWA#r51@&b{4Tulx+EIV+7wr zp?V-vFQgy;cLWmsd{vCxuzS|fAr=GMpH|rw_HfLka!{KxXXZBX(*3wI*a)(XA0~DA z%I3z;6ce}6^7!6D^FcqaA>h`$Z(T>dta;-G>LXe_7eX=Mr4uRqXz<$Vg){8e-4gx! z=MC^c6I>G?MF`?5e#uL!DU5ZMikYlI!7)kZcw{8Nkv#um3Nh-)3P9cda{SI*l_Vj* zgmDqm-rQ|lMj62Kp2>~)`df|Xk_)I(Z9_tXRs%)^`D(tS4W-!`=#DLO1?kENJjqR~ z>!6Kc$1Qp!B*Wen;)xa*j)t*_b|*{N3xo;faE!1iMGG!RIe7_yfH?U;VlM9Wdh-P;sDx1v(ENh-zl_0)0u~SH>^7#a~t2T#B%2&`+LXhE>OQQ{w3AK-+Qd zIRxCsb*OaorH1rAO-(oXZV&wW@%%JR(IR~99k$5p%V)`uT^kyd^XSPFj%hyK{3Yfk z?`J8#JVawHRoT)=qiXrY{1`AYobf219^&*}5FddT{Nr-<@;lMs5T@q&Hr2V$d=_cZ zZMe-P@ylLV_tjd;Ev)fNyi$_Ov+;L>1}a&?qMZ5r@gEIND9w(eion{Ip2n^+|>wi8n!K*v#9#fh6E{D^@R9J7CV%L%rj#rl;w0$JoYrm)y5VTb- zJRDP!(t(e7iY%X~u)~vJ>Mm!1g+zpC6vkIn*6^u;`?wJg4lu*=pW1jzBsf87ma&l} zEuLUJY9|y*L5ohrvxESDCc9FsjJlqex^7!-w|UIvRaUM#bz0w5+T%$IN$=2aLf-Nc z@#x|=J8122lIk%QNlq6>?-A8q^vPz);GfayvQN?0S1o>v{ZQ72WU&utV;Bo=(@NY> z%d#wm%BOF&FWi^G zbV|7AK`b|J!aVckp+9we9lh@bqURZX&TG@0e+1w`$w?(Q;KTaDrFQH4P;c4o{ zDnfF`uKkXVURG%^g6P24`k6G*FOFqOd3m>ARd$q&5j;1+xqPgWSt>=`z zL=}=Govl5h6~+7bBVP?(m0;%UJWPq2Cfa#IO!8CNq0TGmE>6b0Jj?F=B8XF(R9jg) zt+uCxiV4!n*^xWMme)3PUDFDCwL{^svqiy_ZOjvjoXTy)(Ch_@v-&=PG}mls z5ay^$p7*I!e-X@^^w@R$KH-u1E6Gg=Rv;Kp4#Ufer}iSc(H3xECYAqPTZVhP9Y}ur z>d;HRIEf#{MAm(*2klHgr$vh;)diYBy;Bvi!*|H@u(aiGYeMt{-|I2 zX?+4G^w>L`+If3HLR*7*az`IbVl;ftcc7zu?>zY9_xiWDb!2%I>UmZ{k*-1a&nF&#t75X)vNVyajH^3MFtQ>ArhusOVwAU8DiYIvp1-AF>^hvk zAY*^1;m0c(dDVc;8i&sPVqSb>X%@(rTg0rMA}s(t$<$DNBkal>U}q~USc(RH;8 z0+@ccEi9g!tjyyI^qA(lonA_mo9G;Z7?d>3Com@}fp)$BftviS0$P=EmgNzhzk0&53)mUPpRaZ?rf13? zX82SPLp14}+-hXt1qPK(hr+y3a|*{Jf@(q`tdCqX)y^=`jhUkXJaM+kRWz>h0(w<^ z${dhvMOPfNk6XQKGA^t1q93bmVEAzTZ1LHG<={#<$x9yf+;Lo?IxZsp$L;4Y!EN94 zTmy}$Y<|vbjzvFf^AVDQiHLdAt#hxS9Iab=@;wt@+gFd)D9d5_x=PPQHH`({pWj@! zt{e`zdEA5w2+l%YTx*H@t5XuVd-6Jqy;1D{S=NU|5R70gWQZzJ#&P^(&`J}~zPiUd zh@s;Wg}oDj6A!ppe|ihz#B@AmVWt<@C$BO2G-FxF{N!rO=d6nW7OIt|d|@+-{c?v2 zT3op$m?Soi%D16&%S~!WiG(o2}_hvv?V65&Ik5T!Gl&FCiS z1@DL5N!Peq)jAcJ@N!F-291z%o2w@5Ey%->;b+c5#GIyR(@KtwbQt8vH)yD5ypdCT znO-R@JL#8(tC2NtImLKS8{uh?Nnt~GvAmR<)_7>8YldvHqU-dBxZ29vuuHm@IEJ-5 z-S?tO#I}R&;SkjfW%-!e_8BT28vs&?CZLB|OkTuW8>|I;?aA54`cmI+af->>H#}@w zmH{`!oe7|@ljd{D8Pz63;Md6TWKYxis(91%Rh}ov;8GHb^BD3bv3ivr+6k#W`?1#} zIl!s}5#}-x@zvA+L%5?^w!R`x)-%fErX=1`1aQW!LWT!Ed$gTDHu@oD!It*T>Rm6 zrO{@(D)Qn_IFs@&s847#0P z8XyAwzPRPKs+3~e2Qt>Z-u(TlH=0DL^m!k3R|FfZMXApkY^`#$Vs7w=NV#h*xG3J& z?}$UtKqUT+m7;%&rB?=`_g>qiuu)7p`U0mXUMX+kIE$(hci{^5<2D2Xecj z_tA;_o9pPB+)#4sN=)ZiPKxj~n@o3-Saas|5@9x!<}M6BhU`kTghagSdED}eZ5EHS3|W^ z*?tSu#F?@A3tQLI-BkG#e>WS;nXRA~d%$d!;%r?Y`TxHo8Fvp-G|UH2GW}X+0Rxi6 zQU6!7GyqS5B%B$5ZK|vkfC$i&??23#>Hipk2`~e$ z!v8Tj761y|$or2oWb#Si@mK(E;J4C$E?q_lpZn_oNH#V=3os1V#s;VW=Rd#!*Z^vH z6ZYTf4{iUZ{J{o@0bM%(u^JA*2-xxcFEhhYIDc=C!B24jo31 to listen to each other (team 0 can only listen to self) + for(%i = 1; %i < 32; %i++) + setSensorGroupListenMask(%i, 0xfffffffe); +} + +function DMGame::initGameVars(%game) +{ + %game.SCORE_PER_KILL = 1; + %game.SCORE_PER_DEATH = -1; + %game.SCORE_PER_SUICIDE = -1; +} + +exec("scripts/aiDeathMatch.cs"); + +function DMGame::allowsProtectedStatics(%game) +{ + return true; +} + +function DMGame::equip(%game, %player) +{ + for(%i =0; %i<$InventoryHudCount; %i++) + %player.client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); + %player.client.clearBackpackIcon(); + + if( $Host::DMSLOnlyMode ) + { + %player.clearInventory(); + %player.setInventory(EnergyPack, 1); + %player.setInventory(Shocklance, 1); + %player.setInventory(RepairKit, 1); + %player.setInventory(TargetingLaser, 1); + %player.use("Shocklance"); + } + else + { + buyDeployableFavorites(%player.client); + %player.setEnergyLevel(%player.getDataBlock().maxEnergy); + %player.selectWeaponSlot( 0 ); + + // do we want to give players a disc launcher instead? GJL: Yes we do! + %player.use("Disc"); + } +} + +function DMGame::pickPlayerSpawn(%game, %client, %respawn) +{ + // all spawns come from team 1 + return %game.pickTeamSpawn(1); +} + +function DMGame::clientJoinTeam( %game, %client, %team, %respawn ) +{ + %game.assignClientTeam( %client ); + + // Spawn the player: + %game.spawnPlayer( %client, %respawn ); +} + +function DMGame::assignClientTeam(%game, %client) +{ + for(%i = 1; %i < 32; %i++) + $DMTeamArray[%i] = false; + + %maxSensorGroup = 0; + %count = ClientGroup.getCount(); + for(%i = 0; %i < %count; %i++) + { + %cl = ClientGroup.getObject(%i); + if(%cl != %client) + { + $DMTeamArray[%cl.team] = true; + if (%cl.team > %maxSensorGroup) + %maxSensorGroup = %cl.team; + } + } + + //now loop through the team array, looking for an empty team + for(%i = 1; %i < 32; %i++) + { + if (! $DMTeamArray[%i]) + { + %client.team = %i; + if (%client.team > %maxSensorGroup) + %maxSensorGroup = %client.team; + break; + } + } + + // set player's skin pref here + setTargetSkin(%client.target, %client.skin); + + // Let everybody know you are no longer an observer: + messageAll( 'MsgClientJoinTeam', '\c1%1 has joined the fray.', %client.name, "", %client, 1 ); + updateCanListenState( %client ); + + //now set the max number of sensor groups... + setSensorGroupCount(%maxSensorGroup + 1); +} + +function DMGame::clientMissionDropReady(%game, %client) +{ + messageClient(%client, 'MsgClientReady',"", %game.class); + messageClient(%client, 'MsgYourScoreIs', "", 0); + messageClient(%client, 'MsgDMPlayerDies', "", 0); + messageClient(%client, 'MsgDMKill', "", 0); + %game.resetScore(%client); + + messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); + + DefaultGame::clientMissionDropReady(%game, %client); +} + +function DMGame::AIHasJoined(%game, %client) +{ + //let everyone know the player has joined the game + //messageAllExcept(%client, -1, 'MsgClientJoinTeam', '%1 has joined the fray.', %client.name, "", %client, 1 ); +} + +function DMGame::checkScoreLimit(%game, %client) +{ + //there's no score limit in DM +} + +function DMGame::createPlayer(%game, %client, %spawnLoc, %respawn) +{ + DefaultGame::createPlayer(%game, %client, %spawnLoc, %respawn); + %client.setSensorGroup(%client.team); +} + +function DMGame::resetScore(%game, %client) +{ + %client.deaths = 0; + %client.kills = 0; + %client.score = 0; + %client.efficiency = 0.0; + %client.suicides = 0; +} + +function DMGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLoc) +{ + cancel(%clVictim.player.alertThread); + DefaultGame::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLoc); +} + +function DMGame::updateKillScores(%game, %clVictim, %clKiller, %damageType, %implement) +{ + if (%game.testKill(%clVictim, %clKiller)) //verify victim was an enemy + { + %game.awardScoreKill(%clKiller); + messageClient(%clKiller, 'MsgDMKill', "", %clKiller.kills); + %game.awardScoreDeath(%clVictim); + } + else if (%game.testSuicide(%clVictim, %clKiller, %damageType)) //otherwise test for suicide + %game.awardScoreSuicide(%clVictim); + + messageClient(%clVictim, 'MsgDMPlayerDies', "", %clVictim.deaths + %clVictim.suicides); +} + +function DMGame::recalcScore(%game, %client) +{ + %killValue = %client.kills * %game.SCORE_PER_KILL; + %deathValue = %client.deaths * %game.SCORE_PER_DEATH; + %suicideValue = %client.suicides * %game.SCORE_PER_SUICIDE; + + if (%killValue - %deathValue == 0) + %client.efficiency = %suicideValue; + else + %client.efficiency = ((%killValue * %killValue) / (%killValue - %deathValue)) + %suicideValue; + + %client.score = mFloatLength(%client.efficiency, 1); + messageClient(%client, 'MsgYourScoreIs', "", %client.score); + %game.recalcTeamRanks(%client); + %game.checkScoreLimit(%client); +} + +function DMGame::timeLimitReached(%game) +{ + logEcho("game over (timelimit)"); + %game.gameOver(); + cycleMissions(); +} + +function DMGame::scoreLimitReached(%game) +{ + logEcho("game over (scorelimit)"); + %game.gameOver(); + cycleMissions(); +} + +function DMGame::gameOver(%game) +{ + //call the default + DefaultGame::gameOver(%game); + + messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.gameover.wav" ); + + cancel(%game.timeThread); + messageAll('MsgClearObjHud', ""); + for(%i = 0; %i < ClientGroup.getCount(); %i ++) { + %client = ClientGroup.getObject(%i); + %game.resetScore(%client); + } +} + +function DMGame::enterMissionArea(%game, %playerData, %player) +{ + %player.client.outOfBounds = false; + messageClient(%player.client, 'EnterMissionArea', '\c1You are back in the mission area.'); + logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") entered mission area"); + cancel(%player.alertThread); +} + +// borlak -- TAKEN FROM TR2 -- thanks! :D +function plzBounceOffGrid(%obj, %bounceForce, %count) +{ + %bounds = MissionArea.area; + %boundsWest = firstWord(%bounds); + %boundsNorth = getWord(%bounds, 1); + %boundsEast = %boundsWest + getWord(%bounds, 2); + %boundsSouth = %boundsNorth + getWord(%bounds, 3); + + %shapePos = %obj.getPosition(); + %shapex = firstWord(%shapePos); + %shapey = getWord(%shapePos, 1); + + if( %shapex >= %boundsWest && %shapex <= %boundsEast && %shapey >= %boundsNorth && %shapey <= %boundsSouth) { + // we don't need to bounce at all + return; + } + + if( %count == 8 ) { + // just kill this retard + %obj.scriptKill($DamageType::OutOfBounds); + return; + } + + if (%bounceForce $= "") + %bounceForce = 65; + + %oldVel = %obj.getVelocity(); + %obj.setVelocity("0 0 0"); + + %vecx = firstWord(%oldVel); + %vecy = getWord(%oldVel, 1); + %vecz = getWord(%oldVel, 2); + + // four cases, not two cases you fucktard kineticpoet + // no wonder the trives of vengrances failed + if(%shapex <= %boundsWest) { + %vecx = mAbs(%vecx); + } + else if(%shapex >= %boundsEast) { + %vecx = -mAbs(%vecx); + } + + if(%shapey <= %boundsNorth) { + %vecy = mAbs(%vecy); + } + else if(%shapey >= %boundsSouth) { + %vecy = -mAbs(%vecy); + } + + %vec = %vecx SPC %vecy SPC %vecz; + + // If the object's speed was pretty slow, give it a boost + %oldSpeed = VectorLen(%oldVel); + if (%oldSpeed < 25) + { + %vec = VectorNormalize(%vec); + %vec = VectorScale(%vec, 25); + } + else + %vec = VectorScale(%vec, 1.15); + + // apply the impulse to the object + //%obj.applyImpulse(%obj.getWorldBoxCenter(), %vec); + %obj.setVelocity(%vec); + + // repeat this bounce 4 times per second. if we're oob for 2 seconds, take action + // don't do this with the flag because that has its own thread + if( %obj.dataBlock !$= "Flag" ) { + schedule(250, 0, plzBounceOffGrid, %obj, %bounceForce, %count + 1); + } +} +function isOutOfBounds(%position) +{ + %shapePos = %position; + %shapex = firstWord(%shapePos); + %shapey = getWord(%shapePos, 1); + %bounds = MissionArea.area; + %boundsWest = firstWord(%bounds); + %boundsNorth = getWord(%bounds, 1); + %boundsEast = %boundsWest + getWord(%bounds, 2); + %boundsSouth = %boundsNorth + getWord(%bounds, 3); + + return (%shapex < %boundsWest || %shapex > %boundsEast || + %shapey < %boundsNorth || %shapey > %boundsSouth); +} + +function DMGame::leaveMissionArea(%game, %playerData, %player) +{ + if(%player.getState() $= "Dead") + return; + + plzBounceOffGrid(%player, 65); +} + +function DMGame::DMAlertPlayer(%game, %count, %player) +{ + // MES - I commented below line out because it prints a blank line to chat window + //messageClient(%player.client, 'MsgDMLeftMisAreaWarn', '~wfx/misc/red_alert.wav'); + if(%count > 1) + %player.alertThread = %game.schedule(1000, "DMAlertPlayer", %count - 1, %player); + else + %player.alertThread = %game.schedule(1000, "MissionAreaDamage", %player); +} + +function DMGame::MissionAreaDamage(%game, %player) +{ + if(%player.getState() !$= "Dead") { + %player.setDamageFlash(0.1); + %prevHurt = %player.getDamageLevel(); + %player.setDamageLevel(%prevHurt + 0.05); + %player.alertThread = %game.schedule(1000, "MissionAreaDamage", %player); + } + else + %game.onClientKilled(%player.client, 0, $DamageType::OutOfBounds); +} + +function DMGame::updateScoreHud(%game, %client, %tag) +{ + // Clear the header: + messageClient( %client, 'SetScoreHudHeader', "", "" ); + + // Send the subheader: + messageClient(%client, 'SetScoreHudSubheader', "", '\tPLAYER\tRATING\tKILLS\tDEATHS'); + + for (%index = 0; %index < $TeamRank[0, count]; %index++) + { + //get the client info + %cl = $TeamRank[0, %index]; + + //get the score + %clScore = mFloatLength( %cl.efficiency, 1 ); + + %clKills = mFloatLength( %cl.kills, 0 ); + %clDeaths = mFloatLength( %cl.deaths + %cl.suicides, 0 ); + %clStyle = %cl == %client ? "" : ""; + + //if the client is not an observer, send the message + if (%client.team != 0) + { + messageClient( %client, 'SetLineHud', "", %tag, %index, '%5\t%1%2%3%4', + %cl.name, %clScore, %clKills, %clDeaths, %clStyle ); + } + //else for observers, create an anchor around the player name so they can be observed + else + { + messageClient( %client, 'SetLineHud', "", %tag, %index, '%5\t%1%2%3%4', + %cl.name, %clScore, %clKills, %clDeaths, %clStyle, %cl ); + } + } + + // Tack on the list of observers: + %observerCount = 0; + for (%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + if (%cl.team == 0) + %observerCount++; + } + + if (%observerCount > 0) + { + messageClient( %client, 'SetLineHud', "", %tag, %index, ""); + %index++; + messageClient(%client, 'SetLineHud', "", %tag, %index, '\tOBSERVERS (%1)TIME', %observerCount); + %index++; + for (%i = 0; %i < ClientGroup.getCount(); %i++) + { + %cl = ClientGroup.getObject(%i); + //if this is an observer + if (%cl.team == 0) + { + %obsTime = getSimTime() - %cl.observerStartTime; + %obsTimeStr = %game.formatTime(%obsTime, false); + messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%1%2', + %cl.name, %obsTimeStr ); + %index++; + } + } + } + + //clear the rest of Hud so we don't get old lines hanging around... + messageClient( %client, 'ClearHud', "", %tag, %index ); +} + +//function DMGame::applyConcussion(%game, %player) +//{ +//} + +package DMGame +{ + +function deployMineCheck(%mineObj, %player) +{ + // explode it vgc + schedule(2000, %mineObj, "explodeMine", %mineObj, true); +} + +}; + +function DMGame::sendGameVoteMenu(%game, %client, %key) +{ + parent::sendGameVoteMenu( %game, %client, %key ); + + %isAdmin = ( %client.isAdmin || %client.isSuperAdmin ); + + if ( %game.scheduleVote $= "" ) + { + if(!%client.isAdmin) + { + if(!$Host::DMSLOnlyMode) + messageClient( %client, 'MsgVoteItem', "", %key, 'DMSLOnlyMode', 'vote to enable Shocklance Only Mode', 'Vote to enable Shocklance Only Mode' ); + else + messageClient( %client, 'MsgVoteItem', "", %key, 'DMSLOnlyMode', 'vote to disable Shocklance Only Mode', 'Vote to disable Shocklance Only Mode' ); + } + else if (%client.ForceVote > 0) + { + if(!$Host::DMSLOnlyMode) + messageClient( %client, 'MsgVoteItem', "", %key, 'DMSLOnlyMode', 'vote to enable Shocklance Only Mode', 'Vote to enable Shocklance Only Mode' ); + else + messageClient( %client, 'MsgVoteItem', "", %key, 'DMSLOnlyMode', 'vote to disable Shocklance Only Mode', 'Vote to disable Shocklance Only Mode' ); + } + else + { + if(!$Host::DMSLOnlyMode) + messageClient( %client, 'MsgVoteItem', "", %key, 'DMSLOnlyMode', 'change to enable Shocklance Only Mode', 'Enable Shocklance Only Mode' ); + else + messageClient( %client, 'MsgVoteItem', "", %key, 'DMSLOnlyMode', 'change to disable Shocklance Only Mode', 'Disable Shocklance Only Mode' ); + } + } +} + +function DMGame::evalVote(%game, %typeName, %admin, %arg1, %arg2, %arg3, %arg4) +{ + switch$ (%typeName) + { + case "DMSLOnlyMode": + %game.DMSLOnlyMode(%admin, %arg1, %arg2, %arg3, %arg4); + } + + parent::evalVote(%game, %typeName, %admin, %arg1, %arg2, %arg3, %arg4); +} + +//--------------------------------DMSLOnlyMode-------------------------------- +// +$VoteMessage["DMSLOnlyMode"] = "turn"; + +function DMGame::DMSLOnlyMode(%game, %admin, %arg1, %arg2, %arg3, %arg4) +{ + if( $countdownStarted && $MatchStarted ) + { + if(%admin) + { + killeveryone(); + + if(%game.DMSLOnlyMode) + { + messageAll('MsgAdminForce', '\c2The Admin has disabled Shocklance Only Mode.'); + + %game.DMSLOnlyMode = false; + } + else + { + messageAll('MsgAdminForce', '\c2The Admin has enabled Shocklance Only Mode.'); + + %game.DMSLOnlyMode = true; + } + } + else + { + %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst; + if(%totalVotes > 0 && (%game.totalVotesFor / ClientGroup.getCount()) > ($Host::VotePasspercent / 100)) + { + killeveryone(); + + if(%game.DMSLOnlyMode) + { + messageAll('MsgVotePassed', '\c2Shocklance Only Mode Disabled.'); + + %game.DMSLOnlyMode = false; + } + else + { + messageAll('MsgVotePassed', '\c2Shocklance Only Mode Enabled.'); + + %game.DMSLOnlyMode = true; + } + } + else + messageAll('MsgVoteFailed', '\c2Mode change did not pass: %1 percent.', mFloor(%game.totalVotesFor/ClientGroup.getCount() * 100)); + } + + $Host::DMSLOnlyMode = %game.DMSLOnlyMode; + } +} +// For voting to work properly - evo admin.ovl +// +// case "DMSLOnlyMode": +// if( %isAdmin && !%client.ForceVote ) +// { +// adminStartNewVote(%client, %typename, %arg1, %arg2, %arg3, %arg4); +// adminLog(%client, " has toggled " @ %arg1 @ " (" @ %arg2 @ ")"); +// } +// else +// { +// if(Game.scheduleVote !$= "") +// { +// messageClient(%client, 'voteAlreadyRunning', '\c2A vote is already in progress.'); +// return; +// } +// %actionMsg = ($Host::DMSLOnlyMode ? "disable Shocklance Only Mode" : "enable Shocklance Only Mode"); +// for(%idx = 0; %idx < ClientGroup.getCount(); %idx++) +// { +// %cl = ClientGroup.getObject(%idx); +// if(!%cl.isAIControlled()) +// { +// messageClient(%cl, 'VoteStarted', '\c2%1 initiated a vote to %2.', %client.name, %actionMsg); +// %clientsVoting++; +// } +// } +// playerStartNewVote(%client, %typename, %arg1, %arg2, %arg3, %arg4, %clientsVoting); +// }