action t_rpg_player() // attached to the player
{
VECTOR player_speed;
player = my; // I'm the player
// c_setminmax (me);
my.items = 0;
my.armour = trpg_armour;
my.attack = trpg_attack;
my.life = trpg_life;
my.ambient = trpg_ambient;
my.skill77 = 12345; // set a unique identifier for the player
set (my, FLAG2); // will be used by enemies' c_scan instructions to detect the player
var forward_on, backward_on, right_on, left_on, run_on, anim_percentage, attack_percentage;
var camera_h_speed = 0, camera_v_speed = 0;
VECTOR horizontal_speed, vertical_speed, temp;
vec_set(horizontal_speed.x, nullvector); // initialize this vector
vec_set(vertical_speed.x, nullvector); // initialize this vector
my.emask |= (ENABLE_IMPACT | ENABLE_ENTITY);
my.event = player_was_hit;
if (my.skill1 == 0) // the player has forgotten to set a value for the quest scanning range?
my.skill1 = 200; // then set a default value of 200 quants
if (my.skill2 == 0) // the player has forgotten to set a value for camera offset x?
my.camera_offset_x = 100; // then set a default camera offset x value of 100 quants
if (my.skill3 == 0) // the player has forgotten to set a value for camera offset y?
my.camera_offset_y = 0; // then set a default camera offset y value of 0 quants (that's the default value in the demo)
if (my.skill4 == 0) // the player has forgotten to set a value for camera offset y?
my.camera_offset_z = 75; // then set a default camera offset z value of 75 quants
if (my.skill5 == 0) // the player has forgotten to set a value for player's distance to ground?
my.dist_to_ground = 30; // then set a default value of 30
if (my.skill6 == 0) // the player has forgotten to set a value for player's walk animation speed?
my.skill6 = 0.5; // then set a default value of 0.5
if (my.skill7 == 0) // the player has forgotten to set a value for player's attack animation speed?
my.skill7 = 20; // then set a default value of 20
if (my.skill8 == 0) // the player has forgotten to set a value for player's attack frames? (the attack animation loops from zero to this frame)
my.skill8 = 62; // then set the best value for the guard model (62)
if (my.skill9 == 0) // the player has forgotten to set a value for player's stand animation speed?
my.skill9 = 1; // then set a default value of 1
if (my.skill10 == 0) // the player has forgotten to set a value for player's footstep distance sound?
my.skill10 = 105; // then set a default value of 105
if (my.skill11 == 0) // the player has forgotten to set a value for player's footstep sound volume?
my.skill11 = 20; // then set a default value of 20
if (my.skill12 == 0) // the player has forgotten to set a value for player's death camera z decrease?
my.skill12 = 30; // then set a default value of 30
if (my.skill13 == 0) // the player has forgotten to set a value for player's death camera roll?
my.skill13 = 40; // then set a default value of 40
if (my.skill14 == 0) // the player has forgotten to set a value for player's death animation speed?
my.skill14 = 2; // then set a default value of 2
if (my.skill15 == 0) // the player has forgotten to set a value for player's death animation frames?
my.skill15 = 96; // then set a default value of 96
var i;
for (i = 0; i < 100; i++)
quest_solved[i] = 0; // reset the quest_solved arrary at the beginning of each level
wait (3);
while(player.life > 0)
{
armour_value_pan.flags |= SHOW;
armour_value_pan.scale_x = maxv(0.01, player.armour / 100);
attack_pan.flags |= SHOW;
attack_pan.scale_x = maxv(0.01, player.attack / 100);
life_pan.flags |= SHOW;
life_pan.scale_x = maxv(0.01, player.life / 100);
c_scan(my.x, my.pan, vector(360, 180, my.quest_scan_range), IGNORE_ME | SCAN_ENTS | SCAN_LIMIT); // scan the entities that are going to give the player some quests to do
// key input start
forward_on = 0; // reset all the key values at the beginning of each frame
backward_on = 0;
right_on = 0;
left_on = 0;
run_on = 0;
// set the proper variables if their corresponding keys are pressed
if(key_pressed(key_for_str(key_forward)))
forward_on = 1;
if(key_pressed(key_for_str(key_backward)))
backward_on = 1;
if(key_pressed(key_for_str(key_left)))
left_on = 1;
if(key_pressed(key_for_str(key_right)))
right_on = 1;
if(key_pressed(key_for_str(key_run)))
run_on = 1;
// key input end
// camera code
vec_set (camera.x, vector(-my.skill2, my.skill3, my.skill4));
vec_rotate (camera.x, player.pan);
vec_add (camera.x, player.x);
// accelerate camera's pan and tilt angles depending on mouse_force.x and mouse_force.y in order to create a smooth camera
camera.pan -= accelerate (camera_h_speed, trpg_camera_h * (mouse_force.x), trpg_camera_h_frict);
camera.tilt += accelerate (camera_v_speed, trpg_camera_v * (mouse_force.y), trpg_camera_v_frict);
my.pan = camera.pan;
// camera code end
// player movement start
// player's horizontal speed (forward / backward / sideways) movement uses acceleration and friction as well
horizontal_speed.x = (horizontal_speed.x > 0) * maxv(horizontal_speed.x - time_step * trpg_friction, 0) + (horizontal_speed.x < 0) * minv(horizontal_speed.x + time_step * trpg_friction, 0);
if(forward_on)
{
horizontal_speed.x += time_step * trpg_fwdbk_accel;
horizontal_speed.x = minv(horizontal_speed.x, time_step * trpg_player_speed * (1 + run_on));
}
if(backward_on)
{
horizontal_speed.x -= time_step * trpg_fwdbk_accel;
horizontal_speed.x = maxv(horizontal_speed.x, -(time_step * trpg_player_speed * (1 + run_on)));
}
horizontal_speed.y = (horizontal_speed.y > 0) * maxv(horizontal_speed.y - time_step * trpg_friction, 0) + (horizontal_speed.y < 0) * minv(horizontal_speed.y + time_step * trpg_friction, 0);
if(left_on)
{
horizontal_speed.y += time_step * trpg_side_accel;
horizontal_speed.y = minv(horizontal_speed.y, time_step * trpg_player_speed * (1 + run_on));
}
if(right_on)
{
horizontal_speed.y -= time_step * trpg_side_accel;
horizontal_speed.y = maxv(horizontal_speed.y, -(time_step * trpg_player_speed * (1 + run_on)));
}
// disable the friction, allow smooth gliding along the surfaces
move_friction = 0;
vec_set(temp.x, my.x);
temp.z -= 10000;
my.z -= c_trace(my.x, temp.x, IGNORE_ME | IGNORE_PASSABLE | USE_BOX) - my.dist_to_ground; // place player's feet on the ground - play with 30
if((forward_on) + (backward_on) + (left_on) + (right_on)) // at least one of the movement keys is being pressed?
{
anim_percentage += my.skill6 * (1 + run_on) * trpg_player_speed * time_step;
ent_animate(my, "walk", anim_percentage, ANM_CYCLE); // play the "stand" aka idle animation
}
else
{
if ((mouse_left) && (mouse_mode == 0)) // the player has pressed the left mouse button?
{
attack_percentage += my.skill7 * time_step;
ent_animate(my, "attack", attack_percentage, ANM_CYCLE); // play the "attack" animation
attack_percentage = minv(my.skill8, attack_percentage);
}
else
{
attack_percentage = 0;
anim_percentage += my.skill9 * time_step;
ent_animate(my, "stand", anim_percentage, ANM_CYCLE); // play the "stand" aka idle animation
}
}
// this c_move instruction does all the job, moving the player in the direction given by horizontal_speed (forward, backward, sideways) and vertical_speed (on the z axis)
my.skill80 += c_move (my, horizontal_speed.x , vertical_speed.x, IGNORE_PASSABLE | GLIDE);
if (my.skill80 > my.skill10) // play with this value
{
SND_CREATE_STATIC(rpg_step, step_wav);
snd_play(rpg_step, my.skill11, 0);
my.skill80 = 0;
}
// player movement end
wait(1);
}
reset (life_pan, SHOW);
my.skill80 = 0; // skill40 controls the "death" animation
camera.z -= my.skill12; // bring the camera closer to the floor
camera.roll = my.skill13; // and rotate its view (the player is dead here)
while (my.skill80 < my.skill15) // don't play all the animation frames because the result doesn't always look good
{
ent_animate(my, "death", my.skill80, NULL); // play the "death" animation
my.skill80 += my.skill14 * time_step; // "death" animation speed
wait (1);
}
set (my, PASSABLE); // the corpse will be passable from now on
}