[T2] Vengeance mod

I am happy to announce that it works (near) perfectly on the x and y axis!


Now let's see if putting the z axis in there is as easy as I think...
 
I tried the current build locally and I thought it worked so much better than previously, so if you have it working even better then I'm anxious to see it.
 
I hope not, because I'm making the last finishing touches to the script. The swinging works fine (more or less), I only have to implement the same method to reeling in, which is basically just a copy-paste type job. Don't go nowhere, this will just take a few minutes!
 
Well, here it is. During testing it sometimes pulled really weird stuff on me with seemingly no good reason... might have been just because I executed the same script a good number of times all over itself... anyway, I think this is a lot closer to the hook in T:V, although still somewhat buggy (a little too much when swinging below something). All in all, if I get to iron those tiny inconveniences, this will be perfect. but enough babbling, here's the code:

Code:
// We cancel schedules when player switches to another weapon - 
// WeaponImage::onUnmount and DefaultGame::onClientKilled

datablock TargetProjectileData(GrappleBeam)
{
   directDamage = 0.0;
   hasDamageRadius = false;
   indirectDamage = 0.0;
   damageRadius = 0.0;
   velInheritFactor = 1.0;

   maxRifleRange = 250;
   beamColor = "0.1 1.0 0.1";
								
   startBeamWidth = 0.30;
   pulseBeamWidth = 0.20;
   beamFlareAngle = 3.0;
   minFlareSize = 0.0;
   maxFlareSize = 400.0;
   pulseSpeed = 6.0;
   pulseLength  = 0.150;

   textureName[0] = "special/nonlingradient";
   textureName[1] = "special/flare";
   textureName[2] = "special/pulse";
   textureName[3] = "special/expFlare";
   beacon = false;
};

datablock ItemData(GrapplingHook) : TargetingLaser
{
   image = GrapplingHookImage;
   pickUpName = "a grappling hook";
   computeCRC = false;
};

datablock ShapeBaseImageData(GrapplingHookImage) : TargetingLaserImage
{
   item = GrapplingHook;
   projectile = GrappleBeam;
   usesEnergy = true;
   minEnergy = 5;
   cutOffEnergy = 10;

   stateName[3] = "Fire";
   stateEnergyDrain[3] = 3;
   stateFire[3] = true;
   stateAllowImageChange[3] = false;
   stateScript[3] = "onFire";
   stateTransitionOnTriggerUp[3] = "ReelIn";
   stateTransitionOnNoAmmo[3] = "ReelIn";
   stateSound[3] = TargetingLaserPaintSound;
   //stateTimeoutValue[3] = 2.0;
   //stateTransitionOnTimeout[3] = "Deconstruction";

   stateTimeoutValue[5] = 1.5;

   stateName[6] = "ReelIn";
   stateFire[6] = true;
   stateSound[6] = TargetingLaserPaintSound;
   stateAllowImageChange[6] = false;
   stateScript[6] = "onReelIn";
   stateTransitionOnTriggerDown[6] = "Deconstruction";
   //stateTimeoutValue[6] = 2.0;
   //stateTransitionOnTimeout[6] = "Deconstruction";
};

function GrapplingHookImage::onFire(%data, %obj, %slot)
{
   //error("GrapplingHookImage::onFire(" SPC %data.getName() SPC %obj.client.nameBase SPC %slot SPC ")");
   %p = Parent::onFire(%data, %obj, %slot);
   if(isObject(%p))
   {
      %obj.grapplePos = %p.getTargetPoint();
	$GrapplePoint = %obj.grapplePos;
      %dist = vectorDist(%obj.grapplePos , %obj.getPosition());
      if(%dist > 250)
      {
         %p.delete();
         %obj.lastProjectile = "";
         %obj.grapplePos = "";
         return;
      }
	$ropeLength = %dist;
      %obj.grappleObject();
      %p.schedule(300, "delete");
   }
}

