T2-AAConstruction/scripts/weapons/modifiertool.cs
Robert MacGregor 23fed9edb7 Initial commit.
2016-02-22 12:04:31 -05:00

708 lines
23 KiB
PHP
Executable file

//Modifier Tool v001
//Parts by Electricutioner and CaptnPower
//Variables:
$ElecMod::MergeTool::Tolerance = 0.05; //how many meters of tolerance do we give the pieces that we merge.
$ElecMod::MergeTool::Timeout = 2; //how many seconds until a selection times out when using the tool
datablock AudioProfile(chsingleshot)
{
filename = "fx/vehicles/tank_chaingun.wav";
description = AudioDefault3d;
preload = true;
effect = AssaultChaingunFireEffect;
};
//Functions:
function MTMerge(%client, %piece1, %piece2)
{
if (!MTCheckCompatability(%client, %piece1, %piece2))
{
%piece1.setCloaked(false);
%piece2.setCloaked(false);
MTClearClientSelection();
return;
}
%piece1.setCloaked(true);
%piece2.setCloaked(true);
schedule(100, 0, "MTScaleShiftMerge", %piece1, %piece2);
if (isEventPending(%client.mergeschedule))
{
cancel(%client.mergeschedule);
MTClearClientSelection();
}
}
//This function checks if 4 corners of the objects are compatable.
function MTCheckCompatability(%client, %piece1, %piece2)
{
//do the pieces exist?
if (!isObject(%piece1) || !isObject(%piece2))
{
messageClient(%client, 'MsgClient', "\c2MT: A piece appears to be missing.");
return;
}
//check if the owners are the same
if (%piece1.owner != %client || %piece2.owner != %client)
{
//with an exemption of admins
if (!%client.isAdmin)
{
if (%piece1.ownerGUID != %client.guid || %piece2.ownerGUID != %client.guid)
{
messageClient(%client, 'MsgClient', "\c2MT: One or more of those pieces do not belong to you.");
return;
}
}
}
//now we need to determine if at least 4 of the pieces axies match
%pos1[0] = %piece1.getEdge("1 1 -1");
%pos1[1] = %piece1.getEdge("-1 1 -1");
%pos1[2] = %piece1.getEdge("1 -1 -1");
%pos1[3] = %piece1.getEdge("-1 -1 -1");
%pos1[4] = %piece1.getEdge("1 1 1");
%pos1[5] = %piece1.getEdge("-1 1 1");
%pos1[6] = %piece1.getEdge("1 -1 1");
%pos1[7] = %piece1.getEdge("-1 -1 1");
%pos2[0] = %piece2.getEdge("1 1 -1");
%pos2[1] = %piece2.getEdge("-1 1 -1");
%pos2[2] = %piece2.getEdge("1 -1 -1");
%pos2[3] = %piece2.getEdge("-1 -1 -1");
%pos2[4] = %piece2.getEdge("1 1 1");
%pos2[5] = %piece2.getEdge("-1 1 1");
%pos2[6] = %piece2.getEdge("1 -1 1");
%pos2[7] = %piece2.getEdge("-1 -1 1");
//then we compare them to see which ones match
%k = 0;
for (%i = 0; %i < 8; %i++)
{
for (%j = 0; %j < 8; %j++)
{
if ($ElecMod::MergeTool::Tolerance >= vectorDist(%pos1[%i], %pos2[%j]))
{
%k++;
}
}
}
//if less then 4 match, they can't be compatable (if more then 4 match... something odd is going on)
if (%k < 4)
{
if (%k == 0)
messageClient(%client, 'MsgClient', "\c2MT: None of the corners are shared on those objects. Cannot merge.");
else
messageClient(%client, 'MsgClient', "\c2MT: Only " @ %k @ " corners of the required 4 are shared.");
return;
}
//if the check survived that, we continue...
return 1;
}
//this function, after the pieces are confirmed, checks to see which of the 6 sides is in contact, refers to another
//function to find the alter side, determines distance between them to find a new "real" scale, and determines the
//new world box center for the object. Piece 1 is resized and moved, piece 2 is deconstructed.
function MTScaleShiftMerge(%piece1, %piece2)
{
//find which axis is touching for a "this is the side we scale" discovery
//table:
//0: X
//1: -X
//2: Y
//3: -Y
//4: Z
//5: -Z
%p1S[0] = %piece1.getEdge("1 0 0");
%p1S[1] = %piece1.getEdge("-1 0 0");
%p1S[2] = %piece1.getEdge("0 1 0");
%p1S[3] = %piece1.getEdge("0 -1 0");
%p1S[4] = %piece1.getEdge("0 0 1");
%p1S[5] = %piece1.getEdge("0 0 -1");
%p2S[0] = %piece2.getEdge("1 0 0");
%p2S[1] = %piece2.getEdge("-1 0 0");
%p2S[2] = %piece2.getEdge("0 1 0");
%p2S[3] = %piece2.getEdge("0 -1 0");
%p2S[4] = %piece2.getEdge("0 0 1");
%p2S[5] = %piece2.getEdge("0 0 -1");
for (%i = 0; %i < 6; %i++)
{
for (%j = 0; %j < 8; %j++)
{
if ($ElecMod::MergeTool::Tolerance >= vectorDist(%p1S[%i], %p2S[%j]))
{
%side1 = %i;
%side2 = %j;
}
}
}
//echo("Sides:" SPC %i SPC %j);
//at this point %side1/2 will contain one of the numbers in the table above
//we get the non-shared side at this point
%ops1 = MTFindOpSide(%side1);
%ops2 = MTFindOpSide(%side2);
//this variable contains the new axis length that we are scaling on...
%newaxis = VectorDist(%p1S[%ops1], %p2S[%ops2]);
%currsize = %piece1.getRealSize();
if (%side1 == 0 || %side1 == 1)
%axis = "x";
if (%side1 == 2 || %side1 == 3)
%axis = "y";
if (%side1 == 4 || %side1 == 5)
%axis = "z";
//echo("Axis:" SPC %axis);
if (%axis $= "x")
%piece1.setRealSize(%newaxis SPC getWords(%currsize, 1, 2));
if (%axis $= "y")
%piece1.setRealSize(getWord(%currsize, 0) SPC %newaxis SPC getWord(%currsize, 2));
if (%axis $= "z")
%piece1.setRealSize(getWords(%currsize, 0, 1) SPC %newaxis);
if (%axis !$= "x" && %axis !$= "y" && %axis !$= "z")
{
error("MT: A scaling error has occured.");
return;
}
%newpos = VectorScale(VectorAdd(%p1S[%ops1], %p2S[%ops2]), 0.5);
%piece1.SetWorldBoxCenter(%newpos);
%piece1.setCloaked(false);
%piece2.setCloaked(false);
//%piece2.delete(); //deleting is bad
disassemble(0, %piece2.owner, %piece2); //disassemble is cleaner
}
//this function does something very simple, it finds whether a number is even or odd, and then adds or subracts
//and returns the initial input with that modification. I can't imagine where else this could be useful.
function MTFindOpSide(%side)
{
%evencheck = %side / 2;
if (%evencheck == mFloor(%evencheck))
%even = 1;
else
%even = 0;
if (%even)
return (%side + 1);
else
return (%side - 1);
}
//simply clears a client variable... woohoo...
function MTClearClientSelection(%client)
{
%client.mergePiece1 = "";
}
//"weapon" datablocks and such
datablock ItemData(MergeTool)
{
className = Weapon;
catagory = "Spawn Items";
shapeFile = "weapon_sniper.dts";
image = MergeToolImage;
mass = 1;
elasticity = 0.2;
friction = 0.6;
pickupRadius = 2;
pickUpName = "a merge tool";
computeCRC = true;
};
datablock ShapeBaseImageData(MergeToolImage)
{
className = WeaponImage;
shapeFile = "weapon_sniper.dts";
item = MergeTool;
usesEnergy = true;
minEnergy = 0;
stateName[0] = "Activate";
stateTransitionOnTimeout[0] = "ActivateReady";
stateSound[0] = SniperRifleSwitchSound;
stateTimeoutValue[0] = 0.1;
stateSequence[0] = "Activate";
stateName[1] = "ActivateReady";
stateTransitionOnLoaded[1] = "Ready";
stateTransitionOnNoAmmo[1] = "NoAmmo";
stateName[2] = "Ready";
stateTransitionOnNoAmmo[2] = "NoAmmo";
stateTransitionOnTriggerDown[2] = "CheckWet";
stateName[3] = "Fire";
stateTransitionOnTimeout[3] = "Reload";
stateTimeoutValue[3] = 0.2; //reload timeout here
stateFire[3] = true;
stateAllowImageChange[3] = false;
stateSequence[3] = "Fire";
stateScript[3] = "onFire";
stateName[4] = "Reload";
stateTransitionOnTimeout[4] = "Ready";
stateTimeoutValue[4] = 0.1;
stateAllowImageChange[4] = false;
stateName[5] = "CheckWet";
stateTransitionOnWet[5] = "Fire";
stateTransitionOnNotWet[5] = "Fire";
stateName[6] = "NoAmmo";
stateTransitionOnAmmo[6] = "Reload";
stateTransitionOnTriggerDown[6] = "DryFire";
stateSequence[6] = "NoAmmo";
stateName[7] = "DryFire";
stateSound[7] = SniperRifleDryFireSound;
stateTimeoutValue[7] = 0.1;
stateTransitionOnTimeout[7] = "Ready";
};
//modified below for calling of the modes
function MergeToolImage::onFire(%data,%obj,%slot)
{
serverPlay3D(chsingleshot, %obj.getTransform());
%client = %obj.client;
if (%obj.modifierMode==5){
%client.scaler=getword($WeaponSetting["modifier4",%client.player.modifierMode2],0);
messageclient(%client, 'MsgClient', "\c2Modifier Tool [Scaler] set to" SPC %client.scaler);
return;
}
%pos = %obj.getMuzzlePoint($WeaponSlot);
%vec = %obj.getMuzzleVector($WeaponSlot);
%targetpos = VectorAdd(%pos, VectorScale(%vec, 200));
%piece = containerRaycast(%pos, %targetpos, $TypeMasks::StaticShapeObjectType | $TypeMasks::ForceFieldObjectType, %obj);//changed to $allobjmask so it can see ff's
%piece = getWord(%piece, 0);
%dataBlockName = %piece.getDataBlock().getName();
if (
%dataBlockName $= "StationInventory" ||
%dataBlockName $= "GeneratorLarge" ||
%dataBlockName $= "SolarPanel" ||
%dataBlockName $= "SensorMediumPulse" ||
%dataBlockName $= "SensorLargePulse"
)
if (%piece.deployed != true)
return;
if (!isObject(%piece))
return;
if (!%client.isAdmin)
{
if (%piece.owner != %client)
{
messageClient(%client, 'MsgClient', "\c2MT: That piece isn't yours.");
return;
}
}
///here the code for the other cheks
if (%obj.modifierMode==1){
swaping(%piece,%obj,%obj.modifierMode2,0);
return;
}
else if (%obj.modifierMode==2){
swaping(%piece,%obj,%obj.modifierMode2,1);
return;
}
else if (%obj.modifierMode==3){
scaling(%piece,%client);
return;
}
else if (%obj.modifierMode==4){
nudging(%piece,%client);
return;
}
if (!isObject(%client.mergePiece1))
{
%client.mergePiece1 = %piece;
%piece.setCloaked(true);
%piece.schedule(290, "setCloaked", false);
%client.mergeschedule = schedule($ElecMod::MergeTool::Timeout * 1000, 0, "MTClearClientSelection", %client);
}
else
{
if (%piece != %client.mergePiece1)
{
MTMerge(%client, %client.mergePiece1, %piece);
MTClearClientSelection(%client);
}
else
{
messageClient(%client, 'MsgClient', "\c2MT: You cannot merge one piece into itself.");
return;
}
}
}
//to electricutioner make shure you keep this in ur next vertion
//cos your merge tool has becomed the modifier tool
function MergeToolImage::onMount(%this,%obj,%slot)
{
Parent::onMount(%this, %obj, %slot);
%obj.usingmodifier = true;
if (%obj.modifierMode2 $= "")
%obj.modifierMode2 = 0;
if (%obj.modifierMode $= "")
%obj.modifierMode = 0;
%obj.client.setWeaponsHudActive("sniperrifle");
%line = getWords($WeaponSettings2["modifier",%this.modifierMode],1,10);
%obj.mountImage(MergeToolImage, 0);
}
function MergeToolImage::onUnmount(%data, %obj, %slot) {
%obj.usingmodifier = false;
WeaponImage::onUnmount(%data, %obj, %slot);
}
//NUDGING
function nudging(%obj,%client){
%obj.setCloaked(true);
%obj.schedule(150, "setCloaked", false);
%dataBlock = %obj.getDataBlock();
%name = %dataBlock.getname();
%className = %dataBlock.className;
if (%obj.squaresize !$="")
return;
%Transform = %obj.getTransform();
%pos = posFromTransform(%Transform);
%dir = %obj.getForwardVector();
if (%client.player.modifierMode2==2)
%axis=realvec(%obj,"1 0 0");//x
if (%client.player.modifierMode2==3)
%axis=realvec(%obj,"-1 0 0");//-x
if (%client.player.modifierMode2==4)
%axis=realvec(%obj,"0 1 0");//y
if (%client.player.modifierMode2==5)
%axis=realvec(%obj,"0 -1 0");//-y
if (%client.player.modifierMode2==6)
%axis=realvec(%obj,"0 0 1");//z
if (%client.player.modifierMode2==7)
%axis=realvec(%obj,"0 0 -1");//-z
if (%client.scaler$="")//if the scaler dosnt exist
%client.scaler=0.1; //default 0.1
%NewPosition=vectorAdd(%pos,vectorScale(%axis,%client.scaler));
if (%client.player.modifierMode2==0) //up
%NewPosition=VectorAdd(%pos,VectorScale("0 0 1",%client.scaler));
if (%client.player.modifierMode2==1) //down
%NewPosition=VectorAdd(%pos,VectorScale("0 0 -1",%client.scaler));
if (%obj.originalpos $="")
%obj.originalpos=%NewPosition;
%dist=VectorDist(%NewPosition,%obj.originalpos);
if (%dist>8){
messageclient(%client, 'MsgClient', "\c2Piece is too far from original position.");
return;
}
if (%obj.isdoor==1){//only scale door that are fully closed and not moving
if (%obj.canmove == false){
messageclient(%client, 'MsgClient', "\c2You cannot move a door that is already moving.");
return;
}
if(%obj.state !$="closed" && %obj.state !$=""){
messageclient(%client, 'MsgClient', "\c2You can only move fully closed doors.");
return;
}
}
%obj.setTransform(%NewPosition);
//below is to make shure that all atatch parts will folow the main piece
checkAfterRot(%obj);
}
//SCALING
function scaling(%obj,%client){
%dataBlock = %obj.getDataBlock();
%name = %dataBlock.getname();
%className = %dataBlock.className;
if (%obj.squaresize !$="")
return;
%Transform = %obj.getTransform();
if (%client.player.modifierMode2==0 || %client.player.modifierMode2==4)//sets
%axis="1 1 1"; //the
if (%client.player.modifierMode2==1 || %client.player.modifierMode2==5)//right
%axis="1 0 0"; //vector
if (%client.player.modifierMode2==2 || %client.player.modifierMode2==6)//for
%axis="0 1 0"; //scaling
if (%client.player.modifierMode2==3 || %client.player.modifierMode2==7)//
%axis="0 0 1"; //
if (%client.player.modifierMode2>3)//inverts it
%axis=VectorScale(%axis,-1); //if its on a -scale
if (%client.scaler$="")//if the scaler dosnt exist
%client.scaler=0.1; //default 0.1
%multiplier=VectorScale(%axis,%client.scaler);//gets the multiplier
if (%obj.isdoor==1){//only scale door that are fully closed and not moving
if (%obj.canmove == false){
messageclient(%client, 'MsgClient', "\c2You cannot scale a door while it is moving.");
return;
}
if(%obj.state !$="closed" && %obj.state !$=""){
messageclient(%client, 'MsgClient', "\c2You can only scale doors while fully closed.");
return;
}
}
//so spines scale corectly
if (%classname $= "spine" || %classname $= "mspine" || %classname $= "spine2" || %classname $= "floor" || %classname $= "wall" || %classname $= "wwall" || %classname $= "floor" || %classname $= "door") {
%multiplier=VectorScale(%multiplier,"0.125 0.166666 1");
%size=Vectoradd(%obj.getScale(),%multiplier);
if (getword(%size,0)<0.001 || getword(%size,1)<0.001 || getword(%size,2)<0.001){ //just so
messageclient(%client, 'MsgClient', "\c2Piece is too small."); //it dont go
return; //to small
}
if (getword(%size,0)>100 || getword(%size,1)>100 || getword(%size,2)>100){ //just so
messageclient(%client, 'MsgClient', "\c2Piece is too big."); //it dont go
return; //to big
}
%obj.setScale(%size);
return;
}
//so if you hit a target its the decorations that scales
if (%name $="DeployedLTarget"){
%size=vectoradd(%obj.lMain.getScale(),%multiplier);
if (getword(%size,0)<0.001 || getword(%size,1)<0.001 || getword(%size,2)<0.001){
messageclient(%client, 'MsgClient', "\c2Piece is too small.");
return;
}
if (getword(%size,0)>100 || getword(%size,1)>100 || getword(%size,2)>100){ //just so
messageclient(%client, 'MsgClient', "\c2Piece is too big."); //it dont go
return; //to big
}
%obj.lMain.setScale(%size);
adjustLMain(%obj);
return;
}
//so both the logo and the projector scales at once
if (%name $="DeployedLogoProjector"){
%size=vectoradd(%obj.getScale(),%multiplier);
if (getword(%size,0)<0.01 || getword(%size,1)<0.01 || getword(%size,2)<0.01){//smaller then that
messageclient(%client, 'MsgClient', "\c2Piece is too small."); //and its to small to deconstruct
return;
}
if (getword(%size,0)>100 || getword(%size,1)>100 || getword(%size,2)>100){ //just so
messageclient(%client, 'MsgClient', "\c2Piece is too big."); //it dont go
return; //to big
}
%obj.setScale(%size);
if (%obj.holo !=""){
if (isobject(%obj.holo)){
%obj.holo.setScale(%size);
adjustHolo(%obj);
}
}
return;
}
%size=vectoradd(%obj.getScale(),%multiplier);
if (getword(%size,0)<0.001 || getword(%size,1)<0.001 || getword(%size,2)<0.001){
messageclient(%client, 'MsgClient', "\c2Piece is too small.");
return;
}
if (getword(%size,0)>100 || getword(%size,1)>100 || getword(%size,2)>100){ //just so
messageclient(%client, 'MsgClient', "\c2Piece is too big."); //it dont go
return; //to big
}
%obj.setScale(%size);
}
//SWAPPING
function swaping(%hitobj,%plyr,%mode,%mode2){
%sender=%plyr.client;
if ( %hitobj.ownerGUID != %sender.guid){
if (!%sender.isadmin && !%sender.issuperadmin){
if (%hitobj.ownerGUID !$=""){
messageclient(%sender, 'MsgClient', '\c2You do not own this.');
return;
}
}
}
if (%hitobj.squaresize !$="")
return;
%classname= %hitobj.getDataBlock().classname;
%objscale = %hitobj.scale;
%grounded = %hitobj.grounded;
%pwrfreq = %hitobj.powerFreq;
%Transform = %hitobj.getTransform();
//////////////
//forcefeild//
//////////////
if (%classname$="forcefield" && %mode2==1){
%db="DeployedForceField"@%mode;
%deplObj = new ("ForceFieldBare")() {
dataBlock = %db;
scale = %objscale;
};
%deplObj.setTransform(%Transform);
if (%hitobj.noSlow == true){
%deplObj.noSlow = true;
%deplObj.pzone.delete();
%deplObj.pzone = "";
}
if (%hitobj.pzone !$= "")
%hitobj.pzone.delete();
%hitobj.delete();
// misc info
addDSurface(%item.surface,%deplObj);
// [[Settings]]:
%deplObj.grounded = %grounded;
%deplObj.needsFit = 1;
// [[Normal Stuff]]:
// set team, owner, and handle
%deplObj.team = %plyr.client.team;
%deplObj.setOwner(%plyr);
// set power frequency
%deplObj.powerFreq = %pwrfreq;
// set the sensor group if it needs one
if (%deplObj.getTarget() != -1)
setTargetSensorGroup(%deplObj.getTarget(), %plyr.client.team);
// place the deployable in the MissionCleanup/Deployables group (AI reasons)
addToDeployGroup(%deplObj);
//let the AI know as well...
AIDeployObject(%plyr.client, %deplObj);
// increment the team count for this deployed object
$TeamDeployedCount[%plyr.team, %item.item]++;
// Power object
checkPowerObject(%deplObj);
return %deplObj;
}
///////////%objscale = %hitobj.scale;
//pads //%oldpos = %hitobj.position;
///////////%oldrot = %hitobj.rotation;
else if (%mode2==0 && ((%classname $= "decoration" && %hitobj.getDataBlock().getname() $="DeployedDecoration6") || %classname $= "crate" || %classname $= "floor" || %classname $= "spine" || %classname $= "mspine" || %classname $= "wall" || %classname $= "wwall" || %classname $= "Wspine" || %classname $= "Sspine" || %classname $= "floor" || %classname $= "door"))
{
%hitobj.setCloaked(true);
%hitobj.schedule(290, "setCloaked", false);
if (%hitobj.isdoor == 1 || %hitobj.getdatablock().getname() $="DeployedTdoor"){
if (%hitobj.canmove == false) //if it cant move
return;
if (%hitobj.state !$="closed" && %hitobj.state !$="")
return;
}
if (%hitobj.isobjective > 0)
return;
%db = getword($WeaponSetting["modifier1",%mode],0);
%count = $WeaponSettings["modifier1"]; //counts
if (%hitobj.getdatablock().getname() $="DeployedFloor")
%datablock="DeployedwWall";
else if (%hitobj.getdatablock().getname() $="DeployedMSpinering")
%datablock="DeployedMSpine";
else if (%hitobj.getdatablock().getname() $="DeployedTdoor"){
%datablock="DeployedMSpine";
}
else
%datablock=%hitobj.getdatablock().getname();
%team = %hitobj.team;
%owner = %hitobj.owner;
if (%hitobj.ownerGUID>0)
%ownerGUID = %hitobj.ownerGUID;
else
%ownerGUID = "";
if (%hitobj.isdoor == 1 || %hitobj.getdatablock().getname() $="DeployedTdoor"){
%issliding = %hitobj.issliding;
%state = %hitobj.state;
%canmove = %hitobj.canmove;
%closedscale = %hitobj.closedscale;
%openedscale = %hitobj.openedscale;
%oldscale = %hitobj.oldscale;
%moving = %hitobj.moving;
%toggletype = %hitobj.toggletype;
%powercontrol = %hitobj.powercontrol;
%Collision = %hitobj.Collision;
%lv = %hitobj.lv;
}
%scale = %hitobj.GetRealSize();
%deplObj = new ("StaticShape")() {
dataBlock = %db;
};
%deplObj.SetRealSize(%scale);
%deplObj.setTransform(%Transform);
//////////////////////////Apply settings//////////////////////////////
// misc info
addDSurface(%item.surface,%deplObj);
// [[Settings]]:
%deplObj.grounded = %grounded;
%deplObj.needsFit = 1;
// set team, owner, and handle
%deplObj.team = %team;
%deplObj.Ownerguid=%ownerGUID;
%deplObj.Owner=%owner;
// set power frequency
%deplObj.powerFreq = %pwrfreq;
%deplObj.OriginalPos = %hitobj.OriginalPos;
// set the sensor group if it needs one
if (%deplObj.getTarget() != -1)
setTargetSensorGroup(%deplObj.getTarget(), %plyr.client.team);
// place the deployable in the MissionCleanup/Deployables group (AI reasons)
addToDeployGroup(%deplObj);
//let the AI know as well...
AIDeployObject(%plyr.client, %deplObj);
// increment the team count for this deployed object
$TeamDeployedCount[%plyr.team, %item.item]++;
%deplObj.deploy();
// Power object
checkPowerObject(%deplObj);
if (%hitobj.isdoor == 1 || %hitobj.getdatablock().getname() $="DeployedTdoor"){
%deplObj.closedscale = %deplObj.getScale();
%deplObj.openedscale = getwords(%deplObj.getScale(),0,1) SPC 0.1;
%deplObj.isdoor = 1;
%deplObj.state = %state ;
%deplObj.canmove = %canmove ;
%deplObj.moving = %moving ;
%deplObj.toggletype = %toggletype ;
%deplObj.powercontrol = %powercontrol;
%deplObj.Collision = %Collision ;
%deplObj.lv = %lv ;
}
%hitobj.delete();
return %deplObj;
}
}