// DisplayName = Sabotage //--- GAME RULES BEGIN --- // Secure The Bomb // Destroy The Enemy Objective With The Bomb // Protect Your Objective From The Bomb //--- GAME RULES END --- $SaboGame::Rounds = 5; $Sabotage::ArmTime = 3; $Sabotage::DefuseTime = 10; $Sabotage::Fuse = 25; datablock StaticShapeData(SabotageObjective) { className = "StaticShape"; shapeFile = "stackable2m.dts"; maxDamage = 0.5; destroyedLevel = 0.5; disabledLevel = 0.3; explosion = HandGrenadeExplosion; expDmgRadius = 1.0; expDamage = 0.05; expImpulse = 200; dynamicType = $TypeMasks::StaticShapeObjectType; deployedObject = true; cmdCategory = "DSupport"; cmdIcon = CMDSensorIcon; cmdMiniIconName = "commander/MiniIcons/com_deploymotionsensor"; targetNameTag = '[Sabotage] Objective'; deployAmbientThread = true; debrisShapeName = "debris_generic_small.dts"; debris = DeployableDebris; heatSignature = 0; needsPower = true; }; datablock ItemData(SabotageBomb) { catagory = "Objectives"; shapefile = "stackable2s.dts"; mass = 1; elasticity = 0.2; friction = 0.6; pickupRadius = 3; pickUpName = "a Bomb"; computeCRC = true; lightType = "PulsingLight"; lightColor = "0.5 0.5 0.5 1.0"; lightTime = "1000"; lightRadius = "3"; isInvincible = true; cmdCategory = "Objectives"; cmdIcon = CMDFlagIcon; cmdMiniIconName = "commander/MiniIcons/com_flag_grey"; targetTypeTag = 'Bomb'; }; function SabotageBomb::onCollision(%data,%obj,%col) { if (%col.getDataBlock().className $= Armor && !%col.client.isJailed) { if (%col.isMounted()) return; // a player hit the flag Game.playerTouchBomb(%col, %obj); } } function SabotageGame::playerTouchBomb(%game, %player, %bomb) { if(%player.getState() $= "Dead") { return; } if(%bomb.isArmed) { } else { cancel(%bomb.resetTime); messageClient(%player.client, 'MsgYouHasBomb', "\c5SABOTAGE: You have the BOMB, Destroy The Objective"); %bomb.Carrier = %player; %bomb.hide(true); %bomb.startFade(0, 0, false); if(%player.team == 1) { %enemyTeam = 2; } else { %enemyTeam = 1; } %game.ObjectiveScan(%player, %enemyTeam); } } function SabotageGame::CheckForDisarm(%game, %bomb) { InitContainerRadiusSearch(%bomb.getPosition(), 25, $TypeMasks::PlayerObjectType); while ((%potentialTarget = ContainerSearchNext()) != 0) { if(%potentialTarget.team != %bomb.ArmTeam) { if(%bomb.BeingDisarmed) { return; } %bomb.BeingDisarmed = 1; %game.StartDisarm(%potentialTarget, %bomb, 0); return; } } %game.schedule(500, "CheckForDisarm", %bomb); } function SabotageGame::ObjectiveScan(%game, %carrier, %enemyTeam) { if(!isObject(%carrier) || %carrier.getState() $= "Dead") { return; } %EnemyObj = %game.TeamObjective[%enemyTeam]; if(vectorDist(%carrier.getPosition(), %EnemyObj.getPosition()) <= 5) { %game.ArmBomb(%carrier, %game.bomb, %enemyTeam, 0); return; } %game.schedule(500, "ObjectiveScan", %carrier, %enemyTeam); } function SabotageGame::ArmBomb(%game, %carrier, %bomb, %ETeam, %ct) { if(!isObject(%carrier) || %carrier.getState() $= "Dead") { return; } %EnemyObj = %game.TeamObjective[%ETeam]; if(vectorDist(%carrier.getPosition(), %EnemyObj.getPosition()) > 12) { %game.schedule(500, "ObjectiveScan", %carrier, %ETeam); } else { BottomPrint(%carrier.client, "ARMING BOMB "@MFloor(%ct)@" / "@$Sabotage::ArmTime*2@"", 1, 2); //Still In Range, Keep Armin %ct++; //7 Seconds To Arm! if(%ct >= $Sabotage::ArmTime*2) { %bomb.armTeam = %carrier.team; recordAction(%carrier, "BOMBARM"); %game.BombDropped(%bomb, %Carrier); //drop the bomb, cause it's armedz MessageAll('MsgBombArmed', "\c5SABOTAGE: The Bomb Has Been Planted!!!"); CompleteNWChallenge(%Carrier, "BombPlanted"); %game.BombBegin(%bomb, %ETeam, 0); } else { %game.schedule(500, "ArmBomb", %carrier, %bomb, %ETeam, %ct); } } } function SabotageGame::StartDisarm(%game, %player, %bomb, %ct) { if(%Player.getState() $= "dead") { %bomb.BeingDisarmed = 0; %game.CheckForDisarm(%bomb); return; } if(!%bomb.BeingDisarmed) { %game.CheckForDisarm(%bomb); return; } if(vectorDist(%player.getPosition(), %bomb.getPosition()) <= 7) { %ct++; BottomPrint(%player.client, "DISARMING BOMB "@MFloor(2)@" / "@$Sabotage::DefuseTime*2@"", 1, 2); if(%ct >= $Sabotage::DefuseTime*2) { cancel(%bomb.DetSchedule); %bomb.isArmed = 0; %bomb.BeingDisarmed = 0; %game.playerTouchBomb(%player, %bomb); messageAll('MsgSPCurrentObjective2', "", "Disarmed"); recordAction(%player.client, "BOMBDIS"); MessageAll('MsgBombArmed', "\c5SABOTAGE: The Bomb Has Been Disarmed!!!"); CompleteNWChallenge(%player.client, "BombDisarmed"); return; } else { %game.schedule(500, "StartDisarm", %player, %bomb, %ct); } } else { %game.CheckForDisarm(%bomb); %bomb.BeingDisarmed = 0; } } function SabotageGame::BombBegin(%game, %bomb, %ETeam, %ct) { %bomb.isArmed = 1; %game.CheckForDisarm(%bomb); %ct++; messageAll('MsgSPCurrentObjective2', "", "Fuse Time: "@MFloor(%ct/2)@"/"@$Sabotage::Fuse@""); if(%ct > $Sabotage::Fuse*2) { %game.BombExplode(%bomb, %ETeam); } else { %bomb.DetSchedule = %game.schedule(500, "BombBegin", %bomb, %ETeam, %ct); } } function SabotageGame::BombExplode(%game, %bomb, %ETeam) { $teamScore[%bomb.armTeam] += 10000; //HA! $TeamWins[%bomb.armTeam]++; for(%i = 0; %i < ClientGroup.getCount(); %i++) { %cl = ClientGroup.getObject(%i); if(%cl.team == %bomb.armTeam) { recordAction(%cl, "SABWIN"); switch($TeamWins[%bomb.armTeam]) { case 1: CompleteNWChallenge(%cl, "BombDetonated"); case 3: CompleteNWChallenge(%cl, "3For5Sabo"); case 5: CompleteNWChallenge(%cl, "BaseDestroyer"); } } } //Boom :) ServerPlay3D("SatchelChargeExplosionSound", %bomb.getPosition()); %c4 = new Item() { datablock = C4Deployed; position = %bomb.getPosition(); scale = ".1 .1 .1"; }; MissionCleanup.add(%c4); schedule(770, 0, "C4GoBoom", %c4); // for(%i = 0; %i < ClientGroup.getCount(); %i++) { %cl = ClientGroup.getObject(%i); if(isObject(%cl.player)) { // %cl.player.clearInventory(); //auto UE if(%cl.team != %bomb.armTeam) { %cl.player.setDamageFlash(100); } } if(%cl.team != %bomb.armTeam) { messageClient(%cl, 'MsgYouHasBomb', "\c5SABOTAGE: We have been defeated... try harder next time..."); } else { messageClient(%cl, 'MsgYouHasBomb', "\c5SABOTAGE: Mission acomplished, great work soldiers. (+250XP)"); %cl.xp += 250; UpdateClientRank(%cl); } } %game.Intermit(); } function SabotageGame::ResetBomb(%game, %bomb) { MessageAll('msgWhoops', "\c5SABOTAGE: Bomb Reset."); %bomb.setPosition($SabotageGame::BombLocation[$CurrentMission]); } function SabotageGame::BombDropped(%game, %bomb, %Carrier) { if(!%bomb.IsArmed) { %bomb.resetTime = %game.schedule(45000,"ResetBomb", %bomb); } %bomb.setPosition(%Carrier.getPosition()); //I think the game does this %bomb.Carrier = 0; //But this is just to be safe %bomb.hide(false); } function SabotageGame::UpdateBombStatus(%game, %bomb) { if(%bomb.Carrier == 0 && !%bomb.isArmed) { %wp = new WayPoint() { position = %bomb.getWorldBoxCenter(); dataBlock = "WayPointMarker"; team = 0; name = "BOMB"; }; messageAll('MsgSPCurrentObjective1', "", "Bomb: Neutral"); MissionCleanup.add(%wp); %wp.schedule(2999,delete); } else if(%bomb.isArmed) { %wp = new WayPoint() { position = %bomb.getWorldBoxCenter(); dataBlock = "WayPointMarker"; team = %bomb.armTeam; name = "ARMED BOMB"; }; messageAll('MsgSPCurrentObjective1', "", "Bomb: Armed"); MissionCleanup.add(%wp); %wp.schedule(2999,delete); } else { if(!%bomb.Carrier.client.IsActivePerk("Bomb Shadower")) { %wp = new WayPoint() { position = %bomb.Carrier.getWorldBoxCenter(); dataBlock = "WayPointMarker"; team = %bomb.Carrier.Team; name = ""@%bomb.Carrier.client.namebase@" - BOMB"; }; messageAll('MsgSPCurrentObjective1', "", "Bomb: "@%bomb.carrier.client.namebase@""); MissionCleanup.add(%wp); %wp.schedule(2999,delete); } else { messageAll('MsgSPCurrentObjective1', "", "Bomb: Shadowed By Carrier"); } } %game.schedule(3000, "UpdateBombStatus", %bomb); } function SabotageGame::AIInit(%game) { //call the default AIInit() function AIInit(); } function SabotageGame::allowsProtectedStatics(%game) { return true; } function SabotageGame::clientMissionDropReady(%game, %client) { messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); messageClient(%client, 'MsgClientReady',"", "SinglePlayerGame"); DefaultGame::clientMissionDropReady(%game, %client); } function SabotageGame::onAIRespawn(%game, %client) { //add the default task if (!%client.defaultTasksAdded) { %client.defaultTasksAdded = true; %client.addTask(AIPickupItemTask); %client.addTask(AIUseInventoryTask); %client.addTask(AITauntCorpseTask); %client.addTask(AIEngageTurretTask); %client.addTask(AIDetectMineTask); %client.addTask(AIBountyPatrolTask); %client.bountyTask = %client.addTask(AIBountyEngageTask); } //set the inv flag %client.spawnUseInv = true; } function SabotageGame::updateKillScores(%game, %clVictim, %clKiller, %damageType, %implement) { if (%game.testKill(%clVictim, %clKiller)) { //verify victim was an enemy %game.awardScoreKill(%clKiller); %game.awardScoreDeath(%clVictim); } else if (%game.testSuicide(%clVictim, %clKiller, %damageType)) //otherwise test for suicide %game.awardScoreSuicide(%clVictim); } function SabotageGame::timeLimitReached(%game) { logEcho("game over (timelimit)"); %game.gameOver(); cycleMissions(); } function SabotageGame::scoreLimitReached(%game) { logEcho("game over (scorelimit)"); %game.gameOver(); cycleMissions(); } function SabotageGame::gameOver(%game) { //call the default DefaultGame::gameOver(%game); $TWM2::PlayingSabo = 0; $FissionEndsGame = 0; $Ion::StopIon = 0; $TeamWins[1] = 0; $TeamWins[2] = 0; //send the winner message %winner = ""; if ($teamScore[1] > $teamScore[2]) %winner = %game.getTeamName(1); else if ($teamScore[2] > $teamScore[1]) %winner = %game.getTeamName(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 if (%winner $= 'Starwolf') messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.swwin.wav" ); else if (%winner $= 'Blood Eagle') messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.bewin.wav" ); else if (%winner $= 'Diamond Sword') messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.dswin.wav" ); else if (%winner $= 'Phoenix') messageAll('MsgGameOver', "Match has ended.~wvoice/announcer/ann.pxwin.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(%j = 1; %j <= %game.numTeams; %j++) $TeamScore[%j] = 0; } function SabotageGame::vehicleDestroyed(%game, %vehicle, %destroyer) { } function SabotageGame::startMatch(%game) { DefaultGame::StartMatch(%game); $TWM2::PlayingSabo = 1; $Ion::StopIon = 1; $FissionEndsGame = 1; $TeamWins[1] = 0; $TeamWins[2] = 0; $SaboGame::RoundNumber = 1; Game.NumTeams = 2; for(%i = 0; %i < ClientGroup.getCount(); %i++) { %cl = ClientGroup.getObject(%i); CenterPrint(%cl, "SABOTAGE", 5, 2); if(isObject(%cl.player)) { %cl.player.setMoveState(true); %cl.player.schedule(5000, "setMoveState", false); } } %game.InitialSetup($CurrentMission); setSensorGroupCount(7); } function SabotageGame::Intermit(%game) { $SaboGame::RoundNumber++; if($SaboGame::RoundNumber > $SaboGame::Rounds) { MessageAll('msgInter', "\c5SABOTAGE: GAME OVER, CHANGING MAP..."); %game.schedule(10000, "GameOver"); CycleMissions(); return; } else { %game.bomb.IsArmed = 0; %game.bomb.carrier = 0; %game.ResetBomb(%game.Bomb); MessageAll('msgInter', "\c5SABOTAGE: INTERMISSION, ROUND "@$SaboGame::RoundNumber@" BEGINNING"); } } function SabotageGame::InitialSetup(%game, %map) { //Team 1 Objective %game.TeamObjective[1] = new StaticShape() { datablock = SabotageObjective; position = $SabotageGame::ObjectiveLocation1[%map]; }; MissionCleanup.add(%game.TeamObjective[1]); %game.TeamObjective[1].wp = new WayPoint() { position = $SabotageGame::ObjectiveLocation1[%map]; dataBlock = "WayPointMarker"; team = 1; name = "TEAM 1 OBJECTIVE"; }; MissionCleanup.add(%game.TeamObjective[1].wp); %game.WPLoop(%game.TeamObjective[1].wp, 1); %game.TeamObjective[1].Invincible = 1; //HA! No Shootin / C4 For You //Team 2 Objective %game.TeamObjective[2] = new StaticShape() { datablock = SabotageObjective; position = $SabotageGame::ObjectiveLocation2[%map]; }; MissionCleanup.add(%game.TeamObjective[2]); %game.TeamObjective[2].wp = new WayPoint() { position = $SabotageGame::ObjectiveLocation2[%map]; dataBlock = "WayPointMarker"; team = 2; name = "TEAM 2 OBJECTIVE"; }; MissionCleanup.add(%game.TeamObjective[2].wp); %game.WPLoop(%game.TeamObjective[2].wp, 2); %game.TeamObjective[2].Invincible = 1; //HA! No Shootin / C4 For You %game.Bomb = new Item() { datablock = SabotageBomb; position = $SabotageGame::BombLocation[%map]; }; MissionCleanup.add(%game.Bomb); %game.UpdateBombStatus(%game.Bomb); messageAll('MsgSPCurrentObjective1', "", "Bomb: Neutral"); messageAll('MsgSPCurrentObjective2', "", "-----"); } function SabotageGame::pickTeamSpawn(%game, %team) { if(%team == 1) { if(!isObject(%game.TeamObjective[1])) { //stops the pre-game fall %pos = vectorAdd($SabotageGame::ObjectiveLocation1[$CurrentMission],GetRandomPosition(5,1)); %pos = vectorAdd(%pos,"0 0 5"); } else { %pos = vectorAdd(%game.TeamObjective[1].getPosition(),GetRandomPosition(5,1)); %pos = vectorAdd(%pos,"0 0 4"); } return %pos; } else if(%team == 2) { if(!isObject(%game.TeamObjective[2])) { //stops the pre-game fall %pos = vectorAdd($SabotageGame::ObjectiveLocation2[$CurrentMission],GetRandomPosition(5,1)); %pos = vectorAdd(%pos,"0 0 5"); } else { %pos = vectorAdd(%game.TeamObjective[2].getPosition(),GetRandomPosition(5,1)); %pos = vectorAdd(%pos,"0 0 4"); } return %pos; } } function SabotageGame::WPLoop(%game, %wp, %team) { %wp.delete(); if(%team == 2) { %game.TeamObjective[2].wp = new WayPoint() { position = $SabotageGame::ObjectiveLocation2[$CurrentMission]; dataBlock = "WayPointMarker"; team = 2; name = "TEAM 2 OBJECTIVE"; }; MissionCleanup.add(%game.TeamObjective[2].wp); %game.schedule(5000, "WPLoop", %game.TeamObjective[2].wp, 2); } else { %game.TeamObjective[1].wp = new WayPoint() { position = $SabotageGame::ObjectiveLocation1[$CurrentMission]; dataBlock = "WayPointMarker"; team = 1; name = "TEAM 1 OBJECTIVE"; }; MissionCleanup.add(%game.TeamObjective[1].wp); %game.schedule(5000, "WPLoop", %game.TeamObjective[1].wp, 1); } } //MissionLists $SabotageGame::ObjectiveLocation1["Strikers2"] = "1.4 148.5 14.2"; $SabotageGame::ObjectiveLocation2["Strikers2"] = "147.7 7.9 14.4"; $SabotageGame::BombLocation["Strikers2"] = "54.8 60.1 28.2"; $SabotageGame::ObjectiveLocation1["Oasis2"] = "-106.6 53.8 134"; $SabotageGame::ObjectiveLocation2["Oasis2"] = "-107.8 -125.4 133"; $SabotageGame::BombLocation["Oasis2"] = "-215.2 -44.7 109.113"; $SabotageGame::ObjectiveLocation1["MyrkWood2"] = "-297.849 -232.002 87.1634"; $SabotageGame::ObjectiveLocation2["MyrkWood2"] = "-162.307 113.314 83.2362"; $SabotageGame::BombLocation["MyrkWood2"] = "-274 -85 74.7"; $SabotageGame::ObjectiveLocation1["DerGott"] = "-2.2 -3.1 157.149"; $SabotageGame::ObjectiveLocation2["DerGott"] = "-202.631 -210.103 157.493"; $SabotageGame::BombLocation["DerGott"] = "-103.026 -95.7017 155.149"; $SabotageGame::ObjectiveLocation1["SideSwipe"] = "-83 -270 355"; $SabotageGame::ObjectiveLocation2["SideSwipe"] = "-82.3 -114 355"; $SabotageGame::BombLocation["SideSwipe"] = "-83.6 -196.2 397"; $SabotageGame::ObjectiveLocation1["HarbingerTower"] = "810.5 -401.1 102"; $SabotageGame::ObjectiveLocation2["HarbingerTower"] = "814.2 -428.7 198"; $SabotageGame::BombLocation["HarbingerTower"] = "799.4 -402.1 116"; $SabotageGame::ObjectiveLocation1["Skyline"] = "-58.8556 -420.953 750.438"; $SabotageGame::ObjectiveLocation2["Skyline"] = "-59.5177 -259.064 773.837"; $SabotageGame::BombLocation["Skyline"] = "-7.6 -339.7 774"; $SabotageGame::ObjectiveLocation1["GeometricOrder"] = "-172.325 -396.557 159.9"; $SabotageGame::ObjectiveLocation2["GeometricOrder"] = "-10.7 -573.29 159.9"; $SabotageGame::BombLocation["GeometricOrder"] = "-79.9 -487.06 165.9"; function GenerateSabotageChallengeMenu(%client, %tag, %index) { if(%client.CheckNWChallengeCompletion("BombDisarmed")) { messageClient( %client, 'SetLineHud', "", %tag, %index, "Bomb Disarmed - Done."); %index++; } else { messageClient( %client, 'SetLineHud', "", %tag, %index, "Bomb Disarmed - Disarm a enemy bomb."); %index++; } // if(%client.CheckNWChallengeCompletion("BombPlanted")) { messageClient( %client, 'SetLineHud', "", %tag, %index, "Bomb Planted - Done."); %index++; } else { messageClient( %client, 'SetLineHud', "", %tag, %index, "Bomb Planted - Arm the bomb at the objective."); %index++; } // if(%client.CheckNWChallengeCompletion("BombDetonated")) { messageClient( %client, 'SetLineHud', "", %tag, %index, "Bomb Detonated - Done."); %index++; } else { messageClient( %client, 'SetLineHud', "", %tag, %index, "Bomb Detonated - Win a Round Of Sabotage."); %index++; } // if(%client.CheckNWChallengeCompletion("3For5Sabo")) { messageClient( %client, 'SetLineHud', "", %tag, %index, "Three For Five - Done."); %index++; } else { messageClient( %client, 'SetLineHud', "", %tag, %index, "Three For Five - Win 3 Rounds Of Sabotage."); %index++; } // if(%client.CheckNWChallengeCompletion("BaseDestroyer")) { messageClient( %client, 'SetLineHud', "", %tag, %index, "Base Destroyer - Done."); %index++; } else { messageClient( %client, 'SetLineHud', "", %tag, %index, "Base Destroyer - Go Undefeated in a full game of Sabotage."); %index++; } // return %index; }