////////////////////////////////////////////////////////////////////
#include <acknex.h>
#include <default.c>
/////////////////////////////////////////////////////////////////////////////////////////////
VECTOR shot_time; // stores the power of the shot
var club_angle = 0; // stores the tilt angle for the club
var level_number = 1;
var number_of_shots = 0; // number of shots per level, used to compute the score per hole
var total_score = 0; // stores the score that is displayed on the screen
VECTOR pos1 = 0; // the 2 vars check if the speed of the ball goes below a certain limit
VECTOR pos2 = 0; // and stop it completely if it goes below that limit
/////////////////////////////////////////////////////////////////////////////////////////////
STRING* level1_wmb = "level1.wmb";
/////////////////////////////////////////////////////////////////////////////////////////////
SOUND* ball_wav = "ball.wav";
SOUND* scored_wav = "scored.wav";
SOUND* applause_wav = "applause.wav";
/////////////////////////////////////////////////////////////////////////////////////////////
ENTITY* ball;
ENTITY* club;
/////////////////////////////////////////////////////////////////////////////////////////////
FONT* eurostarbold_FONT = "eurostarbold.tga#22";
/////////////////////////////////////////////////////////////////////////////////////////////
ENTITY* my_cube =
{
type = "skycube+6.tga";
layer = 5;
flags2 = SKY|CUBE|VISIBLE;
}
/////////////////////////////////////////////////////////////////////////////////////////////
PANEL* shot_pan =
{
BMAP = "bar.pcx";
pos_x = 0;
pos_y = 590;
layer = 10;
flags = OVERLAY | VISIBLE;
}
PANEL* hudleft_pan =
{
BMAP = "left.tga";
pos_x = 0;
pos_y = 0;
layer = 10;
digits (50, 30, 1, eurostarbold_font, 1, level_number);
flags = OVERLAY | VISIBLE;
}
PANEL* hudright_pan =
{
BMAP = "right.tga";
pos_x = 674;
pos_y = 0;
layer = 10;
digits (30, 30, 3, eurostarbold_font, 1, total_score);
flags = OVERLAY | VISIBLE;
}
PANEL* congratulations_pan =
{
BMAP = "congratulations.pcx";
pos_x = 144;
pos_y = 200;
layer = 10;
}
/////////////////////////////////////////////////////////////////////////////////////////////
// Prototypes
function move_club();
function kick_ball();
function move_club();
function golf_startup();
function restart_hole();
/////////////////////////////////////////////////////////////////////////////////////////////
function main()
{
video_mode = 7; // 800x600 pixels
video_depth = 32; // 32 bit mode
video_screen = 1; // start in full screen mode
wait(2);
camera.arc -= 5;
level_load (level1_wmb);
wait (3);
ball = ent_create ("ball.mdl", vector(0, 0, -390), NULL); // create the ball and place it at the start of the first course / hole
wait(1);
ph_setgravity (vector(0, 0, -386)); // set the gravity
phent_settype (ball, PH_RIGID, PH_SPHERE); // set the physics ENTITY type
phent_setmass (ball, 2, PH_SPHERE); // and its mass
phent_setfriction (ball, 60); // set the friction
phent_setdamping (ball, 25, 30); // set the damping
phent_setelasticity (ball, 85, 90); // set the elasticity
club = ent_create ("club.wmb", nullvector, move_club); // create the club (use a better looking mdl file here)
wait(1);
while (1)
{
camera.x = ball.x - 700; // keep the camera 700 quants behind the ball at all times
camera.y = ball.y;
camera.z = ball.z + 500; // and 500 quants above it
camera.tilt = -25; // make the camera look down at the ball
wait (1);
}
}
function kick_ball() // moves the ball when the player presses the left mouse button
{
if (is(club,INVISIBLE)) {return;} // don't hit the ball if the club is INVISIBLE
while ((mouse_left) && (shot_time.x < 1000)) // wait until the player releases the mouse button or the shot power has reached its max
{
shot_time.x += 50 * time_step; // increase the power of the shot
club.tilt = -shot_time.x / 20; // and tilt the club backwards accordingly
wait (1);
}
while (mouse_left) // wait until the player releases the left mouse button
{
if (shot_time.x >= 1000) // a max power shot is on its way?
{
club.tilt = -shot_time.x / 20; // then keep the club in its proper position!
}
wait (1);
}
number_of_shots += 1; // increase the number of shots
shot_time.y = 0;
shot_time.z = 0;
vec_rotate (shot_time, club.pan); // rotate shot_time in the direction pointer by the club
phent_addvelcentral (ball, shot_time); // and add a linear velocity to the ball
snd_play (ball_wav, 100, 0); // play the ball impact sound
vec_zero(shot_time); // and then reset the shot power
}
function move_club()
{
var temp;
set(my,PASSABLE); // the club is made PASSABLE
while (1)
{
club_angle += 3 * (mouse_force.x - mouse_force.y); // and changes its angle according to the movement of the mouse
my.x = ball.x - 30 * sin(club_angle); // the distance between the club and the ball is kept at 30 quants at all times
my.y = ball.y + 30 * cos(club_angle); // use the same value here
my.z = ball.z + 175; // the club is placed 175 quants above the ball; examine the club ENTITY in Wed to see why
vec_set(temp, ball.x); // keep the club rotated towards the ball at all times
vec_sub(temp, my.x);
vec_to_angle(my.pan, temp);
my.tilt = 0; // but don't alter its tilt
wait (1);
}
}
function restart_hole()
{
phent_settype (ball, 0, PH_SPHERE); // disable the physics for this ball for a bit
if (level_number == 1) // the player is playing the first level?
{
vec_set (ball.x, vector (0, 0, -390)); // then move on at the beginning of the first hole
}
if (level_number == 2) // the player is playing the second level?
{
vec_set (ball.x, vector (1070, 620, -390)); // then move on at the beginning of the second hole
}
if (level_number == 3) // the player is playing the third level?
{
vec_set (ball.x, vector (1800, -680, -390)); // then move on at the beginning of the third hole
}
wait (1);
phent_settype (ball, PH_RIGID, PH_SPHERE); // now register the physics ENTITY again
}
function golf_startup()
{
on_mouse_left = kick_ball; // press the left mouse button to strike the ball
on_r = restart_hole; // press the "R" key to restart the current level
while ((!ball) || (!club)) {wait (1);} // wait until the ball and the club are loaded
while (1)
{
shot_pan.scale_x = maxv(0.001, shot_time.x * 0.55); // increase the scale of the red bar depending on the power of the shot
vec_set (pos1.x, ball.x); // store the initial position of the ball
wait (1);
vec_set (pos2.x, ball.x); // and store it again after a frame
if (vec_dist (pos2.x, pos1.x) < 0.04) // if the ball has moved more than 0.2 quants during the frame
{
if (is(club,INVISIBLE)) // if the club is INVISIBLE
{
phent_clearvelocity (ball); // stop the ball (it is moving too slow and is boring to watch)
reset(club,INVISIBLE); // and then make the club VISIBLE, so that we can strike the ball again
}
}
else // the ball is still moving quite fast?
{
set(club,INVISIBLE); // then hide the club - don't allow the player to strike the ball
}
if (ball.z < -420) // the ball has fallen into a hole?
{
set(club,INVISIBLE); // then hide the club
snd_play (scored_wav, 100, 0);
wait (-1);
snd_play (applause_wav, 100, 0);
wait (-2);
total_score += maxv (10, (50 - 10 * number_of_shots)); // compute the score based on the number of strikes
if (level_number == 3) // game over?
{
wait (-3); // allow the player to see the total score
set(congratulations_pan,VISIBLE); // show the "congratulations" panel
while (!key_any) {wait (1);} // wait until the player presses a key
sys_exit(NULL); // and then shut down the engine
}
if (level_number == 2) // finished the second level?
{
level_number += 1; // then increase the level counter
phent_settype (ball, 0, PH_SPHERE); // disable the physics for this ball for a bit
vec_set (ball.x, vector (1800, -680, -390)); // so that we can move it to the third hole
wait (3);
phent_settype (ball, PH_RIGID, PH_SPHERE); // register the physics ENTITY again
phent_setmass (ball, 2, PH_SPHERE); // and its mass
phent_setfriction (ball, 60); // set the friction
phent_setdamping (ball, 25, 30); // set the damping
phent_setelasticity (ball, 85, 90); // set the elasticity
}
if (level_number == 1) // finished the first level?
{
level_number += 1; // then increase the level counter
phent_settype (ball, 0, PH_SPHERE); // disable the physics for this ball for a bit
vec_set (ball.x, vector (1070, 620, -390)); // so that we can move it to the second hole
wait (3);
phent_settype (ball, PH_RIGID, PH_SPHERE); // register the physics ENTITY again
phent_setmass (ball, 2, PH_SPHERE); // and its mass
phent_setfriction (ball, 60); // set the friction
phent_setdamping (ball, 25, 30); // set the damping
phent_setelasticity (ball, 85, 90); // set the elasticity
}
number_of_shots = 0; // a new hole starts, so we clear the number of shots
}
}
}