[T2] Vengeance mod

In our case %obj is the ID of the player object. This exists as long as the player does, after which it is discarded and the number possibly reassigned to something else.

So %obj is the player. %client is the ID of the client which always exists as long as the client is connected to the server.

Easy way to track yourself is to capture your client ID. Do this by issuing a listplayers(); in the console. This will show your client ID. What I do is take this number and attach it to a global varible. $Me = ID; Then to get my player is $me.player; This will return my Player ID. From that you can echo the ropelength etc. echo($Me.player.ropelength);

Local var = %
Global = $

A local is only available in the function it is used in/passed on to. A Global can be accessed by any function at any time, it is never unavailable unless your make it null $Global = "";
 
So how can I get the client number of the shooter via script? MAking an array with the client numbers should be sufficient. (in the worst case I'll just set the values to "" in deconstruct() )
 
If you have either the player object or the client object you can get the other.
%player.client will return the client for the player. (%player is sometimes known as %obj)
%client.player will return the player for the client.
 
Well, here it is. It probably still has some bugs, but under normal circumstances it should work fine. Reeling in too much might cause lockups, other than that it should be allright. Basically it's the same as the previous version, only with a little manual fixing for the stretchiness of the line. Not very elegant, but - hey, this is my first time scripting for T2 :). Well, have fun with it, and I'm sorry I couldn't try out the rocket pod and the buckler yet.

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.client] = %obj.grapplePos;
      %dist = vectorDist(%obj.grapplePos , %obj.getPosition());
      if(%dist > 250)
      {
         %p.delete();
         %obj.lastProjectile = "";
         %obj.grapplePos = "";
         return;
      }
	$ropeLength[%obj.client] = %dist;
	echo("**********" NL "**********" NL $ropeLength[%obj.client]);
      %obj.grappleObject();
      %p.schedule(300, "delete");
   }
}

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

      if(%obj.getState() !$= "Dead")
      {
	%pos = %obj.getWorldBoxCenter();
	%dist = VectorLen(VectorSub(%pos, $GrapplePoint[%obj.client]));
	%vel = %obj.getVelocity();
	%rad = VectorSub($GrapplePoint[%obj.client], %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);
	echo($ropeLength[%obj.client]);
	if (VectorLen(VectorSub(VectorAdd(%pos, %vel), $GrapplePoint[%obj.client])) > $ropeLength[%obj.client]) {
		%radVel = ((%radx * velx) + (%rady * %vely) + (%radz * %velz)) / $ropeLength[%obj.client];
		%mass = %obj.getDataBlock().mass;
		%force = VectorScale(VectorNormalize(%rad), %radVel);

		%newVel = VectorSub(%vel, %force);

		if (mSgn(%radz) == 1) {
			%force = VectorScale("0 0" SPC %radz, 1 / %dist);
			%newVel = VectorAdd(%newVel, %force);
		}
		%obj.SetVelocity(%newVel);

	}


         %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;
      }
	echo("**********" NL $ropeLength[%obj.client]);
      %obj.reelIn();
   }
}

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

      if(%obj.getState() !$= "Dead")
      {
	echo($ropeLength[%obj.client]);
	if ($ropeLength[%obj.client] > 2) $ropeLength[%obj.client] -= $TractorPower;
	%pos = %obj.getWorldBoxCenter();
	%dist = VectorLen(VectorSub(%pos, $GrapplePoint[%obj.client]));
	%vel = %obj.getVelocity();
	%rad = VectorSub($GrapplePoint[%obj.client], %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);
	if (VectorLen(VectorSub(VectorAdd(%pos, %vel), $GrapplePoint[%obj.client])) > $ropeLength[%obj.client]) {
		%radVel = ((%radx * velx) + (%rady * %vely) + (%radz * %velz)) / $ropeLength[%obj.client];
		%mass = %obj.getDataBlock().mass;
		%force = VectorScale(VectorNormalize(%rad), %radVel);

		%newVel = VectorSub(%vel, %force);

		if (mSgn(%radz) == 1) {
			%force = VectorScale("0 0" SPC %radz, 1 / %dist);
			%newVel = VectorAdd(%newVel, %force);
		}
		%newVel = VectorAdd(%newVel, VectorScale(%rad, $TractorPower));
		%obj.SetVelocity(%newVel);

	}


         %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);

}


function mSgn(%value) {

	if (%value == 0) return "0";
	else return %value / mAbs(%value);
}

I did a little swinging around with it on Escalade, seems nice and energetic, Jim should have no problems with it. :D Other than that, please test if multiple people using it at the same time is working properly.

Good night everyone and see you in 8 days!
 
