kung foo man
11th October 2013, 11:11
Just found this old function, don't remember where I initially found it:
orientToNormal( normal )
{
hor_normal = ( normal[ 0 ], normal[ 1 ], 0 );
hor_length = length( hor_normal );
if ( !hor_length )
return( 0, 0, 0 );
hor_dir = vectornormalize( hor_normal );
neg_height = normal[ 2 ] * - 1;
tangent = ( hor_dir[ 0 ] * neg_height, hor_dir[ 1 ] * neg_height, hor_length );
plant_angle = vectortoangles( tangent );
//println("^6hor_normal is ", hor_normal);
//println("^6hor_length is ", hor_length);
//println("^6hor_dir is ", hor_dir);
//println("^6neg_height is ", neg_height);
//println("^6tangent is ", tangent);
//println("^6plant_angle is ", plant_angle);
return plant_angle;
}
Dunno which yaw angle it computes though
serthy
15th October 2013, 18:51
480
i call it TANKTRESS ... :cool:
call on map start before any wait statements:
init()
{
level.killtube = true;
if( level.killtube )
{
level.model_body[0] = "xmodel/furniture_bedmattress1";
level.model_tower[0] = "xmodel/prop_barrel_benzin";
level.model_gun[0] = "xmodel/weapon_30cal";
level.model_track[0] = "xmodel/tag_origin";
level.model_track_scroll[0] = "xmodel/tag_origin";
}
else
{
level.model_body[0] = "xmodel/serthy_tank_a_body";
level.model_tower[0] = "xmodel/serthy_tank_a_tower";
level.model_gun[0] = "xmodel/serthy_tank_a_gun";
level.model_track[0] = "xmodel/serthy_tank_a_track";
level.model_track_scroll[0] = "xmodel/serthy_tank_a_track_scroll";
}
precacheModel( level.model_body[0] );
precacheModel( level.model_tower[0] );
precacheModel( level.model_gun[0] );
precacheModel( level.model_track[0] );
precacheModel( level.model_track_scroll[0] );
if( level.killtube )
{
level.model_body[1] = "xmodel/furniture_bedmattress1";
level.model_tower[1] = "xmodel/prop_barrel_benzin";
level.model_gun[1] = "xmodel/weapon_30cal";
level.model_track[1] = "xmodel/tag_origin";
level.model_track_scroll[1] = "xmodel/tag_origin";
}
else
{
level.model_body[1] = "xmodel/serthy_tank_b_body";
level.model_tower[1] = "xmodel/serthy_tank_b_tower";
level.model_gun[1] = "xmodel/serthy_tank_b_gun";
level.model_track[1] = "xmodel/serthy_tank_b_track";
level.model_track_scroll[1] = "xmodel/serthy_tank_b_track_scroll";
}
precacheModel( level.model_body[1] );
precacheModel( level.model_tower[1] );
precacheModel( level.model_gun[1] );
precacheModel( level.model_track[1] );
precacheModel( level.model_track_scroll[1] );
spawns = getEntArray( "mp_tdm_spawn" , "classname" );
for( i = 0 ; isDefined( spawns ) && i < spawns.size && i < 15 ; i++ )
{
level thread spawnTank( spawns[i].origin );
}
}
spawnTank( pos )
{
wait( 1.0 );
tank = spawn( "script_model" , pos + ( 0 , 0 , 0 ) );
tank.body = spawn( "script_model" , pos + ( 0 , 0 , 0 ) );
tank.tower = spawn( "script_model" , pos + ( 0 , 0 , 0 ) );
tank.gun = spawn( "script_model" , pos + ( 60 , 0 , 80 ) );
if( level.killtube )
tank.gun.origin = pos + ( 10 , 0 , 30 );
tank.typeID = randomInt( 2 );
tank setModel( level.model_track[tank.typeID] );
tank.body setModel( level.model_body[tank.typeID] );
tank.tower setModel( level.model_tower[tank.typeID] );
tank.gun setModel( level.model_gun[tank.typeID] );
tank.gun linkTo( tank.tower );
tank.vehicleType = "tank";
tank.targetname = "vehicle";
tank.speed = 0;
tank.maxSpeed = 30;
tank.minSpeed = -10;
tank.gear = 1;
tank.maxHealth = 200;
tank.health = tank.maxHealth;
tank.anglesF = anglesToForward( tank.angles );
tank.anglesR = anglesToRight( tank.angles );
tank.anglesU = anglesToUp( tank.angles );
tank thread tankTriggerLogic();
tank thread tankLogic();
}
tankTriggerLogic()
{
trigger = spawn( "trigger_radius" , self.origin , 0 , 200 , 200 );
trigger enableLinkTo();
trigger linkTo( self );
self.trigger = trigger;
trigger endon( "death" );
while( isDefined( self ) )
{
trigger waittill( "trigger" , player );
if( !isDefined( player ) || !isPlayer( player ) || !isAlive( player ) || !player useButtonPressed() )
continue;
else if( isDefined( player.vehicle ) || isDefined( self.driver ) || isDefined( player.isBot ) )
continue;
self thread attachPlayer( player );
}
trigger unLink();
trigger notify( "death" );
wait( 0.05 );
if( isDefined( trigger ) )
trigger delete();
}
monitorPlayer()
{
self endon( "disconenct" );
self endon( "exitVehicle" );
self waittill( "killed_player" );
assert( isDefined( self.vehicle ) );
self.vehicle detachPlayer( self );
}
attachPlayer( player )
{
player endon( "disconenct" );
player endon( "killed_player" );
if( !isDefined( self.driver ) )
{
self.driver = player;
player setOrigin( self.origin + ( 0 , 0 , 70 ) );
player linkTo( self );
player disableWeapon();
player.vehicle = self;
player hide();
player setModel( "" );
player setClientCvar( "cg_thirdperson" , 1 );
player setClientCvar( "cg_thirdpersonrange" , 200 );
player setClientCvar( "cg_thirdpersonangle" , 0 );
player thread monitorPlayer();
}
else
{
return iPrintLn( "Tank tried to attach player as driver while having a driver!" );
}
}
detachPlayer( player )
{
player endon( "disconenct" );
wait( 0.05 );
player unlink();
player enableWeapon();
player setClientCvar( "cg_thirdperson" , 0 );
//if( isDefined( player.pers["savedmodel"] ) );
// player loadModel( player.pers["savedmodel"] );
player.vehicle = undefined;
self.driver = undefined;
player notify( "exitVehicle" );
}
checkCollission( trace )
{
if( trace["fraction"] == 1 )
return false;
if( isDefined( trace["entity"] ) )
{
if( isPlayer( trace["entity"] ) )
trace["entity"] suicide();
return false;
}
return true;
}
vectorScale( v , s )
{
return ( v[0] * s , v[1] * s , v[2] * s );
}
tankLogic()
{
self endon( "death" );
self endon( "destroyed" );
speedTreshold = 3;
timeStep = 0.1;
for( i = 0 ; true ; i++ )
{
wait( timeStep / 2 );
self.anglesF = anglesToForward( self.angles );
self.anglesR = anglesToRight( self.angles );
self.anglesU = anglesToUp( self.angles );
self.nextAngles = self.angles;
buttonMelee = false;
buttonAttack = false;
buttonUse = false;
pitch = undefined;
desiredDir = self.angles;
if( !isDefined( self.driver ) )
{
if( self.speed != 0 )
{
if( self.speed > 0 )
self.speed -= 1;
else
self.speed += 1;
}
}
else
{
buttonMelee = self.driver meleeButtonPressed();
buttonAttack = self.driver attackButtonPressed();
buttonUse = self.driver useButtonPressed();
if( buttonMelee )
{
if( buttonUse )
{
if( self.speed > 0 )
{
self.speed -= 6;
if( self.speed < 0 )
self.speed = 0;
}
else
self.speed -= 1;
}
else
{
self.speed += 2;
}
}
else
{
if( self.speed * self.gear < speedTreshold )
self.speed = 0;
else
self.speed -= ( self.gear * 1 );
}
}
if( self.speed > self.maxSpeed )
self.speed = self.maxSpeed;
else if( self.speed < self.minSpeed )
self.speed = self.minSpeed;
self.gear = 1;
if( self.speed < 0 )
self.gear = -1;
if( ( self.speed * self.gear >= speedTreshold ) || buttonAttack && i % 2 == 0 )
{
s = vectorScale( self.anglesR , 60 );
f = vectorScale( self.anglesF , 100 + self.speed );
b = vectorScale( self.anglesF , -70 );
h = ( 0 , 0 , 164 );
flt = bulletTrace( self.origin + f - s + h , self.origin + f - s - h , false , self );
frt = bulletTrace( self.origin + f + s + h , self.origin + f + s - h , false , self );
bt = bulletTrace( self.origin + b + h , self.origin + b - h , false , self );
diff = frt["position"] - flt["position"];
nextPos = flt["position"] + vectorScale( diff , 0.5 ) - vectorScale( self.anglesF , 100 );
playerDir = self.driver getPlayerAngles();
if( buttonAttack )
desiredDir = playerDir;
yaw = desiredDir[1] - self.angles[1];
while( yaw < -180 )
yaw += 360;
while( yaw > 180 )
yaw -= 360;
pitch = vectorToAngles( flt["position"] + vectorScale( diff , 0.5 ) - bt["position"] );
yaw = self.angles[1] + ( yaw * 15 / 180 );
roll = vectorToAngles( diff );
if( ( self.speed * self.gear >= speedTreshold ) || buttonAttack )
{
self.nextAngles = ( pitch[0] , yaw , roll[0] );
self rotateTo( self.nextAngles , timeStep , 0 , 0 );
self.body rotateTo( self.nextAngles , timeStep , 0 , 0 );
self moveTo( nextPos + ( 0 , 0 , 1 ) , timeStep , 0 , 0 );
self.tower moveTo( nextPos + ( 0 , 0 , 1 ) , timeStep , 0 , 0 );
self.body moveTo( nextPos + ( 0 , 0 , 1 ) , timeStep , 0 , 0 );
if( self.model != level.model_track_scroll[self.typeID] )
self setModel( level.model_track_scroll[self.typeID] );
}
}
else
{
if( self.model != level.model_track[self.typeID] )
self setModel( level.model_track[self.typeID] );
}
if( isDefined( self.driver ) )
{
pa = self.driver getPlayerAngles();
pu = anglesToUp( pa );
pr = anglesToRight( pa );
pf = anglesToForward( pa );
ta = self.nextAngles;
tu = anglesToUp( ta );
tr = anglesToRight( ta );
tf = anglesToForward( ta );
sa = self.tower.angles;
su = anglesToUp( sa );
sr = anglesToRight( sa );
sf = anglesToForward( sa );
//project playerdir onto tanks xy plane
//a = vectorToAngles( pf - vectorScale( tu , vectorDot( tu , pf ) ) );
d = vectorDot( tu , pf );
a = sf;
if( d < 0.98 && d > -0.98 )
a = vectorNormalize( pf - vectorScale( tu , d ) );
dbgHeight = 64;
dbgLength = 60;
if( level.killtube )
{
dbgHeight = 0;
dbgLength = 30;
}
line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( a , dbgLength ) , ( 1 , 0 , 1 ) );
line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( pf , dbgLength ) , ( 1 , 1 , 0 ) );
line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( tu , dbgLength ) , ( 0 , 1 , 0 ) );
line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( tf , dbgLength ) , ( 0 , 1 , 0 ) );
line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( tr , dbgLength ) , ( 0 , 1 , 0 ) );
//line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( tf , 0 - dbgLength ) , ( 0 , 1 , 0 ) );
//line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( tr , 0 - dbgLength ) , ( 0 , 1 , 0 ) );
line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( su , dbgLength ) , ( 0 , 0 , 1 ) );
line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( sf , dbgLength ) , ( 0 , 0 , 1 ) );
line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( sr , dbgLength ) , ( 0 , 0 , 1 ) );
//line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( sf , 0 - dbgLength ) , ( 0 , 0 , 1 ) );
//line( self.origin + ( 0 , 0 , dbgHeight ) , self.origin + ( 0 , 0 , dbgHeight ) + vectorScale( sr , 0 - dbgLength ) , ( 0 , 0 , 1 ) );
r = sa[2];
if( vectorDot( tu , su ) < 0.999 )
{
r = vectorToAngles( vectorNormalize( tu - su ) );
r = r[0];
}
while( r < -180 )
r += 360;
while( r > 180 )
r -= 360;
a = vectorToAngles( a );
a = ( a[0] , a[1] , r );
if( i % 2 == 0 )
self.tower rotateTo( a , timeStep , 0 , 0 );
}
}
}
sign( x )
{
if( x < 0 )
return -1;
return 1;
}
vectorcross(a,b)
{
return ( a[1] * b[2] - b[1] * a[2] , a[2] * b[0] - b[2] * a[0] , a[0] * b[1] - b[0] * a[1] );
}
sqrt( x )
{
y = x;
for( z = x / 4 ; abs( z - y ) >= 0.001 ; y = ( ( z + ( x / z ) ) / 2 ) )
{
z = y;
}
return y;
}
abs( x )
{
if( x < 0 )
x = 0 - x;
return x;
}
aTan2( y,x) {
coeff_1 = 3.14159265359 / 4;
coeff_2 = 3 * coeff_1;
abs_y = abs(y);
if (x >= 0 ) {
r = (x - abs_y) / (x + abs_y);
angle = coeff_1 - coeff_1 * r;
} else {
r = (x + abs_y) / (abs_y - x);
angle = coeff_2 - coeff_1 * r;
}
if(y < 0)
angle *= -1;
return angle;
}
Hold [F] for to drive
Hold [F + Melee] to break/ drive backwards
Hold [Attack] to align the Tanktress to the current direction
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.