//FUNCTION pTurret()
//controls the turret of the tank and the firing mechanism
//stays oriented with the tank's roll and tilt
//points in the direction of the mouse
function pTurret()
{
wait(1); //wait a frame for c_setminmax
c_setminmax(me); //set the bounding box
set(my,FLAG2 | SHADOW | CAST | METAL); //set flags
my.pan = player.pan;
cannonFire(); //call cannonFire() to allow shooting
while(player.health > 0) //while the player is alive
{
my.pan += -20 * mouse_force.x * time_step;
vec_set(my.x,player.x); //keep the turret at the tank's position
my.tilt = player.tilt; //set the tilt to player tilt.
proc_mode = PROC_LATE; //move to the end of the scheduler to smooth out its movement with the body
wait(1); //avoid missing loops.
}
}
action pTank()
{
ANGLE slopeAng;
VECTOR smkSpot;
var engSnd;
var counter;
wait(1); //wait for the first frame for c_setminmax
c_setminmax(me); //set the bounding box
set(my,FLAG2 | SHADOW | CAST | METAL); //set some flags
player = my; //set the point
my.health = 100; //set health to the default 100
my.maxHealth = 100;
my.velocity = 30;
my.damage = 25;
turret = ent_create("tankturret.mdl",my.x,pTurret); //create the turret and give it a pointer
vec_for_min(my.bottom,me); //find the bottom of the tank
engSnd = ent_playloop(my,engine,1000);
kill(); //REMOVE BEFORE PUBLISH
articBlast();
while(my.health > 0) //while the tank is alive
{
my.pan += 10 * (key_a - key_d) * time_step; //turn the tank via [A] and [D]
speed.x = my.velocity * (key_w - key_s) * time_step; //move the tank via [W] and [S]
speed.y = 0; //no side movement
c_trace(my.x,vector(my.x,my.y,-2000),IGNORE_ME | IGNORE_PASSABLE | USE_BOX); //trace to find the ground
my.distDown = my.z + my.bottom - target.z; //find distance to the ground
if(my.distDown > 0) //if in the air
my.g = -30 * time_step; //fall down
else { //else
my.g = 0; //don't fall down (keeps the tank from sliding down slopes)
//vec_to_angle(slopeAng.tilt,normal);
//my.tilt = ang(90 - slopeAng.tilt);
}
var distCovered = c_move(my,speed,vector(0,0,my.g),IGNORE_FLAG2 | IGNORE_PASSABLE | GLIDE); //move, ignoring FLAG2, PASSABLE. glide when hitting blocks
if((distCovered > 0) && (my.distDown < 0)) //if moving and not airborne
{
if(counter <= 0)
{
you = ent_create("tracks.tga",my.x,track);
you.pan = my.pan + 90;
counter = 1.5;
}
else
{
counter -= 1 * time_step;
}
}
else
{
counter = 0;
}
if(((my.health / my.maxHealth) <= 0.25) && (pEffects))
{
vec_for_vertex(smkSpot,my,173);
ent_create("smoke.tga",smkSpot,smoke);
}
wait(1); //avoid endless loops
}
snd_stop(engSnd);
ent_playsound(my,crash,1000);
}
This tank can move up and down hills, turn to shoot at the enemy and lay down a track as if its churning up dirt as it moves. It will also spew smoke if it becomes wounded
What is left: Fix gravity so it doesn't stop falling in mid-air. Replace the model so I can separate the cannon from the turret, allowing me to shoot up and down as well as side to side. Make it sit on a slope at the proper angle.
This is the most recent screen shot of the project. Here you can see the enemy tank is smoking. Tanks smoke if their health is less than 25% of the max. The smoke, in order to keep the game small, does not occur if the tank is not in view and is limited to 150 sprites.
function smoke()
{
VECTOR test;
set(my,PASSABLE | TRANSLUCENT);
my.alpha = 25 + random(25);
reset(my,DECAL);
while(my.alpha > 0)
{
vec_set(test,my.x);
if(vec_to_screen(test,camera) == NULL) break;
my.speedx = random(20) - 10;
my.speedy = random(10) - 5;
my.speedz = 8 * time_step;
c_move(me,vector(my.speedx,my.speedy,0),vector(0,0,my.speedz),IGNORE_PASSABLE);
my.alpha -= 1 * time_step;
wait(1);
}
smokeNum--;
ent_remove(me);
}
The above code is the function of each smoke sprite in the effect. Each one rises up by its z-value but moves at random x and y values. Setting DECAL makes the smoke effect face me at all times. The smoke exists as long as it is in the camera view and as long as its alpha is greater than zero (alpha is a measure of opacity, 0 being completely invisible).
while(thisCodeDoesntWork)
{
smashComputer(); //take out some pent out anger
throwDartsAtBoss(); //take out more anger
sleep(6*60*60); //sleep six hours
}