[/code]
#include <acknex.h>
#include <default.c>
//
#define MODE_STAND 0
#define MODE_WALK 1
#define MODE_RUN 2
#define MODE_DEATH 3
#define MODE_ATTACK 4
#define MODE_STOP 5
#define MODE_MARCH 6
#define MODE_STANDBY 7
STRING* buff = " ";
static int NPC_Counter = 0;
typedef struct
{
var health;
var shield;
var count;
var state;
var pathnode;
var lin_speed;
var rot_speed;
var anim_speed;
var vision_range;
var weapon_type;
var weapon;
var weapon_range;
var ammo;
ENTITY* model;
} entity3d;
function act_player(entity3d* ent);
function all_events();
function check_downward(entity3d* ent, vmin, vmax);
function act_enemy(entity3d* ent);
function main()
{
level_load(NULL); // load the game level
entity3d hero;
hero.model = ent_create ("player.mdl", vector(0,0,0), NULL);
act_player(hero);
NPC_Counter++;
entity3d enemy;
enemy.model = ent_create ("player.mdl", vector(40,40,0), NULL);
act_enemy(enemy);
NPC_Counter++;
}
function act_player(entity3d* ent)
{
ent.state = MODE_WALK;
ent.health = 100;
ent.vision_range = 200;
ent.lin_speed = 5;
ent.rot_speed = 1;
ent.model.scale_x = .5;
ent.model.scale_y = .5;
ent.model.scale_z = .5;
ent.model.emask |= (ENABLE_BLOCK | ENABLE_ENTITY | ENABLE_IMPACT);
ent.model.event = all_events;
//set(ent.model, INVISIBLE);
player = my = ent.model;
while(1)
{
camera.x = my.x;
camera.y = my.y;
camera.z = my.z + 5;
camera.pan = my.pan;
camera.tilt = my.tilt;
move_mode = IGNORE_PASSABLE + USE_BOX;
// movement keys 'WASD'
if(key_w == 1)
{
ent_move (vector(5 * time_step,0,0), nullvector);
// little up-down movement while walking
my.z += .5 * sin(total_ticks * 25) * time_step;
// if inclined, get straight while walking
if(my.tilt < 1) my.tilt += .25;
if(my.tilt > 1) my.tilt -= .25;
}
if(key_s == 1)
{
ent_move (vector(-5 * time_step,0,0), nullvector);
if(my.tilt < 1)
my.tilt += .25;
if(my.tilt > 1)
my.tilt -= .25;
}
if(key_a == 1)
my.pan += 3 * time_step;
if(key_d == 1)
my.pan -= 3 * time_step;
if(key_q == 1) // do not allow more than 30 deg inclination
{
if(my.tilt > 30)
my.tilt = 30;
my.tilt += 1;
}
if(key_z == 1) // do not allow more than 30 deg inclination
{
if(my.tilt < -30)
my.tilt = -30;
my.tilt -= 1;
}
check_downward(&ent, 0, 3);
wait(1);
}
}
function check_downward(entity3d* ent, vmin, vmax)
{
proc_kill(4);
var dist_trace;
VECTOR temp;
// check downward
vec_set (temp.x, ent.model.x);
temp.z = ent.model.z - 15000;
trace_mode = IGNORE_ME + IGNORE_SPRITES + USE_BOX + IGNORE_PASSABLE;
dist_trace = trace (ent.model.x, temp.x);
// stay above ground
if(dist_trace < vmin)
ent.model.z += 1;
if(dist_trace > vmax)
ent.model.z -= 1;
if(dist_trace > (vmax + 5))
ent.model.z -= 3;
if(dist_trace < (vmin - 4))
ent.model.z += 3;
}
function act_enemy(entity3d* ent)
{
var percent;
var d1;
var d2;
var vmin = 0;
var vmax = 3;
VECTOR temp;
var dist_trace;
my = ent.model;
my.scale_x = .4;
my.scale_y = .4;
my.scale_z = .4;
while(!player){wait(1);}
ent.state = MODE_WALK;
ent.health = 100;
ent.vision_range = 250;
while(ent.health > 10)
{
d1 = vec_dist(ent.model.x, player.x);
if (ent.state == MODE_WALK)
{
percent += 3 * time_step;
ent_animate(ent.model,"walk", percent, ANM_CYCLE);
percent %= 100;
}
if (ent.state == MODE_ATTACK)
{
vec_set(temp,my.x);
if(vec_dist(me.x, player.x)<1000 && vec_to_screen(temp,camera)!=NULL)
{
str_for_num(buff, ent.health);
draw_text(buff, temp.x, temp.y-20, vector(200,200,200));
}
// perform animation
percent += 3 * time_step;
ent_animate(my,"attack", percent, ANM_CYCLE);
percent %= 100;
// rotate to the target
vec_set(temp,player.x);
vec_sub(temp,my.x);
vec_to_angle(my.pan,temp); // now MY looks at YOU
}
// traced something in range AND is the player
if((c_trace (my.x, player.x, IGNORE_ME | IGNORE_PASSABLE) < ent.vision_range) && (you == player))
{
d2 = vec_dist(my.x,player.x);
//im moving toward the player
if((d2 <= d1) && ( ent.health > 30))
{
ent.state = MODE_ATTACK;
}
}
else
{
ent.state = MODE_WALK;
}
wait(1);
check_downward(&ent, vmin, vmax);
}
}
function all_events()
{
switch (event_type)
{
case EVENT_BLOCK:
return;
case EVENT_ENTITY:
return;
}
}
[code]