[/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_DIYING 6
var video_depth = 32; // 32 bit mode
var d3d_lockable = 1;
var horz_res;
var vert_res;
var hero_health;
var hero_ammo;
typedef struct
{
int canfire;
int health;
int ammo;
var count;
int state;
int lin_speed;
int rot_speed;
int anim_speed;
int range;
ENTITY* model;
}entity3d;
entity3d* hero;
entity3d* enemy1;
entity3d* enemy2;
entity3d* enemy3;
STRING* buff = " ";
STRING* work01_wmb = "arabcity.wmb";
void ReloadTime(seconds, entity3d* ent);
void ActionPlayer(entity3d* ent);
void CheckDownward(entity3d* ent, vmin, vmax);
void ActionEnemy(entity3d* ent);
entity3d* LoadEntity(STRING* modelname, VECTOR* position);
void InitPlayer(entity3d* ent);
void target_under_reticle();
/* weapon haircross */
PANEL* PanAim =
{
bmap = "center_red.bmp";
layer = 1;
flags = VISIBLE | OVERLAY;
}
FONT* digits_font = "Arial#32b";
PANEL* PanHealth = // health counter display
{
layer = 5;
digits = 0,450,"Health:%3.0f",digits_font,1,hero_health; // Error if struct element used
flags = TRANSLUCENT,VISIBLE;
}
PANEL* PanAmmo = // ammo counter display
{
layer = 5;
digits = 0,400,"Ammo:%3.0f",digits_font,1,hero_ammo;
flags = TRANSLUCENT,VISIBLE;
}
////////////////////////////////////////////////////////////////////
void main()
{
fps_max = 60;
level_load (work01_wmb);
wait(5);
/* center gun reticle */
PanAim.pos_x = (screen_size.x - bmap_width(PanAim.bmap))/2;
PanAim.pos_y = (screen_size.y - bmap_height(PanAim.bmap))/2;
horz_res = screen_size.x / 2;
vert_res = screen_size.y / 2;
hero = LoadEntity("player.mdl", vector(270,120,20));
InitPlayer(hero);
enemy1 = LoadEntity("gangst1.mdl", vector(300,-300, 25));
enemy2 = LoadEntity("gangst1.mdl", vector(250,-300, 25));
enemy3 = LoadEntity("gangst1.mdl", vector(250,-200, 25));
while(1)
{
ActionPlayer(hero);
ActionEnemy(enemy1);
ActionEnemy(enemy2);
ActionEnemy(enemy3);
wait(1);
}
}
// assign diferent values for the player
void InitPlayer(entity3d* ent)
{
player = ent.model;
ent.model.scale_x = .5;
ent.model.scale_y = .5;
ent.model.scale_z = .5;
set(ent.model, INVISIBLE);
ent.lin_speed = 3;
ent.rot_speed = 2;
ent.health = 100;
ent.range = 250;
ent.ammo = 50;
}
void ReloadTime(seconds, entity3d* ent)
{
static float counter = 0;
counter += .1 * time_step;
if(counter > seconds)
{
counter = 0.0;
ent.canfire = 0;
}
}
void ActionPlayer(entity3d* ent)
{
camera.x = ent.model.x;
camera.y = ent.model.y;
camera.z = ent.model.z + 5;
camera.pan = ent.model.pan;
camera.tilt = ent.model.tilt;
move_mode = USE_BOX;
if( key_w || key_s )
{
// little vertical movement while walking
ent.model.z += .5 * sin(total_ticks * 25) * time_step;
// move
c_move (ent.model, vector(ent.lin_speed * time_step * (key_w - key_s),0,0), nullvector, move_mode);
// restore '0' tilt while walking
if(ent.model.tilt < 1)
ent.model.tilt += .25;
if(ent.model.tilt > 1)
ent.model.tilt -= .25;
}
if(key_a)
ent.model.pan += ent.rot_speed * time_step;
if(key_d)
ent.model.pan -= ent.rot_speed * time_step;
if(key_q)
{
if(ent.model.tilt > 30)
ent.model.tilt = 30;
ent.model.tilt += 1;
}
if(key_z)
{
if(ent.model.tilt < -30)
ent.model.tilt = -30;
ent.model.tilt -= 1;
}
// stay above ground
CheckDownward(ent, 20, 23);
// update panel variables
hero_health = ent.health;
hero_ammo = ent.ammo;
//if (trigger pressed "space bar") && (still have ammo)
if((ent.ammo > 0) && (key_space == 1) && (ent.canfire == 0) )
{
ent.canfire = 1;
target_under_reticle();
ent.ammo -= 1;
}
ReloadTime(2, ent);
}
entity3d* LoadEntity(STRING* modelname, VECTOR* position)
{
// allocate memory for entity
entity3d* ptr = malloc(sizeof(entity3d));
zero(*ptr);
ptr->model = ent_create (modelname, position, NULL);
ptr->model.scale_x = .4;
ptr->model.scale_y = .4;
ptr->model.scale_z = .4;
ptr->state = MODE_WALK;
ptr->lin_speed = 2;
ptr->rot_speed = 2 * sign(random(1) - random(1));
ptr->health = 10;
ptr->range = 150;
ptr->anim_speed = 3;
ptr->ammo = 100;
ptr->canfire = 0;
return ptr;
}
// process bullets hits
void ProcessHits()
{
switch(hit.entity)
{
case hero.model: hero.health -= 1; break;
case enemy1.model: enemy1.health -= 1; break;
case enemy2.model: enemy2.health -= 1; break;
case enemy3.model: enemy3.health -= 1; break;
}
}
void CheckDownward(entity3d* ent, vmin, vmax)
{
proc_kill(4);
var dist;
VECTOR temp;
// check downward
vec_set (temp, ent.model.x);
temp.z = ent.model.z - 15000;
trace_mode = IGNORE_ME + IGNORE_SPRITES + USE_BOX + IGNORE_PASSABLE;
dist = c_trace (ent.model.x, temp,trace_mode);
// stay above ground
if(dist < vmin) { ent.model.z += 1; }
if(dist > vmax) { ent.model.z -= 1; }
if(dist > (vmax + 5)) { ent.model.z -= 3; } // fall faster
if(dist < (vmin - 4)) { ent.model.z += 3; }
}
void ActionEnemy( entity3d* ent )
{
proc_kill(5);
var vmin = 20;
var vmax = 23;
VECTOR temp;
if(!player) return;
if(ent.state == MODE_DEATH)
return;
if( ent.health == 5)
{
ent.state = MODE_DIYING;
ent.health = 0;
ent.count = 17; // set the first 'death' frame
ent.model.frame = ent.count;
}
if (ent.state == MODE_DIYING)
{
if(ent.model.frame < 22) // do 'death' animation once
{
ent.model.frame = ent.count;
ent.count += .25 * time_step;
}
else
{ // slowly disolve
set(ent.model,TRANSLUCENT);
if (ent.model.alpha > 0)
ent.model.alpha -= 1 * time_step;
if (integer(ent.model.alpha) == 0)
{
set(ent.model,PASSABLE);
set(ent.model,INVISIBLE);
ent.state = MODE_DEATH;
}
}
return;
}
if (ent.state == MODE_WALK)
{
ent.count += ent.anim_speed * time_step;
ent_animate(ent.model,"walk", ent.count, ANM_CYCLE);
ent.count %= 100;
trace_mode = IGNORE_ME + IGNORE_SPRITES + USE_BOX + IGNORE_PASSABLE;
c_move (ent.model,vector(ent.lin_speed * time_step,0,0), nullvector,IGNORE_SPRITES + USE_BOX);
if (trace_hit)
ent.model.pan += ent.rot_speed; //vec_to_angle(ent.model.pan,bounce);
}
if (ent.state == MODE_ATTACK)
{
// show my health if i'm near player
vec_set(temp,ent.model.x);
if(vec_dist(ent.model.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
ent.count += ent.anim_speed * time_step;
ent_animate(ent.model,"attack", ent.count, ANM_CYCLE);
ent.count %= 100;
// rotate to the target
vec_set(temp,player.x);
vec_sub(temp,ent.model.x);
vec_to_angle(ent.model.pan,temp);
// fire only at frame 23
if ( (integer(ent.model.frame) == 23) && (ent.canfire == 0) )
{
ent.canfire = 1;
c_trace (ent.model.x, player.x, IGNORE_ME | IGNORE_PASSABLE |IGNORE_SPRITES);
if (trace_hit)
ProcessHits();
}
// ready to fire on next frame '23'
if (ent.model.frame > 25)
ent.canfire = 0;
}
// traced something in range AND is the player
if (vec_dist(ent.model.x, player.x) < ent.range)
{
c_trace (ent.model.x, player.x, IGNORE_ME | IGNORE_PASSABLE |IGNORE_SPRITES);
ent.state = MODE_ATTACK;
}
else
ent.state = MODE_WALK;
CheckDownward(ent, vmin, vmax);
}
///////////////////////////////
//TARGET ENTITY UNDER RETICLE//
///////////////////////////////
void target_under_reticle()
{
VECTOR tmp;
VECTOR temp;
//AUM_21 idea code
temp.x = player.x + 2000 * cos(player.pan);
temp.y = player.y + 2000 * sin(player.pan);
temp.z = player.z + player.tilt;
tmp.x = player.x + 25 * cos(player.pan);
tmp.y = player.y + 25 * sin(player.pan);
tmp.z = player.z;
temp.x = horz_res;
temp.y = vert_res;
temp.z = 20000;
tmp.x = horz_res;
tmp.y = vert_res;
tmp.z = 75;
vec_for_screen (temp, camera);
vec_for_screen (tmp, camera);
//set trace mode
trace_mode = IGNORE_ME + IGNORE_PASSABLE + IGNORE_SPRITES;
//trace from the players position to the target position
c_trace(tmp.x,temp.x, trace_mode);
if (trace_hit)
ProcessHits();
}
[code]