//A7 Acknex Engine v.7.7/////////////////////////////////////////////////////
//Lite_C Language////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//AUM TEMPLATE 3rd person camera //
//Contains; //
//1. Player //
//2. Cameras //
//3. Chest and Key //
//4. NPC on path but moves to intercept player //
//5. Object management //
//6. Attached weapon //
//7. Level change //
//NB = Note Well..11/05/09 Not working yet, still under construction //
//..13/05/09 Working some now, still under construction //
/////////////////////////////////////////////////////////////////////////////
//LICENSE: Free. (This block must not be removed*). //
//CONDITIONS:Must include similar statement to ;Source A7UT_3rdP - Adapted.//
//to ensure full working knowledge base for users //
/////////////////////////////////////////////////////////////////////////////
//PROTOTYPE level for .......... School Project. //
//PURPOSE: Learning medium for a basic working level. //
//BRIEF: 1 level - Airport/Hanger to arbortorium tunnel systems and //
//3 rooms. //
//NPC = Grunts and Boss. //
//End room contains sea dock tunnel. //
//Discription: Player is armed with a mission and must find a way into //
//arbortorium complex.(no clues are given, user must use common sense) //
//Once in, player navigates through complex meeting security personal //
//along the way. //
//Player must neutralise security team to reach boat access area. //
//example scenario ends. //
/////////////////////////////////////////////////////////////////////////////
//-------------------------------------------------------------------------//
//Compiled and Authored by KiwiBoy and Nems referencing AUM scripts as //
//much as possible for code comparison 'tweak' implementation as learning //
//resource. AUM article numbers not included to aid research skills. //
//-------------------------------------------------------------------------//
//-------------------------------------------------------------------------//
//* To use as a base in other projects, copy and paste the code base into a//
// new file and save as or delete this block then save as. //
//CONDITIONS:Must include similar statement to ;Source A7UT_3rdP - Adapted.//
//to ensure full working knowledge base for users //
//-------------------------------------------------------------------------//
//-------------------------------------------------------------------------//
//Foundation = Treat all lines as Algorithyms, all algorithyms as lego //
//blocks then build your code and always refer to the manual //
/////////////////////////////////////////////////////////////////////////////
//CONTRIBUTORS
/////////////////////////////////////////////////////////////////////////////
//EDIT notes //
//(*MW) = Morrowing camera and player code updated to lite-c //
//(*ALC) = Q&A AUM Level change //
//(*AEP) = Q&A AUM Enemy leaves path to confront player //
//(*AOC) = Q&A AUM Open chest //
//(*APB) = Q&A AUM Push Box //
// //
//-------------------------------------------------------------------------//
//Contributors, commenting //
//Format: (insert Source) insert Content [insert Edit author] //
//[GP/AUM] = George Pirvue Aum User Magazine //
//[KB] = KiwiBoy //
//***Add your handle and name here for all edits and place on edit line //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//AUM series author; George Dan Pirvue, Randombytes Software //
//Entire code base used here is sourced exclusively from the AUM series //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//'Base script' is a functional programme geared towards level designers //
//for testing purposes. //
//It should comprise of: //
//1. Game window open :suggests bug free script //
//2. Free camera :view non interactive game world //
//3. Game start :start game mode //
//4. Ingame editor/Debugger :basic is good //
//5. player/camera :interact with game world //
//6. object managers :control test objects //
//7. scene managers :control scenes //
//8. FXs :determine effects on objects - scenes //
//9. NPCs :determine behaviour and weapon effects //
//0. Recorders :record shots, scenes, debug panel etc //
/////////////////////////////////////////////////////////////////////////////
//v.00.001b
//*************************************************************************[KB]
//Code: Base Script||------------------------------------------------------>>
/////////////////////////////////////////////////////////////////////////////
#include <acknex.h>
#include <default.c>
//all added includes need to follow below syntax, " " instead of <>
#include "objctloader.c"
//------------------------------------------------------------------------->>
//vars Global variables set or unset[KB]
var camera_distance = 200; // [set] (*MW)distance from the player to the camera in 3rd person mode[GP/AUM]
var camera_height = 60; // [set] (*MW)distance from the origin of the player to the camera (on the z axis)[GP/AUM]
var distance_traced; // [unset] (*MW)distance that is return by a trace instruction[GP/AUM]
var camera_mode; // [unset] (*MW)starts in 3rd person mode, changes to 1 for first person[GP/AUM]
var stop_player = 0; // [set] (*MW)set it to 1 to stop the player until stop_player is set to 0 again[GP/AUM]
var player_speed = 15; // [set] (*MW)
var got_key = 0; // [set] (*ALC)
var entity_speed = 3; // [set] (*AEP)
var movement_enabled = 0; // [set] (*AEP)
var dist_to_node; // [unset] (*AEP)
var current_node = 1; // [set] (*AEP)
var angle_difference = 0; // [set] (*AEP)
var jumping = 0; // [set]
//-------------------------------------------------------------------------<<
//------------------------------------------------------------------------->>
//VECTORS are variables that uses coordinate systems[KB]
VECTOR temporary_distance;//(*MW)
VECTOR temp_angle;//(*AEP)
VECTOR pos_node; //(*AEP) stores the position of the node[GP/AUM]
//-------------------------------------------------------------------------<<
//------------------------------------------------------------------------->>
//Sound pointer[KB]
SOUND* step_wav = "step.wav";//(*MW)insert your own names between quote marks, e.g. step_wav = "insert_here.wav"[KB]
//-------------------------------------------------------------------------<<
//------------------------------------------------------------------------->>
//STRINGs[KB]
STRING* message_str = "#50"; //(*ALC) this string can store up to 50 characters[GP/AUM]
STRING* prize_mdl = "prize.mdl";
//-------------------------------------------------------------------------<<
//------------------------------------------------------------------------->>
//Bmaps[KB]
BMAP* pointer_tga = "cross.tga";//crosshair[KB]
//-------------------------------------------------------------------------<<
//------------------------------------------------------------------------->>
//Function Prototypes[KB]
function avoid_obstacles();//(*MW)
function first_person_camera();//(*MW)
function third_person_camera();//(*MW)
function move_target();//(*AEP)
function open_chest();//(*AOC)
function spinning_model();//(*AOC)
function player_jumps();
//-------------------------------------------------------------------------<<
//------------------------------------------------------------------------->>
//Entities[KB]
//-------------------------------------------------------------------------<<
//------------------------------------------------------------------------->>
//Definitions defines skill usage and pre-empts the skills exclusively[KB]
#define flare skill4//(*MW)Kept
#define health skill40 //(*MW)use skill40 to store health for the player and its enemies[GP/AUM]kept[KB]
//-------------------------------------------------------------------------<<
//------------------------------------------------------------------------->>
//Panels
//(*ALC)
//------------------------------------------------------------------------->>
TEXT* message_txt =
{
pos_x = 200;
pos_y = 20;
string(message_str);
flags = VISIBLE;
}
//-------------------------------------------------------------------------<<
//------------------------------------------------------------------------->>
//mix n match script[KB]
action players_code() // attach this action to your player[GP/AUM]
{
on_f1 = first_person_camera;//toggles camera mode[GP/AUM]
on_f3 = third_person_camera;
VECTOR temp;//LOCAL VARIABLES[KB]
VECTOR movement_speed; // player's movement speed[GP/AUM]
VECTOR trace_coords;
var anim_percentage; // animation percentage[GP/AUM]
var jump_percentage; // animation percentage for jumping[GP/AUM]
var distance_to_ground; // the distance between player's origin and the ground[GP/AUM]
var jump_height;//LOCAL VARIABLES[KB]
var reached_height;
var time_passed = 0;
var jump = 0;
player = my; // I'm the player[GP/AUM]
set(my, SHADOW);
// set (my, TRANSLUCENT); // the player is transparent[GP/AUM]
// my.alpha = 100; // but opaque if the camera doesn't run into obstacles[GP/AUM]
my.skill41 = camera_height; // and its height[GP/AUM]
my.skill42 = camera_distance; // we store the distance to the camera[GP/AUM]
camera_mode = 3; // the game starts with the camera in 3rd person mode[GP/AUM]
my.health = 100;
while (my.health > 0)
{
while (stop_player == 1) {wait (1);}
player.pan = camera.pan;
camera.x = player.x - camera_distance * cos(player.pan); // keep the camera behind the player[GP/AUM]
camera.y = player.y - camera_distance * sin(player.pan); // at the distance given by camera_distance[GP/AUM]
camera.z = player.z + camera_height + 0.8 * sin(my.skill46 * 3.6); // and above the player[GP/AUM]
camera.pan -= 10 * mouse_force.x * time_step; // the camera has the same pan angle with the player[GP/AUM]
camera.tilt += 7 * mouse_force.y * time_step; // and can tilt freely[GP/AUM]
camera_distance = minv(maxv(camera_distance, 5), 500);
vec_set (temp.x, my.x); // copy player's position to temp[GP/AUM]
temp.z -= 10000; // set temp.z 10000 quants below player's origin[GP/AUM]
distance_to_ground = c_trace (my.x, temp.x, IGNORE_ME | USE_BOX);
movement_speed.x = 10 * (key_w - key_s) * time_step; // move the player using "W" and "S"[GP/AUM]
movement_speed.y = 10 * (key_a - key_d) * time_step; // don't move sideways[GP/AUM]
movement_speed.z = -(distance_to_ground - 15); // 20 = experimental value[GP/AUM]
c_move (my, movement_speed.x, nullvector, IGNORE_PASSABLE | GLIDE); // move the player[GP/AUM]
if (!key_w && !key_s) // the player isn't moving?[GP/AUM]
{
anim_percentage += 4 * time_step; // 2 = "stand" animation speed[GP/AUM]
ent_animate(my, "stand", anim_percentage, ANM_CYCLE);
}
else // the player is moving?[GP/AUM]
{
ent_animate(my, "walk", anim_percentage, ANM_CYCLE); // play the "walk" animation[GP/AUM]
anim_percentage += 8 * time_step; // 5 = "walk" animation speed[GP/AUM]
}
if ((key_w ==1) && (key_r ==1)) // [KB]
{
anim_percentage += 4 * time_step; // 2 = "stand" animation speed[GP/AUM]
ent_animate(my, "run", anim_percentage, ANM_CYCLE);
movement_speed.x += 10 *(c_move (my, movement_speed.x, nullvector, IGNORE_PASSABLE | GLIDE)) *time_step;
}
if (camera_mode == 3) // if we are in 3rd person mode[GP/AUM]
{
avoid_obstacles(); // run the function that avoids camera collisions with the relief[GP/AUM]
}
//JUMP, Not working[KB]
if (key_space && !reached_height)
{
jump = 1;
my.z += 5 * time_step;
jump_height = minv(180, jump_height + 15 * time_step); // 40 sets the height, 5 sets the ascending speed[GP/AUM]
if (jump_height == 180) // reached the maximum height? Then start descending![GP/AUM]
{
reached_height = 1;
jump_height = maxv(0, jump_height - 5 * time_step); // 5 sets the falling speed[GP/AUM]
}
}
else // space isn't pressed anymore?[GP/AUM]
{
jump_height = maxv(0, jump_height - 3 * time_step); // use a smaller falling speed (3) for smaller jumps[GP/AUM]
if (!jump_height && !key_space) // the player has touched the ground?[GP/AUM]
{
reached_height = 0; // then allow it to jump again[GP/AUM]
jump = 0;
}
}
if (!jump_height) // the player isn't jumping?[GP/AUM]
{
if (key_w != 1 && key_s != 1) // the player isn't moving?[GP/AUM]
{
ent_animate(my, "stand", anim_percentage, ANM_CYCLE); // play the "stand" animation[GP/AUM]
}
else // the player is moving?[GP/AUM]
{
ent_animate(my, "walk", anim_percentage, ANM_CYCLE); // play the "walk" animation[GP/AUM]
}
anim_percentage += 5 * time_step; // 5 = animation speed[GP/AUM]
jump_percentage = 0; // always start jumping with the first frame[GP/AUM]
}
if(key_space != 0)
{
jump_percentage += 5 * time_step; // 5 = jump animation speed[GP/AUM]
ent_animate(my, "jump", jump_percentage, ANM_CYCLE); // play the "jump" animation[GP/AUM]
}
wait (1);
}
}
////////////////////////////////////////
function avoid_obstacles()//(*MW)
{
vec_set (temporary_distance.x, camera.x);
temporary_distance.z -= 50; // sets a position closer to the feet of the player; 50 = experimental value[GP/AUM]
distance_traced = c_trace (player.x, temporary_distance.x, IGNORE_ME | IGNORE_PASSABLE); // trace between the player and temporary_distance[GP/AUM]
if (distance_traced == 0) // no obstacles on the way?[GP/AUM]
{
my.alpha = minv(100, my.alpha + 3 * time_step); // then increase player's alpha up to 100[GP/AUM]
if (player.alpha == 100)
{
reset(player, TRANSLUCENT);
}
else
{
set(player, TRANSLUCENT);
}
if (camera_distance < my.skill40) // if the camera got closer to the player[GP/AUM]
{
camera_distance += 1; // restore the initial camera_distance slowly[GP/AUM]
}
}
else // obstacles encountered?[GP/AUM]
{
distance_traced -= 2; // then bring the camera 2 quants closer to the player![GP/AUM]
my.alpha = (distance_traced / (my.skill40 + 1)) * 100; // decrease player's alpha; don't allow a division by zero[GP/AUM]
camera.x = player.x - distance_traced * cos(camera.pan); // place the camera behind the player[GP/AUM]
camera.y = player.y - distance_traced * sin(camera.pan); // at the new distance given by distance_traced[GP/AUM]
}
}
function first_person_camera() //(*MW) press "F1" to run this function[GP/AUM]
{
camera_distance = 0; // place the camera at player's position[GP/AUM]
camera_height = 150; // play with this value[GP/AUM]
set (player, INVISIBLE); // make the player model invisible[GP/AUM]
camera_mode = 1; // set the camera_mode variable to 1st person[GP/AUM]
}
function third_person_camera() // (*MW)press "F3" to run this function[GP/AUM]
{
camera_height = player.skill41; // restore the height[GP/AUM]
camera_distance = player.skill42; // restore the distance from the player to the camera[GP/AUM]
reset (player, INVISIBLE); // and show the player[GP/AUM]
camera_mode = 3; // set the camera_mode variable to 3rd person[GP/AUM]
}
//------------------------------------------------------------------------<<
//------------------------------------------------------------------------>>
//get key to open door and change levels[KB]
action my_key()//(*ALC)
{
set(my, PASSABLE);
while (!player) {wait (1);} // wait until the player is loaded[GP/AUM]
while (vec_dist (player.x, my.x) > 50) // this loop runs until the player picks up the key[GP/AUM]
{
my.pan += 5 * time_step; // 5 gives the rotation speed of the key[GP/AUM]
wait (1);
}
// the player has got the key here[GP/AUM]
got_key = 1; // so let's set the variable named got_key to 1[GP/AUM]
set(my, INVISIBLE);
}
action level_end() //(*ALC)takes the player to the second level if he has got the key first[GP/AUM]
{
while (!player) {wait (1);} // wait until the player is loaded[GP/AUM]
while (1)
{
if (vec_dist(player.x, my.x) < 100) // the player is closer than 100 quants to the exit gate?[GP/AUM]
{
if (got_key) // the player has got the key?[GP/AUM]
{
level_load("level5.wmb"); // then let's load the second level[GP/AUM]
break; // and let's get out of this while loop, no need to run it anymore[GP/AUM]
}
else // the player has come close to the exit gate, but hasn't got the key[GP/AUM]
{
str_cpy(message_str, "You need to pick up the key first. Go and find it!");
}
}
else // the player is away from the exit gate[GP/AUM]
{
str_cpy(message_str, ""); // so let's reset the message[GP/AUM]
}
wait (1);
}
}
//------------------------------------------------------------------------<<
//------------------------------------------------------------------------>>
//(*AEP) Path NPC moves off to intercept player[KB]
function move_target()//(*AEP)
{
while(1)
{
if(movement_enabled)
{
entity_speed = minv(5, entity_speed + 0.5 * time_step);
ent_animate(my, "walk", my.skill46, ANM_CYCLE); // play its "walk" frames animation[GP/AUM]
my.skill46 += 5 * time_step;
my.skill46 %= 100; // loop the animation[[GP/AUM]]
c_move(my, vector(entity_speed * time_step, 0, 0), nullvector, IGNORE_PASSABLE | GLIDE);
vec_to_angle (my.pan, vec_diff (temp_angle, pos_node, my.x));
}
wait(1);
}
}
action my_enemy() //(*AEP) attach this action to your enemy model[GP/AUM]
{
VECTOR temp;
while (!player) {wait (1);}
move_target();
result = path_scan(me, my.x, my.pan, vector(90, 80, 400)); // scan the area looking for the player[GP/AUM]
if (result) {movement_enabled = 1;}
path_getnode (my, 1, pos_node, NULL);
vec_to_angle (my.pan, vec_diff (temp_angle, pos_node, my.x)); // rotate towards the node[GP/AUM]
while(1)
{
if ((c_scan(my.x, my.pan, vector(180, 90, 1000), IGNORE_ME) > 0) && (you == player)) // detected the player?[GP/AUM]
break; // then get out of this loop![GP/AUM]
dist_to_node = vec_dist(my.x, pos_node);
if(dist_to_node < 50) // close to the node?[GP/AUM]
{
current_node = path_nextnode(my, current_node, 1);
if (!current_node) {current_node = 1;} // reached the end of the path? Then start over![GP/AUM]
path_getnode (my, current_node, pos_node, NULL);
}
wait(1);
}
// the enemy has spotted the player here[GP/AUM]
while (1) // so it rotates towards it and starts chasing it[GP/AUM]
{
vec_set(temp, player.x);
vec_sub(temp, my.x);
vec_to_angle(my.pan, temp);
my.tilt = 0;
wait (1);
}
}
//------------------------------------------------------------------------<<
//------------------------------------------------------------------------>>
//(*AOC)[KB]
function spinning_model()
{
var init_z;
init_z = my.z;
set (my, PASSABLE);
while (my.z < init_z + 300) // the prize will move 300 quants upwards[GP/AUM]
{
my.z += 10 * time_step;
my.pan += 8 * time_step;
wait (1);
}
while (my.z > init_z) // and then it will return to its initial height[GP/AUM]
{
my.z -= 7 * time_step;
my.pan += 6 * time_step;
wait (1);
}
while (1)
{
my.pan += 4 * time_step;
if (vec_dist (player.x, my.x) < 30) // the player has come very close to the prize? (play with 30)[GP/AUM]
break; // then get out of the loop[GP/AUM]
wait (1);
}
ent_remove (my); // the prize will disappear (it has been picked up)[GP/AUM]
// increase player's health, score, etc here[GP/AUM]
}
function open_chest()
{
if (!you) return; // didn't collide with an entity? Then don't do anything![GP/AUM]
if (you != player) return; // didn't collide with the player? Then don't do anything[GP/AUM]
my.event = NULL; // don't react to other impacts from now on[GP/AUM]
var anim_percentage = 0;
while (anim_percentage < 100)
{
ent_animate(my, "open", anim_percentage, NULL); // play the "chest opening" animation[GP/AUMG]
anim_percentage += 2 * time_step; // 2 gives the animation speed[GGP/AUM]
wait (1);
}
// the chest is open here, so let's create a reward (a spinning model) inside it[GP/AUM]
ent_create(prize_mdl, my.x, spinning_model);
wait (-1); // wait for a second[GP/AUM]
ent_remove(my); // now remove the chest model, allowing the player to come close to the reward[GP/AUM]
}
action my_chest() // the chest should have a size of 100 quants or so[GP/AUM]
{
set (my, POLYGON);
while (!player) {wait (1);} // make sure that the player exists in the level[GP/AUM]
my.emask |= (ENABLE_IMPACT | ENABLE_ENTITY); // the chest is sensitive to impacts with other entities[GP/AUM]
my.event = open_chest;
}
//------------------------------------------------------------------------<<
//------------------------------------------------------------------------>>
action slider()//door[KB]
{
if((vec_dist(my.x, player.x) > 100)){wait(1);}
if((vec_dist(my.x, your.x) < 100) && (event_type = EVENT_ENTITY))
{
my.y += 1 * time_step;
if(my.y > 100)
{
my.y = 100;
}
}
}
//------------------------------------------------------------------------<<
//------------------------------------------------------------------------>>
////////////////////////////////////////////////////////////////////////////
void main()//Basic main set up. **Can be written in oether ways[KB]
{
var shadow_stencil = 1;//intitialise stencil shadows
var video_screen = 2;//set game screen in windowed mode
vec_set(screen_color,vector(225,0,0));
vec_set(sky_color,vector(225,0,0));//create a background color for fog use
video_switch(9,0,2);//1024x768 window mode
video_window(vector(150,200,0),vector(1024,648,0),48,"Final Run...!");//set window pos and give it a unique title
level_load("FinalRun.wmb");//load the level
wait(3);//Give time to load all elements. increase as neccessary.
camera.clip_far = 5000;//dont show objects beyond this range. Tweak as needed.
camera.clip_near = 0;//Dont clip near objects
move_friction = 0;//gliding requires this
ent_create("cbabe.mdl",vector(-6817.000,-14.000,586.000),players_code);// create the player entity[insert your own names between quote marks "" ""]
// ent_createlayer("scifi1b+6.tga", SKY | CUBE | VISIBLE, 0); // create the sky layer[ditto as above]
fps_max = 100;//limit fps (time variable relies on this setting, 100 = default)
shadow_stencil = 4;//quick sorting for faster fps
enable_polycollision = 1;//needed for OBB (object oriented bounding box)collision detection system
sun_light = 100;
d3d_fogcolor1.red = 8;
d3d_fogcolor1.green = 8;
d3d_fogcolor1.blue = 8;
fog_color = 1;
fog_color = 5;//default fog values, 1 = white, 2 = blue, 3 = red, 4 = black
camera.fog_start = 0.01 * camera.clip_far; //vary to suit level but uses clip_far range
camera.fog_end = 0.6 * camera.clip_far; //so make it dense near the end
sky_clip = 45;
}
/////////////////////////////////////////////////////////////////////////////
//** example from A6[KB]GP/AUM
/* //begin 'block' comment
string GameLevel_1 = "Escape2.wmb";
function fog();
function start_game();
function main()
{
var d3d_mipmapping = 1;
video_switch(7, 16, 2);
fps_max = 60;//stop fps issues with FPS over 100
enable_polycollision = 2;
game_started = 1;
start_game();
}
function start_game()
{
wait(1);
me = null;
level_load (GameLevel_1);
wait (3);
camera.clip_far = 8000;
camera.clip_near = 0;
var d3d_autotransparency=0;
var d3d_entsort = 2;
d3d_alphadepth = 16; // set all TGA alpha images to 16 bit mode
d3d_texdepth = 4; // compress all except TGA based textures
d3d_texdepth = 24; // render PCX and BMP images in 24 bit mode
set_camera();
fog();
}
function fog()
{
while(game_started == 1)
{
bg_color = 5;
d3d_fogcolor1.red = 8;
d3d_fogcolor1.green = 8;
d3d_fogcolor1.blue = 8;
fog_color = 1;
fog_color = 5;//default fog values, 1 = white, 2 = blue, 3 = red, 4 = black
camera.fog_start = 0.02 * camera.clip_far; //vary to suit level but uses clip_far range
camera.fog_end = 0.5 * camera.clip_far; //so make it dense near the end
wait(1);
}
}
*/ //end 'block' comment[KB]
///////////////////////////////////////////////////////////////////////////////
//(AUM Q&A)crosshair[KB]
function mouse_startup()
{
mouse_mode = 1;
mouse_map = pointer_tga;//set to your own file e.g. cross[KB]
while (1)
{
vec_set(mouse_pos, mouse_cursor);
wait(1);
}
}
//////////////////////////////////////////////////////////////////////////////////
//(Wiki)Materials [KB]
MATERIAL* mtl_fixalpha =
{
effect =
"
technique right_alpha1
{
pass p0
{
zWriteEnable=true;
alphaTestEnable=true;
CullMode=CCW;//..............> CCW = see one side, none = see both sides[KB]
}
}
";
}
action alphafix()
{
reset(my, TRANSLUCENT);
my.flare =0;
set(my, OVERLAY);
my.material=mtl_fixalpha;
while(you != NULL)
{
set(my, POLYGON);
}
wait(1);
}
/////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////