--------------------------------------------------------------------------------------------------------------- Undeploying Tutorial --------------------------------------------------------------------------------------------------------------- This tutorial will show you how to undeploy an already deployabled item (ie: pick up a deployed item and turn it back into a pack). It also has an optional team undeploying feature with vote function. Step #1 // ------------------------------------------ // ControlDefaults.cs // ------------------------------------------ function ServerCmdStartUseBackpack( %client, %data ) { %client.deployPack = false; %client.getControlObject().use( %data ); } should become function ServerCmdStartUseBackpack( %client, %data ) { if((%client.player.getMountedImage($BackpackSlot) == 0) && (%client.player.thrownChargeId == 0)) pickupDeployable(%client); else { %client.deployPack = false; %client.getControlObject().use( %data ); } } Step #2 Add this to the datablocks of all deployables you want to be able to pick back up: deployedFrom = NameOfDeployable; such as, in DeployedStationInventory, add this: deployedFrom = InventoryDeployable; here's a list of all the base deployables, what deployedFrom should be equal to, and where they're found. Deployable DeployedFrom = File Found DeployedInventoryStation InventoryDeployable deployables.cs DeployedMotionSensor MotionSensorDeployable deployables.cs DeployedPulseSensor PulseSensorDeployable deployables.cs TurretDeployedFloorIndoor TurretIndoorDeployable IndoorDeployableBarrel.cs TurretDeployedWallIndoor TurretIndoorDeployable IndoorDeployableBarrel.cs TurretDeployedCeilingIndoor TurretIndoorDeployable IndoorDeployableBarrel.cs TurretDeployedoutdoor TurretOutdoorDeployable OutdoorDeployableBarrel.cs Step #3 // ------------------------------------------ // Deployables.cs // ------------------------------------------ 3a) In function ShapeBaseImageData::onDeploy, add this above return %deployObj; %plyr.client.justdeployed = 1; schedule(2000, 0, "resetjustdeployed", %plyr.client); 3b) Add this function below the previous function function resetjustdeployed(%client) { %client.justdeployed = 0; } These two changes create a 2 second pause between when someone places a deployable and can pick it back up again. I find it usefull in that sometimes I'm hitting the button over and over again to find a suitible deploy spot and don't want to accidentially pick the deployable right back up. 3c) Add this function to the bottom of deployables.cs. It handles the actual undeploying. function pickupDeployable(%client) { %player = %client.player; %Masks = $TypeMasks::StaticShapeObjectType | $TypeMasks::TurretObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::ItemObjectType; %eyeVec = VectorNormalize(%player.getEyeVector()); %srchRange = VectorScale(%eyeVec, 5.0); // look 5m for a Deployable %plTm = %player.getEyeTransform(); %plyrLoc = firstWord(%plTm) @ " " @ getWord(%plTm, 1) @ " " @ getWord(%plTm, 2); %srchEnd = VectorAdd(%plyrLoc, %srchRange); %potDep = ContainerRayCast(%player.getEyeTransform(), %srchEnd, %Masks); if (%potDep) { %datablock = %potDep.getDataBlock(); %item = %datablock.getName(); %deployedFrom = %datablock.deployedFrom; if (%deployedFrom !$= "") { if (%potDep.getDamageLevel() < 0.5) { if (%player.maxInventory(%deployedFrom) > 0) { if (%potDep.team == %player.team) { if (%client == %potDep.owner) { if (!%client.justdeployed == 1) { %player.setInventory(%deployedFrom, 1); %player.mountImage(%deployedFrom.image,$BackpackSlot); %client.setBackpackHudItem(%deployedFrom.getName(), 1); ItemData::onInventory(%deployedFrom,%player,1); if ((%item $= "DeployedPulseSensor") || (%item $= "DeployedMotionSensor")) { %player.deploySensors--; %client.updateSensorPackText(%player.deploySensors); } if (%item $= DeployedBunker || %item $= DeployedBunker2) //Optional for multi object deployables UndeploySpecialCase(%potDep, %item); else %potDep.schedule(50, "delete"); $TeamDeployedCount[%player.team, %deployedFrom]--; } else messageClient(%client, 'MsgJustDeployed', '\c0Just deployed, must wait a moment.'); } else messageClient(%client, 'MsgNotDeployer', '\c0You did not deploy this.'); } else messageClient(%client, 'MsgWrongTeam', '\c0Access Denied. Wrong Team.'); } else messageClient(%client, 'MsgTooSmall', '\c0You can\'t pick up the deployable in this armor.'); } else messageClient(%client, 'MsgDisabled', '\c0Deployable is damaged.'); } else messageClient(%client, 'MsgNotDeployable', '\c0Not a Deployable.'); } else messageClient(%client, 'MsgNothing', '\c0No Deployables in sight.'); } 3d) Add this function if you use any deployables that have multiple objects attached, such as the deployable bunker or deployables that have a beacon attached. This part isn't needed if you don't use multi object deployables. function UndeploySpecialCase(%obj, %name) { if (%name $= DeployedBunker) { //Add all parts of the bunker to be deleted here. Use DeployedBunker::onDestroyed as an example } else if (%name $= DeployedBunker2) { //Add all parts of the bunker to be deleted here. Use DeployedBunker2::onDestroyed as an example } } -------------------------------------------------------------------------------------------- Optional Team undeploying -------------------------------------------------------------------------------------------- This part will allow teamates to undeploy your items, and add a vote function to enable and disable team undeploying. Step #5 // ------------------------------------------ // Deployables.cs // ------------------------------------------ In the newly create function pickupDeployable, find this line: if (%client == %potDep.owner) and change it to this: if (($teamUndeploy) || (%client == %potDep.owner)) Step #6 // ------------------------------------------ // DefaultGames.cs // ------------------------------------------ 6a) in function DefaultGame::sendGameVoteMenu, add these lines to the top: if ($TeamUndeploy != 1) $teamUndeploy = 0; Next, in the same function, find: if ( $teamDamage ) messageClient( %client, 'MsgVoteItem', "", %key, 'VoteTeamDamage', 'disable team damage', 'Vote to Disable Team Damage' ); else messageClient( %client, 'MsgVoteItem', "", %key, 'VoteTeamDamage', 'enable team damage', 'Vote to Enable Team Damage' ); and add this below it: if ( $teamUndeploy ) messageClient( %client, 'MsgVoteItem', "", %key, 'VoteTeamUndeploy', 'disable team undeploying', 'Vote to Disable Team Undeploying' ); else messageClient( %client, 'MsgVoteItem', "", %key, 'VoteTeamUndeploy', 'enable team undeploying', 'Vote to Enable Team Undeploying' ); Also find: if ( $teamDamage ) messageClient( %client, 'MsgVoteItem', "", %key, 'VoteTeamDamage', 'disable team damage', 'Disable Team Damage' ); else messageClient( %client, 'MsgVoteItem', "", %key, 'VoteTeamDamage', 'enable team damage', 'Enable Team Damage' ); and add this below it: if ( $teamUndeploy ) messageClient( %client, 'MsgVoteItem', "", %key, 'VoteTeamUndeploy', 'disable team undeploying', 'Disable Team Undeploying' ); else messageClient( %client, 'MsgVoteItem', "", %key, 'VoteTeamUndeploy', 'enable team undeploying', 'Enable Team Undeploying' ); 6b) In function DefaultGame::evalVote, add this: case "voteTeamUndeploy": %game.voteTeamUndeploy(%admin, %arg1, %arg2, %arg3, %arg4); 6c) Next, add this function below function DefaultGame::voteTeamDamage: function DefaultGame::voteTeamUndeploy(%game, %admin) { %setto = ""; %cause = ""; if(%admin) { if($teamUndeploy) { messageAll('MsgAdminForce', '\c2The Admin has disabled team undeploying.'); $Host::TeamUndeployOn = $TeamUndeploy = 0; %setto = "disabled"; } else { messageAll('MsgAdminForce', '\c2The Admin has enabled team undeploying.'); $Host::TeamUndeployOn = $TeamUndeploy = 1; %setto = "enabled"; } %cause = "(admin)"; } else { %totalVotes = %game.totalVotesFor + %game.totalVotesAgainst; if(%totalVotes > 0 && (%game.totalVotesFor / (ClientGroup.getCount() - $HostGameBotCount)) > ($Host::VotePasspercent / 100)) { if($teamUndeploy) { messageAll('MsgVotePassed', '\c2Team undeploying was disabled by vote.'); $Host::TeamUndeployOn = $TeamUndeploy = 0; %setto = "disabled"; } else { messageAll('MsgVotePassed', '\c2Team undeploying was enabled by vote.'); $Host::TeamUndeployOn = $TeamUndeploy = 1; %setto = "enabled"; } %cause = "(vote)"; } else { if($teamUndeploy) messageAll('MsgVoteFailed', '\c2Disable team undeploying vote did not pass: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100)); else messageAll('MsgVoteFailed', '\c2Enable team undeploying vote did not pass: %1 percent.', mFloor(%game.totalVotesFor/(ClientGroup.getCount() - $HostGameBotCount) * 100)); } } if(%setto !$= "") logEcho("team undeploying "@%setto SPC %cause); } Step #7 // ------------------------------------------ // Admin.cs // ------------------------------------------ 7a) Add these lines to the top of the file: $VoteMessage["VoteTeamUndeploy", 0] = "enable team undeploying"; $VoteMessage["VoteTeamUndeploy", 1] = "disable team undeploying"; 7b) In function serverCmdStartNewVote, change these lines: if( $VoteMessage[ %typeName ] $= "" && %typeName !$= "VoteTeamDamage" ) if( $VoteMessage[ %typeName ] $= "" && %typeName !$= "VoteHoardMode" ) if( $VoteMessage[ %typeName ] $= "" && %typeName !$= "VoteGreedMode" ) %typePass = false; to this: if( $VoteMessage[ %typeName ] $= "" && %typeName !$= "VoteTeamDamage" ) if( $VoteMessage[ %typeName ] $= "" && %typeName !$= "VoteHoardMode" ) if( $VoteMessage[ %typeName ] $= "" && %typeName !$= "VoteGreedMode" ) if( $VoteMessage[ %typeName ] $= "" && %typeName !$= "VoteTeamUndeploy" ) %typePass = false; Next, below these lines: if(( $VoteMessage[ %typeName, $TeamDamage ] $= "" && %typeName $= "VoteTeamDamage" )) %typePass = false; Add this: if(( $VoteMessage[ %typeName, $TeamUndeploy ] $= "" && %typeName $= "VoteTeamUndeploy" )) %typePass = false; Finially, below these lines: else if( %typeName $= "VoteTeamDamage" || %typeName $= "VoteGreedMode" || %typeName $= "VoteHoardMode" ) %actionMsg = $VoteMessage[ %typeName, $TeamDamage ]; Add this: else if( %typeName $= "VoteTeamUndeploy") %actionMsg = $VoteMessage[ %typeName, $TeamUndeploy ]; Step #8 // ------------------------------------------ // Server.cs // ------------------------------------------ In function loadMissionStage2, change these lines: // Set the team damage here so that the game type can override it: if ( isDemo() ) $TeamDamage = 0; else if ( $Host::TournamentMode ) $TeamDamage = 1; else $TeamDamage = $Host::TeamDamageOn; to this: // Set the team damage and undeploying here so that the game type can override it: if ( isDemo() ) { $TeamDamage = 0; $TeamUndeploy = 0; } else if ( $Host::TournamentMode ) { $TeamDamage = 1; $TeamUndeploy = 1; } else { $TeamDamage = $Host::TeamDamageOn; $TeamUndeploy = $Host::TeamUndeployOn; }