It feels derived from the previous hook. :) It really comes down to whether you expect 'pendulum' swinging or something more energetic. I have no idea what T:V is like. I can see a use for both.

On the 'open' T2 maps, I prefer the version 4 hook with a power of 3. Feels like more of an 'active' mode of transportation to me. But I can see using the new one also. A little more passive. On the big open T2 maps the ability to launch with the v4 hook is usefull. But that may not be an accurate model of the T:V hook.

We need someone who has used the T:V hook to comment.
 
I like the rocket pod actually. I'm sure there will be comments about the laser. I dont mind it.

Edit - Three shots takes out a base turret. (18 rockets I guess)

The buckler surprised me somewhat. Of course, I"m not entirely certain what the buckler does, but isnt it a frisbee - captain america - tron thingy? Sounds nasty to model. (Except for defensive uses).
 
Last edited:
JimBodkins said:
I like the rocket pod actually. I'm sure there will be comments about the laser. I dont mind it.

Edit - Three shots takes out a base turret. (18 rockets I guess)

The buckler surprised me somewhat. Of course, I"m not entirely certain what the buckler does, but isnt it a frisbee - captain america - tron thingy? Sounds nasty to model. (Except for defensive uses).

Well I can dump the laser, it was just easy to do. Ilys used a raycast so I can use that. I am using a raycast for the buckler.

The buckler in T:V relects projectiles away from you when they hit you in the front. I wasn't about to go through the hell of spitting out projectiles that hit the player, so the one in the mod just enables you to take no damage in the front.

In T:V when you fire the buckner it ends up being a guided shield that will return to you at the end of whatever its range is unless it hits something like terrain in which case its gone. Rather then go collision checking in T2 I opted to just have it return at the end of its flight life when it explodes.
It's a little more newbie this way but the amount of code to make it act exactly like in T:V would be retarded.

You can switch weapons and shoot while it is in flight. Sometimes however it won't return, lil bug but I let it go for this release, I allready know what the problem is.
 
can u make the tlaser beam on for the entire time the rope is attached to something? would make things a little easier to keep track of
 
Krytoss said:
can u make the tlaser beam on for the entire time the rope is attached to something? would make things a little easier to keep track of

I think ZOD found that not possible at the time. However, I was wondering if he could use the same tecnique for the rope that he used for the rocket pod laser. Maybe yes, maybe no. :)
 
JimBodkins said:
I think ZOD found that not possible at the time. However, I was wondering if he could use the same tecnique for the rope that he used for the rocket pod laser. Maybe yes, maybe no. :)
I just did a basic text search through beta 5 source code and didn't see any references:
coupleBeam.gif
In the TargetProjectileData datablock for the TL, coupleBeam = 1 is the default value and makes the beam follow the player's aim. coupleBeam = 0 makes it stick to the original target. I'm guessing that's that you would want for a grappling hook.
 
coupleBeam = 0; isn't doing anything :confused:

Also this new hook is kinda meh :ftard:

Other things are progressing nicely however :rainbow:
 
Missile launcher is comming along nicely. ZOD, one slight code change, check that the position from the raycast is not null as that is what is returned when looking at the sky when the check distance is set too high, or change the check distance to something smaller (500 seems to work fine, as most maps do not have a fog distance higher than that).
There also seems to be a bug that doesnt change the object target for all the missiles. One of them still dumb fires.

EDIT: Easy fix.
Code:
   for(%i = 1; %i <= 7; %i++)
   {
      %missile = %obj.lastMissile[%i];
      if(isObject(%missile))
         %missile.setObjectTarget(%obj.misTarget);
   }
 
Last edited:
ilys said:
Missile launcher is comming along nicely. ZOD, one slight code change, check that the position from the raycast is not null as that is what is returned when looking at the sky when the check distance is set too high, or change the check distance to something smaller (500 seems to work fine, as most maps do not have a fog distance higher than that).
There also seems to be a bug that doesnt change the object target for all the missiles. One of them still dumb fires.

Yeah I got a handle on that one stray missile, is all fixed now. Yes pointing at the sky sends the missiles to nullsville so I think to do is set no target if we get a null result :)
 
Is it me, or does the locked target disappear after a short time? It also disappears when you run out of ammo. Makes controling the missiles for more than a short period of time a pain.
 
ilys said:
Is it me, or does the locked target disappear after a short time? It also disappears when you run out of ammo. Makes controling the missiles for more than a short period of time a pain.
It gets removed about 3 seconds after you fire via state script which also kills the searching schedule at the same time.

I took care of the problem, I just leave the target up, its deleted when you switch weapons or die die die!
 
Last edited:
Back
Top