Update: Added all the needed code to function ForceFieldBare::damage in gameBase.cs (12/09/01)
Update: added one line to the forceFieldBare datablock to make fields team permiable. 11/29/01
Step #1 // ------------------------------------------ // defaultGame.cs // ------------------------------------------ function DefaultGame::clearDeployableMaxes(%game) { $TeamDeployedCount[%i, ForceFieldDeployable] = 0; } Step #2 // ------------------------------------------ // deployables.cs // ------------------------------------------ 2a)Near the top of the file add this: $TeamDeployableMax[ForceFieldDeployable] = 10; Step #3 // ------------------------------------------ // inventoryHud.cs // ------------------------------------------ Add this near the top of the file: $InvPack[18] = "ForceField"; $NTInvPack[11] = "ForceField"; $NameToInv["ForceField"] = "ForceFieldDeployable"; Step #4 // ------------------------------------------ // pack.cs // ------------------------------------------ exec("scripts/packs/DeployableForceField.cs"); Step #5 // ------------------------------------------ // repairpack.cs // ------------------------------------------ This will handle repairing the forcefield directly. Note: you need to add this to any repair guns your mod uses. 5a) In function repairGunImage::onValidate, add $TypeMasks::ForceFieldObjectType to %searchmasks. 5b) Still in function repairGunImage::onValidate, above this line: if(%scanTarg && !(%scanTarg.getType() & $TypeMasks::InteriorObjectType)) add this: if (%scanTarg) { if (%scanTarg.getType() & $TypeMasks::ForceFieldObjectType) { if (%scanTarg.getDataBlock().getName() $= "DeployedForceField2") %scanTarg = %scanTarg.parent; else %scanTarg = ""; } } 5c) In function repairGunImage::onRepair, add $TypeMasks::ForceFieldObjectType to %searchmasks. 5d) Still in function repairGunImage::onRepair, above these lines: if (%scanTarg) { %pos = getWords(%scanTarg, 1, 3); %obstructMask = $TypeMasks::InteriorObjectType | $TypeMasks::TerrainObjectType; %obstruction = ContainerRayCast(%muzPoint, %pos, %obstructMask, %obj); if (%obstruction) %scanTarg = "0"; } add this: if (%scanTarg) { if (%scanTarg.getType() & $TypeMasks::ForceFieldObjectType) { if (%scanTarg.getDataBlock().getName() $= "DeployedForceField2") { %pos = getWords(%scanTarg, 1, 3); %scanTarg = %scanTarg.parent SPC %pos; } else %scanTarg = ""; } } 5e) In function startRepairing change these lines: %player.repairProjectile = new RepairProjectile() { dataBlock = DefaultRepairBeam; initialDirection = %initialDirection; initialPosition = %initialPosition; sourceObject = %player; sourceSlot = $WeaponSlot; targetObject = %player.repairing; }; MissionCleanup.add(%player.repairProjectile); to this: if (%player.repairing.getDataBlock().getName() $= "DeployedForceField") %targetObject = %player.repairing.field; else %targetObject = %player.repairing; %player.repairProjectile = new RepairProjectile() { dataBlock = DefaultRepairBeam; initialDirection = %initialDirection; initialPosition = %initialPosition; sourceObject = %player; sourceSlot = $WeaponSlot; targetObject = %targetObject; }; MissionCleanup.add(%player.repairProjectile); Step #6 // ------------------------------------------ // player.cs // ------------------------------------------ 6a) In each player datablock add this. Since it's a deployable, only mediums and heavies need it. max[ForceFieldDeployable] = 1; Step #7 // ------------------------------------------ // Projectiles.cs // ------------------------------------------ All of this takes place in function RadiusExplosion 1a) replace: InitContainerRadiusSearch(%position, %radius, $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::TurretObjectType | $TypeMasks::ItemObjectType); with this: InitContainerRadiusSearch(%position, %radius, $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::TurretObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::ItemObjectType); 1b) Below these lines: if (%dist > %radius) continue; add this: if (%targetObject.getType() & $TypeMasks::ForceFieldObjectType) if (%targetObject.getDataBlock().getName() !$= "DeployedForceField2") continue; 1c) Finially, replace %coverage = calcExplosionCoverage(%position, %targetObject, ($TypeMasks::InteriorObjectType | $TypeMasks::TerrainObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::VehicleObjectType)); with this: if (%targetObject.getType() & $TypeMasks::ForceFieldObjectType) %coverage = calcExplosionCoverage(%position, %targetObject, ($TypeMasks::InteriorObjectType | $TypeMasks::TerrainObjectType | $TypeMasks::VehicleObjectType)); else %coverage = calcExplosionCoverage(%position, %targetObject, ($TypeMasks::InteriorObjectType | $TypeMasks::TerrainObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::VehicleObjectType)); Step #8 // ------------------------------------------ // gameBase.cs // ------------------------------------------ Change function ForceFieldBare::damage, to this: function ForceFieldBare::damage(%this, %sourceObject, %position, %amount, %damageType) { if (%this.getDataBlock().getName() $= "DeployedForceField2") %this.parent.getDataBlock().damageObject(%this.parent, %sourceObject, %position, %amount, %damageType); } Step #9 // ------------------------------------------ // DeployableForceField.cs // ------------------------------------------ Create a file called DeployableForceField.cs in your packs directory. Add all this into it: datablock StaticShapeData(DeployedForceField) : StaticShapeDamageProfile { className = ForceField; shapeFile = "turret_muzzlepoint.dts"; maxDamage = 4.0; destroyedLevel = 4.0; disabledLevel = 3.0; dynamicType = $TypeMasks::StaticShapeObjectType; deployedObject = true; cmdCategory = "DSupport"; cmdIcon = CMDSensorIcon; cmdMiniIconName = "commander/MiniIcons/com_deploymotionsensor"; targetNameTag = 'Force'; targetTypeTag = 'Field'; deployAmbientThread = true; heatSignature = 0; }; datablock ForceFieldBareData(DeployedForceField2) : StaticShapeDamageProfile { fadeMS = 1000; baseTranslucency = 0.5; powerOffTranslucency = 0.0; teamPermiable = true; otherPermiable = false; color = "0.0 0.7 0.99"; powerOffColor = "0.0 0.0 0.0"; targetTypeTag = 'ForceField'; texture[0] = "skins/forcef1"; texture[1] = "skins/forcef2"; texture[2] = "skins/forcef3"; texture[3] = "skins/forcef4"; texture[4] = "skins/forcef5"; framesPerSec = 10; numFrames = 5; scrollSpeed = 15; umapping = 1.0; vmapping = 0.15; deployedFrom = ForceFieldDeployable; }; datablock ShapeBaseImageData(ForceFieldDeployableImage) { mass = 20; emap = true; shapeFile = "Stackable1s.dts"; item = ForceFieldDeployable; mountPoint = 1; offset = "0 0 0"; deployed = DeployedForceField; heatSignature = 0; stateName[0] = "Idle"; stateTransitionOnTriggerDown[0] = "Activate"; stateName[1] = "Activate"; stateScript[1] = "onActivate"; stateTransitionOnTriggerUp[1] = "Idle"; isLarge = true; maxDepSlope = 360; // 30 deploySound = ItemPickupSound; minDeployDis = 0.5; maxDeployDis = 5.0; }; datablock ItemData(ForceFieldDeployable) { className = Pack; catagory = "Deployables"; shapeFile = "Stackable1s.dts"; mass = 5.0; elasticity = 0.2; friction = 0.6; pickupRadius = 1; rotate = true; image = "ForceFieldDeployableImage"; pickUpName = "a force field"; heatSignature = 0; emap = true; }; function ForceFieldDeployable::onPickup(%this, %obj, %shape, %amount) { // created to prevent console errors } function DeployedForceField::onDestroyed(%this, %obj, %prevState) { $TeamDeployedCount[%obj.team, ForceFieldDeployable]--; %obj.field.pzone.schedule(480, "delete"); %obj.field.schedule(490, "delete"); %obj.schedule(500, "delete"); } function ForceFieldDeployableImage::onDeploy(%item, %plyr, %slot) { %mask = $TypeMasks::InteriorObjectType | $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType; %vec = %plyr.getEyeVector(); %deplObj = Parent::onDeploy(%item, %plyr, %slot); %x1 = getWord(%vec, 0); %y1 = getWord(%vec, 1); %z1 = getWord(%vec, 2); %endpos = VectorAdd(%item.surfacePt, "0 0 10"); %res = containerRayCast(%item.surfacePt, %endpos, %mask, 0); if(%res) %zscale=VectorDist("0 0 " @ getword(%res,3),"0 0 " @ getword(%item.SurfacePt,2)); else %zscale=10; %extra = %x1; %x2 = %y1; %y2 = %extra; %vec2 = %x2 * -1 SPC %y2 SPC 0; %vec3 = %x2 SPC %y2 * -1 SPC 0; %initpos = VectorAdd(%item.SurfacePt, "0 0 " @ (%zscale / 2.4)); %endpos = VectorAdd(%initpos, VectorScale(%vec2, 10)); %res = containerRayCast(%initpos, %endpos, %mask, 0); if(%res) %left=VectorDist(getword(%res,1) SPC getword(%res,2) @ " 0", getword(%item.SurfacePt, 0) SPC getword(%item.SurfacePt, 1) @ " 0"); else %left=10; %endpos = VectorAdd(%initpos, VectorScale(%vec3, 10)); %res = containerRayCast(%initpos, %endpos, %mask, 0); if(%res) %right=VectorDist(getword(%res,1) SPC getword(%res,2) @ " 0", getword(%item.SurfacePt, 0) SPC getword(%item.SurfacePt, 1) @ " 0"); else %right=10; %wid = %left + %right + 0.2; %av = %wid * 2 / 3; %movepos = VectorAdd(%item.SurfacePt, VectorScale(%vec2, (%left * 1.4))); %centerpos = VectorAdd(%movepos, VectorScale(%vec3, %av)); %centerpos = VectorAdd(%centerpos, "0 0 " @ (%zscale / 2)); if ((%x1 > 0) && (%y1 >= 0)) { %zone = 0; %rad = mAtan(%x1, %y1); } else if((%x1 >= 0) && (%y1 < 0)) { %zone = 1; %y1 *= -1; %rad = mAtan(%y1, %x1); } else if((%x1 < 0) && (%y1 <= 0)) { %zone = 2; %y1 *= -1; %x1 *= -1; %rad = mAtan(%x1, %y1); } else if((%x1 <= 0) && (%y1 > 0)) { %zone = 3; %x1 *= -1; %rad = mAtan(%y1, %x1); } %angle = mRadtoDeg(%rad); if (%zone == 1) %angle += 90; else if (%zone == 2) %angle += 180; else if (%zone == 3) %angle += 270; %rot = " 0 0 1 " @ %angle; %pos = getWords(%deplObj.getTransform(), 0, 2); %deplObj.field = new ForceFieldBare() { position = %movepos; rotation = %rot; scale = %wid @ " 0.02 " @ %zscale; dataBlock = "DeployedForceField2"; parent = %deplObj; team = %plyr.team; }; %deplObj.field.active = true; %deplObj.field.setSelfPowered(); MissionCleanup.add(%deplObj.field); %deplObj.setTransform(%centerpos); %deplObj.team = %plyr.client.team; %deplObj.field.team = %plyr.client.team; %deplObj.owner = %plyr.client; %deplObj.field.owner = %plyr.client; %deplObj.field.pzone.team = %plyr.client.Team; if(%deplObj.field.getTarget() != -1) setTargetSensorGroup(%deplObj.field.getTarget(), %plyr.client.team); %deplObj.zscale = %zscale / 2; } function DeployedForceField2::onAdd(%data, %obj) { Parent::onAdd(%data, %obj); for (%i=0; %i < PZones.getCount(); %i++) { if (PZones.getObject(%i).ffield == %obj) %obj.pzone = PZones.getObject(%i); } } function DeployedForceField2::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType) { %targetObject.parent.getDataBlock().damageObject(%targetObject.parent, %sourceObject, %position, %amount, %damageType); } function ForceFieldBare::isMounted() { }