mirror of
https://github.com/Ragora/T2-ACCM.git
synced 2026-03-08 06:50:32 +00:00
Initial commit.
This commit is contained in:
commit
f5a6cfce9b
262 changed files with 128936 additions and 0 deletions
722
Scripts/ModScripts/AI/DroneAI.cs
Normal file
722
Scripts/ModScripts/AI/DroneAI.cs
Normal file
|
|
@ -0,0 +1,722 @@
|
|||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
// Drone AI by Dondelium_X
|
||||
// CCM v3.4
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
$Drone::DetectDist = 500;
|
||||
$Drone::TurnImpulse = 123;
|
||||
$Drone::FrdImpulse = 525;
|
||||
//$Drone::TurnImpulse = 675 / 3;
|
||||
//$Drone::FrdImpulse = 525 * 3;
|
||||
$Drone::newTargetChance = "1 100";
|
||||
|
||||
$Drone::paths = 4;
|
||||
$Drone::path[1,1] = "0 1500 1000";
|
||||
$Drone::path[1,2] = "1500 0 1000";
|
||||
$Drone::path[1,3] = "0 -1500 1000";
|
||||
$Drone::path[1,4] = "-1500 0 1000";
|
||||
|
||||
$Drone::path[2,1] = "0 -1500 1000";
|
||||
$Drone::path[2,2] = "-1500 0 1000";
|
||||
$Drone::path[2,3] = "0 1500 1000";
|
||||
$Drone::path[2,4] = "1500 0 1000";
|
||||
|
||||
$Drone::path[3,1] = "0 2500 750";
|
||||
$Drone::path[3,2] = "0 2500 1250";
|
||||
$Drone::path[3,3] = "0 -2500 1250";
|
||||
$Drone::path[3,4] = "0 -2500 750";
|
||||
|
||||
$Drone::path[4,1] = "2500 0 750";
|
||||
$Drone::path[4,2] = "2500 0 1250";
|
||||
$Drone::path[4,3] = "-2500 0 1250";
|
||||
$Drone::path[4,4] = "-2500 0 750";
|
||||
|
||||
//-----Manuver Index-----
|
||||
|
||||
$flightManuvers::Behind[0] = Immelman;
|
||||
$flightManuvers::Behind[1] = HalfFlip;
|
||||
$flightManuvers::Behind[2] = BreakRight;
|
||||
$flightManuvers::Behind[3] = BreakLeft;
|
||||
$flightManuvers::Behind[4] = BarrelRoll;
|
||||
$flightManuvers::Behind[5] = WingWaggle;
|
||||
$flightManuvers::Behind[6] = Reversal;
|
||||
|
||||
|
||||
//-----Manuvers-----
|
||||
|
||||
//Immelman
|
||||
$flightManuver::Points[Immelman] = 5; //This signifies how many points are in the manuver
|
||||
$flightManuver::Point[Immelman,0] = "0 1 0 0 0 1"; //each point represents the 3 numbers of the vector of the desired forward vector,
|
||||
$flightManuver::Point[Immelman,1] = "0 0 1 0 -1 0"; //and then the 3 numbers of the vector for the desired Up vector
|
||||
$flightManuver::Point[Immelman,2] = "0 -1 0 0 0 -1";
|
||||
$flightManuver::Point[Immelman,3] = "0 -1 0 1 0 0";
|
||||
$flightManuver::Point[Immelman,4] = "0 -1 0 0 0 1";
|
||||
|
||||
//halfFlip
|
||||
$flightManuver::Points[HalfFlip] = 3;
|
||||
$flightManuver::Point[HalfFlip,0] = "0 1 0 0 0 1";
|
||||
$flightManuver::Point[HalfFlip,1] = "0 0 1 0 -1 0";
|
||||
$flightManuver::Point[HalfFlip,2] = "0 -1 0 0 0 -1";
|
||||
|
||||
//breakRight
|
||||
$flightManuver::Points[BreakRight] = 3;
|
||||
$flightManuver::Point[BreakRight,0] = "0 1 0 0 0 1";
|
||||
$flightManuver::Point[BreakRight,1] = "0 1 0 1 0 0";
|
||||
$flightManuver::Point[BreakRight,2] = "1 0 0 0 -1 0";
|
||||
|
||||
//BreakLeft
|
||||
$flightManuver::Points[BreakLeft] = 3;
|
||||
$flightManuver::Point[BreakLeft,0] = "0 1 0 0 0 1";
|
||||
$flightManuver::Point[BreakLeft,1] = "0 1 0 -1 0 0";
|
||||
$flightManuver::Point[BreakLeft,2] = "-1 0 0 0 -1 0";
|
||||
|
||||
//BarrelRoll
|
||||
$flightManuver::Points[BarrelRoll] = 5;
|
||||
$flightManuver::Point[BarrelRoll,0] = "0 1 0 0 0 1";
|
||||
$flightManuver::Point[BarrelRoll,1] = "0 1 0 1 0 0";
|
||||
$flightManuver::Point[BarrelRoll,2] = "0 1 0 0 0 -1";
|
||||
$flightManuver::Point[BarrelRoll,3] = "0 1 0 -1 0 0";
|
||||
$flightManuver::Point[BarrelRoll,4] = "0 1 0 0 0 1";
|
||||
|
||||
//WingWaggle
|
||||
$flightManuver::Points[WingWaggle] = 4;
|
||||
$flightManuver::Point[WingWaggle,0] = "0 1 0 0 0 1";
|
||||
$flightManuver::Point[WingWaggle,1] = "-1 1 0 0 0 1";
|
||||
$flightManuver::Point[WingWaggle,2] = "1 1 0 0 0 1";
|
||||
$flightManuver::Point[WingWaggle,3] = "0 1 0 0 0 1";
|
||||
|
||||
//Reversal
|
||||
$flightManuver::Points[Reversal] = 7;
|
||||
$flightManuver::Point[Reversal,0] = "0 1 0 0 0 1";
|
||||
$flightManuver::Point[Reversal,1] = "0 0 1 0 -1 0";
|
||||
$flightManuver::Point[Reversal,2] = "0 0 1 1 0 0";
|
||||
$flightManuver::Point[Reversal,3] = "1 0 0 0 0 -1";
|
||||
$flightManuver::Point[Reversal,4] = "0 0 -1 -1 0 0";
|
||||
$flightManuver::Point[Reversal,5] = "0 0 -1 0 1 0";
|
||||
$flightManuver::Point[Reversal,6] = "0 1 0 0 0 1";
|
||||
|
||||
//This is a function for mass spawning
|
||||
function DroneBattle(%pos, %radius, %number, %teamlow, %teamhigh, %maxskill){
|
||||
for(%i = 0; %i < %number; %i++){
|
||||
%startpos = vectorAdd(%pos,(getRandom(0, %radius) - (%radius / 2))@" "@(getRandom(0, %radius) - (%radius / 2))@" 0");
|
||||
%rotation = "0 0 1 "@getRandom(1,360);
|
||||
if(%teamlow != %teamhigh)
|
||||
%team = getRandom(%teamlow,%teamhigh);
|
||||
else
|
||||
%team = %teamlow;
|
||||
StartDrone(%startpos,%rotation,%team,getRandom(1,%maxskill));
|
||||
}
|
||||
}
|
||||
|
||||
//This sets up the drone and the functions needed to start the drone.
|
||||
function StartDrone(%pos, %rotation, %team, %skill){
|
||||
if(%team $= "")
|
||||
%team = 0;
|
||||
if(%pos $= "")
|
||||
%pos = "0 0 300";
|
||||
if(%rotation $= "")
|
||||
%rotation = "1 0 0 0";
|
||||
if(%skill !$= "ace"){
|
||||
if(%skill $= "" || %skill < 1)
|
||||
%skill = 1;
|
||||
else if(%skill > 10)
|
||||
%skill = 10;
|
||||
}
|
||||
%Drone = new FlyingVehicle()
|
||||
{
|
||||
dataBlock = ScoutFlyer;
|
||||
position = %pos;
|
||||
rotation = %rotation;
|
||||
team = %team;
|
||||
};
|
||||
MissionCleanUp.add(%Drone);
|
||||
|
||||
setTargetSensorGroup(%Drone.getTarget(), %team);
|
||||
|
||||
%drone.isdrone = 1;
|
||||
%drone.dodgeGround = 0;
|
||||
|
||||
if(%skill $= "ace"){
|
||||
%skill = 10;
|
||||
%drone.isace = 1;
|
||||
}
|
||||
|
||||
%drone.skill = 0.2 + (%skill / 12.5);
|
||||
|
||||
schedule(100, 0, "DroneForwardImpulse", %drone);
|
||||
schedule(101, 0, "DronefindTarget", %drone);
|
||||
schedule(102, 0, "DroneScanGround", %drone);
|
||||
|
||||
return %drone;
|
||||
}
|
||||
|
||||
//This makes the drone move forward until it dies
|
||||
function DroneForwardImpulse(%obj){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
if(!%obj.isace){
|
||||
if(vectorLen(%obj.getVelocity()) < 165)
|
||||
%obj.applyImpulse(%obj.getPosition(),vectorScale(%obj.getForwardVector(),$Drone::FrdImpulse));
|
||||
}
|
||||
else{
|
||||
if(vectorLen(%obj.getVelocity()) < 225)
|
||||
%obj.applyImpulse(%obj.getPosition(),vectorScale(%obj.getForwardVector(),$Drone::FrdImpulse * 3));
|
||||
}
|
||||
schedule(100, 0, "DroneForwardImpulse", %obj);
|
||||
}
|
||||
|
||||
function DroneScanGround(%obj){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
%vec = %obj.getForwardVector();
|
||||
%vector = vectorAdd(%obj.getPosition(),"0 0 -500");
|
||||
%searchResult = containerRayCast(%obj.getWorldBoxCenter(), %vector, $TypeMasks::TerrainObjectType, %obj);
|
||||
if(%searchResult){
|
||||
%z = getWord(%vec,2);
|
||||
%height = vectorDist(%obj.getPosition(),posFromRaycast(%searchresult));
|
||||
if(%z < 0){
|
||||
if(%height <= (200 + ((%z * -1) * 300))){
|
||||
%obj.dodgeground = 1;
|
||||
schedule(100, 0, "DroneDodgeGround", %obj);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
schedule(100, 0, "DroneScanGround", %obj);
|
||||
}
|
||||
|
||||
function DroneDodgeGround(%obj){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
%vec = %obj.getForwardVector();
|
||||
%z = getWord(%vec,2);
|
||||
if(%z > 0){
|
||||
%obj.dodgeground = 0;
|
||||
schedule(100, 0, "DronefindTarget", %obj);
|
||||
schedule(101, 0, "DroneScanGround", %obj);
|
||||
return;
|
||||
}
|
||||
%pos = vectorAdd(%obj.getPosition(),%vec);
|
||||
%obj.applyImpulse(%pos,vectorScale("0 0 1",$Drone::TurnImpulse * %obj.skill));
|
||||
schedule(100, 0, "DroneDodgeGround", %obj);
|
||||
}
|
||||
|
||||
//This function checks the area around it for any targets.
|
||||
function DronefindTarget(%obj){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
%pos = %obj.getposition();
|
||||
InitContainerRadiusSearch(%pos, $drone::detectdist + (800 + (600 * %obj.skill)), $TypeMasks::VehicleObjectType);
|
||||
while ((%searchResult = containerSearchNext()) != 0){
|
||||
%objtarget = firstWord(%searchResult);
|
||||
if(isObject(%objtarget) && %objTarget !$= %obj){
|
||||
%trgtype = %objtarget.getClassName();
|
||||
if(%trgtype $= "FlyingVehicle" && %objtarget.team != %obj.team){
|
||||
%testPos = %objtarget.getWorldBoxCenter();
|
||||
%distance = vectorDist(%objtarget.getPosition(),%pos);
|
||||
if (%distance > 0){
|
||||
%target = %objtarget;
|
||||
DroneDetermineManuver(%obj, %target);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
schedule(100, 0, "DronePatrol", %obj);
|
||||
}
|
||||
|
||||
function DronePatrol(%obj){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
if($Drone::paths > 0){
|
||||
if(%obj.path $= ""){
|
||||
%obj.path = getRandom(1,$Drone::paths);
|
||||
%obj.point = 0;
|
||||
}
|
||||
%obj.point++;
|
||||
if($Drone::path[%obj.path,%obj.point] $= ""){
|
||||
schedule(100, 0, "DronefindTarget", %obj);
|
||||
%obj.path = "";
|
||||
%obj.point = "";
|
||||
}
|
||||
else
|
||||
schedule(100,0,"dronemovetopoint",%obj,$Drone::path[%obj.path,%obj.point]);
|
||||
}
|
||||
else
|
||||
schedule(500, 0, "DronefindTarget", %obj);
|
||||
}
|
||||
|
||||
function DroneMoveToPoint(%obj,%Tpos){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
if(%obj.dodgeground == 1)
|
||||
return;
|
||||
%pos = %obj.getPosition();
|
||||
%objfrd = %obj.getForwardVector();
|
||||
%objup = %obj.getUpVector();
|
||||
|
||||
%dist = vectorDist(%pos,%Tpos);
|
||||
%aimvec = vectorNormalize(vectorSub(%Tpos,%pos));
|
||||
|
||||
%vec = vectorSub(%aimvec , %objfrd);
|
||||
%vec = vectorCross(%vec, %objfrd);
|
||||
%vec = vectorNormalize(vectorCross(%objfrd, %vec));
|
||||
if(vectorDist(%objfrd,vectorNormalize(%aimvec)) < 0.1)
|
||||
%obj.applyImpulse(vectorAdd(%obj.getPosition(),vectorScale(%objfrd,($Drone::TurnImpulse / 2))),%vec);
|
||||
else if(vectorDist(%objup, %vec) > 0.1){
|
||||
%vec = vectorSub(%vec, %objup);
|
||||
%vec = vectorCross(%vec, %objup);
|
||||
%vec = vectorNormalize(vectorCross(%objup, %vec));
|
||||
%pos = vectorAdd(%obj.getPosition(),vectorScale(%objup,$Drone::TurnImpulse * 3 * %obj.skill));
|
||||
%obj.applyImpulse(%pos,%vec);
|
||||
}
|
||||
else
|
||||
%obj.applyImpulse(vectorAdd(%obj.getPosition(),%objfrd),vectorScale(%vec,$Drone::TurnImpulse * %obj.skill));
|
||||
if(getRandom(0,getWord($Drone::newTargetChance,1)) <= (getWord($Drone::newTargetChance,0) * 10))
|
||||
schedule(100, 0, "DronefindTarget", %obj, %target);
|
||||
else if(%dist < 25)
|
||||
schedule(100, 0, "DronePatrol", %obj);
|
||||
else
|
||||
schedule(100, 0, "DroneMoveToPoint", %obj, %tpos);
|
||||
}
|
||||
|
||||
//This function figures out what the drone should do from where the target is.
|
||||
function DroneDetermineManuver(%obj, %target){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
if(!isObject(%target)){
|
||||
DronefindTarget(%obj);
|
||||
return;
|
||||
}
|
||||
%pos = %obj.getPosition();
|
||||
%Tpos = %Target.getPosition();
|
||||
%objfrd = %obj.getForwardVector();
|
||||
%trgfrd = %target.getForwardVector();
|
||||
%vec = vectorSub(%Tpos,%pos);
|
||||
%dirdist = vectorDist(%objfrd,vectorNormalize(%vec));
|
||||
%vecdist = vectorDist(%objfrd,%trgfrd);
|
||||
if(%dirdist > 1.41){
|
||||
if(%vecdist < 1.41 && vectorDist(%pos,%Tpos) < 2000){
|
||||
UnderFireManuver(%obj, $flightManuvers::Behind[getRandom(0,6)], "");
|
||||
}
|
||||
else
|
||||
TurnToFire(%obj, %target);
|
||||
}
|
||||
else
|
||||
TurnToFire(%obj, %target);
|
||||
%obj.target = %target;
|
||||
}
|
||||
|
||||
function TurnToFire(%obj, %target){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
if(!isObject(%target)){
|
||||
DronefindTarget(%obj);
|
||||
return;
|
||||
}
|
||||
if(%obj.dodgeground == 1)
|
||||
return;
|
||||
|
||||
%pos = %obj.getPosition();
|
||||
%Tpos = %target.getPosition();
|
||||
%objfrd = %obj.getForwardVector();
|
||||
%trgfrd = %target.getForwardVector();
|
||||
%objup = %obj.getUpVector();
|
||||
%Tvel = %target.getVelocity();
|
||||
|
||||
%dist = vectorDist(%pos,%Tpos);
|
||||
%aimPos = vectorAdd(%Tpos, vectorScale(%Tvel,(%dist / 1750)));
|
||||
%aimvec = vectorNormalize(vectorSub(%aimPos,%pos));
|
||||
|
||||
if(vectorDist(%objfrd,%aimvec) < 0.1 && %dist <= 1000){
|
||||
if((vectorDist(%objfrd,%trgfrd) < 0.2 || vectorDist(%objfrd,%trgfrd) > 1.8) && %obj.missiling != 1){
|
||||
%obj.setImageTrigger(4, true);
|
||||
%obj.missiling = 1;
|
||||
}
|
||||
else if(%obj.missiling == 1){
|
||||
%obj.setImageTrigger(4, false);
|
||||
%obj.missiling = 0;
|
||||
}
|
||||
// if (%obj.firing != 1){
|
||||
%obj.setImageTrigger(2, true);
|
||||
%obj.setImageTrigger(3, true);
|
||||
%obj.firing = 1;
|
||||
// }
|
||||
}
|
||||
else{
|
||||
if(%obj.firing == 1){
|
||||
%obj.setImageTrigger(2, false);
|
||||
%obj.setImageTrigger(3, false);
|
||||
%obj.firing = 0;
|
||||
}
|
||||
if(%obj.missiling == 1){
|
||||
%obj.setImageTrigger(4, false);
|
||||
%obj.missiling = 0;
|
||||
}
|
||||
}
|
||||
%vec = vectorSub(%aimvec , %objfrd);
|
||||
%vec = vectorCross(%vec, %objfrd);
|
||||
%vec = vectorNormalize(vectorCross(%objfrd, %vec));
|
||||
if(vectorDist(%objfrd,%trgfrd) > 1.8 && %dist <= 120){
|
||||
%vec = vectorScale(%vec, -1);
|
||||
if(vectorDist(%objfrd,vectorNormalize(%aimvec)) > 1.8)
|
||||
%obj.applyImpulse(vectorAdd(%obj.getPosition(),vectorScale(%objfrd,($Drone::TurnImpulse / 2))),%vec);
|
||||
else if(vectorDist(%objup, %vec) > 0.1){
|
||||
%vec = vectorSub(%vec, %objup);
|
||||
%vec = vectorCross(%vec, %objup);
|
||||
%vec = vectorNormalize(vectorCross(%objup, %vec));
|
||||
%pos = vectorAdd(%obj.getPosition(),vectorScale(%objup,$Drone::TurnImpulse * 3 * %obj.skill));
|
||||
%obj.applyImpulse(%pos,%vec);
|
||||
}
|
||||
else
|
||||
%obj.applyImpulse(vectorAdd(%obj.getPosition(),%objfrd),vectorScale(%vec,$Drone::TurnImpulse * %obj.skill));
|
||||
}
|
||||
else if(vectorDist(%objfrd,vectorNormalize(%aimvec)) < 0.1)
|
||||
%obj.applyImpulse(vectorAdd(%obj.getPosition(),vectorScale(%objfrd,($Drone::TurnImpulse / 2))),%vec);
|
||||
else if(vectorDist(%objup, %vec) > 0.1){
|
||||
%vec = vectorSub(%vec, %objup);
|
||||
%vec = vectorCross(%vec, %objup);
|
||||
%vec = vectorNormalize(vectorCross(%objup, %vec));
|
||||
%pos = vectorAdd(%obj.getPosition(),vectorScale(%objup,$Drone::TurnImpulse * 3 * %obj.skill));
|
||||
%obj.applyImpulse(%pos,%vec);
|
||||
}
|
||||
else
|
||||
%obj.applyImpulse(vectorAdd(%obj.getPosition(),%objfrd),vectorScale(%vec,$Drone::TurnImpulse * %obj.skill));
|
||||
if(getRandom(0,getWord($Drone::newTargetChance,1)) <= getWord($Drone::newTargetChance,0))
|
||||
schedule(100, 0, "DronefindTarget", %obj, %target);
|
||||
else
|
||||
schedule(100, 0, "TurnToFire", %obj, %target);
|
||||
}
|
||||
|
||||
//This function preforms the manuver choosen in Determine Maunver function.
|
||||
function UnderFireManuver(%obj, %manuver, %point, %count){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
if(%obj.dodgeground == 1)
|
||||
return;
|
||||
if(%count $= "")
|
||||
%count = 0;
|
||||
if(%point $= ""){
|
||||
%point = 0;
|
||||
SetPointVectors(%obj, %manuver);
|
||||
}
|
||||
if(%count >= 30){
|
||||
schedule(100, 0, "DroneDetermineManuver", %obj, %obj.target);
|
||||
return;
|
||||
}
|
||||
%frdvec = %obj.getForwardVector();
|
||||
%upvec = %obj.getUpVector();
|
||||
if(vectorDist(%frdvec, %obj.pointvecfront[%point]) < 0.15 && vectorDist(%upvec, %obj.pointvectop[%point]) < 0.15){
|
||||
%point++;
|
||||
if(%point < $flightManuver::Points[%manuver])
|
||||
schedule(100, 0, "UnderFireManuver", %obj, %manuver, %point, 0);
|
||||
else
|
||||
schedule(100, 0, "DroneDetermineManuver", %obj, %obj.target);
|
||||
return;
|
||||
}
|
||||
if(vectorDist(%frdvec, %obj.pointvecfront[%point]) > 0.1){
|
||||
%vec = vectorSub(%obj.pointvecfront[%point], %frdvec);
|
||||
%vec = vectorCross(%vec, %frdvec);
|
||||
%vec = vectorCross(%frdvec, %vec);
|
||||
%obj.applyImpulse(vectorAdd(%obj.getPosition(),vectorScale(%frdvec,$Drone::TurnImpulse * %obj.skill)),%vec);
|
||||
}
|
||||
if(vectorDist(%upvec, %obj.pointvectop[%point]) > 0.1){
|
||||
%vec = vectorSub(%obj.pointvectop[%point], %upvec);
|
||||
%vec = vectorCross(%vec, %upvec);
|
||||
%vec = vectorCross(%upvec, %vec);
|
||||
%pos = vectorAdd(%obj.getPosition(),vectorScale(%upvec,$Drone::TurnImpulse * 3 * %obj.skill));
|
||||
%obj.applyImpulse(%pos,%vec);
|
||||
}
|
||||
%count++;
|
||||
schedule(100, 0, "UnderFireManuver", %obj, %manuver, %point, %count);
|
||||
}
|
||||
|
||||
//This function finds what vectors each point in the manuver is compaired to the drone.
|
||||
function SetPointVectors(%obj, %manuver){
|
||||
%up = %obj.getUpVector();
|
||||
%forward = %obj.getForwardVector();
|
||||
%right = vectorNormalize(vectorSub(%obj.getEdge("1 0 0"),%obj.getEdge("-1 0 0")));
|
||||
for(%i = 0; %i < $flightManuver::Points[%manuver]; %i++){
|
||||
%pointdir = $flightManuver::Point[%manuver, %i];
|
||||
%topvec = "0 0 0";
|
||||
%frontvec = "0 0 0";
|
||||
if(getWord(%pointdir, 0) > 0)
|
||||
%frontvec = vectorAdd(%frontvec, %right);
|
||||
else if(getWord(%pointdir, 0) < 0)
|
||||
%frontvec = vectorAdd(%frontvec, vectorScale(%right, -1));
|
||||
if(getWord(%pointdir, 1) > 0)
|
||||
%frontvec = vectorAdd(%frontvec, %forward);
|
||||
else if(getWord(%pointdir, 1) < 0)
|
||||
%frontvec = vectorAdd(%frontvec, vectorScale(%forward, -1));
|
||||
if(getWord(%pointdir, 2) > 0)
|
||||
%frontvec = vectorAdd(%frontvec, %up);
|
||||
else if(getWord(%pointdir, 2) < 0)
|
||||
%frontvec = vectorAdd(%frontvec, vectorScale(%up, -1));
|
||||
|
||||
if(getWord(%pointdir, 3) > 0)
|
||||
%topvec = vectorAdd(%topvec, %right);
|
||||
else if(getWord(%pointdir, 3) < 0)
|
||||
%topvec = vectorAdd(%topvec, vectorScale(%right, -1));
|
||||
if(getWord(%pointdir, 4) > 0)
|
||||
%topvec = vectorAdd(%topvec, %forward);
|
||||
else if(getWord(%pointdir, 4) < 0)
|
||||
%topvec = vectorAdd(%topvec, vectorScale(%forward, -1));
|
||||
if(getWord(%pointdir, 5) > 0)
|
||||
%topvec = vectorAdd(%topvec, %up);
|
||||
else if(getWord(%pointdir, 5) < 0)
|
||||
%topvec = vectorAdd(%topvec, vectorScale(%up, -1));
|
||||
|
||||
%obj.pointvecfront[%i] = vectorNormalize(%frontvec);
|
||||
%obj.pointvectop[%i] = vectorNormalize(%topvec);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
// Tank AI by Dondelium_X
|
||||
// CCM v3.4
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
$DTank::ForwardForce = 7000;
|
||||
$DTank::BackForce = 3000;
|
||||
$DTank::TurnForce = 2500;
|
||||
|
||||
function StartDTank(%pos,%team,%skill){
|
||||
if(%team $= "")
|
||||
%team = 0;
|
||||
if(%pos $= "")
|
||||
%pos = "0 0 300";
|
||||
if(%skill $= "" || %skill < 1)
|
||||
%skill = 1;
|
||||
else if(%skill > 10)
|
||||
%skill = 10;
|
||||
|
||||
%Drone = new HoverVehicle()
|
||||
{
|
||||
dataBlock = HeavyTank;
|
||||
position = %pos;
|
||||
rotation = "0 0 1 0";
|
||||
team = %team;
|
||||
};
|
||||
MissionCleanUp.add(%Drone);
|
||||
|
||||
setTargetSensorGroup(%Drone.getTarget(), %team);
|
||||
|
||||
%drone.skill = 0.6 + (%skill / 25);
|
||||
|
||||
schedule(100, 0, "DTankScanTargets",%drone);
|
||||
}
|
||||
|
||||
function DTankScanTargets(%obj){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
%pos = %obj.getposition();
|
||||
%closestClient = -1;
|
||||
%closestDistance = 32767;
|
||||
%scandist = 2000 * %obj.skill;
|
||||
%airtrgs = "";
|
||||
%groundtrgs = "";
|
||||
%inftrgs = "";
|
||||
InitContainerRadiusSearch(%pos, %scanDist, $TypeMasks::VehicleObjectType | $TypeMasks::PlayerObjectType);
|
||||
while ((%searchResult = containerSearchNext()) != 0){
|
||||
%objtarget = firstWord(%searchResult);
|
||||
if(isObject(%objtarget) && %objTarget !$= %obj && %objtarget.team != %obj.team){
|
||||
%trgtype = %objtarget.getClassName();
|
||||
if(%trgtype $= "FlyingVehicle")
|
||||
%airtrgs = %airtrgs SPC %objtarget;
|
||||
else if(%trgtype $= "HoverVehicle")
|
||||
%groundtrgs = %groundtrgs SPC %objtarget;
|
||||
else if(%trgtype $= "Player")
|
||||
%inftrgs = %inftrgs SPC %objtarget;
|
||||
}
|
||||
}
|
||||
if(%groundtrgs){
|
||||
%target = firstWord(%groundtrgs);
|
||||
%groundtrgs = getWords(%groundtrgs,1,4);
|
||||
DTankGroundCombat(%obj, %target,%groundtrgs);
|
||||
}
|
||||
else if(%inftrgs){
|
||||
%target = firstWord(%inftrgs);
|
||||
%inftrgs = getWords(%inftrgs,1,4);
|
||||
DTankInfCombat(%obj, %target,%inftrgs);
|
||||
}
|
||||
else if(%airtrgs){
|
||||
%target = firstWord(%airtrgs);
|
||||
%airtrgs = getWords(%airtrgs,1,4);
|
||||
DTankAACombat(%obj, %target,%airtrgs);
|
||||
}
|
||||
else{
|
||||
schedule(3000, 0, "DTankScanTargets", %obj);
|
||||
}
|
||||
}
|
||||
|
||||
function DTankGroundCombat(%obj, %target, %Trglist){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
if(!isObject(%target)){
|
||||
%obj.turretobject.setImageTrigger(4,false);
|
||||
%obj.firing = "";
|
||||
if(%TrgList){
|
||||
%target = firstWord(%Trglist);
|
||||
%trglist = getWords(%trglist,1,4);
|
||||
}
|
||||
else{
|
||||
DTankScanTargets(%obj);
|
||||
return;
|
||||
}
|
||||
}
|
||||
%pos = %obj.getPosition();
|
||||
%tpos = %target.getPosition();
|
||||
%frdvec = vectorNormalize(getWords(%obj.getForwardVector(),0,1) SPC "0");
|
||||
%chkvec = vectorSub(%tpos,%pos);
|
||||
%chkvec = vectorNormalize(getWords(%chkvec,0,1) SPC "0");
|
||||
%turnvec = vectorsub(%chkvec,%frdvec);
|
||||
%vecdif = vectorlen(%turnvec);
|
||||
if(vectorDist(%pos,%tpos) > 2000){
|
||||
if(%obj.firing){
|
||||
%obj.firing = "";
|
||||
%obj.turret.setImageTrigger(4,false);
|
||||
}
|
||||
%target = "";
|
||||
}
|
||||
else if(vectorDist(%pos,%tpos) > 500){
|
||||
if(%vecdif >= "0.1"){
|
||||
%vec = vectorCross(%turnvec, %frdvec);
|
||||
%vec = vectorNormalize(vectorCross(%obj.getForwardVector(), %vec));
|
||||
%Imppos = vectorAdd(%pos,%obj.getForwardVector());
|
||||
%obj.applyImpulse(%Imppos,vectorScale(%vec,$DTank::TurnForce * %obj.skill));
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(!%obj.firing){
|
||||
%obj.firing = 1;
|
||||
%obj.turretobject.firetype = 3;
|
||||
%obj.turretobject.setTargetObject(%Target);
|
||||
%obj.turretobject.aquireTime = getSimTime();
|
||||
%obj.turretobject.setImageTrigger(4,true);
|
||||
}
|
||||
if(%vecdif < "1.2" || %vecdif >= "1.6"){
|
||||
%Tvec1 = vectorNormalize(vectorcross(%chkvec,"0 0 1"));
|
||||
%Tvec2 = vectorScale(%Tvec1,-1);
|
||||
if(vectordist(%frdvec,%Tvec1) < vectorDist(%frdvec,%Tvec2))
|
||||
%tovec = vectorSub(%Tvec1,%frdvec);
|
||||
else
|
||||
%tovec = vectorSub(%Tvec2,%frdvec);
|
||||
%vec = vectorCross(%Tvec2, %frdvec);
|
||||
%vec = vectorNormalize(vectorCross(%obj.getForwardVector(), %vec));
|
||||
%Imppos = vectorAdd(%pos,%obj.getForwardVector());
|
||||
%obj.applyImpulse(%Imppos,vectorScale(%vec,$DTank::TurnForce * %obj.skill));
|
||||
}
|
||||
}
|
||||
%obj.applyImpulse(%pos,vectorScale(%obj.getForwardVector(),$DTank::ForwardForce));
|
||||
schedule(100, 0, "DTankGroundCombat",%obj,%target,%Trglist);
|
||||
}
|
||||
|
||||
function DTankAACombat(%obj, %target, %Trglist){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
if(!isObject(%target)){
|
||||
%obj.turretobject.setImageTrigger(2,false);
|
||||
%obj.firing = "";
|
||||
if(%TrgList){
|
||||
%target = firstWord(%Trglist);
|
||||
%trglist = getWords(%trglist,1,4);
|
||||
}
|
||||
else{
|
||||
DTankScanTargets(%obj);
|
||||
return;
|
||||
}
|
||||
}
|
||||
%pos = %obj.getPosition();
|
||||
%tpos = %target.getPosition();
|
||||
if(vectorDist(%pos,%tpos) < 750){
|
||||
if(!%obj.firing){
|
||||
%obj.firing = 1;
|
||||
%obj.turretobject.setTargetObject(%Target);
|
||||
%obj.turretobject.aquireTime = getSimTime();
|
||||
%obj.turretobject.setImageTrigger(2,true);
|
||||
}
|
||||
}
|
||||
else if(vectorDist(%pos,%tpos) > 2000){
|
||||
if(%obj.firing){
|
||||
%obj.firing = "";
|
||||
%obj.turretobject.setImageTrigger(2,false);
|
||||
}
|
||||
%target = "";
|
||||
}
|
||||
schedule(100, 0, "DTankAACombat",%obj,%target,%Trglist);
|
||||
}
|
||||
|
||||
function DTankInfCombat(%obj, %target, %Trglist){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
if(!isObject(%target) || %target.getState() $= "dead"){
|
||||
%obj.turretobject.setImageTrigger(3,false);
|
||||
%obj.firing = "";
|
||||
if(%TrgList){
|
||||
%target = firstWord(%Trglist);
|
||||
%trglist = getWords(%trglist,1,4);
|
||||
}
|
||||
else{
|
||||
DTankScanTargets(%obj);
|
||||
return;
|
||||
}
|
||||
}
|
||||
%pos = %obj.getPosition();
|
||||
%tpos = %target.getPosition();
|
||||
%frdvec = vectorNormalize(getWords(%obj.getForwardVector(),0,1) SPC "0");
|
||||
%chkvec = vectorSub(%tpos,%pos);
|
||||
%chkvec = vectorNormalize(getWords(%chkvec,0,1) SPC "0");
|
||||
%turnvec = vectorsub(%chkvec,%frdvec);
|
||||
%vecdif = vectorlen(%turnvec);
|
||||
if(vectorDist(%pos,%tpos) > 2000){
|
||||
if(%obj.firing){
|
||||
%obj.firing = "";
|
||||
%obj.turret.setImageTrigger(3,false);
|
||||
}
|
||||
%target = "";
|
||||
}
|
||||
else if(vectorDist(%pos,%tpos) > 300){
|
||||
if(%vecdif >= "0.1"){
|
||||
%vec = vectorCross(%turnvec, %frdvec);
|
||||
%vec = vectorNormalize(vectorCross(%obj.getForwardVector(), %vec));
|
||||
%Imppos = vectorAdd(%pos,%obj.getForwardVector());
|
||||
%obj.applyImpulse(%Imppos,vectorScale(%vec,$DTank::TurnForce * %obj.skill));
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(!%obj.firing){
|
||||
%obj.firing = 1;
|
||||
%obj.turretobject.firetype = 1;
|
||||
%obj.turretobject.setTargetObject(%Target);
|
||||
%obj.turretobject.aquireTime = getSimTime();
|
||||
%obj.turretobject.setImageTrigger(3,true);
|
||||
}
|
||||
if(vectorDist(%pos,%tpos) < 100){
|
||||
if(%vecdif <= "1.6"){
|
||||
%vec = vectorCross(%turnvec, %frdvec);
|
||||
%vec = vectorNormalize(vectorCross(%obj.getForwardVector(), %vec));
|
||||
%Imppos = vectorAdd(%pos,%obj.getForwardVector());
|
||||
%obj.applyImpulse(%Imppos,vectorScale(%vec,$DTank::TurnForce * %obj.skill * "-1"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(%vecdif < "1.2" || %vecdif >= "1.6"){
|
||||
%Tvec1 = vectorNormalize(vectorcross(%chkvec,"0 0 1"));
|
||||
%Tvec2 = vectorScale(%Tvec1,-1);
|
||||
if(vectordist(%frdvec,%Tvec1) < vectorDist(%frdvec,%Tvec2))
|
||||
%tovec = vectorSub(%Tvec1,%frdvec);
|
||||
else
|
||||
%tovec = vectorSub(%Tvec2,%frdvec);
|
||||
%vec = vectorCross(%Tvec2, %frdvec);
|
||||
%vec = vectorNormalize(vectorCross(%obj.getForwardVector(), %vec));
|
||||
%Imppos = vectorAdd(%pos,%obj.getForwardVector());
|
||||
%obj.applyImpulse(%Imppos,vectorScale(%vec,$DTank::TurnForce * %obj.skill));
|
||||
}
|
||||
}
|
||||
}
|
||||
%obj.applyImpulse(%pos,vectorScale(%obj.getForwardVector(),$DTank::ForwardForce));
|
||||
schedule(100, 0, "DTankInfCombat",%obj,%target,%Trglist);
|
||||
}
|
||||
283
Scripts/ModScripts/AI/S11AI.cs
Normal file
283
Scripts/ModScripts/AI/S11AI.cs
Normal file
|
|
@ -0,0 +1,283 @@
|
|||
$S11manuverforce = 75;
|
||||
$S11flyforce = 350;
|
||||
$S11forwardspeed = 120;
|
||||
$S11hoverheight = 3;
|
||||
$S11hoverforce = 100;
|
||||
$S11reconheight = "450 550";
|
||||
$S11reconradius = 700;
|
||||
|
||||
$S11[move] = "TAKEOFF MOVE LAND IDLE";
|
||||
$S11[guard] = "TAKEOFF RECON";
|
||||
$S11[attack] = "TAKEOFF MOE FIRE MOVE LAND IDLE";
|
||||
$S11[rearm] = "TAKEOFF MOVE LAND REARM TAKEOFF MOVE LAND IDLE";
|
||||
|
||||
function S11Think(%obj){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
if(%obj.tasks !$= ""){
|
||||
%task = getWord(%obj.tasks,0);
|
||||
%fun = "S11"@%task;
|
||||
%obj.mode = %task;
|
||||
if(%obj.specvar[%task] !$= "")
|
||||
schedule(10, 0, %fun, %obj, %obj.specvar[%task]);
|
||||
else
|
||||
schedule(10, 0, %fun, %obj);
|
||||
}
|
||||
else{
|
||||
%obj.mode = "IDLE";
|
||||
S11IDLE(%obj);
|
||||
}
|
||||
}
|
||||
|
||||
function S11IDLE(%obj){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
if(%obj.mode !$= "IDLE")
|
||||
return;
|
||||
|
||||
%pos = %obj.getPosition();
|
||||
%mask = $TypeMasks::InteriorObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::TerrainObjectType;
|
||||
%vector = vectorAdd(%pos,vectorScale("0 0 -1",$S11hoverheight));
|
||||
%searchResult = containerRayCast(%pos, %vector, %mask, %obj);
|
||||
if(%searchresult){
|
||||
%obj.applyImpulse(%pos,vectorScale("0 0 1",$S11hoverforce));
|
||||
}
|
||||
|
||||
schedule(100, 0, "S11IDLE", %obj);
|
||||
}
|
||||
|
||||
function S11TAKEOFF(%obj){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
if(%obj.mode !$= "TAKEOFF")
|
||||
return;
|
||||
%pos = %obj.getPosition();
|
||||
%mask = $TypeMasks::InteriorObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::TerrainObjectType;
|
||||
%vector = vectorAdd(%pos,"0 0 -20");
|
||||
%searchResult = containerRayCast(%pos, %vector, %mask, %obj);
|
||||
if(%searchresult)
|
||||
%obj.applyImpulse(%pos,"0 0 200");
|
||||
else{
|
||||
%obj.tasks = getWords(%obj.tasks,1,(getNumberOfWords(%obj.tasks) - 1));
|
||||
S11Think(%obj);
|
||||
return;
|
||||
}
|
||||
schedule(100, 0, "S11TAKEOFF", %obj);
|
||||
}
|
||||
|
||||
function S11LAND(%obj){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
if(%obj.mode !$= "LAND")
|
||||
return;
|
||||
|
||||
%pos = %obj.getPosition();
|
||||
%mask = $TypeMasks::InteriorObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::TerrainObjectType;
|
||||
%vector = vectorAdd(%pos,"0 0" SPC (-10 - $S11hoverheight));
|
||||
%searchResult = containerRayCast(%pos, %vector, %mask, %obj);
|
||||
if(%searchresult){
|
||||
%dist = vectorDist(%pos,posfromraycast(%searchresult));
|
||||
if(%dist <= $S11hoverheight){
|
||||
%obj.tasks = getWords(%obj.tasks,1,(getNumberOfWords(%obj.tasks) - 1));
|
||||
S11Think(%obj);
|
||||
return;
|
||||
}
|
||||
%speed = vectorScale("0 0 -1",%dist);
|
||||
%obj.setVelocity(%speed);
|
||||
}
|
||||
else{
|
||||
%vel = %obj.getVelocity();
|
||||
%reqvel = "0 0 -15";
|
||||
%impvec = vectorScale(vectorSub(%reqvel,%vel),%obj.getDatablock().mass);
|
||||
%obj.applyImpulse(%pos,%impvec);
|
||||
}
|
||||
schedule(100, 0, "S11LAND", %obj);
|
||||
}
|
||||
|
||||
function S11MOVE(%obj, %movepos){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
if(%obj.mode !$= "MOVE")
|
||||
return;
|
||||
|
||||
%pos = %obj.getPosition();
|
||||
%mask = $TypeMasks::InteriorObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::TerrainObjectType;
|
||||
%vector = vectorAdd(%pos,"0 0 -150");
|
||||
%searchResult = containerRayCast(%pos, %vector, %mask, %obj);
|
||||
%vec = "0 0 0";
|
||||
%frd = %obj.getForwardVector();
|
||||
if(vectorlen(%obj.getVelocity()) <= $S11forwardspeed)
|
||||
%vec = vectorScale(%frd,$S11flyforce);
|
||||
if(%searchresult)
|
||||
%vec = vectorAdd(%vec,"0 0 150");
|
||||
%tstpos = getWords(%movepos,0,1) SPC getWord(%pos,2);
|
||||
%dist = vectorDist(%tstpos,%pos);
|
||||
if(%dist > 10){
|
||||
%aimvec = vectorSub(%tstpos,%pos);
|
||||
%tvec = vectorNormalize(vectorCross(%aimvec, %frd));
|
||||
%tvec = vectorNormalize(vectorCross(%frd, %tvec));
|
||||
%obj.applyImpulse(vectorAdd(%pos,%frd),vectorScale(%tvec,$S11manuverforce));
|
||||
}
|
||||
else{
|
||||
if(%obj.specvar["MOVE",2] !$= ""){
|
||||
%obj.specvar["MOVE"] = %obj.specvar["MOVE",2];
|
||||
%obj.specvar["MOVE",2] = "";
|
||||
}
|
||||
%obj.tasks = getWords(%obj.tasks,1,(getNumberOfWords(%obj.tasks) - 1));
|
||||
S11Think(%obj);
|
||||
return;
|
||||
}
|
||||
%obj.applyImpulse(%pos,%vec);
|
||||
schedule(100, 0, "S11MOVE",%obj,%movepos);
|
||||
}
|
||||
|
||||
function S11RECON(%obj,%reconPos){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
if(%obj.mode !$= "RECON")
|
||||
return;
|
||||
|
||||
%pos = %obj.getPosition();
|
||||
%mask = $TypeMasks::InteriorObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::TerrainObjectType;
|
||||
%vector = vectorAdd(%pos,"0 0 -1000");
|
||||
%searchResult = containerRayCast(%pos, %vector, %mask, %obj);
|
||||
if(%searchresult){
|
||||
%frd = %obj.getForwardVector();
|
||||
%vec = "0 0 0";
|
||||
if(vectorlen(%obj.getVelocity()) <= $S11forwardspeed)
|
||||
%vec = vectorScale(%frd,$S11flyforce);
|
||||
%dist = vectorDist(%pos,posfromraycast(%searchresult));
|
||||
if(%dist < getWord($S11reconheight,0))
|
||||
%vec = vectorAdd(%vec,"0 0 450");
|
||||
if(%dist > getWord($S11reconheight,1))
|
||||
%vec = vectorAdd(%vec,"0 0 -450");
|
||||
|
||||
%tstpos = getWords(%reconPos,0,1) SPC getWord(%pos,2);
|
||||
%dist = vectorDist(%tstpos,%pos);
|
||||
if(%dist > $S11reconradius){
|
||||
%aimvec = vectorSub(%tstpos,%pos);
|
||||
%tvec = vectorNormalize(vectorCross(%aimvec, %frd));
|
||||
%tvec = vectorNormalize(vectorCross(%frd, %tvec));
|
||||
%obj.applyImpulse(vectorAdd(%pos,%frd),vectorScale(%tvec,$S11manuverforce));
|
||||
}
|
||||
%obj.applyImpulse(%pos,%vec);
|
||||
}
|
||||
else{
|
||||
%vel = %obj.getVelocity();
|
||||
%reqvel = "0 0 -50";
|
||||
%impvec = vectorScale(vectorSub(%reqvel,%vel),%obj.getDatablock().mass);
|
||||
%obj.applyImpulse(%pos,%impvec);
|
||||
}
|
||||
schedule(100, 0, "S11RECON",%obj,%reconpos);
|
||||
}
|
||||
|
||||
function S11MOE(%obj,%target){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
if(%obj.mode !$= "MOE")
|
||||
return;
|
||||
if(!isObject(%target)){
|
||||
%obj.tasks = getWords(%obj.tasks,1,(getNumberOfWords(%obj.tasks) - 1));
|
||||
S11Think(%obj);
|
||||
return;
|
||||
}
|
||||
|
||||
%pos = %obj.getPosition();
|
||||
%frd = %obj.getForwardVector();
|
||||
%mask = $TypeMasks::InteriorObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::ForceFieldObjectType | $TypeMasks::TerrainObjectType;
|
||||
%vector = vectorAdd(%pos,vectorScale(%frd,100));
|
||||
%searchResult = containerRayCast(%pos, %vector, %mask, %obj);
|
||||
if(!%searchResult){
|
||||
%tstvec = vectorAdd(%vector,"0 0 -50");
|
||||
%searchResult2 = containerRayCast(%vector, %tstvec, %mask, %obj);
|
||||
if(%searchResult2)
|
||||
%dir = "1";
|
||||
else
|
||||
%dir = "-1";
|
||||
}
|
||||
else
|
||||
%dir = "2";
|
||||
|
||||
%impvec = vectorScale(%obj.getUpVector(),$S11manuverforce * %dir);
|
||||
|
||||
%Tpos = %target.getPosition();
|
||||
%tstpos = getWords(%TPos,0,1) SPC getWord(%pos,2);
|
||||
%aimvec = VectorNormalize(vectorSub(%tstpos,%pos));
|
||||
%dist = vectorDist(%frd,%aimvec);
|
||||
if(%dist > 0.1){
|
||||
%aimvec = vectorSub(%tstpos,%pos);
|
||||
%tvec = vectorNormalize(vectorCross(%aimvec, %frd));
|
||||
%tvec = vectorNormalize(vectorCross(%frd, %tvec));
|
||||
%impvec = vectorAdd(%impvec,vectorScale(%tvec,$S11manuverforce));
|
||||
}
|
||||
if(vectorDist(%pos, %Tpos) < 500){
|
||||
%obj.tasks = getWords(%obj.tasks,1,(getNumberOfWords(%obj.tasks) - 1));
|
||||
S11Think(%obj);
|
||||
return;
|
||||
}
|
||||
|
||||
%obj.applyImpulse(vectorAdd(%pos,%frd),%impvec);
|
||||
if(vectorlen(%obj.getVelocity()) <= $S11forwardspeed)
|
||||
%obj.applyImpulse(%pos,vectorScale(%obj.getForwardVector(),$S11flyforce));
|
||||
|
||||
schedule(100, 0, "S11MOE", %obj,%target);
|
||||
}
|
||||
|
||||
function S11REARM(%obj){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
if(%obj.mode !$= "REARM")
|
||||
return;
|
||||
|
||||
%obj.setVelocity("0 0 0");
|
||||
|
||||
if (%obj.turret.inv[AALauncherAmmo] < 1)
|
||||
%obj.turret.setInventory(AALauncherAmmo, 1);
|
||||
else if(%DamageLevel > 0)
|
||||
%obj.setRepairRate(0.01);
|
||||
else {
|
||||
%obj.setRepairRate(0);
|
||||
S11Think(%obj);
|
||||
return;
|
||||
}
|
||||
|
||||
schedule(100, 0, "S11REARM", %obj, %target);
|
||||
}
|
||||
|
||||
function S11FIRE(%obj,%target){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
if(%obj.mode !$= "FIRE")
|
||||
return;
|
||||
if(!isObject(%target)){
|
||||
%obj.tasks = getWords(%obj.tasks,1,(getNumberOfWords(%obj.tasks) - 1));
|
||||
S11Think(%obj);
|
||||
return;
|
||||
}
|
||||
%turret = %obj.turret;
|
||||
if(%turret.inv[AALauncherAmmo] >= 1){
|
||||
%turret.target = %target;
|
||||
if(%obj.aiming != 1){
|
||||
%obj.aiming = 1;
|
||||
%turret.setTargetObject(%target);
|
||||
%turret.aquireTime = getSimTime();
|
||||
%turret.setImageTrigger(2,true);
|
||||
}
|
||||
else if(isObject(%turret.TLB)){
|
||||
%turret.setImageTrigger(3,true);
|
||||
}
|
||||
}
|
||||
else{
|
||||
%obj.aiming = 0;
|
||||
%turret.setImageTrigger(2,false);
|
||||
%turret.setImageTrigger(3,false);
|
||||
%obj.tasks = getWords(%obj.tasks,1,(getNumberOfWords(%obj.tasks) - 1));
|
||||
S11Think(%obj);
|
||||
return;
|
||||
}
|
||||
%frd = %obj.getForwardVector();
|
||||
%impvec = vectorAdd(vectorScale(%frd,$S11flyforce),"0 0 150");
|
||||
if(vectorlen(%obj.getVelocity()) <= $S11forwardspeed)
|
||||
%obj.applyImpulse(%obj.getPosition(),%impvec);
|
||||
schedule(100, 0, "S11FIRE", %obj, %target);
|
||||
}
|
||||
107
Scripts/ModScripts/AI/S17AI.cs
Normal file
107
Scripts/ModScripts/AI/S17AI.cs
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
$S17moveforce = 500;
|
||||
|
||||
function S17Think(%obj){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
if(%obj.task !$= ""){
|
||||
%task = %obj.task;
|
||||
%fun = "S17"@%task;
|
||||
%obj.mode = %task;
|
||||
cancel(%obj.loop);cancel(%obj.loop);cancel(%obj.loop);
|
||||
if(%obj.specvar[%task] !$= "")
|
||||
%obj.loop = schedule(10, 0, %fun, %obj, %obj.specvar[%task]);
|
||||
else
|
||||
%obj.loop = schedule(10, 0, %fun, %obj);
|
||||
}
|
||||
}
|
||||
|
||||
function S17GUARD(%obj,%pos){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
%obj.mode = "MOVE";
|
||||
S17MOVE(%obj,%pos);
|
||||
}
|
||||
|
||||
function S17MOVE(%obj,%pos){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
if(%obj.mode !$= "MOVE")
|
||||
return;
|
||||
|
||||
%objpos = %obj.getPosition();
|
||||
%dist = vectorDist(%pos,%objpos);
|
||||
if(%dist > 10){
|
||||
%vec = vectorNormalize(vectorSub(%pos,%objpos));
|
||||
%vec = vectorScale(%vec,$S17moveforce);
|
||||
%obj.applyImpulse(%objpos,%vec);
|
||||
}
|
||||
else
|
||||
return;
|
||||
%obj.loop = schedule(100, 0, "S17MOVE",%obj,%pos);
|
||||
}
|
||||
|
||||
function S17ATTACK(%obj,%target){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
if(!isObject(%target)){
|
||||
%obj.val = "";
|
||||
return;
|
||||
}
|
||||
if(%obj.mode !$= "ATTACK"){
|
||||
%obj.val = "";
|
||||
return;
|
||||
}
|
||||
|
||||
%objpos = %obj.getPosition();
|
||||
%trgpos = %target.getPosition();
|
||||
%dist = vectorDist(%trgpos,%objpos);
|
||||
if(%dist > 100){
|
||||
%vec = vectorNormalize(vectorSub(%pos,%objpos));
|
||||
%vec = vectorScale(%vec,$S17moveforce);
|
||||
%obj.applyImpulse(%objpos,%vec);
|
||||
}
|
||||
else {
|
||||
%vec = vectorSub(%trgpos,%objpos);
|
||||
%random = getRandom(1,2);
|
||||
if(%obj.val $= ""){
|
||||
if(%random == 1)
|
||||
%obj.val = "0 0 -1";
|
||||
else
|
||||
%obj.val = "0 0 1";
|
||||
}
|
||||
%vec = vectorNormalize(vectorCross(%vec,%val));
|
||||
%vec = vectorScale(%vec,$S17moveforce);
|
||||
%obj.applyImpulse(%objpos,%vec);
|
||||
}
|
||||
%obj.loop = schedule(100, 0, "S17ATTACK",%obj,%target);
|
||||
}
|
||||
|
||||
function S17REARM(%obj,%target){
|
||||
if(!isObject(%obj))
|
||||
return;
|
||||
if(!isObject(%target)){
|
||||
%target.setRepairRate(0);
|
||||
return;
|
||||
}
|
||||
if(%obj.mode !$= "REARM"){
|
||||
%target.setRepairRate(0);
|
||||
return;
|
||||
}
|
||||
|
||||
%objpos = %obj.getPosition();
|
||||
%trgpos = %target.getPosition();
|
||||
%dist = vectorDist(%trgpos,%objpos);
|
||||
%DamageLevel = %targetObject.getDamageLevel();
|
||||
if(%dist > 6){
|
||||
%vec = vectorNormalize(vectorCross(%vec,%val));
|
||||
%vec = vectorScale(%vec,$S17moveforce);
|
||||
%obj.applyImpulse(%objpos,%vec);
|
||||
}
|
||||
else if(%DamageLevel > 0)
|
||||
%obj.setRepairRate(0.01);
|
||||
else {
|
||||
%obj.setRepairRate(0);
|
||||
return;
|
||||
}
|
||||
%obj.loop = schedule(100, 0, "S17ATTACK",%obj,%target);
|
||||
}
|
||||
71
Scripts/ModScripts/AI/SentinelAI.cs
Normal file
71
Scripts/ModScripts/AI/SentinelAI.cs
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
$sent::patrolwaittime = 10; // 10 secs
|
||||
$sent::patrolsaturation = 2; // 2 sentinel patrolling one point at a time
|
||||
|
||||
// 1 = Normal Sentinel
|
||||
// 2 = Sentinel Monitor
|
||||
|
||||
//==============================================================================
|
||||
// CreateSentinel
|
||||
//------------------------------------------------------------------------------
|
||||
// %pos = position
|
||||
// %team = team
|
||||
// %quantity = how many sentinels to spawn
|
||||
// %type = the type of sentinel to spawn [regular/monitor]
|
||||
//------------------------------------------------------------------------------
|
||||
// It creates a sentinel.
|
||||
//==============================================================================
|
||||
function CreateSentinel(%pos, %quantity, %type)
|
||||
{
|
||||
if(%quantity < 1)
|
||||
return;
|
||||
|
||||
while(%quantity)
|
||||
{
|
||||
%data = (%type == 2 ? "SentinelMonitor" : "SentinelVehicle");
|
||||
%sent = new FlyingVehicle() {
|
||||
datablock = %data;
|
||||
};
|
||||
|
||||
%sent.setTransform(%pos SPC "0 0 1 0");
|
||||
%sent.team = 1;
|
||||
|
||||
MissionCleanup.add(%sent);
|
||||
|
||||
setTargetSensorGroup(%sent.getTarget(), 1);
|
||||
|
||||
$ignoreNextBotConnection = true;
|
||||
%ai = aiConnect("_AISent");
|
||||
ChangeName(%ai, "Sentinel"@%ai);
|
||||
|
||||
%ai.isSentinel = true;
|
||||
%ai.sentVehicle = %sent;
|
||||
%ai.sentinelType = %type;
|
||||
|
||||
%ai.setControlObject(%sent);
|
||||
|
||||
// SentinelAI_PatrolArea(%ai);
|
||||
warn("Sentinel created: "@%ai@", VEHID"@%sent);
|
||||
%quantity--;
|
||||
}
|
||||
}
|
||||
|
||||
function DropSentinel(%id)
|
||||
{
|
||||
if(!isObject(%id) || %id.isSentinel != true)
|
||||
return;
|
||||
|
||||
if(isObject(%id.sentVehicle) && %id.sentVehicle.getDamageState() !$= "Destroyed")
|
||||
%id.sentVehicle.setDamageState(Destroyed);
|
||||
|
||||
%id.drop();
|
||||
}
|
||||
|
||||
function AIConnection::Sentinel_MoveTo(%client, %coords)
|
||||
{
|
||||
%client.clearStep();
|
||||
|
||||
%client.setPilotAim(%coords);
|
||||
%client.setPilotDestination(%coords);
|
||||
}
|
||||
|
||||
function AIConnection::Sentinel_Damaged
|
||||
654
Scripts/ModScripts/AI/SentinelData.cs
Normal file
654
Scripts/ModScripts/AI/SentinelData.cs
Normal file
|
|
@ -0,0 +1,654 @@
|
|||
//==============================================================================
|
||||
// Sentinel Data - Made by Blnukem
|
||||
//==============================================================================
|
||||
// Sentinel Sounds
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
datablock EffectProfile(SentinelTurretSwitchEffect)
|
||||
{
|
||||
effectname = "powered/turret_light_activate";
|
||||
minDistance = 2.5;
|
||||
maxDistance = 5.0;
|
||||
};
|
||||
|
||||
datablock EffectProfile(SentinelTurretFireEffect)
|
||||
{
|
||||
filename = "fx/vehicles/tank_chaingun.wav";
|
||||
minDistance = 2.5;
|
||||
maxDistance = 8.0;
|
||||
};
|
||||
|
||||
datablock EffectProfile(SentinelDeactivateEffect)
|
||||
{
|
||||
effectname = "powered/turret_heavy_reload";
|
||||
minDistance = 2.5;
|
||||
maxDistance = 5.0;
|
||||
};
|
||||
|
||||
datablock EffectProfile(SentinelActivateEffect)
|
||||
{
|
||||
effectname = "powered/turret_light_reload";
|
||||
minDistance = 2.5;
|
||||
maxDistance = 5.0;
|
||||
};
|
||||
|
||||
datablock EffectProfile(SentinelIdleEffect)
|
||||
{
|
||||
effectname = "powered/turret_light_idle";
|
||||
minDistance = 1;
|
||||
maxDistance = 2;
|
||||
};
|
||||
|
||||
datablock AudioProfile(SentinelTurretSwitchSound)
|
||||
{
|
||||
filename = "fx/powered/turret_light_activate.wav";
|
||||
description = AudioClose3d;
|
||||
preload = true;
|
||||
effect = SentinelTurretSwitchEffect;
|
||||
};
|
||||
|
||||
datablock AudioProfile(SentinelTurretFireSound)
|
||||
{
|
||||
filename = "fx/vehicles/tank_chaingun.wav";
|
||||
description = AudioDefaultLooping3d;
|
||||
preload = true;
|
||||
effect = SentinelTurretFireEffect;
|
||||
};
|
||||
|
||||
datablock AudioProfile(SentinelIdleSound)
|
||||
{
|
||||
filename = "fx/powered/turret_light_idle.wav";
|
||||
description = AudioDefaultLooping3d;
|
||||
preload = true;
|
||||
effect = SentinelIdleEffect;
|
||||
};
|
||||
|
||||
datablock AudioProfile(SentinelActivateSound)
|
||||
{
|
||||
filename = "fx/powered/turret_light_reload.wav";
|
||||
description = AudioClose3d;
|
||||
preload = true;
|
||||
effect = SentinelActivateEffect;
|
||||
};
|
||||
|
||||
datablock AudioProfile(SentinelDeactivateSound)
|
||||
{
|
||||
filename = "fx/powered/turret_heavy_reload.wav";
|
||||
description = AudioClose3d;
|
||||
preload = true;
|
||||
effect = SentinelDeactivateEffect;
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// Vehicle Data
|
||||
//==============================================================================
|
||||
// Standard Sentinel
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
datablock FlyingVehicleData(SentinelVehicle) : SentinelDamageProfile
|
||||
{
|
||||
spawnOffset = "0.0 0.0 0.1";
|
||||
|
||||
catagory = "Sentinels";
|
||||
shapeFile = "stackable2s.dts";
|
||||
multipassenger = false;
|
||||
computeCRC = true;
|
||||
|
||||
debrisShapeName = "debris_generic.dts";
|
||||
debris = TurretDebris;
|
||||
renderWhenDestroyed = false;
|
||||
|
||||
drag = 0.15;
|
||||
density = 1.0;
|
||||
|
||||
numMountPoints = 0;
|
||||
|
||||
cameraMaxDist = 15;
|
||||
cameraOffset = 2.5;
|
||||
cameraLag = 0.9;
|
||||
explosion = TurretExplosion;
|
||||
explosionDamage = 0.5;
|
||||
explosionRadius = 5.0;
|
||||
|
||||
maxDamage = 0.5;
|
||||
destroyedLevel = 0.5;
|
||||
|
||||
isShielded = true;
|
||||
energyPerDamagePoint = 160;
|
||||
maxEnergy = 280;
|
||||
rechargeRate = 0.8;
|
||||
|
||||
minDrag = 30;
|
||||
rotationalDrag = 2000;
|
||||
|
||||
maxAutoSpeed = 15;
|
||||
autoAngularForce = 400;
|
||||
autoLinearForce = 300;
|
||||
autoInputDamping = 0.95;
|
||||
|
||||
maxSteeringAngle = 5;
|
||||
horizontalSurfaceForce = 6;
|
||||
verticalSurfaceForce = 4;
|
||||
maneuveringForce = 5000;
|
||||
steeringForce = 3000;
|
||||
steeringRollForce = 0;
|
||||
rollForce = 10;
|
||||
hoverHeight = 10;
|
||||
createHoverHeight = 2;
|
||||
maxForwardSpeed = 15;
|
||||
|
||||
jetForce = 4500;
|
||||
minJetEnergy = 0;
|
||||
jetEnergyDrain = 0; // Auto stabilize speed
|
||||
vertThrustMultiple = 0;
|
||||
|
||||
mass = 100;
|
||||
bodyFriction = 0;
|
||||
bodyRestitution = 0.5;
|
||||
minRollSpeed = 0;
|
||||
softImpactSpeed = 14;
|
||||
hardImpactSpeed = 25;
|
||||
|
||||
minImpactSpeed = 10;
|
||||
speedDamageScale = 0.06;
|
||||
|
||||
collDamageThresholdVel = 23.0;
|
||||
collDamageMultiplier = 0.02;
|
||||
|
||||
jetSound = "";
|
||||
engineSound = SentinelIdleSound;
|
||||
softImpactSound = SoftImpactSound;
|
||||
hardImpactSound = HardImpactSound;
|
||||
|
||||
softSplashSoundVelocity = 10.0;
|
||||
mediumSplashSoundVelocity = 15.0;
|
||||
hardSplashSoundVelocity = 20.0;
|
||||
exitSplashSoundVelocity = 10.0;
|
||||
|
||||
exitingWater = VehicleExitWaterMediumSound;
|
||||
impactWaterEasy = VehicleImpactWaterSoftSound;
|
||||
impactWaterMedium = VehicleImpactWaterMediumSound;
|
||||
impactWaterHard = VehicleImpactWaterMediumSound;
|
||||
waterWakeSound = VehicleWakeMediumSplashSound;
|
||||
|
||||
dustEmitter = LiftoffDustEmitter;
|
||||
triggerDustHeight = 1.0;
|
||||
dustHeight = 0.1;
|
||||
canControl = false;
|
||||
|
||||
minMountDist = 4;
|
||||
|
||||
splashEmitter[0] = VehicleFoamDropletsEmitter;
|
||||
splashEmitter[1] = VehicleFoamEmitter;
|
||||
|
||||
shieldImpact = VehicleShieldImpact;
|
||||
|
||||
cmdCategory = "Tactical";
|
||||
cmdIcon = CMDFlyingScoutIcon;
|
||||
cmdMiniIconName = "commander/MiniIcons/com_scout_grey";
|
||||
targetNameTag = 'Standard';
|
||||
targetTypeTag = 'Sentinel';
|
||||
sensorData = combatSensor;
|
||||
sensorRadius = combatSensor.detectRadius;
|
||||
sensorColor = "9 9 255";
|
||||
|
||||
checkRadius = 5.5;
|
||||
observeParameters = "1 5 5";
|
||||
canObserve = true;
|
||||
|
||||
runningLight[0] = ShrikeLight1;
|
||||
|
||||
shieldEffectScale = "2.0 2.0 2.0";
|
||||
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// Sentinel Monitor Vehicle Data
|
||||
//==============================================================================
|
||||
|
||||
datablock FlyingVehicleData(SentinelMonitor) : SentinelDamageProfile
|
||||
{
|
||||
spawnOffset = "0.0 0.0 0.0";
|
||||
|
||||
catagory = "Sentinels";
|
||||
shapeFile = "beacon.dts";
|
||||
multipassenger = false;
|
||||
computeCRC = true;
|
||||
|
||||
debrisShapeName = "debris_generic.dts";
|
||||
debris = TurretDebris;
|
||||
renderWhenDestroyed = false;
|
||||
|
||||
drag = 4.15;
|
||||
density = 1.0;
|
||||
|
||||
numMountPoints = 0;
|
||||
|
||||
cameraMaxDist = 15;
|
||||
cameraOffset = 2.5;
|
||||
cameraLag = 0.9;
|
||||
explosion = TurretExplosion;
|
||||
explosionDamage = 0.5;
|
||||
explosionRadius = 5.0;
|
||||
|
||||
maxDamage = 50.00;
|
||||
destroyedLevel = 50.00;
|
||||
|
||||
isShielded = true;
|
||||
rechargeRate = 2.5;
|
||||
energyPerDamagePoint = 1;
|
||||
maxEnergy = 500;
|
||||
rechargeRate = 50.0;
|
||||
|
||||
minDrag = 30;
|
||||
rotationalDrag = 2000;
|
||||
|
||||
maxAutoSpeed = 15;
|
||||
autoAngularForce = 400;
|
||||
autoLinearForce = 300;
|
||||
autoInputDamping = 0.95;
|
||||
|
||||
maxSteeringAngle = 5;
|
||||
horizontalSurfaceForce = 6;
|
||||
verticalSurfaceForce = 4;
|
||||
maneuveringForce = 5000;
|
||||
steeringForce = 1000;
|
||||
steeringRollForce = 0;
|
||||
rollForce = 100;
|
||||
hoverHeight = 15;
|
||||
createHoverHeight = 2;
|
||||
maxForwardSpeed = 15;
|
||||
|
||||
jetForce = 1500;
|
||||
minJetEnergy = 0;
|
||||
jetEnergyDrain = 0; // Auto stabilize speed
|
||||
vertThrustMultiple = 0;
|
||||
|
||||
mass = 100;
|
||||
bodyFriction = 0;
|
||||
bodyRestitution = 0.5;
|
||||
minRollSpeed = 0;
|
||||
softImpactSpeed = 14;
|
||||
hardImpactSpeed = 25;
|
||||
|
||||
minImpactSpeed = 25;
|
||||
speedDamageScale = 0.06;
|
||||
|
||||
collDamageThresholdVel = 23.0;
|
||||
collDamageMultiplier = 0.02;
|
||||
|
||||
minTrailSpeed = 0.1;
|
||||
trailEmitter = ContrailEmitter;
|
||||
|
||||
jetSound = "";
|
||||
engineSound = SentinelIdleSound;
|
||||
softImpactSound = SoftImpactSound;
|
||||
hardImpactSound = HardImpactSound;
|
||||
|
||||
softSplashSoundVelocity = 10.0;
|
||||
mediumSplashSoundVelocity = 15.0;
|
||||
hardSplashSoundVelocity = 20.0;
|
||||
exitSplashSoundVelocity = 10.0;
|
||||
|
||||
exitingWater = VehicleExitWaterMediumSound;
|
||||
impactWaterEasy = VehicleImpactWaterSoftSound;
|
||||
impactWaterMedium = VehicleImpactWaterMediumSound;
|
||||
impactWaterHard = VehicleImpactWaterMediumSound;
|
||||
waterWakeSound = VehicleWakeMediumSplashSound;
|
||||
|
||||
dustEmitter = LiftoffDustEmitter;
|
||||
triggerDustHeight = 2.0;
|
||||
dustHeight = 0.0;
|
||||
canControl = false;
|
||||
|
||||
damageEmitter[0] = LightDamageSmoke;
|
||||
damageEmitter[1] = LightDamageSmoke;
|
||||
damageEmitter[2] = DamageBubbles;
|
||||
damageEmitterOffset[0] = "0.0 0.0 0.0 ";
|
||||
damageLevelTolerance[0] = 0.3;
|
||||
damageLevelTolerance[1] = 0.7;
|
||||
numDmgEmitterAreas = 1;
|
||||
|
||||
minMountDist = 4;
|
||||
|
||||
splashEmitter[0] = VehicleFoamDropletsEmitter;
|
||||
splashEmitter[1] = VehicleFoamEmitter;
|
||||
|
||||
shieldImpact = VehicleShieldImpact;
|
||||
|
||||
cmdCategory = "Tactical";
|
||||
cmdIcon = CMDCameraIcon;
|
||||
cmdMiniIconName = "commander/MiniIcons/com_camera_grey";
|
||||
targetNameTag = '';
|
||||
targetTypeTag = 'Monitor';
|
||||
sensorData = combatSensor;
|
||||
sensorRadius = combatSensor.detectRadius;
|
||||
sensorColor = "9 9 255";
|
||||
|
||||
checkRadius = 10.5;
|
||||
observeParameters = "1 5 5";
|
||||
canObserve = true;
|
||||
|
||||
runningLight[0] = ShrikeLight1;
|
||||
|
||||
shieldEffectScale = "2.0 2.0 2.0";
|
||||
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// Image Data
|
||||
//==============================================================================
|
||||
// Standard Sentinel Image Data:
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
datablock ShapeBaseImageData(BodyImage) : SentinelVehicle
|
||||
{
|
||||
offset = "0.0 -0.2 0.3";
|
||||
rotation = "0 0 1 0";
|
||||
shapeFile = "turret_mortar_large.dts";
|
||||
};
|
||||
|
||||
datablock ShapeBaseImageData(RightWing) : SentinelVehicle
|
||||
{
|
||||
offset = "0.2 0.0 0.4";
|
||||
rotation = "0 0 -1 90";
|
||||
shapeFile = "pack_deploy_sensor_pulse.dts";
|
||||
};
|
||||
|
||||
datablock ShapeBaseImageData(LeftWing) : SentinelVehicle
|
||||
{
|
||||
offset = "-0.2 0.0 0.4";
|
||||
rotation = "0 0 1 90";
|
||||
shapeFile = "pack_deploy_sensor_pulse.dts";
|
||||
};
|
||||
|
||||
datablock ShapeBaseImageData(Eye) : SentinelVehicle
|
||||
{
|
||||
offset = "0.0 1.1 0.22";
|
||||
rotation = "1 0 0 90";
|
||||
shapeFile = "beacon.dts";
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// Sentinel Monitor Image Data:
|
||||
//==============================================================================
|
||||
|
||||
datablock ShapeBaseImageData(Front) : SentinelMonitor
|
||||
{
|
||||
offset = "0.0 -0.02 0.0";
|
||||
rotation = "1.0 0.0 0.0 90.0";
|
||||
shapeFile = "camera.dts";
|
||||
};
|
||||
|
||||
datablock ShapeBaseImageData(Rear) : SentinelMonitor
|
||||
{
|
||||
offset = "0.0 0.02 0.0";
|
||||
rotation = "-1.0 0.0 0.0 90.0";
|
||||
shapeFile = "camera.dts";
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// Decals and Projectiles
|
||||
//==============================================================================
|
||||
// Default Sentinel bullet Decal image:
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
datablock DecalData(SentinelDecal1)
|
||||
{
|
||||
sizeX = 0.15;
|
||||
sizeY = 0.15;
|
||||
textureName = "special/bullethole3";
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// Standard Sentinel Bullet:
|
||||
//==============================================================================
|
||||
|
||||
datablock TracerProjectileData(SentinelBullet)
|
||||
{
|
||||
doDynamicClientHits = true;
|
||||
|
||||
directDamage = 0.15;
|
||||
directDamageType = $DamageType::Sentinel;
|
||||
explosion = "ChaingunExplosion";
|
||||
splash = ChaingunSplash;
|
||||
HeadMultiplier = 1.5;
|
||||
LegsMultiplier = 0.5;
|
||||
|
||||
kickBackStrength = 50.0;
|
||||
sound = ChaingunProjectile;
|
||||
|
||||
dryVelocity = 800.0;
|
||||
wetVelocity = 100.0;
|
||||
velInheritFactor = 1.0;
|
||||
fizzleTimeMS = 3000;
|
||||
lifetimeMS = 3000;
|
||||
explodeOnDeath = false;
|
||||
reflectOnWaterImpactAngle = 0.0;
|
||||
explodeOnWaterImpact = false;
|
||||
deflectionOnWaterImpact = 0.0;
|
||||
fizzleUnderwaterMS = 3000;
|
||||
|
||||
tracerLength = 10.0;
|
||||
tracerAlpha = false;
|
||||
tracerMinPixels = 6;
|
||||
tracerColor = 10.0/255.0 @ " " @ 30.0/255.0 @ " " @ 240.0/255.0 @ " 0.75";
|
||||
tracerTex[0] = "special/tracer00";
|
||||
tracerTex[1] = "special/tracercross";
|
||||
tracerWidth = 0.15;
|
||||
crossSize = 0.20;
|
||||
crossViewAng = 0.990;
|
||||
renderCross = true;
|
||||
|
||||
decalData[0] = SentinelDecal1;
|
||||
|
||||
hasLight = true;
|
||||
lightRadius = 8.0;
|
||||
lightColor = "0.5 0.5 0.175";
|
||||
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// Turret Data
|
||||
//==============================================================================
|
||||
// Standard Sentinel Turret:
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
datablock TurretData(SentinelTurret) : TurretDamageProfile
|
||||
{
|
||||
className = VehicleTurret;
|
||||
catagory = "Turrets";
|
||||
shapeFile = "turret_belly_base.dts";
|
||||
preload = true;
|
||||
|
||||
mass = 1.0;
|
||||
maxDamage = 1.0;
|
||||
destroyedLevel = 1.0;
|
||||
repairRate = 0;
|
||||
maxDamage = SentinelVehicle.maxDamage;
|
||||
destroyedLevel = SentinelVehicle.destroyedLevel;
|
||||
rechargeRate = 0.15;
|
||||
|
||||
thetaMin = 90;
|
||||
thetaMax = 180;
|
||||
thetaNull = 90;
|
||||
|
||||
rechargeRate = 0.15;
|
||||
|
||||
isShielded = false;
|
||||
energyPerDamagePoint = 110;
|
||||
maxEnergy = 60;
|
||||
renderWhenDestroyed = true;
|
||||
barrel = SentinelTurretBarrel;
|
||||
heatSignature = 0;
|
||||
|
||||
canControl = false;
|
||||
cmdCategory = "DTactical";
|
||||
cmdIcon = CMDTurretIcon;
|
||||
cmdMiniIconName = "commander/MiniIcons/com_turret_grey";
|
||||
targetNameTag = 'Sentinel';
|
||||
targetTypeTag = 'Turret';
|
||||
|
||||
firstPersonOnly = true;
|
||||
|
||||
debrisShapeName = "debris_generic_small.dts";
|
||||
debris = TurretDebrisSmall;
|
||||
};
|
||||
|
||||
datablock TurretImageData(SentinelTurretBarrel)
|
||||
{
|
||||
shapeFile = "turret_muzzlepoint.dts";
|
||||
mountPoint = 0;
|
||||
|
||||
projectile = SentinelBullet;
|
||||
projectileType = TracerProjectile;
|
||||
|
||||
usesEnergy = true;
|
||||
fireEnergy = 0.0;
|
||||
minEnergy = 10.0;
|
||||
emap = true;
|
||||
|
||||
activationMS = 700;
|
||||
deactivateDelayMS = 1500;
|
||||
thinkTimeMS = 120;
|
||||
degPerSecTheta = 2000;
|
||||
degPerSecPhi = 2000;
|
||||
attackRadius = 100;
|
||||
|
||||
casing = ShellDebris;
|
||||
shellExitDir = "0.0 -0.5 -0.5";
|
||||
shellExitOffset = "0.0 0.0 0.0";
|
||||
shellExitVariance = 20.0;
|
||||
shellVelocity = 5.0;
|
||||
|
||||
projectileSpread = 2.0 / 1000.0;
|
||||
|
||||
stateName[0] = "Activate";
|
||||
stateTransitionOnNotLoaded[0] = "Dead";
|
||||
stateTransitionOnLoaded[0] = "ActivateReady";
|
||||
|
||||
stateName[1] = "ActivateReady";
|
||||
stateSequence[1] = "Activate";
|
||||
stateSound[1] = SentinelActivateSound;
|
||||
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";
|
||||
stateSequence[3] = "Fire";
|
||||
stateSequenceRandomFlash[3] = true;
|
||||
stateSound[3] = ChaingunFireSound;
|
||||
stateAllowImageChange[3] = false;
|
||||
stateEmitter[3] = "GunFireEffectEmitter";
|
||||
stateEmitterNode[3] = "muzzlepoint1";
|
||||
stateEmitterTime[3] = 0.1;
|
||||
stateScript[3] = "onFire";
|
||||
stateFire[3] = true;
|
||||
stateEjectShell[3] = true;
|
||||
stateTimeoutValue[3] = 0.1;
|
||||
stateTransitionOnTimeout[3] = "Fire";
|
||||
stateTransitionOnTriggerUp[3] = "Reload";
|
||||
stateTransitionOnNoAmmo[3] = "noAmmo";
|
||||
|
||||
stateName[4] = "Reload";
|
||||
stateTimeoutValue[4] = 0.01;
|
||||
stateAllowImageChange[4] = false;
|
||||
stateWaitForTimeout[4] = true;
|
||||
stateSequence[4] = "Reload";
|
||||
stateTransitionOnTimeout[4] = "Ready";
|
||||
stateTransitionOnNotLoaded[4] = "Deactivate";
|
||||
stateTransitionOnNoAmmo[4] = "NoAmmo";
|
||||
|
||||
stateName[5] = "Deactivate";
|
||||
stateSequence[5] = "Activate";
|
||||
stateSound[5] = SentinelDeactivateSound;
|
||||
stateEmitter[5] = "GunFireEffectEmitter";
|
||||
stateEmitterNode[5] = "muzzlepoint1";
|
||||
stateEmitterTime[5] = 0.2;
|
||||
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";
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
// Vehicle Functions
|
||||
//==============================================================================
|
||||
// Sentinel Functions:
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
function SentinelVehicle::deleteAllMounted(%data, %obj) {
|
||||
$HostGamePlayerCount = ClientGroup.GetCount();
|
||||
%turret = %obj.getMountNodeObject(10);
|
||||
if (!%turret)
|
||||
return;
|
||||
|
||||
%turret.altTrigger = 0;
|
||||
%turret.fireTrigger = 0;
|
||||
|
||||
if (%client = %turret.getControllingClient()) {
|
||||
%client.player.setControlObject(%client.player);
|
||||
%client.player.mountImage(%client.player.lastWeapon, $WeaponSlot);
|
||||
%client.player.mountVehicle = false;
|
||||
|
||||
%client.player.bomber = false;
|
||||
%client.player.isBomber = false;
|
||||
}
|
||||
%turret.schedule(0, delete);
|
||||
}
|
||||
|
||||
function SentinelVehicle::onAdd(%this, %obj)
|
||||
{
|
||||
Parent::onAdd(%this, %obj);
|
||||
if (%obj.clientControl)
|
||||
serverCmdResetControlObject(%obj.clientControl);
|
||||
|
||||
%obj.mountImage(BodyImage, 1);
|
||||
%obj.mountImage(RightWing, 2);
|
||||
%obj.mountImage(LeftWing, 3);
|
||||
%obj.mountImage(Eye, 4);
|
||||
|
||||
%turret = TurretData::create(SentinelTurret);
|
||||
%turret.scale = "0.45 0.45 0.45";
|
||||
MissionCleanup.add(%turret);
|
||||
%turret.team = 1;
|
||||
%turret.selectedWeapon = 1;
|
||||
%turret.setSelfPowered();
|
||||
%obj.mountObject(%turret, 10);
|
||||
%turret.mountImage(SentinelTurretBarrel, 0);
|
||||
%obj.turretObject = %turret;
|
||||
%turret.setCapacitorRechargeRate( %turret.getDataBlock().capacitorRechargeRate );
|
||||
%turret.vehicleMounted = %obj;
|
||||
%turret.setAutoFire(true);
|
||||
%turret.mountImage(AIAimingTurretBarrel, 1);
|
||||
|
||||
setTargetSensorGroup(%turret.getTarget(), %turret.team);
|
||||
setTargetNeverVisMask(%turret.getTarget(), 0xffffffff);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// Monitor Functions:
|
||||
//==============================================================================
|
||||
|
||||
function SentinelMonitor::onAdd(%this, %obj)
|
||||
{
|
||||
Parent::onAdd(%this, %obj);
|
||||
if (%obj.clientControl)
|
||||
serverCmdResetControlObject(%obj.clientControl);
|
||||
|
||||
%obj.mountImage(Front, 1);
|
||||
%obj.mountImage(Rear, 2);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue