// DisplayName = Capture and Hold //--- GAME RULES BEGIN --- //Teams try to capture marked objectives //Capturing player gets a point 12 seconds after a capture //Hold objectives in order to score //A team scores 2 points per second it holds an objective //Turrets and inventory stations convert when their switch is taken //--- GAME RULES END --- //exec the AI scripts exec("scripts/aiCnH.cs"); package CnHGame { function FlipFlop::playerTouch(%data, %flipflop, %player) { if(%flipflop.team != %player.client.team) { Parent::playerTouch(%data, %flipflop, %player); Game.startTimerPlayerFFCap(%player.client, %flipflop); } } function Flipflop::objectiveInit(%data, %flipflop) { %flipflop.tCapThread = ""; %flipflop.tHoldThread = ""; %flipflop.pCapThread = ""; Parent::objectiveInit(%data, %flipflop); } }; //--------- CnH SCORING INIT ------------------ function CnHGame::initGameVars(%game) { %game.SCORE_PER_SUICIDE = -1; %game.SCORE_PER_TEAMKILL = -1; %game.SCORE_PER_DEATH = -1; %game.SCORE_PER_KILL = 1; %game.SCORE_PER_PLYR_FLIPFLOP_CAP = 1; %game.SCORE_PER_TEAM_FLIPFLOP_CAP = 1; %game.SCORE_PER_TEAM_FLIPFLOP_HOLD = 1; %game.SCORE_PER_TURRET_KILL = 1; %game.SCORE_PER_FLIPFLOP_DEFEND = 1; %game.SCORE_LIMIT_PER_TOWER = 1200; //default of 1200 points per tower required to win @ 1 pt per %game.TIME_REQ_TEAM_HOLD_BONUS milliseconds %game.TIME_REQ_PLYR_CAP_BONUS = 12 * 1000; //player must hold a switch 12 seconds to get a point for it. %game.TIME_REQ_TEAM_CAP_BONUS = 12 * 1000; //time after touching it takes for team to get a point %game.TIME_REQ_TEAM_HOLD_BONUS = 0.5 * 1000; //recurring time it takes team to earn a point when flipflop held %game.RADIUS_FLIPFLOP_DEFENSE = 20; //meters } function CnHGame::setUpTeams(%game) { DefaultGame::setUpTeams(%game); // reset the visibility of team 0 (team is still defaulted as friendly) setSensorGroupAlwaysVisMask(0, 0); } //-- tracking --- // .deaths .kills .suicides .teamKills .turretKills // .flipFlopDefends .flipFlopsCapped function CnHGame::startMatch(%game) { for(%i = 0; %i <= %game.numTeams; %i++) $TeamScore[%i] = 0; DefaultGame::startMatch(%game); } function CnHGame::checkScoreLimit(%game, %team) { %scoreLimit = %game.getScoreLimit(); if($TeamScore[%team] >= %scoreLimit) %game.scoreLimitReached(); } function CnHGame::getScoreLimit(%game) { %scoreLimit = MissionGroup.CnH_scoreLimit; if(%scoreLimit $= "") %scoreLimit = %game.getNumFlipFlops() * %game.SCORE_LIMIT_PER_TOWER; return %scoreLimit; } function CnHGame::scoreLimitReached(%game) { logEcho("game over (scorelimit)"); %game.gameOver(); cycleMissions(); } function CnHGame::timeLimitReached(%game) { logEcho("game over (timelimit)"); %game.gameOver(); cycleMissions(); } function CnHGame::gameOver(%game) { //call the default DefaultGame::gameOver(%game); // stop all bonus timers %game.stopScoreTimers(); //send the winner message %winner = ""; if ($teamScore[1] > $teamScore[2]) %winner = $teamName[1]; else if ($teamScore[2] > $teamScore[1]) %winner = $teamName[2]; if (%winner $= 'Storm') messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.stowins.wav" ); else if (%winner $= 'Inferno') messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.infwins.wav" ); else messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.gameover.wav" ); messageAll('MsgClearObjHud', ""); for(%i = 0; %i < ClientGroup.getCount(); %i ++) { %client = ClientGroup.getObject(%i); %game.resetScore(%client); } for ( %team = 1; %team <= %game.numTeams; %team++ ) { $TeamScore[%team] = 0; messageAll('MsgCnHTeamCap', "", -1, -1, -1, %team, $TeamScore[%team], %game.getScoreLimit()); } } function CnHGame::stopScoreTimers(%game) { // find all switches and cancel any timers associated with them %ffGroup = nameToId("MissionCleanup/FlipFlops"); if(%ffGroup <= 0) return; for(%i = 0; %i < %ffGroup.getCount(); %i++) { %curFF = %ffGroup.getObject(%i); cancel(%curFF.tHoldThread); cancel(%curFF.pCapThread); cancel(%curFF.tCapThread); } } function CnHGame::clientMissionDropReady(%game, %client) { messageClient(%client, 'MsgClientReady',"", %game.class); %scoreLimit = %game.getScoreLimit(); for(%i = 1; %i <= %game.numTeams; %i++) { %teamHeld = %game.countFlipsHeld(%i); messageClient(%client, 'MsgCnHAddTeam', "", %i, $TeamName[%i], $TeamScore[%i], %scoreLimit, %teamHeld); } //%game.populateTeamRankArray(%client); //messageClient(%client, 'MsgYourRankIs', "", -1); messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); DefaultGame::clientMissionDropReady(%game, %client); } function CnHGame::assignClientTeam(%game, %client, %respawn) { DefaultGame::assignClientTeam(%game, %client, %respawn); // if player's team is not on top of objective hud, switch lines messageClient(%client, 'MsgCheckTeamLines', "", %client.team); } function CnHGame::getNumFlipFlops() { %ffGroup = nameToID("MissionCleanup/FlipFlops"); return %ffGroup.getCount(); } function CnHGame::countFlipsHeld(%game, %team) { %teamHeld = 0; // count how many flipflops each team holds %ffSet = nameToID("MissionCleanup/FlipFlops"); if(%ffSet > 0) { %numFF = %ffSet.getCount(); for(%j = 0; %j < %numFF; %j++) { %curFF = %ffSet.getObject(%j); if(%curFF.team == %team) %teamHeld++; } } return %teamHeld; } function CnHGame::countFlips(%game) { return true; } function CnHGame::equip(%game, %player) { for(%i =0; %i<$InventoryHudCount; %i++) %player.client.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); //%player.setArmor("Light"); %player.setInventory(Blaster,1); %player.setInventory(Chaingun, 1); %player.setInventory(ChaingunAmmo, 100); %player.setInventory(Disc,1); %player.setInventory(DiscAmmo, 20); %player.setInventory(TargetingLaser, 1); %player.setInventory(Grenade,6); %player.setInventory(Beacon, 3); %player.setInventory(RepairKit,1); %player.weaponCount = 3; %player.use("Blaster"); } //--------------- Scoring functions ----------------- function CnHGame::recalcScore(%game, %cl) { %killValue = %cl.kills * %game.SCORE_PER_KILL; %deathValue = %cl.deaths * %game.SCORE_PER_DEATH; if (%killValue - %deathValue == 0) %killPoints = 0; else %killPoints = (%killValue * %killValue) / (%killValue - %deathValue); %cl.offenseScore = %killPoints; %cl.offenseScore += %cl.suicides * %game.SCORE_PER_SUICIDE; //-1 %cl.offenseScore += %cl.teamKills * %game.SCORE_PER_TEAMKILL; // -1 %cl.offenseScore += %cl.flipFlopsCapped * %game.SCORE_PER_PLYR_FLIPFLOP_CAP; %cl.defenseScore = %cl.turretKills * %game.SCORE_PER_TURRET_KILL; // 1 %cl.defenseScore += %cl.flipFlopDefends * %game.SCORE_PER_FLIPFLOP_DEFEND; %cl.score = mFloor(%cl.offenseScore + %cl.defenseScore); //track switches held (not touched), switches defended, kills, deaths, suicides, tks %game.recalcTeamRanks(%cl); } function CnHGame::updateKillScores(%game, %clVictim, %clKiller, %damageType, %implement) { if(%game.testTurretKill(%implement)) //check for turretkill before awarded a non client points for a kill { %game.awardScoreTurretKill(%clVictim, %implement); } else if (%game.testKill(%clVictim, %clKiller)) //verify victim was an enemy { %game.awardScoreKill(%clKiller); %game.awardScoreDeath(%clVictim); //see if we were defending a flip flop %flipflop = %game.testPlayerFFDefend(%clVictim, %clKiller); if (isObject(%flipflop)) %game.awardScorePlayerFFDefend(%clKiller, %flipflop); } else { if (%game.testSuicide(%clVictim, %clKiller, %damageType)) //otherwise test for suicide { %game.awardScoreSuicide(%clVictim); } else { if (%game.testTeamKill(%clVictim, %clKiller)) //otherwise test for a teamkill %game.awardScoreTeamKill(%clVictim, %clKiller); } } } function CnHGame::testPlayerFFDefend(%game, %victimID, %killerID) { if (!isObject(%victimId) || !isObject(%killerId) || %killerId.team <= 0) return -1; //loop through the flipflops looking for one within range that belongs to the killer... %ffGroup = nameToID("MissionCleanup/FlipFlops"); for (%i = 0; %i < %ffGroup.getCount(); %i++) { %ffObj = %ffGroup.getObject(%i); if (VectorDist(%ffObj.position, %victimID.plyrPointOfDeath) < %game.RADIUS_FLIPFLOP_DEFENSE) { if (%ffObj.team == %killerID.team) return %ffObj; } } //none were found return -1; } function CnHGame::awardScorePlayerFFDefend(%game, %cl, %flipflop) { %cl.flipFlopDefends++; if (%game.SCORE_PER_FLIPFLOP_DEFEND != 0) { messageClient(%cl, 'msgFFDef', '\c0You received a %1 point bonus for defending %2.', %game.SCORE_PER_FLIPFLOP_DEFEND, %game.cleanWord(%flipflop.name)); messageTeamExcept(%cl, 'msgFFDef', '\c0Teammate %1 received a %2 point bonus for defending %3', %cl.name, %game.SCORE_PER_FLIPFLOP_DEFEND, %game.cleanWord(%flipflop.name)); } %game.recalcScore(%cl); } function CnHGame::awardScorePlayerFFCap(%game, %cl, %this) { if(!($missionRunning)) return; %cl.flipFlopsCapped++; if (%game.SCORE_PER_PLYR_FLIPFLOP_CAP != 0) { messageClient(%cl, 'msgFFDef', '\c0You received a %1 point bonus for holding the %2.', %game.SCORE_PER_PLYR_FLIPFLOP_CAP, %game.cleanWord(%this.name)); messageTeamExcept(%cl, 'msgFFDef', '\c0Teammate %1 received a %2 point bonus for holding the %3', %cl.name, %game.SCORE_PER_PLYR_FLIPFLOP_CAP, %game.cleanWord(%this.name)); } %game.recalcScore(%cl); } function CnHGame::awardScoreTeamFFCap(%game, %team, %this) { cancel(%this.tCapThread); if(!($missionRunning)) return; $TeamScore[%team] +=%game.SCORE_PER_TEAM_FLIPFLOP_CAP; %sLimit = %game.getScoreLimit(); if (%game.SCORE_PER_TEAM_FLIPFLOP_CAP) messageAll('MsgCnHTeamCap', "", -1, -1, -1, %team, $teamScore[%team], %sLimit); if (%game.SCORE_PER_TEAM_FLIPFLOP_HOLD != 0) %this.tHoldThread = %game.schedule(%game.TIME_REQ_TEAM_HOLD_BONUS, "awardScoreTeamFFHold", %team, %this); %game.checkScoreLimit(%team); } function CnHGame::awardScoreTeamFFHold(%game, %team, %this) { cancel(%this.tHoldThread); if(!($missionRunning)) return; $TeamScore[%team] +=%game.SCORE_PER_TEAM_FLIPFLOP_HOLD; %sLimit = %game.getScoreLimit(); if (%game.SCORE_PER_TEAM_FLIPFLOP_HOLD) messageAll('MsgCnHTeamCap', "", $TeamName[%team], %game.SCORE_PER_TEAM_FLIPFLOP_HOLD, %game.cleanWord(%this.name), %team, $teamScore[%team], %sLimit); // if either team's score is divisible by 100, send a console log message if(($TeamScore[%team] / 100) == (mFloor($TeamScore[%team] / 100))) for(%i = 1; %i <= %game.numTeams; %i++) logEcho("team "@%i@" score "@$TeamScore[%i]); %game.checkScoreLimit(%team); %this.tHoldThread = %game.schedule(%game.TIME_REQ_TEAM_HOLD_BONUS, "awardScoreTeamFFHold", %team, %this); } function CnHGame::testValidRepair(%game, %obj) { return ((%obj.lastDamagedByTeam != %obj.team) && (%obj.repairedBy.team == %obj.team)); } function CnHGame::genOnRepaired(%game, %obj, %objName) { if (%game.testValidRepair(%obj)) { %repairman = %obj.repairedBy; messageTeam(%repairman.team, 'msgGenRepaired', '\c0%1 repaired the %2 Generator!', %repairman.name, %obj.nameTag); } } function CnHGame::stationOnRepaired(%game, %obj, %objName) { if (%game.testValidRepair(%obj)) { %repairman = %obj.repairedBy; messageTeam(%repairman.team, 'msgStationRepaired', '\c0%1 repaired the %2 Inventory Station!', %repairman.name, %obj.nameTag); } } function CnHGame::sensorOnRepaired(%game, %obj, %objName) { if (%game.testValidRepair(%obj)) { %repairman = %obj.repairedBy; messageTeam(%repairman.team, 'msgSensorRepaired', '\c0%1 repaired the %2 Pulse Sensor!', %repairman.name, %obj.nameTag); } } function CnHGame::turretOnRepaired(%game, %obj, %objName) { if (%game.testValidRepair(%obj)) { %repairman = %obj.repairedBy; messageTeam(%repairman.team, 'msgTurretRepaired', '\c0%1 repaired the %2 Turret!', %repairman.name, %obj.nameTag); } } function CnHGame::vStationOnRepaired(%game, %obj, %objName) { if (%game.testValidRepair(%obj)) { %repairman = %obj.repairedBy; messageTeam(%repairman.team, 'msgTurretRepaired', '\c0%1 repaired the %2 Vehicle Station!', %repairman.name, %obj.nameTag); } } function CnHGame::startTimerPlayerFFCap(%game, %cl, %this) { cancel(%this.pCapThread); //stop the last owner from collecting a cap bonus %this.pCapThread = %game.schedule(%game.TIME_REQ_PLYR_CAP_BONUS, "awardScorePlayerFFCap", %cl, %this); cancel(%this.tCapThread); //stop the old owners from collecting any cap bonus cancel(%this.tHoldThread); //stop the old owners from collecting any hold bonus %this.tCapThread = %game.schedule(%game.TIME_REQ_TEAM_CAP_BONUS, "awardScoreTeamFFCap", %cl.team, %this); } function CnHGame::startTimerTeamFFCap(%game, %team, %this, %time) { %this.tCapThread = %game.schedule(%time, "awardScoreTeamFFCap", %team, %this); } //------------------------------------------------------------------------ function CnHGame::resetScore(%game, %client) { %client.offenseScore = 0; %client.kills = 0; %client.deaths = 0; %client.suicides = 0; %client.teamKills = 0; %client.flipFlopsCapped = 0; %client.defenseScore = 0; %client.turretKills = 0; %client.flipFlopDefends = 0; %client.score = 0; for ( %team = 1; %team <= %game.numTeams; %team++ ) if($TeamScore[%team] != 0) $TeamScore[%team] = 0; } function CnHGame::applyConcussion(%game, %player) { }