function Player::grappleObject(%obj)
{
   if(isObject(%obj))
   {
      if(isEventPending(%obj.grappleSchedule)) 
         cancel(%obj.grappleSchedule);

      if(%obj.getState() !$= "Dead")
      {
        // %obj.setVelocity("0 0 5");
	%pos = %obj.getWorldBoxCenter();
	%dist = VectorLen(VectorSub(%pos, $GrapplePoint));
	%vel = %obj.getVelocity();
	if (VectorLen(VectorAdd(%pos, %vel)) > $RopeLength) {
		//%mass = %obj.getDatablock().mass;
		%rad = VectorSub($GrapplePoint, %pos);
		%radx = getWord(%rad, 0); %velx = getWord(%vel, 0);
		%rady = getWord(%rad, 1); %vely = getWord(%vel, 1);
		%radz = getWord(%rad, 2); %velz = getWord(%vel, 2);
		%radH = mSqrt(%radx * %radx + %rady * %rady);
		%VelH = mSqrt(%velx * %velx + %vely * %vely);
		%VecH = %velx SPC %vely SPC "0";
		%radVel = ((%radx * velx) + (%rady * %vely)) / %radH;
		//%tanVel = mSqrt(%VelH * %velH - %radVel * %radVel);

		%tanDir = VectorCross(%rad, "0 0 10");
		%tanx = getWord(%tanDir, 0); %tany = getWord(%tanDir, 1);
		%tanVel = (%velx * %tanx + %vely * %tany) / VectorLen(%tanDir);
		%tanVec = VectorScale(VectorNormalize(%tanDir), %tanVel);
		%radVec = VectorScale(VectorNormalize(%rad), -%radVel);
		%radVecH = getWord(%radVec, 0) SPC getWord(%radVec, 1) SPC "0";

		if (mSgn(getWord(VectorAdd(%radVecH, %tanVec), 0)) != mSgn(getWord(VectorNormalize(%VecH), 0))
		   && mSgn(getWord(VectorAdd(%radVecH, %tanVec), 1)) != mSgn(getWord(VectorNormalize(%VecH), 1))) {
			%tanVec = VectorScale(%tanVec, -1);
		}
		
		%newVel = VectorScale(VectorNormalize(%tanVec), VectorLen(%tanVel));

		%ZtanDir = VectorCross(%rad, %tanDir);
		if (mSgn(getWord(%ZtanDir, 0)) != mSgn(getWord(%vel, 0))
		    && mSgn(getWord(%ZtanDir, 1)) != mSgn(getWord(%vel, 1)))
			%ZtanDir = VectorScale(%ZtanDir, -1);
		%Ztanx = getWord(%ZtanDir, 0); %Ztany = getWord(%ZtanDir, 1); %Ztanz = getWord(%ZtanDir, 2);
		%ZtanH = mSqrt(%Ztanx * %Ztanx + %Ztany * %Ztany);
		%Zvel = (%velH * %ZtanH + %velz * %Ztanz) / VectorLen(%ZtanDir);
		%newZVec = VectorScale(VectorNormalize(%ZtanDir), %Zvel);

		if (mSgn(%radz) == 1 && mSgn(%velz) == -1)
			%newVel = VectorAdd(%newVel, "0 0 5");
		%newVel = VectorAdd(%newVel, %newZVec);
		%obj.setVelocity(%newVel);
		echo("Applying force:" SPC %force);
	}

         %obj.grappleSchedule = %obj.schedule(250, "grappleObject");
      }
   }
}

function GrapplingHookImage::onReelIn(%data, %obj, %slot)
{
   if(isObject(%obj))
   {
      if(isEventPending(%obj.grappleSchedule)) 
         cancel(%obj.grappleSchedule);

      %dist = vectorDist(%obj.grapplePos , %obj.getPosition());
      if(%dist > 250)
      {
         %data.deconstruct(%obj, %slot);
         return;
      }
      %obj.reelIn();
   }
}

$TractorPower = 3;
function Player::reelIn(%obj)
{
   if(isObject(%obj))
   {
      if(isEventPending(%obj.reelSchedule)) 
         cancel(%obj.reelSchedule);

      if(%obj.getState() !$= "Dead")
      {
         %pos = %obj.getWorldBoxCenter();
	%dist = VectorLen(VectorSub(%pos, $GrapplePoint));
	%vel = %obj.getVelocity();
	if (VectorLen(VectorAdd(%pos, %vel)) > $RopeLength) {
		//%mass = %obj.getDatablock().mass;
		%rad = VectorSub($GrapplePoint, %pos);
		%radx = getWord(%rad, 0); %velx = getWord(%vel, 0);
		%rady = getWord(%rad, 1); %vely = getWord(%vel, 1);
		%radz = getWord(%rad, 2); %velz = getWord(%vel, 2);
		%radH = mSqrt(%radx * %radx + %rady * %rady);
		%VelH = mSqrt(%velx * %velx + %vely * %vely);
		%VecH = %velx SPC %vely SPC "0";
		%radVel = ((%radx * velx) + (%rady * %vely)) / %radH;
		//%tanVel = mSqrt(%VelH * %velH - %radVel * %radVel);

		%tanDir = VectorCross(%rad, "0 0 10");
		%tanx = getWord(%tanDir, 0); %tany = getWord(%tanDir, 1);
		%tanVel = (%velx * %tanx + %vely * %tany) / VectorLen(%tanDir);
		%tanVec = VectorScale(VectorNormalize(%tanDir), %tanVel);
		%radVec = VectorScale(VectorNormalize(%rad), -%radVel);
		%radVecH = getWord(%radVec, 0) SPC getWord(%radVec, 1) SPC "0";

		if (mSgn(getWord(VectorAdd(%radVecH, %tanVec), 0)) != mSgn(getWord(VectorNormalize(%VecH), 0))
		   && mSgn(getWord(VectorAdd(%radVecH, %tanVec), 1)) != mSgn(getWord(VectorNormalize(%VecH), 1))) {
			%tanVec = VectorScale(%tanVec, -1);
		}
		
		%newVel = VectorScale(VectorNormalize(%tanVec), VectorLen(%tanVel));

		%ZtanDir = VectorCross(%rad, %tanDir);
		if (mSgn(getWord(%ZtanDir, 0)) != mSgn(getWord(%vel, 0))
		    && mSgn(getWord(%ZtanDir, 1)) != mSgn(getWord(%vel, 1)))
			%ZtanDir = VectorScale(%ZtanDir, -1);
		%Ztanx = getWord(%ZtanDir, 0); %Ztany = getWord(%ZtanDir, 1); %Ztanz = getWord(%ZtanDir, 2);
		%ZtanH = mSqrt(%Ztanx * %Ztanx + %Ztany * %Ztany);
		%Zvel = (%velH * %ZtanH + %velz * %Ztanz) / VectorLen(%ZtanDir);
		%newZVec = VectorScale(VectorNormalize(%ZtanDir), %Zvel);

		if (mSgn(%radz) == 1 && mSgn(%velz) == -1)
			%newVel = VectorAdd(%newVel, "0 0 5");
		%newVel = VectorAdd(%newVel, %newZVec);
		%newVel = VectorAdd(%newVel, VectorScale(VectorNormalize(%rad), $TractorPower));
		$RopeLength = $RopeLength - $TractorPower;
		%obj.setVelocity(%newVel);
		echo("Applying force:" SPC %force);
	}

         %obj.reelSchedule = %obj.schedule(250, "reelIn");
      }
   }
}

