Deployable Disc Turret Tut Code: -------------------------------------------------------------------------------- //-------------------------------------------------------------------------- // Deployable Disc Turret - based on the laser turret by Founder and ZOD // Please credit the authors if you use this in your mod. //-------------------------------------------------------------------------- Step #1 // This stuff goes in inventoryHud.cs $InvPack[27] = "Disc Turret"; $NameToInv["Disc Turret"] = "DiscTurretDeployable"; Step #2 // This stuff goes in hud.cs $BackpackHudData[20, itemDataName] = "DiscTurretDeployable"; $BackpackHudData[20, bitmapName] = "gui/hud_new_packturret"; Step #3 // Don't forget to put this in your armors datablock // So thay can see it in the inventory list. // max[DiscTurretDeployable] = 1; Step #4 // If you want the disc turret deployble indoors. // if not you can skip this section. // Find function ShapeBaseImageData::testInvalidDeployConditions(%item, %plyr, %slot) in deployables.cs // Locate the lines in that function that read: // if (!%item.deployed.checkDeployPos(%xform)) // { // %disqualified = $NotDeployableReason::ObjectTooClose; // } // Replace them with the following: if (!%item.deployed.checkDeployPos(%xform)) { // Edit for certain items - ZOD/Founder if(%item.item $= "DiscTurretDeployable") { %disqualified = $NotDeployableReason::None; } else { %disqualified = $NotDeployableReason::ObjectTooClose; } } Step #5 // This goes below the deployed turret functions section in deployables.cs around line 1375 using // tribel IDE // this is a good place to start adding a new deplyble. //============================================= >Modification Zone< //-------------------------------------------------------------------------- // Datablocks Disc turret //-------------------------------------- $TeamDeployableMax[DiscTurretDeployable] = 10; $TeamDeployableMin[DiscTurretDeployable] = 10; datablock SensorData(DiscTurretSensor) { detects = true; detectsUsingLOS = true; detectsPassiveJammed = false; detectsActiveJammed = false; detectsCloaked = false; detectionPings = true; detectRadius = 100; }; datablock TurretData(DiscTurretDeployed) : TurretDamageProfile { className = DeployedTurret; shapeFile = "turret_outdoor_deploy.dts"; mass = 5.0; maxDamage = 1.5; //was 0.5; destroyedLevel = 0.5; disabledLevel = 0.21; explosion = SmallTurretExplosion; expDmgRadius = 5.0; expDamage = 0.25; expImpulse = 500.0; repairRate = 0; heatSignature = 0.0; deployedObject = true; thetaMin = 5; thetaMax = 145; thetaNull = 90; primaryAxis = zaxis; isShielded = true; energyPerDamagePoint = 30; maxEnergy = 30; rechargeRate = 0.20; //was 0.10; barrel = DeployableDiscTurretBarrel; canControl = true; cmdCategory = "DTactical"; cmdIcon = CMDTurretIcon; cmdMiniIconName = "commander/MiniIcons/com_turret_grey"; targetNameTag = 'Disc'; targetTypeTag = 'Turret'; sensorData = DiscTurretSensor; sensorRadius = DiscTurretSensor.detectRadius; sensorColor = "191 0 226"; firstPersonOnly = true; renderWhenDestroyed = false; debrisShapeName = "debris_generic_small.dts"; debris = TurretDebrisSmall; }; datablock TurretImageData(DeployableDiscTurretBarrel) { shapeFile = "weapon_disc.dts"; item = DiscTurretBarrel; rotation = "0 1 0 90"; //rotation = "0 0 0 0"; offset = "0 0 0"; projectile = DiscProjectile; projectileType = LinearProjectile; usesEnergy = true; fireEnergy = 10; ///was 20 minEnergy = 10; ///was 20 lightType = "WeaponFireLight"; lightColor = "0.25 0.15 0.15 1.0"; lightTime = "1000"; lightRadius = "2"; muzzleFlash = IndoorTurretMuzzleFlash; // Turret parameters activationMS = 150; deactivateDelayMS = 300; thinkTimeMS = 150; degPerSecTheta = 580; degPerSecPhi = 960; attackRadius = 150; //100 // State Data stateName[0] = "Preactivate"; stateTransitionOnLoaded[0] = "Activate"; stateTransitionOnNoAmmo[0] = "NoAmmo"; stateName[1] = "Activate"; stateTransitionOnTimeout[1] = "Ready"; stateTimeoutValue[1] = 0.5; stateSequence[1] = "Activated"; stateSound[1] = DiscSwitchSound; stateName[2] = "Ready"; stateTransitionOnNoAmmo[2] = "NoAmmo"; stateTransitionOnTriggerDown[2] = "Fire"; stateSequence[2] = "DiscSpin"; stateSound[2] = DiscLoopSound; stateName[3] = "Fire"; stateTransitionOnTimeout[3] = "Reload"; stateTimeoutValue[3] = 1.25; stateFire[3] = true; stateRecoil[3] = LightRecoil; stateAllowImageChange[3] = false; stateSequence[3] = "Fire"; stateScript[3] = "onFire"; stateSound[3] = DiscFireSound; stateName[4] = "Reload"; stateTransitionOnNoAmmo[4] = "NoAmmo"; stateTransitionOnTimeout[4] = "Ready"; stateTimeoutValue[4] = 0.5; // 0.25 load, 0.25 spinup stateAllowImageChange[4] = false; stateSequence[4] = "Reload"; stateSound[4] = DiscReloadSound; stateName[5] = "NoAmmo"; stateTransitionOnAmmo[5] = "Reload"; stateSequence[5] = "NoAmmo"; stateTransitionOnTriggerDown[5] = "DryFire"; stateName[6] = "DryFire"; //stateSound[6] = DiscDryFireSound; stateTimeoutValue[6] = 1.0; stateTransitionOnTimeout[6] = "NoAmmo"; }; datablock ShapeBaseImageData(DiscTurretDeployableImage) { mass = 15; shapeFile = "pack_deploy_turreti.dts"; item = DiscTurretDeployable; mountPoint = 1; offset = "0 0 0"; deployed = DiscTurretDeployed; stateName[0] = "Idle"; stateTransitionOnTriggerDown[0] = "Activate"; stateName[1] = "Activate"; stateScript[1] = "onActivate"; stateTransitionOnTriggerUp[1] = "Idle"; isLarge = true; emap = true; maxDepSlope = 360; deploySound = TurretDeploySound; minDeployDis = 0.5; maxDeployDis = 5.0; }; datablock ItemData(DiscTurretDeployable) { className = Pack; catagory = "Deployables"; shapeFile = "pack_deploy_turreti.dts"; mass = 3.0; elasticity = 0.2; friction = 0.6; pickupRadius = 1; rotate = false; image = "DiscTurretDeployableImage"; pickUpName = "a Disc turret pack"; emap = true; }; //-------------------------------------------------------------------------- // Functions //-------------------------------------- function DiscTurretDeployableImage::testObjectTooClose(%item) { %mask = ($TypeMasks::VehicleObjectType | $TypeMasks::MoveableObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::ItemObjectType | $TypeMasks::PlayerObjectType); InitContainerRadiusSearch( %item.surfacePt, $MinDeployDistance, %mask ); %test = containerSearchNext(); return %test; } function DiscTurretDeployableImage::testNoTerrainFound(%item) { // created to prevent console errors } function DiscTurretDeployableImage::testNoInteriorFound(%item) { // created to prevent console errors } function DiscTurretDeployableImage::testTurretTooClose(%item, %plyr) { InitContainerRadiusSearch(%item.surfacePt, $TurretIndoorSpaceRadius, $TypeMasks::StaticShapeObjectType); // old function was only checking whether the first object found was a turret -- also wasn't checking // which team the object was on %turretInRange = false; while((%found = containerSearchNext()) != 0) { %foundName = %found.getDataBlock().getName(); if((%foundname $= TurretDeployedFloorIndoor) || (%foundName $= TurretDeployedWallIndoor) || (%foundName $= TurretDeployedCeilingIndoor) || (%foundName $= TurretDeployedOutdoor) || (%foundName $= DiscTurretDeployed)) if (%found.team == %plyr.team) { %turretInRange = true; break; } } return %turretInRange; } function DiscTurretDeployableImage::testTurretSaturation(%item) { %highestDensity = 0; InitContainerRadiusSearch(%item.surfacePt, $TurretIndoorSphereRadius, $TypeMasks::StaticShapeObjectType); %found = containerSearchNext(); while(%found) { %foundName = %found.getDataBlock().getName(); if((%foundname $= TurretDeployedFloorIndoor) || (%foundName $= TurretDeployedWallIndoor) || (%foundName $= TurretDeployedCeilingIndoor) || (%foundName $= TurretDeployedOutdoor) || (%foundName $= DiscTurretDeployed)) { //found one %numTurretsNearby++; %nearbyDensity = testNearbyDensity(%found, $TurretIndoorSphereRadius); if (%nearbyDensity > %highestDensity) %highestDensity = %nearbyDensity; } %found = containerSearchNext(); } if (%numTurretsNearby > %highestDensity) %highestDensity = %numTurretsNearby; return %highestDensity > $TurretIndoorMaxPerSphere; } function DiscTurretDeployableImage::onDeploy(%item, %plyr, %slot) { %searchRange = 5.0; %mask = $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType; %eyeVec = %plyr.getEyeVector(); %eyeTrans = %plyr.getEyeTransform(); %eyePos = posFromTransform(%eyeTrans); %nEyeVec = VectorNormalize(%eyeVec); %scEyeVec = VectorScale(%nEyeVec, %searchRange); %eyeEnd = VectorAdd(%eyePos, %scEyeVec); %searchResult = containerRayCast(%eyePos, %eyeEnd, %mask, 0); if(!%searchResult ) { messageClient(%plyr.client, 'MsgBeaconNoSurface', 'c2Cannot place turret. You are too far from surface.'); return 0; } %terrPt = posFromRaycast(%searchResult); %terrNrm = normalFromRaycast(%searchResult); %intAngle = getTerrainAngle(%terrNrm); %rotAxis = vectorNormalize(vectorCross(%terrNrm, "0 0 1")); if (getWord(%terrNrm, 2) == 1 || getWord(%terrNrm, 2) == -1) %rotAxis = vectorNormalize(vectorCross(%terrNrm, "0 1 0")); %rotation = %rotAxis @ " " @ %intAngle; %plyr.unmountImage(%slot); %plyr.decInventory(%item.item, 1); %deplObj = new Turret() { dataBlock = %item.deployed; position = VectorAdd(%terrPt, VectorScale(%terrNrm, 0.03)); rotation = %rotation; }; %deplObj.setRechargeRate(%deplObj.getDatablock().rechargeRate); %deplObj.team = %plyr.client.team; %deplObj.owner = %plyr.client; %deplObj.setOwnerClient(%plyr.client); if(%deplObj.getTarget() != -1) setTargetSensorGroup(%deplObj.getTarget(), %plyr.client.team); addToDeployGroup(%deplObj); AIDeployObject(%plyr.client, %deplObj); serverPlay3D(%item.deploySound, %deplObj.getTransform()); $TeamDeployedCount[%plyr.team, %item.item]++; %deplObj.deploy(); %deplObj.playThread($AmbientThread, "ambient"); return %deplObj; } function DiscTurretDeployable::onPickup(%this, %obj, %shape, %amount) { // created to prevent console errors } function DeployableDiscTurretBarrel::onFire( %data, %obj, %slot ) { %energy = %obj.getEnergyLevel(); %p = new (LinearProjectile)() { dataBlock = DiscProjectile; initialDirection = %obj.getMuzzleVector(%slot); initialPosition = %obj.getMuzzlePoint(%slot); sourceObject = %obj; damageFactor = 1; sourceSlot = %slot; }; %p.setEnergyPercentage(1); %obj.lastProjectile = %p; MissionCleanup.add(%p); %obj.setEnergyLevel(%energy - %data.fireEnergy); } function DiscTurretDeployed::onDestroyed(%this, %obj, %prevState) { Parent::onDestroyed(%this, %obj, %prevState); $TeamDeployedCount[%obj.team, DiscTurretDeployable]--; %obj.schedule(500, "delete"); } -------------------------------------------------------------------------------- Step #6 // Don't forget to reset the deploy count in defaultGame.cs - // Add to function DefaultGame::clearDeployableMaxes(%game) $TeamDeployedCount[%i, DiscTurretDeployable] = 0; -------------------------------------------------------------------------------- --