Free laser turret with your next purchase! -ZOD This was requested by Ultima. I've decided to hand it out so I know who to blame for leaking it Code: -------------------------------------------------------------------------------- //-------------------------------------------------------------------------- // Deployable Laser Turret - by Founder and ZOD // Please credit the authors if you use this in your mod. //-------------------------------------------------------------------------- $TeamDeployableMax[TurretLaserDeployable] = 6; $TeamDeployableMin[TurretLaserDeployable] = 3; // This stuff goes in inventoryHud.cs $InvPack[27] = "Laser Turret"; $NameToInv["Laser Turret"] = "TurretLaserDeployable"; // This stuff goes in hud.cs //$BackpackHudData[20, itemDataName] = "TurretLaserDeployable"; //$BackpackHudData[20, bitmapName] = "gui/hud_new_packturret"; $ControlObjectReticle[DeployableLaserBarrel, bitmap] = "hud_ret_sniper"; $ControlObjectReticle[DeployableLaserBarrel, frame] = false; // Don't forget to put this in your armors datablock // max[TurretLaserDeployable] = 1; // 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 $= "TurretLaserDeployable") { // %disqualified = $NotDeployableReason::None; // } // else { // %disqualified = $NotDeployableReason::ObjectTooClose; // } // } // This goes as the last line in deployables.cs // exec("scripts/turrets/laserTurret.cs"); // Don't forget to reset the deploy count in defaultGame.cs - // Add to function DefaultGame::clearDeployableMaxes(%game) // $TeamDeployedCount[%i, TurretLaserDeployable] = 0; //-------------------------------------------------------------------------- // Datablocks //-------------------------------------- datablock SensorData(LaserTurretSensor) { detects = true; detectsUsingLOS = true; detectsPassiveJammed = false; detectsActiveJammed = false; detectsCloaked = false; detectionPings = true; detectRadius = 100; }; datablock TurretData(LaserDeployed) : TurretDamageProfile { className = DeployedTurret; shapeFile = "camera.dts"; mass = 5.0; maxDamage = 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.10; barrel = DeployableLaserBarrel; canControl = true; cmdCategory = "DTactical"; cmdIcon = CMDTurretIcon; cmdMiniIconName = "commander/MiniIcons/com_turret_grey"; targetNameTag = 'Laser'; targetTypeTag = 'Turret'; sensorData = LaserTurretSensor; sensorRadius = LaserTurretSensor.detectRadius; sensorColor = "191 0 226"; firstPersonOnly = true; renderWhenDestroyed = false; debrisShapeName = "debris_generic_small.dts"; debris = TurretDebrisSmall; }; datablock TurretImageData(DeployableLaserBarrel) { shapeFile = "turret_muzzlepoint.dts"; item = LaserTurretBarrel; rotation = "0 0 0 0"; offset = "0 0 0"; projectile = BasicSniperShot; projectileType = SniperProjectile; usesEnergy = true; fireEnergy = 20; minEnergy = 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 = 100; // State transitions stateName[0] = "Activate"; stateTransitionOnNotLoaded[0] = "Dead"; stateTransitionOnLoaded[0] = "ActivateReady"; stateName[1] = "ActivateReady"; stateSequence[1] = "Activate"; stateSound[1] = IBLSwitchSound; stateTimeoutValue[1] = 1; stateTransitionOnTimeout[1] = "Ready"; stateTransitionOnNotLoaded[1] = "Deactivate"; stateTransitionOnNoAmmo[1] = "NoAmmo"; stateName[2] = "Ready"; stateTransitionOnNotLoaded[2] = "Deactivate"; stateTransitionOnTriggerDown[2] = "Fire"; stateTransitionOnNoAmmo[2] = "NoAmmo"; stateName[3] = "Fire"; stateTransitionOnTimeout[3] = "Reload"; stateTimeoutValue[3] = 0.3; stateFire[3] = true; stateShockwave[3] = true; stateRecoil[3] = LightRecoil; stateAllowImageChange[3] = false; stateSequence[3] = "Fire"; stateSound[3] = IBLFireSound; stateScript[3] = "onFire"; stateName[4] = "Reload"; stateTimeoutValue[4] = 0.8; stateAllowImageChange[4] = false; stateSequence[4] = "Reload"; stateTransitionOnTimeout[4] = "Ready"; stateTransitionOnNotLoaded[4] = "Deactivate"; stateTransitionOnNoAmmo[4] = "NoAmmo"; stateName[5] = "Deactivate"; stateSequence[5] = "Activate"; stateDirection[5] = false; stateTimeoutValue[5] = 1; stateTransitionOnLoaded[5] = "ActivateReady"; stateTransitionOnTimeout[5] = "Dead"; stateName[6] = "Dead"; stateTransitionOnLoaded[6] = "ActivateReady"; stateName[7] = "NoAmmo"; stateTransitionOnAmmo[7] = "Reload"; stateSequence[7] = "NoAmmo"; }; datablock ShapeBaseImageData(TurretLaserDeployableImage) { mass = 15; shapeFile = "pack_deploy_turreti.dts"; item = TurretLaserDeployable; mountPoint = 1; offset = "0 0 0"; deployed = LaserDeployed; 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(TurretLaserDeployable) { className = Pack; catagory = "Deployables"; shapeFile = "pack_deploy_turreti.dts"; mass = 3.0; elasticity = 0.2; friction = 0.6; pickupRadius = 1; rotate = false; image = "TurretLaserDeployableImage"; pickUpName = "a laser turret pack"; emap = true; }; //-------------------------------------------------------------------------- // Functions //-------------------------------------- function TurretLaserDeployableImage::testObjectTooClose(%item) { %mask = ($TypeMasks::VehicleObjectType | $TypeMasks::MoveableObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::ItemObjectType | $TypeMasks::PlayerObjectType); InitContainerRadiusSearch( %item.surfacePt, $MinDeployDistance, %mask ); %test = containerSearchNext(); return %test; } function TurretLaserDeployableImage::testNoTerrainFound(%item) { // created to prevent console errors } function TurretLaserDeployableImage::testNoInteriorFound(%item) { // created to prevent console errors } function TurretLaserDeployableImage::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 $= LaserDeployed)) if (%found.team == %plyr.team) { %turretInRange = true; break; } } return %turretInRange; } function TurretLaserDeployableImage::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 $= LaserDeployed)) { //found one %numTurretsNearby++; %nearbyDensity = testNearbyDensity(%found, $TurretIndoorSphereRadius); if (%nearbyDensity > %highestDensity) %highestDensity = %nearbyDensity; } %found = containerSearchNext(); } if (%numTurretsNearby > %highestDensity) %highestDensity = %numTurretsNearby; return %highestDensity > $TurretIndoorMaxPerSphere; } function TurretLaserDeployableImage::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 TurretLaserDeployable::onPickup(%this, %obj, %shape, %amount) { // created to prevent console errors } function DeployableLaserBarrel::onFire( %data, %obj, %slot ) { %energy = %obj.getEnergyLevel(); %p = new (SniperProjectile)() { dataBlock = BasicSniperShot; 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 LaserDeployed::onDestroyed(%this, %obj, %prevState) { Parent::onDestroyed(%this, %obj, %prevState); $TeamDeployedCount[%obj.team, TurretLaserDeployable]--; %obj.schedule(500, "delete"); }