function GrapplingHookImage::deconstruct(%data, %obj, %slot)
{
   if (isObject(%obj.lastProjectile))
   {
      %obj.lastProjectile.delete();
      %obj.lastProjectile = "";
   }
   %obj.grapplePos = "";
   if(isEventPending(%obj.grappleSchedule)) 
      cancel(%obj.grappleSchedule);

   if(isEventPending(%obj.reelSchedule)) 
      cancel(%obj.reelSchedule);

   %obj.use(%obj.prevWeapon);
}


function mSgn(%value) {

	if (%value == 0) return "0";
	else return %value / mAbs(%value);
}
 
Either it doesnt work, or is too slow to be usable or I installed it wrong. (put it in grapplinghook.cs in scripts\weapons). Deleted dso's

I liked the one in ZODs recent beta more I think.
 
Ya, I just added the code to grapplinghook.cs on my server, deleted dso's and restarted.. acting pretty strange.. I'm gonna revert back to the old Grapple (5.30.04) for now.

Maybe serverside grapple is being weird when sending info to client?? Anway.. back to 5.30.04 :)
 
Beta 2 seems better. Hook seems to work. Dont know how realistic it is, but it seems flexible. It can be used slow, fast, for swinging, launching etc.

We need to playtest some things. Everything actually. Turret barrels would be good. I think they will change game play. If for no other reason than to be usefull they will take a player per turret. They arent 'AI'. I found the missle turret to be very usefull. ZOD removed it. That was a mistake. I understand that it can be 'devastating'. But that is only true if it is either used (it is useless mounted without a player controlling it). Plus, it becomes an obvious target. I would like the missle barrel reinstated please.

BTW, I did find base++ at PJ's. Thanks KO.
 
I just discovered a fast exit loop using the hook and speed boost.

I was in the tower on Kata. Exited, looked back at the tower, fired hook at top of tower, accelerated over the top of tower, unhooked and hit speed boost and was at the enemy base so fast it was amazing. :) The hook will change the game as much as skiing IMO.
 
JimBodkins said:
I just discovered a fast exit loop using the hook and speed boost.

I was in the tower on Kata. Exited, looked back at the tower, fired hook at top of tower, accelerated over the top of tower, unhooked and hit speed boost and was at the enemy base so fast it was amazing. :) The hook will change the game as much as skiing IMO.

I'm not sure how similar this grapple is to T:V's, and we need to remember the physics for T:V will probably be vastly different from anything T2's could do.

It was fun however, flying with the grapple, although I'm still no fan of the current gravity.
 
Well, that's true. Although it probably wont happen, I would like to see vengeance mod in T2 more than I would like to see a classic mod in vengeance. I plan on buying the new game, but lots of things that are fun will never make it to T:V. Playing both would be fun I think. I dont think mod Vengeance will ever be T:V. :)
 
I don't know how much more I can do with the hook... debugging it is pretty hard, because it's god damn difficult to compare a heap of vectors... right now I'm thinking of a kind of merged version of the two versions.


And just to clear it up, what we need (and will have in T:V) is something that does not let you out of a sphere, and also transfers your existing speed in the right directions on the surface of that sphere. Basically it's a bitch, but school's slowly coming to an end and I have more and more time. Problem is I won't be here whole next week, but I want to get it working until then, so rest assured that I have the right motivation. :)
 
I noticed in the pack that i download, Alpha 7, that there was no buckler. Is there planned to be one in the beta/gold, or is it just too hard to code since you don't have the source code of t2? Or does not having the source code of t2 matter?
 
Back
Top